@bloom-housing/ui-components 5.1.1-alpha.19 → 5.1.1-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/package.json +2 -2
- package/src/blocks/HousingCounselor.tsx +8 -3
- package/src/blocks/ImageCard.tsx +9 -2
- package/src/blocks/StatusItem.tsx +17 -6
- package/src/forms/DOBField.tsx +16 -7
- package/src/forms/DateField.tsx +16 -7
- package/src/forms/Dropzone.tsx +12 -3
- package/src/forms/FieldGroup.tsx +13 -2
- package/src/forms/HouseholdMemberForm.tsx +4 -1
- package/src/forms/HouseholdSizeField.tsx +15 -5
- package/src/forms/TimeField.tsx +15 -6
- package/src/headers/Hero.tsx +8 -1
- package/src/headers/SiteHeader.tsx +11 -4
- package/src/helpers/formOptions.tsx +4 -1
- package/src/helpers/formatYesNoLabel.ts +8 -6
- package/src/navigation/ProgressNav.tsx +21 -3
- package/src/notifications/AlertBox.docs.mdx +41 -0
- package/src/notifications/AlertBox.scss +63 -41
- package/src/notifications/AlertBox.tsx +13 -9
- package/src/notifications/StatusMessage.tsx +8 -2
- package/src/notifications/alertTypes.ts +1 -0
- package/src/page_components/ApplicationTimeline.tsx +14 -4
- package/src/page_components/listing/listing_sidebar/GetApplication.tsx +31 -16
- package/src/page_components/listing/listing_sidebar/ListingUpdated.tsx +5 -1
- package/src/page_components/listing/listing_sidebar/OrDivider.tsx +4 -2
- package/src/page_components/listing/listing_sidebar/ReferralApplication.tsx +7 -4
- package/src/page_components/listing/listing_sidebar/events/DownloadLotteryResults.tsx +6 -1
- package/src/tables/AgTable.tsx +10 -3
- package/src/tables/StandardTable.tsx +13 -5
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,22 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [5.1.1-alpha.21](https://github.com/bloom-housing/bloom/compare/@bloom-housing/ui-components@5.1.1-alpha.20...@bloom-housing/ui-components@5.1.1-alpha.21) (2022-08-31)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @bloom-housing/ui-components
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [5.1.1-alpha.20](https://github.com/bloom-housing/bloom/compare/@bloom-housing/ui-components@5.1.1-alpha.19...@bloom-housing/ui-components@5.1.1-alpha.20) (2022-08-31)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @bloom-housing/ui-components
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
6
22
|
## [5.1.1-alpha.19](https://github.com/bloom-housing/bloom/compare/@bloom-housing/ui-components@5.1.1-alpha.18...@bloom-housing/ui-components@5.1.1-alpha.19) (2022-08-31)
|
|
7
23
|
|
|
8
24
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bloom-housing/ui-components",
|
|
3
|
-
"version": "5.1.1-alpha.
|
|
3
|
+
"version": "5.1.1-alpha.21",
|
|
4
4
|
"author": "Sean Albert <sean.albert@exygy.com>",
|
|
5
5
|
"description": "Shared user interface components for Bloom affordable housing system",
|
|
6
6
|
"homepage": "https://github.com/bloom-housing/bloom/tree/master/shared/ui-components",
|
|
@@ -110,5 +110,5 @@
|
|
|
110
110
|
"ts-jest": "^26.4.1",
|
|
111
111
|
"typesafe-actions": "^5.1.0"
|
|
112
112
|
},
|
|
113
|
-
"gitHead": "
|
|
113
|
+
"gitHead": "f8a82a28d1aeb9658dea57517bbb7de7a2c3405f"
|
|
114
114
|
}
|
|
@@ -9,6 +9,11 @@ export interface HousingCounselorProps {
|
|
|
9
9
|
name: string
|
|
10
10
|
phone?: string
|
|
11
11
|
website?: string
|
|
12
|
+
strings?: {
|
|
13
|
+
callNumber?: string
|
|
14
|
+
languageServices?: string
|
|
15
|
+
website?: string
|
|
16
|
+
}
|
|
12
17
|
}
|
|
13
18
|
|
|
14
19
|
const LanguageLabel = (language: string) => {
|
|
@@ -24,7 +29,7 @@ const HousingCounselor = (props: HousingCounselorProps) => {
|
|
|
24
29
|
<div className="resource-item text-base">
|
|
25
30
|
<h3 className="font-sans text-lg">{props.name}</h3>
|
|
26
31
|
<p className="text-sm text-gray-800 pb-2">
|
|
27
|
-
{t("housingCounselors.languageServices")}
|
|
32
|
+
{props.strings?.languageServices ?? t("housingCounselors.languageServices")}
|
|
28
33
|
{props.languages.map((language) => LanguageLabel(language))}
|
|
29
34
|
</p>
|
|
30
35
|
{props.addressStreet && (
|
|
@@ -35,13 +40,13 @@ const HousingCounselor = (props: HousingCounselorProps) => {
|
|
|
35
40
|
{props.phone && (
|
|
36
41
|
<a className="icon-item pb-1" href={`tel:+1${props.phone}`}>
|
|
37
42
|
<Icon symbol="phone" size="medium" fill={IconFillColors.primary} />
|
|
38
|
-
{` ${t("housingCounselors.call", { number: props.phone })}`}
|
|
43
|
+
{` ${props.strings?.callNumber ?? t("housingCounselors.call", { number: props.phone })}`}
|
|
39
44
|
</a>
|
|
40
45
|
)}
|
|
41
46
|
{props.website && (
|
|
42
47
|
<a className="icon-item" href={props.website}>
|
|
43
48
|
<Icon symbol="globe" size="medium" fill={IconFillColors.primary} />
|
|
44
|
-
{` ${t("t.website")}`}
|
|
49
|
+
{` ${props.strings?.website ?? t("t.website")}`}
|
|
45
50
|
</a>
|
|
46
51
|
)}
|
|
47
52
|
</div>
|
package/src/blocks/ImageCard.tsx
CHANGED
|
@@ -5,10 +5,10 @@ import "./ImageCard.scss"
|
|
|
5
5
|
import { Tag } from "../text/Tag"
|
|
6
6
|
import { ApplicationStatusType } from "../global/ApplicationStatusType"
|
|
7
7
|
import { AppearanceStyleType } from "../global/AppearanceTypes"
|
|
8
|
-
import { t } from "../helpers/translator"
|
|
9
8
|
import { Icon, IconFillColors, UniversalIconType } from "../icons/Icon"
|
|
10
9
|
import { Modal } from "../overlays/Modal"
|
|
11
10
|
import { Button } from "../actions/Button"
|
|
11
|
+
import { t } from "../helpers/translator"
|
|
12
12
|
|
|
13
13
|
export interface StatusBarType {
|
|
14
14
|
status?: ApplicationStatusType
|
|
@@ -53,6 +53,9 @@ export interface ImageCardProps {
|
|
|
53
53
|
moreImagesLabel?: string
|
|
54
54
|
/** The aria label of the clickable region of the images grid */
|
|
55
55
|
moreImagesDescription?: string
|
|
56
|
+
strings?: {
|
|
57
|
+
defaultImageAltText?: string
|
|
58
|
+
}
|
|
56
59
|
}
|
|
57
60
|
|
|
58
61
|
/**
|
|
@@ -119,7 +122,11 @@ const ImageCard = (props: ImageCardProps) => {
|
|
|
119
122
|
{props.imageUrl ? (
|
|
120
123
|
<img
|
|
121
124
|
src={props.imageUrl}
|
|
122
|
-
alt={
|
|
125
|
+
alt={
|
|
126
|
+
props.description ??
|
|
127
|
+
props.strings?.defaultImageAltText ??
|
|
128
|
+
t("listings.buildingImageAltText")
|
|
129
|
+
}
|
|
123
130
|
/>
|
|
124
131
|
) : props.images && displayedImages ? (
|
|
125
132
|
displayedImages.map((image, index) => (
|
|
@@ -10,6 +10,15 @@ interface StatusItemProps {
|
|
|
10
10
|
confirmationNumber?: string
|
|
11
11
|
listingName: string
|
|
12
12
|
listingURL: string
|
|
13
|
+
strings?: {
|
|
14
|
+
applicationDeadline?: string
|
|
15
|
+
edited?: string
|
|
16
|
+
seeListing?: string
|
|
17
|
+
status?: string
|
|
18
|
+
submittedStatus?: string
|
|
19
|
+
viewApplication?: string
|
|
20
|
+
yourNumber?: string
|
|
21
|
+
}
|
|
13
22
|
}
|
|
14
23
|
|
|
15
24
|
const StatusItem = (props: StatusItemProps) => {
|
|
@@ -22,7 +31,8 @@ const StatusItem = (props: StatusItemProps) => {
|
|
|
22
31
|
<h3 className="status-item__title">{props.listingName}</h3>
|
|
23
32
|
{props.applicationDueDate && (
|
|
24
33
|
<p className="status-item__due">
|
|
25
|
-
{t("listings.applicationDeadline")}:
|
|
34
|
+
{props.strings?.applicationDeadline ?? t("listings.applicationDeadline")}:{" "}
|
|
35
|
+
{props.applicationDueDate}
|
|
26
36
|
</p>
|
|
27
37
|
)}
|
|
28
38
|
</header>
|
|
@@ -32,7 +42,7 @@ const StatusItem = (props: StatusItemProps) => {
|
|
|
32
42
|
{props.confirmationNumber && (
|
|
33
43
|
<>
|
|
34
44
|
<span className="status-item__confirm-text">
|
|
35
|
-
{t("application.yourLotteryNumber")}:
|
|
45
|
+
{props.strings?.yourNumber ?? t("application.yourLotteryNumber")}:
|
|
36
46
|
</span>
|
|
37
47
|
<br />
|
|
38
48
|
<span className="status-item__confirm-number">{props.confirmationNumber}</span>
|
|
@@ -43,11 +53,12 @@ const StatusItem = (props: StatusItemProps) => {
|
|
|
43
53
|
<div className="status-item__action">
|
|
44
54
|
<p className="status-item__status">
|
|
45
55
|
<span className={"status-item__label"}>
|
|
46
|
-
{t("application.status")}:
|
|
56
|
+
{props.strings?.status ?? t("application.status")}:{" "}
|
|
57
|
+
{props.strings?.submittedStatus ?? t("application.statuses.submitted")}
|
|
47
58
|
</span>
|
|
48
59
|
</p>
|
|
49
60
|
<a href={props.applicationURL} className="button is-small">
|
|
50
|
-
{t("application.viewApplication")}
|
|
61
|
+
{props.strings?.viewApplication ?? t("application.viewApplication")}
|
|
51
62
|
</a>
|
|
52
63
|
</div>
|
|
53
64
|
</section>
|
|
@@ -55,13 +66,13 @@ const StatusItem = (props: StatusItemProps) => {
|
|
|
55
66
|
<footer className="status-item__footer">
|
|
56
67
|
<div className="status-item_links">
|
|
57
68
|
<LinkComponent className="status-item__link lined" href={props.listingURL}>
|
|
58
|
-
{t("t.seeListing")}
|
|
69
|
+
{props.strings?.seeListing ?? t("t.seeListing")}
|
|
59
70
|
</LinkComponent>
|
|
60
71
|
</div>
|
|
61
72
|
|
|
62
73
|
<div className="status-item__meta">
|
|
63
74
|
<p className="status-item__date">
|
|
64
|
-
{t("application.edited")}: {props.applicationUpdatedAt}
|
|
75
|
+
{props.strings?.edited ?? t("application.edited")}: {props.applicationUpdatedAt}
|
|
65
76
|
</p>
|
|
66
77
|
</div>
|
|
67
78
|
</footer>
|
package/src/forms/DOBField.tsx
CHANGED
|
@@ -25,6 +25,15 @@ export interface DOBFieldProps {
|
|
|
25
25
|
required?: boolean
|
|
26
26
|
disabled?: boolean
|
|
27
27
|
readerOnly?: boolean
|
|
28
|
+
strings?: {
|
|
29
|
+
dateError?: string
|
|
30
|
+
day?: string
|
|
31
|
+
dayPlaceholder?: string
|
|
32
|
+
month?: string
|
|
33
|
+
monthPlaceholder?: string
|
|
34
|
+
year?: string
|
|
35
|
+
yearPlaceholder?: string
|
|
36
|
+
}
|
|
28
37
|
}
|
|
29
38
|
|
|
30
39
|
const DOBField = (props: DOBFieldProps) => {
|
|
@@ -55,10 +64,10 @@ const DOBField = (props: DOBFieldProps) => {
|
|
|
55
64
|
<div className="field-group--date">
|
|
56
65
|
<Field
|
|
57
66
|
name={getFieldName("birthMonth")}
|
|
58
|
-
label={t("t.month")}
|
|
67
|
+
label={props.strings?.month ?? t("t.month")}
|
|
59
68
|
disabled={props.disabled}
|
|
60
69
|
readerOnly={true}
|
|
61
|
-
placeholder={t("account.settings.placeholders.month")}
|
|
70
|
+
placeholder={props.strings?.monthPlaceholder ?? t("account.settings.placeholders.month")}
|
|
62
71
|
defaultValue={defaultDOB?.birthMonth ? defaultDOB.birthMonth : ""}
|
|
63
72
|
error={error?.birthMonth !== undefined}
|
|
64
73
|
validation={{
|
|
@@ -77,10 +86,10 @@ const DOBField = (props: DOBFieldProps) => {
|
|
|
77
86
|
/>
|
|
78
87
|
<Field
|
|
79
88
|
name={getFieldName("birthDay")}
|
|
80
|
-
label={t("t.day")}
|
|
89
|
+
label={props.strings?.day ?? t("t.day")}
|
|
81
90
|
disabled={props.disabled}
|
|
82
91
|
readerOnly={true}
|
|
83
|
-
placeholder={t("account.settings.placeholders.day")}
|
|
92
|
+
placeholder={props.strings?.dayPlaceholder ?? t("account.settings.placeholders.day")}
|
|
84
93
|
defaultValue={defaultDOB?.birthDay ? defaultDOB.birthDay : ""}
|
|
85
94
|
error={error?.birthDay !== undefined}
|
|
86
95
|
validation={{
|
|
@@ -99,10 +108,10 @@ const DOBField = (props: DOBFieldProps) => {
|
|
|
99
108
|
/>
|
|
100
109
|
<Field
|
|
101
110
|
name={getFieldName("birthYear")}
|
|
102
|
-
label={t("t.year")}
|
|
111
|
+
label={props.strings?.year ?? t("t.year")}
|
|
103
112
|
disabled={props.disabled}
|
|
104
113
|
readerOnly={true}
|
|
105
|
-
placeholder={t("account.settings.placeholders.year")}
|
|
114
|
+
placeholder={props.strings?.yearPlaceholder ?? t("account.settings.placeholders.year")}
|
|
106
115
|
defaultValue={defaultDOB?.birthYear ? defaultDOB.birthYear : ""}
|
|
107
116
|
error={error?.birthYear !== undefined}
|
|
108
117
|
validation={{
|
|
@@ -126,7 +135,7 @@ const DOBField = (props: DOBFieldProps) => {
|
|
|
126
135
|
{(error?.birthMonth || error?.birthDay || error?.birthYear) && (
|
|
127
136
|
<div className="field error">
|
|
128
137
|
<span id={`${id}-error`} className="error-message">
|
|
129
|
-
{errorMessage ? errorMessage : t("errors.dateOfBirthError")}
|
|
138
|
+
{errorMessage ? errorMessage : props.strings?.dateError ?? t("errors.dateOfBirthError")}
|
|
130
139
|
</span>
|
|
131
140
|
</div>
|
|
132
141
|
)}
|
package/src/forms/DateField.tsx
CHANGED
|
@@ -25,6 +25,15 @@ export interface DateFieldProps {
|
|
|
25
25
|
required?: boolean
|
|
26
26
|
watch: UseFormMethods["watch"]
|
|
27
27
|
dataTestId?: string
|
|
28
|
+
strings?: {
|
|
29
|
+
dateError?: string
|
|
30
|
+
day?: string
|
|
31
|
+
dayPlaceholder?: string
|
|
32
|
+
month?: string
|
|
33
|
+
monthPlaceholder?: string
|
|
34
|
+
year?: string
|
|
35
|
+
yearPlaceholder?: string
|
|
36
|
+
}
|
|
28
37
|
}
|
|
29
38
|
|
|
30
39
|
const DateField = (props: DateFieldProps) => {
|
|
@@ -44,10 +53,10 @@ const DateField = (props: DateFieldProps) => {
|
|
|
44
53
|
<div className="field-group--date">
|
|
45
54
|
<Field
|
|
46
55
|
name={getFieldName("month")}
|
|
47
|
-
label={t("t.month")}
|
|
56
|
+
label={props.strings?.month ?? t("t.month")}
|
|
48
57
|
disabled={props.disabled}
|
|
49
58
|
readerOnly={true}
|
|
50
|
-
placeholder={t("account.settings.placeholders.month")}
|
|
59
|
+
placeholder={props.strings?.monthPlaceholder ?? t("account.settings.placeholders.month")}
|
|
51
60
|
defaultValue={defaultDate?.month ?? ""}
|
|
52
61
|
error={error?.month !== undefined}
|
|
53
62
|
validation={{
|
|
@@ -65,10 +74,10 @@ const DateField = (props: DateFieldProps) => {
|
|
|
65
74
|
/>
|
|
66
75
|
<Field
|
|
67
76
|
name={getFieldName("day")}
|
|
68
|
-
label={t("t.day")}
|
|
77
|
+
label={props.strings?.day ?? t("t.day")}
|
|
69
78
|
disabled={props.disabled}
|
|
70
79
|
readerOnly={true}
|
|
71
|
-
placeholder={t("account.settings.placeholders.day")}
|
|
80
|
+
placeholder={props.strings?.dayPlaceholder ?? t("account.settings.placeholders.day")}
|
|
72
81
|
defaultValue={defaultDate?.day ?? ""}
|
|
73
82
|
error={error?.day !== undefined}
|
|
74
83
|
validation={{
|
|
@@ -86,10 +95,10 @@ const DateField = (props: DateFieldProps) => {
|
|
|
86
95
|
/>
|
|
87
96
|
<Field
|
|
88
97
|
name={getFieldName("year")}
|
|
89
|
-
label={t("t.year")}
|
|
98
|
+
label={props.strings?.year ?? t("t.year")}
|
|
90
99
|
disabled={props.disabled}
|
|
91
100
|
readerOnly={true}
|
|
92
|
-
placeholder={t("account.settings.placeholders.year")}
|
|
101
|
+
placeholder={props.strings?.yearPlaceholder ?? t("account.settings.placeholders.year")}
|
|
93
102
|
defaultValue={defaultDate?.year ?? ""}
|
|
94
103
|
error={error?.year !== undefined}
|
|
95
104
|
validation={{
|
|
@@ -113,7 +122,7 @@ const DateField = (props: DateFieldProps) => {
|
|
|
113
122
|
{(error?.month || error?.day || error?.year) && (
|
|
114
123
|
<div className="field error">
|
|
115
124
|
<span id={`${id}-error`} className="error-message">
|
|
116
|
-
{errorMessage ? errorMessage : t("errors.dateError")}
|
|
125
|
+
{errorMessage ? errorMessage : props.strings?.dateError ?? t("errors.dateError")}
|
|
117
126
|
</span>
|
|
118
127
|
</div>
|
|
119
128
|
)}
|
package/src/forms/Dropzone.tsx
CHANGED
|
@@ -11,6 +11,12 @@ interface DropzoneProps {
|
|
|
11
11
|
accept?: string | string[]
|
|
12
12
|
progress?: number
|
|
13
13
|
className?: string
|
|
14
|
+
strings?: {
|
|
15
|
+
chooseFromFolder?: string
|
|
16
|
+
dragHere?: string
|
|
17
|
+
dropHere?: string
|
|
18
|
+
orString?: string
|
|
19
|
+
}
|
|
14
20
|
}
|
|
15
21
|
|
|
16
22
|
const Dropzone = (props: DropzoneProps) => {
|
|
@@ -51,11 +57,14 @@ const Dropzone = (props: DropzoneProps) => {
|
|
|
51
57
|
<div className={dropzoneClasses.join(" ")} {...getRootProps()}>
|
|
52
58
|
<input id={props.id} {...getInputProps()} data-test-id={"dropzone-input"} />
|
|
53
59
|
{isDragActive ? (
|
|
54
|
-
<p>{t("t.dropFilesHere")}</p>
|
|
60
|
+
<p>{props.strings?.dropHere ?? t("t.dropFilesHere")}</p>
|
|
55
61
|
) : (
|
|
56
62
|
<p>
|
|
57
|
-
{
|
|
58
|
-
|
|
63
|
+
{props.strings?.dragHere ?? t("t.dragFilesHere")}{" "}
|
|
64
|
+
{props.strings?.orString ?? t("t.or")}{" "}
|
|
65
|
+
<u className="text-primary">
|
|
66
|
+
{props.strings?.chooseFromFolder ?? t("t.chooseFromFolder").toLowerCase()}
|
|
67
|
+
</u>
|
|
59
68
|
</p>
|
|
60
69
|
)}
|
|
61
70
|
</div>
|
package/src/forms/FieldGroup.tsx
CHANGED
|
@@ -37,6 +37,11 @@ interface FieldGroupProps {
|
|
|
37
37
|
register: UseFormMethods["register"]
|
|
38
38
|
type?: string
|
|
39
39
|
validation?: RegisterOptions
|
|
40
|
+
strings?: {
|
|
41
|
+
description?: string
|
|
42
|
+
readLess?: string
|
|
43
|
+
readMore?: string
|
|
44
|
+
}
|
|
40
45
|
}
|
|
41
46
|
|
|
42
47
|
const FieldGroup = ({
|
|
@@ -54,6 +59,7 @@ const FieldGroup = ({
|
|
|
54
59
|
fieldLabelClassName,
|
|
55
60
|
groupSubNote,
|
|
56
61
|
dataTestId,
|
|
62
|
+
strings,
|
|
57
63
|
}: FieldGroupProps) => {
|
|
58
64
|
// Always align two-option radio groups side by side
|
|
59
65
|
if (fields?.length === 2) {
|
|
@@ -103,7 +109,12 @@ const FieldGroup = ({
|
|
|
103
109
|
|
|
104
110
|
{item.description && (
|
|
105
111
|
<div className="ml-8 -mt-1 mb-5">
|
|
106
|
-
<ExpandableContent
|
|
112
|
+
<ExpandableContent
|
|
113
|
+
strings={{
|
|
114
|
+
readMore: strings?.readMore ?? t("t.readMore"),
|
|
115
|
+
readLess: strings?.readLess ?? t("t.readLess"),
|
|
116
|
+
}}
|
|
117
|
+
>
|
|
107
118
|
<p className="field-note mb-2 -mt-2">{item.description}</p>
|
|
108
119
|
</ExpandableContent>
|
|
109
120
|
</div>
|
|
@@ -143,7 +154,7 @@ const FieldGroup = ({
|
|
|
143
154
|
name={`${name}-${item.value}`}
|
|
144
155
|
register={register}
|
|
145
156
|
defaultValue={item.defaultText}
|
|
146
|
-
placeholder={t("t.description")}
|
|
157
|
+
placeholder={strings?.description ?? t("t.description")}
|
|
147
158
|
className={"mb-4"}
|
|
148
159
|
disabled={item.disabled}
|
|
149
160
|
dataTestId={item.dataTestId}
|
|
@@ -10,6 +10,9 @@ export interface HouseholdMemberFormProps {
|
|
|
10
10
|
memberId?: number
|
|
11
11
|
memberLastName: string
|
|
12
12
|
subtitle: string
|
|
13
|
+
strings?: {
|
|
14
|
+
edit?: string
|
|
15
|
+
}
|
|
13
16
|
}
|
|
14
17
|
|
|
15
18
|
const HouseholdMemberForm = (props: HouseholdMemberFormProps) => {
|
|
@@ -26,7 +29,7 @@ const HouseholdMemberForm = (props: HouseholdMemberFormProps) => {
|
|
|
26
29
|
type={"button"}
|
|
27
30
|
data-test-id={"app-household-member-edit-button"}
|
|
28
31
|
>
|
|
29
|
-
{t("t.edit")}
|
|
32
|
+
{props.strings?.edit ?? t("t.edit")}
|
|
30
33
|
</button>
|
|
31
34
|
) : (
|
|
32
35
|
<Icon
|
|
@@ -14,6 +14,13 @@ export interface HouseholdSizeFieldProps {
|
|
|
14
14
|
householdSizeMin: number
|
|
15
15
|
register: UseFormMethods["register"]
|
|
16
16
|
validate: boolean
|
|
17
|
+
strings?: {
|
|
18
|
+
dontQualifyDescription?: string
|
|
19
|
+
dontQualifyHeader?: string
|
|
20
|
+
getAssistance?: string
|
|
21
|
+
householdTooBigError?: string
|
|
22
|
+
householdTooSmallError?: string
|
|
23
|
+
}
|
|
17
24
|
}
|
|
18
25
|
|
|
19
26
|
const HouseholdSizeField = (props: HouseholdSizeFieldProps) => {
|
|
@@ -26,6 +33,7 @@ const HouseholdSizeField = (props: HouseholdSizeFieldProps) => {
|
|
|
26
33
|
clearErrors,
|
|
27
34
|
error,
|
|
28
35
|
assistanceUrl,
|
|
36
|
+
strings,
|
|
29
37
|
} = props
|
|
30
38
|
if (!householdSizeMax || !validate) {
|
|
31
39
|
return <></>
|
|
@@ -44,11 +52,11 @@ const HouseholdSizeField = (props: HouseholdSizeFieldProps) => {
|
|
|
44
52
|
? register({
|
|
45
53
|
min: {
|
|
46
54
|
value: householdSizeMin || 0,
|
|
47
|
-
message: t("errors.householdTooSmall"),
|
|
55
|
+
message: strings?.householdTooSmallError ?? t("errors.householdTooSmall"),
|
|
48
56
|
},
|
|
49
57
|
max: {
|
|
50
58
|
value: householdSizeMax,
|
|
51
|
-
message: t("errors.householdTooBig"),
|
|
59
|
+
message: strings?.householdTooBigError ?? t("errors.householdTooBig"),
|
|
52
60
|
},
|
|
53
61
|
})
|
|
54
62
|
: register
|
|
@@ -61,12 +69,14 @@ const HouseholdSizeField = (props: HouseholdSizeFieldProps) => {
|
|
|
61
69
|
className="block mt-0 line-normal text-red-700"
|
|
62
70
|
>
|
|
63
71
|
<AlertBox type="alert" inverted onClose={() => clearErrors()}>
|
|
64
|
-
{t("application.household.dontQualifyHeader")}
|
|
72
|
+
{strings?.dontQualifyHeader ?? t("application.household.dontQualifyHeader")}
|
|
65
73
|
</AlertBox>
|
|
66
74
|
<AlertNotice title={error?.message} type="alert" inverted>
|
|
67
|
-
<p className="mb-2">
|
|
75
|
+
<p className="mb-2">
|
|
76
|
+
{strings?.dontQualifyDescription ?? t("application.household.dontQualifyInfo")}
|
|
77
|
+
</p>
|
|
68
78
|
<p>
|
|
69
|
-
<a href={assistanceUrl}>{t("pageTitle.getAssistance")}</a>
|
|
79
|
+
<a href={assistanceUrl}>{strings?.getAssistance ?? t("pageTitle.getAssistance")}</a>
|
|
70
80
|
</p>
|
|
71
81
|
</AlertNotice>
|
|
72
82
|
</ErrorMessage>
|
package/src/forms/TimeField.tsx
CHANGED
|
@@ -29,6 +29,14 @@ export type TimeFieldProps = {
|
|
|
29
29
|
watch: UseFormMethods["watch"]
|
|
30
30
|
seconds?: boolean
|
|
31
31
|
dataTestId?: string
|
|
32
|
+
strings?: {
|
|
33
|
+
hour?: string
|
|
34
|
+
minutes?: string
|
|
35
|
+
minutesPlaceholder?: string
|
|
36
|
+
seconds?: string
|
|
37
|
+
time?: string
|
|
38
|
+
timeError?: string
|
|
39
|
+
}
|
|
32
40
|
}
|
|
33
41
|
|
|
34
42
|
export const formatDateToTimeField = (date: Date) => {
|
|
@@ -56,6 +64,7 @@ const TimeField = ({
|
|
|
56
64
|
defaultValues,
|
|
57
65
|
disabled,
|
|
58
66
|
dataTestId,
|
|
67
|
+
strings,
|
|
59
68
|
}: TimeFieldProps) => {
|
|
60
69
|
const fieldName = (baseName: string) => {
|
|
61
70
|
return [name, baseName].filter((item) => item).join(".")
|
|
@@ -82,7 +91,7 @@ const TimeField = ({
|
|
|
82
91
|
<div className="field-group--date">
|
|
83
92
|
<Field
|
|
84
93
|
name={fieldName("hours")}
|
|
85
|
-
label={t("t.hour")}
|
|
94
|
+
label={strings?.hour ?? t("t.hour")}
|
|
86
95
|
defaultValue={defaultValues?.hours ?? ""}
|
|
87
96
|
readerOnly={true}
|
|
88
97
|
placeholder="HH"
|
|
@@ -106,10 +115,10 @@ const TimeField = ({
|
|
|
106
115
|
|
|
107
116
|
<Field
|
|
108
117
|
name={fieldName("minutes")}
|
|
109
|
-
label={t("t.minutes")}
|
|
118
|
+
label={strings?.minutes ?? t("t.minutes")}
|
|
110
119
|
defaultValue={defaultValues?.minutes ?? ""}
|
|
111
120
|
readerOnly={true}
|
|
112
|
-
placeholder={t("account.settings.placeholders.month")}
|
|
121
|
+
placeholder={strings?.minutesPlaceholder ?? t("account.settings.placeholders.month")}
|
|
113
122
|
error={error}
|
|
114
123
|
validation={{
|
|
115
124
|
required: required || innerRequiredRule,
|
|
@@ -130,7 +139,7 @@ const TimeField = ({
|
|
|
130
139
|
|
|
131
140
|
{seconds && (
|
|
132
141
|
<Field
|
|
133
|
-
label={t("t.seconds")}
|
|
142
|
+
label={strings?.seconds ?? t("t.seconds")}
|
|
134
143
|
defaultValue={defaultValues?.seconds ?? ""}
|
|
135
144
|
name={fieldName("seconds")}
|
|
136
145
|
readerOnly={true}
|
|
@@ -158,7 +167,7 @@ const TimeField = ({
|
|
|
158
167
|
name={fieldName("period")}
|
|
159
168
|
id={fieldName("period")}
|
|
160
169
|
labelClassName="sr-only"
|
|
161
|
-
label={t("t.time")}
|
|
170
|
+
label={strings?.time ?? t("t.time")}
|
|
162
171
|
register={register}
|
|
163
172
|
options={["am", "pm"]}
|
|
164
173
|
keyPrefix="t"
|
|
@@ -172,7 +181,7 @@ const TimeField = ({
|
|
|
172
181
|
|
|
173
182
|
<div id={`${id}-error`} className="field error">
|
|
174
183
|
<ErrorMessage id={"time-field-error"} error={error}>
|
|
175
|
-
{t("errors.timeError")}
|
|
184
|
+
{strings?.timeError ?? t("errors.timeError")}
|
|
176
185
|
</ErrorMessage>
|
|
177
186
|
</div>
|
|
178
187
|
</fieldset>
|
package/src/headers/Hero.tsx
CHANGED
|
@@ -14,6 +14,9 @@ export interface HeroProps {
|
|
|
14
14
|
secondaryButtonLink?: string
|
|
15
15
|
secondaryButtonTitle?: string
|
|
16
16
|
title: React.ReactNode
|
|
17
|
+
strings?: {
|
|
18
|
+
allApplicationsClosed?: string
|
|
19
|
+
}
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
const HeroButton = (props: { title: string; href: string; className?: string }) => (
|
|
@@ -26,7 +29,11 @@ const Hero = (props: HeroProps) => {
|
|
|
26
29
|
let subHeader, styles
|
|
27
30
|
let classNames = ""
|
|
28
31
|
if (props.allApplicationsClosed) {
|
|
29
|
-
subHeader =
|
|
32
|
+
subHeader = (
|
|
33
|
+
<h2 className="hero__subtitle">
|
|
34
|
+
{props.strings?.allApplicationsClosed ?? t("welcome.allApplicationClosed")}
|
|
35
|
+
</h2>
|
|
36
|
+
)
|
|
30
37
|
} else if (props.children) {
|
|
31
38
|
subHeader = <h2 className="hero__subtitle">{props.children}</h2>
|
|
32
39
|
}
|
|
@@ -38,6 +38,11 @@ export interface SiteHeaderProps {
|
|
|
38
38
|
noticeMobile?: boolean
|
|
39
39
|
siteHeaderWidth?: SiteHeaderWidth
|
|
40
40
|
title?: string
|
|
41
|
+
strings?: {
|
|
42
|
+
close?: string
|
|
43
|
+
logoAriaLable?: string
|
|
44
|
+
menu?: string
|
|
45
|
+
}
|
|
41
46
|
}
|
|
42
47
|
|
|
43
48
|
const SiteHeader = (props: SiteHeaderProps) => {
|
|
@@ -240,7 +245,7 @@ const SiteHeader = (props: SiteHeaderProps) => {
|
|
|
240
245
|
setMobileDrawer(false)
|
|
241
246
|
}
|
|
242
247
|
}}
|
|
243
|
-
aria-label={t("t.close")}
|
|
248
|
+
aria-label={props.strings?.close ?? t("t.close")}
|
|
244
249
|
>
|
|
245
250
|
<Icon size="small" symbol="arrowForward" fill={"#ffffff"} className={"pl-2"} />
|
|
246
251
|
</button>
|
|
@@ -377,7 +382,9 @@ const SiteHeader = (props: SiteHeaderProps) => {
|
|
|
377
382
|
}
|
|
378
383
|
}}
|
|
379
384
|
>
|
|
380
|
-
<div className={"pr-2 text-tiny text-primary uppercase"}>
|
|
385
|
+
<div className={"pr-2 text-tiny text-primary uppercase"}>
|
|
386
|
+
{props.strings?.menu ?? t("t.menu")}
|
|
387
|
+
</div>
|
|
381
388
|
<Icon
|
|
382
389
|
symbol={mobileMenu ? "closeSmall" : "hamburger"}
|
|
383
390
|
size={"base"}
|
|
@@ -400,7 +407,7 @@ const SiteHeader = (props: SiteHeaderProps) => {
|
|
|
400
407
|
className={"navbar-mobile-menu-button"}
|
|
401
408
|
unstyled
|
|
402
409
|
>
|
|
403
|
-
{mobileMenu ? t("t.close") : t("t.menu")}
|
|
410
|
+
{mobileMenu ? props.strings?.close ?? t("t.close") : props.strings?.menu ?? t("t.menu")}
|
|
404
411
|
</Button>
|
|
405
412
|
)}
|
|
406
413
|
</>
|
|
@@ -415,7 +422,7 @@ const SiteHeader = (props: SiteHeaderProps) => {
|
|
|
415
422
|
props.logoWidth && "navbar-custom-width"
|
|
416
423
|
}`}
|
|
417
424
|
href={props.homeURL}
|
|
418
|
-
aria-label={t("t.homePage")}
|
|
425
|
+
aria-label={props.strings?.logoAriaLable ?? t("t.homePage")}
|
|
419
426
|
>
|
|
420
427
|
<div className={`logo-content ${props.imageOnly && "navbar-image-only-container"}`}>
|
|
421
428
|
<img
|
|
@@ -5,6 +5,9 @@ import { SelectOption } from "../forms/Select"
|
|
|
5
5
|
export interface FormOptionsProps {
|
|
6
6
|
options: (string | SelectOption)[]
|
|
7
7
|
keyPrefix?: string
|
|
8
|
+
strings?: {
|
|
9
|
+
selectOne?: string
|
|
10
|
+
}
|
|
8
11
|
}
|
|
9
12
|
|
|
10
13
|
export const numberOptions = (end: number, start = 1): SelectOption[] => {
|
|
@@ -21,7 +24,7 @@ export const FormOptions = (props: FormOptionsProps) => {
|
|
|
21
24
|
if (option == "" || option["value"] == "") {
|
|
22
25
|
return (
|
|
23
26
|
<option value="" key="select-one">
|
|
24
|
-
{t("t.selectOne")}
|
|
27
|
+
{props.strings?.selectOne ?? t("t.selectOne")}
|
|
25
28
|
</option>
|
|
26
29
|
)
|
|
27
30
|
} else {
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { t } from "./translator"
|
|
2
2
|
|
|
3
|
-
export const formatYesNoLabel = (
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
export const formatYesNoLabel = (
|
|
4
|
+
value: boolean | null,
|
|
5
|
+
strings?: { yesString?: string; noString?: string; notApplicableString?: string }
|
|
6
|
+
) => {
|
|
7
|
+
if (value === null || typeof value == "undefined")
|
|
8
|
+
return strings?.notApplicableString ?? t("t.n/a")
|
|
9
|
+
if (value) return strings?.yesString ?? t("t.yes")
|
|
10
|
+
return strings?.noString ?? t("t.no")
|
|
9
11
|
}
|