@bloom-housing/ui-components 6.0.0 → 6.0.1-alpha.1
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 +236 -7
- package/index.ts +1 -0
- package/package.json +3 -5
- package/src/actions/Button.tsx +1 -0
- package/src/actions/LinkButton.tsx +1 -0
- package/src/blocks/FormCard.scss +1 -0
- package/src/blocks/HousingCounselor.tsx +8 -3
- package/src/blocks/ImageCard.tsx +24 -13
- package/src/blocks/MediaCard.docs.mdx +37 -0
- package/src/blocks/MediaCard.scss +10 -11
- package/src/blocks/MediaCard.tsx +4 -4
- package/src/blocks/StandardCard.tsx +1 -1
- package/src/blocks/StatusItem.tsx +17 -6
- package/src/forms/DOBField.tsx +20 -8
- package/src/forms/DateField.tsx +16 -7
- package/src/forms/Dropzone.scss +7 -0
- package/src/forms/Dropzone.tsx +18 -5
- package/src/forms/Field.tsx +5 -0
- package/src/forms/FieldGroup.tsx +14 -3
- package/src/forms/HouseholdMemberForm.tsx +4 -1
- package/src/forms/HouseholdSizeField.tsx +16 -6
- package/src/forms/TimeField.tsx +15 -6
- package/src/global/custom_counter.scss +1 -1
- package/src/global/forms.scss +38 -5
- package/src/global/headers.scss +1 -1
- package/src/global/markdown.scss +2 -2
- package/src/global/vendor/ag_grid.scss +43 -9
- package/src/headers/Hero.tsx +8 -1
- package/src/headers/PageHeader.scss +3 -2
- package/src/headers/PageHeader.tsx +5 -1
- package/src/headers/SiteHeader.tsx +11 -4
- package/src/helpers/formOptions.tsx +4 -1
- package/src/helpers/formatYesNoLabel.ts +8 -6
- package/src/locales/es.json +1 -1
- package/src/locales/general.json +9 -4
- package/src/locales/tl.json +1 -1
- package/src/locales/vi.json +1 -1
- package/src/locales/zh.json +1 -1
- package/src/navigation/Breadcrumbs.scss +1 -0
- package/src/navigation/Breadcrumbs.tsx +1 -1
- package/src/navigation/FooterNav.tsx +5 -1
- package/src/navigation/LanguageNav.tsx +1 -1
- package/src/navigation/ProgressNav.docs.mdx +47 -0
- package/src/navigation/ProgressNav.scss +101 -56
- package/src/navigation/ProgressNav.tsx +45 -15
- package/src/navigation/SideNav.scss +56 -0
- package/src/navigation/SideNav.tsx +2 -2
- package/src/navigation/TabNav.scss +1 -1
- package/src/navigation/TabNav.tsx +1 -1
- package/src/navigation/Tabs.scss +25 -6
- package/src/notifications/AlertBox.docs.mdx +41 -0
- package/src/notifications/AlertBox.scss +78 -41
- package/src/notifications/AlertBox.tsx +20 -14
- package/src/notifications/SiteAlert.tsx +3 -0
- package/src/notifications/StatusMessage.tsx +8 -2
- package/src/notifications/alertTypes.ts +1 -0
- package/src/overlays/Modal.scss +3 -1
- package/src/page_components/ApplicationTimeline.scss +6 -6
- package/src/page_components/ApplicationTimeline.tsx +17 -7
- package/src/page_components/NavigationHeader.tsx +10 -10
- package/src/page_components/forgot-password/FormForgotPassword.tsx +1 -1
- package/src/page_components/listing/AdditionalFees.tsx +1 -1
- package/src/page_components/listing/ListingCard.scss +4 -0
- package/src/page_components/listing/ListingCard.tsx +18 -3
- package/src/page_components/listing/listing_sidebar/Contact.tsx +2 -2
- 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/page_components/sign-in/FormSignIn.tsx +1 -1
- package/src/page_components/sign-in/FormSignInErrorBox.tsx +1 -1
- package/src/sections/InfoCardGrid.scss +1 -1
- package/src/sections/InfoCardGrid.tsx +4 -1
- package/src/sections/ListSection.tsx +1 -1
- package/src/tables/AgTable.tsx +56 -26
- package/src/tables/StandardTable.tsx +19 -7
- package/src/text/Tag.scss +7 -0
- package/src/text/Tag.tsx +2 -0
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) => {
|
|
@@ -35,6 +44,8 @@ const DOBField = (props: DOBFieldProps) => {
|
|
|
35
44
|
return [name, baseName].filter((item) => item).join(".")
|
|
36
45
|
}
|
|
37
46
|
|
|
47
|
+
const hasError = error?.birthMonth || error?.birthDay || error?.birthYear
|
|
48
|
+
|
|
38
49
|
const birthDay = watch(getFieldName("birthDay")) ?? defaultDOB?.birthDay
|
|
39
50
|
const birthMonth = watch(getFieldName("birthMonth")) ?? defaultDOB?.birthMonth
|
|
40
51
|
|
|
@@ -47,6 +58,7 @@ const DOBField = (props: DOBFieldProps) => {
|
|
|
47
58
|
|
|
48
59
|
const labelClasses = ["field-label--caps"]
|
|
49
60
|
if (props.readerOnly) labelClasses.push("sr-only")
|
|
61
|
+
if (hasError) labelClasses.push("text-alert")
|
|
50
62
|
|
|
51
63
|
return (
|
|
52
64
|
<fieldset id={id}>
|
|
@@ -55,10 +67,10 @@ const DOBField = (props: DOBFieldProps) => {
|
|
|
55
67
|
<div className="field-group--date">
|
|
56
68
|
<Field
|
|
57
69
|
name={getFieldName("birthMonth")}
|
|
58
|
-
label={t("t.month")}
|
|
70
|
+
label={props.strings?.month ?? t("t.month")}
|
|
59
71
|
disabled={props.disabled}
|
|
60
72
|
readerOnly={true}
|
|
61
|
-
placeholder={t("account.settings.placeholders.month")}
|
|
73
|
+
placeholder={props.strings?.monthPlaceholder ?? t("account.settings.placeholders.month")}
|
|
62
74
|
defaultValue={defaultDOB?.birthMonth ? defaultDOB.birthMonth : ""}
|
|
63
75
|
error={error?.birthMonth !== undefined}
|
|
64
76
|
validation={{
|
|
@@ -77,10 +89,10 @@ const DOBField = (props: DOBFieldProps) => {
|
|
|
77
89
|
/>
|
|
78
90
|
<Field
|
|
79
91
|
name={getFieldName("birthDay")}
|
|
80
|
-
label={t("t.day")}
|
|
92
|
+
label={props.strings?.day ?? t("t.day")}
|
|
81
93
|
disabled={props.disabled}
|
|
82
94
|
readerOnly={true}
|
|
83
|
-
placeholder={t("account.settings.placeholders.day")}
|
|
95
|
+
placeholder={props.strings?.dayPlaceholder ?? t("account.settings.placeholders.day")}
|
|
84
96
|
defaultValue={defaultDOB?.birthDay ? defaultDOB.birthDay : ""}
|
|
85
97
|
error={error?.birthDay !== undefined}
|
|
86
98
|
validation={{
|
|
@@ -99,10 +111,10 @@ const DOBField = (props: DOBFieldProps) => {
|
|
|
99
111
|
/>
|
|
100
112
|
<Field
|
|
101
113
|
name={getFieldName("birthYear")}
|
|
102
|
-
label={t("t.year")}
|
|
114
|
+
label={props.strings?.year ?? t("t.year")}
|
|
103
115
|
disabled={props.disabled}
|
|
104
116
|
readerOnly={true}
|
|
105
|
-
placeholder={t("account.settings.placeholders.year")}
|
|
117
|
+
placeholder={props.strings?.yearPlaceholder ?? t("account.settings.placeholders.year")}
|
|
106
118
|
defaultValue={defaultDOB?.birthYear ? defaultDOB.birthYear : ""}
|
|
107
119
|
error={error?.birthYear !== undefined}
|
|
108
120
|
validation={{
|
|
@@ -123,10 +135,10 @@ const DOBField = (props: DOBFieldProps) => {
|
|
|
123
135
|
/>
|
|
124
136
|
</div>
|
|
125
137
|
|
|
126
|
-
{
|
|
138
|
+
{hasError && (
|
|
127
139
|
<div className="field error">
|
|
128
140
|
<span id={`${id}-error`} className="error-message">
|
|
129
|
-
{errorMessage ? errorMessage : t("errors.dateOfBirthError")}
|
|
141
|
+
{errorMessage ? errorMessage : props.strings?.dateError ?? t("errors.dateOfBirthError")}
|
|
130
142
|
</span>
|
|
131
143
|
</div>
|
|
132
144
|
)}
|
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.scss
CHANGED
package/src/forms/Dropzone.tsx
CHANGED
|
@@ -11,6 +11,13 @@ interface DropzoneProps {
|
|
|
11
11
|
accept?: string | string[]
|
|
12
12
|
progress?: number
|
|
13
13
|
className?: string
|
|
14
|
+
maxFiles?: number
|
|
15
|
+
strings?: {
|
|
16
|
+
chooseFromFolder?: string
|
|
17
|
+
dragHere?: string
|
|
18
|
+
dropHere?: string
|
|
19
|
+
orString?: string
|
|
20
|
+
}
|
|
14
21
|
}
|
|
15
22
|
|
|
16
23
|
const Dropzone = (props: DropzoneProps) => {
|
|
@@ -18,6 +25,8 @@ const Dropzone = (props: DropzoneProps) => {
|
|
|
18
25
|
const classNames = ["field"]
|
|
19
26
|
if (props.className) classNames.push(props.className)
|
|
20
27
|
|
|
28
|
+
const maxFiles = props.maxFiles || 1
|
|
29
|
+
|
|
21
30
|
const onDrop = useCallback(
|
|
22
31
|
(acceptedFiles) => {
|
|
23
32
|
acceptedFiles.forEach((file: File) => uploader(file))
|
|
@@ -27,7 +36,8 @@ const Dropzone = (props: DropzoneProps) => {
|
|
|
27
36
|
const { getRootProps, getInputProps, isDragActive } = useDropzone({
|
|
28
37
|
onDrop,
|
|
29
38
|
accept: props.accept,
|
|
30
|
-
maxFiles: 1,
|
|
39
|
+
maxFiles: maxFiles > 1 ? maxFiles : undefined,
|
|
40
|
+
multiple: maxFiles > 1,
|
|
31
41
|
})
|
|
32
42
|
|
|
33
43
|
const dropzoneClasses = ["dropzone", "control"]
|
|
@@ -42,7 +52,7 @@ const Dropzone = (props: DropzoneProps) => {
|
|
|
42
52
|
<label htmlFor={props.id} className="label">
|
|
43
53
|
{props.label}
|
|
44
54
|
</label>
|
|
45
|
-
{props.helptext && <p className="
|
|
55
|
+
{props.helptext && <p className="dropzone__helptext">{props.helptext}</p>}
|
|
46
56
|
{props.progress && props.progress === 100 ? (
|
|
47
57
|
<></>
|
|
48
58
|
) : props.progress && props.progress > 0 ? (
|
|
@@ -51,11 +61,14 @@ const Dropzone = (props: DropzoneProps) => {
|
|
|
51
61
|
<div className={dropzoneClasses.join(" ")} {...getRootProps()}>
|
|
52
62
|
<input id={props.id} {...getInputProps()} data-test-id={"dropzone-input"} />
|
|
53
63
|
{isDragActive ? (
|
|
54
|
-
<p>{t("t.dropFilesHere")}</p>
|
|
64
|
+
<p>{props.strings?.dropHere ?? t("t.dropFilesHere")}</p>
|
|
55
65
|
) : (
|
|
56
66
|
<p>
|
|
57
|
-
{
|
|
58
|
-
|
|
67
|
+
{props.strings?.dragHere ?? t("t.dragFilesHere")}{" "}
|
|
68
|
+
{props.strings?.orString ?? t("t.or")}{" "}
|
|
69
|
+
<u className="text-primary">
|
|
70
|
+
{props.strings?.chooseFromFolder ?? t("t.chooseFromFolder").toLowerCase()}
|
|
71
|
+
</u>
|
|
59
72
|
</p>
|
|
60
73
|
)}
|
|
61
74
|
</div>
|
package/src/forms/Field.tsx
CHANGED
|
@@ -31,6 +31,7 @@ export interface FieldProps {
|
|
|
31
31
|
setValue?: UseFormMethods["setValue"]
|
|
32
32
|
dataTestId?: string
|
|
33
33
|
hidden?: boolean
|
|
34
|
+
bordered?: boolean
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
const Field = (props: FieldProps) => {
|
|
@@ -53,6 +54,9 @@ const Field = (props: FieldProps) => {
|
|
|
53
54
|
controlClasses.push(props.controlClassName)
|
|
54
55
|
}
|
|
55
56
|
|
|
57
|
+
if (props.bordered && (props.type === "radio" || props.type === "checkbox"))
|
|
58
|
+
controlClasses.push("field-border")
|
|
59
|
+
|
|
56
60
|
const formatValue = () => {
|
|
57
61
|
if (props.getValues && props.setValue) {
|
|
58
62
|
const currencyValue = props.getValues(props.name)
|
|
@@ -77,6 +81,7 @@ const Field = (props: FieldProps) => {
|
|
|
77
81
|
if (props.type === "radio") {
|
|
78
82
|
labelClasses.push("font-semibold")
|
|
79
83
|
}
|
|
84
|
+
if (props.error) labelClasses.push("text-alert")
|
|
80
85
|
|
|
81
86
|
return (
|
|
82
87
|
<label className={labelClasses.join(" ")} htmlFor={props.id || props.name}>
|
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,8 +59,9 @@ const FieldGroup = ({
|
|
|
54
59
|
fieldLabelClassName,
|
|
55
60
|
groupSubNote,
|
|
56
61
|
dataTestId,
|
|
62
|
+
strings,
|
|
57
63
|
}: FieldGroupProps) => {
|
|
58
|
-
// Always align two-option radio groups side by side
|
|
64
|
+
// Always default align two-option radio groups side by side
|
|
59
65
|
if (fields?.length === 2) {
|
|
60
66
|
fieldGroupClassName = `${fieldGroupClassName} flex`
|
|
61
67
|
fieldClassName = `${fieldClassName} flex-initial mr-4`
|
|
@@ -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
|
|
@@ -58,15 +66,17 @@ const HouseholdSizeField = (props: HouseholdSizeFieldProps) => {
|
|
|
58
66
|
<ErrorMessage
|
|
59
67
|
id={"householdsize-error"}
|
|
60
68
|
error={!!error}
|
|
61
|
-
className="block mt-0 line-normal text-
|
|
69
|
+
className="block mt-0 line-normal text-alert"
|
|
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/global/forms.scss
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
.field {
|
|
2
|
+
--bordered-border-width: 1px;
|
|
3
|
+
--bordered-border-radius: var(--bloom-s1_5);
|
|
4
|
+
--bordered-vertical-padding: var(--bloom-s4);
|
|
5
|
+
--bordered-leftward-padding: 2.875rem;
|
|
6
|
+
--bordered-checked-bg-color: var(--bloom-color-gray-100);
|
|
7
|
+
|
|
2
8
|
margin-bottom: 1.25rem;
|
|
3
9
|
|
|
4
10
|
* > &:last-child {
|
|
@@ -29,6 +35,34 @@
|
|
|
29
35
|
@apply mt-0;
|
|
30
36
|
}
|
|
31
37
|
|
|
38
|
+
.field-border {
|
|
39
|
+
label {
|
|
40
|
+
background-color: var(--bloom-color-white);
|
|
41
|
+
padding-top: var(--bordered-vertical-padding);
|
|
42
|
+
padding-bottom: var(--bordered-vertical-padding);
|
|
43
|
+
padding-left: var(--bordered-leftward-padding);
|
|
44
|
+
border-width: var(--bordered-border-width);
|
|
45
|
+
border-radius: var(--bordered-border-radius);
|
|
46
|
+
border-color: var(--bloom-color-gray-450);
|
|
47
|
+
}
|
|
48
|
+
input[type="checkbox"] + label::before,
|
|
49
|
+
input[type="radio"] + label::before,
|
|
50
|
+
input[type="checkbox"]:focus + label::before,
|
|
51
|
+
input[type="radio"]:focus + label::before {
|
|
52
|
+
background-color: none;
|
|
53
|
+
box-shadow: 0 0 0 1px white, 0 0 0 2px var(--bloom-color-gray-450);
|
|
54
|
+
}
|
|
55
|
+
input[type="checkbox"]:focus + label,
|
|
56
|
+
input[type="radio"]:focus + label {
|
|
57
|
+
box-shadow: 0 0 0 1px white, 0 0 0 2px var(--bloom-color-accent-cool),
|
|
58
|
+
0 0 3px 4px var(--bloom-color-accent-cool);
|
|
59
|
+
}
|
|
60
|
+
input[type="checkbox"]:checked + label,
|
|
61
|
+
input[type="radio"]:checked + label {
|
|
62
|
+
background-color: var(--bordered-checked-bg-color);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
32
66
|
.control {
|
|
33
67
|
position: relative;
|
|
34
68
|
|
|
@@ -196,7 +230,7 @@
|
|
|
196
230
|
|
|
197
231
|
&.error {
|
|
198
232
|
label {
|
|
199
|
-
@apply text-
|
|
233
|
+
@apply text-alert;
|
|
200
234
|
}
|
|
201
235
|
|
|
202
236
|
.control {
|
|
@@ -208,7 +242,7 @@
|
|
|
208
242
|
}
|
|
209
243
|
|
|
210
244
|
.prepend {
|
|
211
|
-
@apply text-
|
|
245
|
+
@apply text-alert;
|
|
212
246
|
}
|
|
213
247
|
}
|
|
214
248
|
|
|
@@ -321,17 +355,16 @@ input[type="number"] {
|
|
|
321
355
|
.field-note {
|
|
322
356
|
@apply text-tiny;
|
|
323
357
|
@apply text-gray-700;
|
|
324
|
-
@apply font-semibold;
|
|
325
358
|
white-space: pre-line;
|
|
326
359
|
}
|
|
327
360
|
|
|
328
361
|
.error-message {
|
|
329
362
|
display: inline-block;
|
|
330
363
|
@apply text-sm;
|
|
331
|
-
@apply text-
|
|
364
|
+
@apply text-alert;
|
|
332
365
|
@apply tracking-wide;
|
|
333
366
|
@apply leading-5;
|
|
334
|
-
@apply mt-
|
|
367
|
+
@apply mt-1;
|
|
335
368
|
}
|
|
336
369
|
|
|
337
370
|
.field-sub-note {
|
package/src/global/headers.scss
CHANGED
package/src/global/markdown.scss
CHANGED
|
@@ -11,6 +11,12 @@
|
|
|
11
11
|
)
|
|
12
12
|
);
|
|
13
13
|
|
|
14
|
+
--ag-selected-row-background-color: var(--bloom-color-primary-light);
|
|
15
|
+
|
|
16
|
+
a {
|
|
17
|
+
color: var(--bloom-color-primary-dark);
|
|
18
|
+
}
|
|
19
|
+
|
|
14
20
|
.ag-row {
|
|
15
21
|
height: ag-param(row-height);
|
|
16
22
|
}
|
|
@@ -72,6 +78,15 @@
|
|
|
72
78
|
@apply border-b-0;
|
|
73
79
|
}
|
|
74
80
|
|
|
81
|
+
.ag-pinned-right-header,
|
|
82
|
+
.ag-cell.ag-cell-first-right-pinned:not(.ag-cell-range-left):not(.ag-cell-range-single-cell) {
|
|
83
|
+
@apply border-gray-450;
|
|
84
|
+
@apply border-r-0;
|
|
85
|
+
@apply border-t-0;
|
|
86
|
+
@apply border-l-4;
|
|
87
|
+
@apply border-b-0;
|
|
88
|
+
}
|
|
89
|
+
|
|
75
90
|
.ag-row {
|
|
76
91
|
@apply border-t-0;
|
|
77
92
|
@apply border-l-0;
|
|
@@ -85,29 +100,48 @@
|
|
|
85
100
|
|
|
86
101
|
.ag-body-viewport {
|
|
87
102
|
::-webkit-scrollbar {
|
|
88
|
-
// -webkit-appearance: none;
|
|
89
103
|
height: 8px;
|
|
90
|
-
@apply bg-gray-600;
|
|
91
104
|
}
|
|
92
105
|
|
|
93
106
|
::-webkit-scrollbar-thumb {
|
|
94
107
|
border-radius: 8px;
|
|
95
|
-
@apply bg-gray-
|
|
108
|
+
@apply bg-gray-550;
|
|
96
109
|
}
|
|
110
|
+
}
|
|
97
111
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.7);
|
|
102
|
-
}
|
|
112
|
+
.ag-body-horizontal-scroll {
|
|
113
|
+
border-bottom: 1px solid var(--bloom-color-gray-500);
|
|
114
|
+
border-radius: var(--bloom-rounded-md);
|
|
103
115
|
}
|
|
104
116
|
|
|
105
117
|
.ag-root-wrapper {
|
|
106
118
|
@apply border-b-0;
|
|
107
119
|
@apply rounded-t-md;
|
|
108
|
-
@apply rounded-b-
|
|
120
|
+
@apply rounded-b-md;
|
|
109
121
|
overflow: visible;
|
|
110
122
|
}
|
|
123
|
+
|
|
124
|
+
.ag-layout-auto-height {
|
|
125
|
+
.ag-center-cols-container,
|
|
126
|
+
.ag-center-cols-clipper {
|
|
127
|
+
--table-min-height: 124px;
|
|
128
|
+
min-height: var(--table-min-height);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.ag-ltr {
|
|
133
|
+
.ag-selection-checkbox {
|
|
134
|
+
margin-right: var(--bloom-s6);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.ag-horizontal-right-spacer:not(.ag-scroller-corner) {
|
|
139
|
+
border: none;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.ag-horizontal-left-spacer:not(.ag-scroller-corner) {
|
|
143
|
+
border: none;
|
|
144
|
+
}
|
|
111
145
|
}
|
|
112
146
|
|
|
113
147
|
.data-pager {
|
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
|
}
|