Skip to content

Commit 410bbc2

Browse files
authored
fix: localise DatePicker validation messages based on configured locale (#4576)
1 parent 2763641 commit 410bbc2

5 files changed

Lines changed: 357 additions & 2 deletions

File tree

packages/eds-core-react/src/components/Datepicker/DatePicker.spec.tsx

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,72 @@ describe('DatePicker', () => {
248248
})
249249
})
250250

251+
it('should display validation errors in the configured locale', () => {
252+
const maxDate = new Date(2024, 0, 1)
253+
const outOfRangeDate = new Date(2024, 5, 15)
254+
255+
const { container, rerender } = render(
256+
<I18nProvider locale={'en-US'}>
257+
<DatePicker
258+
label={'Datepicker'}
259+
value={outOfRangeDate}
260+
maxValue={maxDate}
261+
/>
262+
</I18nProvider>,
263+
)
264+
265+
// English: "Value must be ... or earlier."
266+
expect(container.textContent).toMatch(/Value must be/)
267+
268+
rerender(
269+
<I18nProvider locale={'nb-NO'}>
270+
<DatePicker
271+
label={'Datepicker'}
272+
value={outOfRangeDate}
273+
maxValue={maxDate}
274+
/>
275+
</I18nProvider>,
276+
)
277+
278+
// Norwegian: "Verdien må være ... eller tidligere."
279+
expect(container.textContent).toMatch(/Verdien/)
280+
})
281+
282+
it('should display localized rangeUnderflow message', () => {
283+
const minDate = new Date(2024, 11, 31)
284+
const tooEarlyDate = new Date(2024, 0, 1)
285+
286+
const { container } = render(
287+
<I18nProvider locale={'nb-NO'}>
288+
<DatePicker
289+
label={'Datepicker'}
290+
value={tooEarlyDate}
291+
minValue={minDate}
292+
/>
293+
</I18nProvider>,
294+
)
295+
296+
// Norwegian: "Verdien må være ... eller senere."
297+
expect(container.textContent).toMatch(/Verdien/)
298+
})
299+
300+
it('should display localized message for unavailable dates', () => {
301+
const unavailableDate = new Date(2024, 4, 30)
302+
303+
const { container } = render(
304+
<I18nProvider locale={'nb-NO'}>
305+
<DatePicker
306+
label={'Datepicker'}
307+
value={unavailableDate}
308+
isDateUnavailable={(d) => d.getDate() === 30}
309+
/>
310+
</I18nProvider>,
311+
)
312+
313+
// Norwegian: "Valgt dato utilgjengelig."
314+
expect(container.textContent).toMatch(/utilgjengelig/)
315+
})
316+
251317
it('should be localized', () => {
252318
const date = new Date(2024, 4, 4)
253319

packages/eds-core-react/src/components/Datepicker/DatePicker.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { tokens } from '@equinor/eds-tokens'
2828
import { Icon } from '../Icon'
2929
import { getCalendarDate } from './utils/get-calendar-date'
3030
import { useGetLocale } from './utils/useGetLocale'
31+
import { getLocalizedValidationErrors } from './utils/getLocalizedValidationErrors'
3132

3233
/**
3334
* DatePicker component encapsulates the logic for selecting a single date.
@@ -144,9 +145,24 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
144145
const { groupProps, buttonProps, fieldProps, calendarProps } =
145146
useDatePicker(dateCreateProps, pickerState, ref)
146147

148+
const localizedErrors = pickerState.displayValidation.isInvalid
149+
? getLocalizedValidationErrors(
150+
pickerState.displayValidation.validationDetails,
151+
locale,
152+
_minValue,
153+
_maxValue,
154+
timezone,
155+
)
156+
: []
157+
158+
const errorMessages =
159+
localizedErrors.length > 0
160+
? localizedErrors
161+
: pickerState.displayValidation.validationErrors
162+
147163
const helperPropsInvalid = pickerState.displayValidation.isInvalid
148164
? {
149-
text: pickerState.displayValidation.validationErrors.join('\n'),
165+
text: errorMessages.join('\n'),
150166
color: tokens.colors.interactive.warning__text.rgba,
151167
icon: <Icon size={16} data={warning_outlined} />,
152168
}

packages/eds-core-react/src/components/Datepicker/DateRangePicker.spec.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,40 @@ describe('DateRangePicker', () => {
150150
expect(disabledMaxElement).toHaveAttribute('aria-disabled', 'true')
151151
})
152152

153+
it('should display validation errors in the configured locale', () => {
154+
const maxDate = new Date(2024, 0, 1)
155+
const outOfRangeDate = {
156+
from: new Date(2024, 5, 10),
157+
to: new Date(2024, 5, 15),
158+
}
159+
160+
const { container, rerender } = render(
161+
<I18nProvider locale={'en-US'}>
162+
<DateRangePicker
163+
label={'DateRangePicker'}
164+
value={outOfRangeDate}
165+
maxValue={maxDate}
166+
/>
167+
</I18nProvider>,
168+
)
169+
170+
// English: "Value must be ... or earlier."
171+
expect(container.textContent).toMatch(/Value must be/)
172+
173+
rerender(
174+
<I18nProvider locale={'nb-NO'}>
175+
<DateRangePicker
176+
label={'DateRangePicker'}
177+
value={outOfRangeDate}
178+
maxValue={maxDate}
179+
/>
180+
</I18nProvider>,
181+
)
182+
183+
// Norwegian: "Verdien må være ... eller tidligere."
184+
expect(container.textContent).toMatch(/Verdien/)
185+
})
186+
153187
it('should be possible to limit specific days', async () => {
154188
const date = {
155189
from: new Date(2024, 4, 4),

packages/eds-core-react/src/components/Datepicker/DateRangePicker.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { tokens } from '@equinor/eds-tokens'
2525
import { Icon } from '../Icon'
2626
import { getCalendarDate } from './utils/get-calendar-date'
2727
import { useGetLocale } from './utils/useGetLocale'
28+
import { getLocalizedValidationErrors } from './utils/getLocalizedValidationErrors'
2829

2930
/**
3031
* DateRangePicker component encapsulates the logic for selecting a range of dates
@@ -133,9 +134,24 @@ export const DateRangePicker = forwardRef(
133134
calendarProps,
134135
} = useDateRangePicker(dateRangePickerStateProps, state, ref)
135136

137+
const localizedErrors = state.displayValidation.isInvalid
138+
? getLocalizedValidationErrors(
139+
state.displayValidation.validationDetails,
140+
locale,
141+
_minValue,
142+
_maxValue,
143+
timezone,
144+
)
145+
: []
146+
147+
const errorMessages =
148+
localizedErrors.length > 0
149+
? localizedErrors
150+
: state.displayValidation.validationErrors
151+
136152
const helperProps = state.displayValidation.isInvalid
137153
? {
138-
text: state.displayValidation.validationErrors.join('\n'),
154+
text: errorMessages.join('\n'),
139155
color: tokens.colors.interactive.warning__text.rgba,
140156
icon: <Icon size={16} data={warning_outlined} />,
141157
}

0 commit comments

Comments
 (0)