Skip to content

Commit a0936db

Browse files
olemartinorgOle Martin Handeland
and
Ole Martin Handeland
authored
Always using autofocus in Datepicker, focussing back to the input when dialog is closed. This fixes the remaining accessibility issues in Datepicker. (#3394)
Co-authored-by: Ole Martin Handeland <git@olemartin.org>
1 parent 5e28fd7 commit a0936db

File tree

5 files changed

+14
-20
lines changed

5 files changed

+14
-20
lines changed

src/app-components/Datepicker/DatePickerCalendar.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ export interface CalendarDialogProps {
1414
minDate?: Date;
1515
locale?: string;
1616
required?: boolean;
17-
autoFocus?: boolean;
1817
onBlur?: () => void;
1918
DropdownCaption: typeof MonthCaption;
2019
}
@@ -26,7 +25,6 @@ export const DatePickerCalendar = ({
2625
maxDate,
2726
locale,
2827
required,
29-
autoFocus,
3028
DropdownCaption,
3129
}: CalendarDialogProps) => {
3230
const currentLocale = getLocale(locale ?? 'nb');
@@ -70,7 +68,7 @@ export const DatePickerCalendar = ({
7068
}
7169
}}
7270
components={{ MonthCaption: DropdownCaption }}
73-
autoFocus={autoFocus}
71+
autoFocus={true}
7472
style={{ minHeight: '405px', maxWidth: '100%' }}
7573
/>
7674
);

src/app-components/Datepicker/DatePickerInput.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React, { useEffect, useState } from 'react';
22
import { PatternFormat } from 'react-number-format';
3+
import type { Ref } from 'react';
34

45
import { Textfield } from '@digdir/designsystemet-react';
56
import { format, isValid } from 'date-fns';
@@ -22,15 +23,10 @@ export interface DatePickerInputProps {
2223
autoComplete?: 'bday';
2324
}
2425

25-
export function DatePickerInput({
26-
id,
27-
value,
28-
datepickerFormat,
29-
timeStamp,
30-
onValueChange,
31-
readOnly,
32-
autoComplete,
33-
}: DatePickerInputProps) {
26+
function DatePickerInputRef(
27+
{ id, value, datepickerFormat, timeStamp, onValueChange, readOnly, autoComplete }: DatePickerInputProps,
28+
ref: Ref<HTMLInputElement>,
29+
) {
3430
const dateValue = strictParseISO(value);
3531
const formattedDateValue = dateValue ? format(dateValue, datepickerFormat) : value;
3632
const [inputValue, setInputValue] = useState(formattedDateValue ?? '');
@@ -58,6 +54,7 @@ export function DatePickerInput({
5854

5955
return (
6056
<PatternFormat
57+
getInputRef={ref}
6158
format={getFormatAsPatternFormat(datepickerFormat)}
6259
customInput={Textfield}
6360
mask='_'
@@ -77,3 +74,6 @@ export function DatePickerInput({
7774
/>
7875
);
7976
}
77+
78+
export const DatePickerInput = React.forwardRef(DatePickerInputRef);
79+
DatePickerInput.displayName = 'DatePickerInput';

src/app-components/Datepicker/Datepicker.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from 'react';
1+
import React, { useRef, useState } from 'react';
22
import type { MonthCaption } from 'react-day-picker';
33

44
import { CalendarIcon } from '@navikt/aksel-icons';
@@ -23,7 +23,6 @@ export type DatePickerControlProps = {
2323
minDate?: Date;
2424
maxDate?: Date;
2525
locale: string;
26-
isMobile?: boolean;
2726
DropdownCaption: typeof MonthCaption;
2827
buttonAriaLabel: string;
2928
calendarIconTitle: string;
@@ -41,12 +40,12 @@ export const DatePickerControl: React.FC<DatePickerControlProps> = ({
4140
minDate,
4241
maxDate,
4342
locale,
44-
isMobile = false,
4543
buttonAriaLabel,
4644
DropdownCaption,
4745
calendarIconTitle,
4846
autoComplete,
4947
}) => {
48+
const inputRef = useRef<HTMLInputElement>(null);
5049
const [isDialogOpen, setIsDialogOpen] = useState(false);
5150
const dateValue = new Date(value);
5251
const dayPickerDate = isValidDate(dateValue) ? dateValue : undefined;
@@ -69,6 +68,7 @@ export const DatePickerControl: React.FC<DatePickerControlProps> = ({
6968
>
7069
<div className={styles.calendarInputWrapper}>
7170
<DatePickerInput
71+
ref={inputRef}
7272
id={id}
7373
value={value}
7474
datepickerFormat={dateFormat}
@@ -107,11 +107,11 @@ export const DatePickerControl: React.FC<DatePickerControlProps> = ({
107107
onSelect={(date) => {
108108
handleDayPickerSelect(date);
109109
setIsDialogOpen(false);
110+
inputRef.current?.focus();
110111
}}
111112
minDate={minDate}
112113
maxDate={maxDate}
113114
required={required}
114-
autoFocus={isMobile}
115115
DropdownCaption={DropdownCaption}
116116
/>
117117
</DatePickerDialog>

src/app-components/DynamicForm/DynamicForm.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,6 @@ export function FieldRenderer({
231231
readOnly={false}
232232
required={required}
233233
locale={locale!}
234-
isMobile={false}
235234
DropdownCaption={DropdownCaption}
236235
buttonAriaLabel={buttonAriaLabel}
237236
calendarIconTitle={calendarIconTitle}

src/layout/Datepicker/DatepickerComponent.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { Label } from 'src/app-components/Label/Label';
77
import { useDataModelBindings } from 'src/features/formData/useDataModelBindings';
88
import { useCurrentLanguage } from 'src/features/language/LanguageProvider';
99
import { useLanguage } from 'src/features/language/useLanguage';
10-
import { useIsMobile } from 'src/hooks/useDeviceWidths';
1110
import { ComponentStructureWrapper } from 'src/layout/ComponentStructureWrapper';
1211
import { DropdownCaption } from 'src/layout/Datepicker/DropdownCaption';
1312
import { getDatepickerFormat } from 'src/utils/dateUtils';
@@ -38,7 +37,6 @@ export function DatepickerComponent({ node, overrideDisplay }: IDatepickerProps)
3837
const calculatedMinDate = getDateConstraint(minDate, 'min');
3938
const calculatedMaxDate = getDateConstraint(maxDate, 'max');
4039
const dateFormat = getDatepickerFormat(getDateFormat(format, languageLocale));
41-
const isMobile = useIsMobile();
4240

4341
const { setValue, formData } = useDataModelBindings(dataModelBindings);
4442
const value = formData.simpleBinding;
@@ -76,7 +74,6 @@ export function DatepickerComponent({ node, overrideDisplay }: IDatepickerProps)
7674
readOnly={readOnly}
7775
required={required}
7876
locale={languageLocale}
79-
isMobile={isMobile}
8077
minDate={calculatedMinDate}
8178
maxDate={calculatedMaxDate}
8279
DropdownCaption={DropdownCaption}

0 commit comments

Comments
 (0)