Skip to content

Commit

Permalink
fix(date-range): date range axe issue
Browse files Browse the repository at this point in the history
added role and corresponding aria attributes to the date picker

fixes #2633
  • Loading branch information
mihai-albu-sage committed Jan 10, 2025
1 parent f49fbff commit 1b031d4
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/components/date-range/date-range-test.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ DateRangeStory.args = {
allowEmptyValueOnStartDate: undefined,
allowEmptyValueOnEndDate: undefined,
labelsInline: false,
datePickerStartAriaLabel: "start aria-label",
datePickerStartAriaLabelledBy: "start aria-labelledby",
datePickerEndAriaLabel: "end aria-label",
datePickerEndAriaLabelledBy: "end aria-labelledby",
};

export const DateRangeCustom = ({
Expand Down
16 changes: 16 additions & 0 deletions src/components/date-range/date-range.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,14 @@ export interface DateRangeProps
isOptional?: boolean;
/** Date format string to be applied to the date inputs */
dateFormatOverride?: string;
/** Prop to specify the aria-label attribute of the start date picker */
datePickerStartAriaLabel?: string;
/** Prop to specify the aria-labelledby attribute of the start date picker */
datePickerStartAriaLabelledBy?: string;
/** Prop to specify the aria-label attribute of the end date picker */
datePickerEndAriaLabel?: string;
/** Prop to specify the aria-labelledby attribute of the end date picker */
datePickerEndAriaLabelledBy?: string;
}

export const DateRange = ({
Expand All @@ -135,6 +143,10 @@ export const DateRange = ({
endRef,
required,
isOptional,
datePickerStartAriaLabel,
datePickerStartAriaLabelledBy,
datePickerEndAriaLabel,
datePickerEndAriaLabelledBy,
...rest
}: DateRangeProps) => {
const { validationRedesignOptIn } = useContext(NewValidationContext);
Expand Down Expand Up @@ -373,6 +385,8 @@ export const DateRange = ({
labelWidth={inlineLabelWidth} // Textbox only applies this when labelsInLine prop is true
tooltipPosition={tooltipPosition}
ref={startRef}
datePickerAriaLabel={datePickerStartAriaLabel}
datePickerAriaLabelledBy={datePickerStartAriaLabelledBy}
/>
<DateInput
my={0} // prevents any form spacing being applied
Expand All @@ -383,6 +397,8 @@ export const DateRange = ({
labelWidth={inlineLabelWidth} // Textbox only applies this when labelsInLine prop is true
tooltipPosition={tooltipPosition}
ref={endRef}
datePickerAriaLabel={datePickerEndAriaLabel}
datePickerAriaLabelledBy={datePickerEndAriaLabelledBy}
/>
</DateRangeContext.Provider>
</StyledDateRange>
Expand Down
44 changes: 44 additions & 0 deletions src/components/date-range/date-range.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,50 @@ test("should close the open 'start' picker when the user moves focus to the `end
expect(within(startDate).queryByRole("grid")).not.toBeInTheDocument();
});

test("should apply aria-label and aria-labelledby to the date picker region", async () => {
const user = userEvent.setup();
render(
<DateRange
startLabel="start"
endLabel="end"
value={["10/10/2016", "11/11/2016"]}
onChange={() => {}}
startDateProps={{ disablePortal: true, "data-role": "start" }}
endDateProps={{ disablePortal: true, "data-role": "end" }}
datePickerStartAriaLabel="start aria-label"
datePickerStartAriaLabelledBy="start aria-labelledby"
datePickerEndAriaLabel="end aria-label"
datePickerEndAriaLabelledBy="end aria-labelledby"
/>,
);
const startDate = screen.getByTestId("start");
const endDate = screen.getByTestId("end");

await user.click(screen.getByRole("textbox", { name: "start" }));

expect(within(startDate).getByRole("region")).toBeVisible();
expect(within(startDate).getByRole("region")).toHaveAttribute(
"aria-label",
"start aria-label",
);
expect(within(startDate).getByRole("region")).toHaveAttribute(
"aria-labelledby",
"start aria-labelledby",
);

await user.click(screen.getByRole("textbox", { name: "end" }));

expect(within(endDate).getByRole("region")).toBeVisible();
expect(within(endDate).getByRole("region")).toHaveAttribute(
"aria-label",
"end aria-label",
);
expect(within(endDate).getByRole("region")).toHaveAttribute(
"aria-labelledby",
"end aria-labelledby",
);
});

test("should close the open 'end' picker when the user moves focus to the `start` input", async () => {
const user = userEvent.setup();
render(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ export interface DatePickerProps {
pickerTabGuardId?: string;
/** Callback triggered when the picker is closed */
onPickerClose?: () => void;
/** Prop to specify the aria-label attribute of the date picker */
ariaLabel?: string;
/** Prop to specify the aria-labelledby attribute of the date picker */
ariaLabelledBy?: string;
}

const popoverMiddleware = [
Expand All @@ -85,6 +89,8 @@ export const DatePicker = ({
setOpen,
pickerTabGuardId,
onPickerClose,
ariaLabel: datePickerAriaLabel,
ariaLabelledBy: datePickerAriaLabelledBy,
}: DatePickerProps) => {
const [focusedMonth, setFocusedMonth] = useState<Date | undefined>(
selectedDays || new Date(),
Expand Down Expand Up @@ -226,6 +232,9 @@ export const DatePicker = ({
onMouseDown={pickerMouseDown}
onKeyUp={handleKeyUp}
onKeyDown={handleOnKeyDown}
role="region"
aria-label={datePickerAriaLabel}
aria-labelledby={datePickerAriaLabelledBy}
>
<div
id={pickerTabGuardId}
Expand Down
8 changes: 8 additions & 0 deletions src/components/date/date.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ export interface DateInputProps
onPickerClose?: () => void;
/** Date format string to be applied to the date inputs */
dateFormatOverride?: string;
/** Prop to specify the aria-label attribute of the date picker */
datePickerAriaLabel?: string;
/** Prop to specify the aria-labelledby attribute of the date picker */
datePickerAriaLabelledBy?: string;
}

export const DateInput = React.forwardRef<HTMLInputElement, DateInputProps>(
Expand Down Expand Up @@ -137,6 +141,8 @@ export const DateInput = React.forwardRef<HTMLInputElement, DateInputProps>(
inputName,
onPickerClose,
onPickerOpen,
datePickerAriaLabel,
datePickerAriaLabelledBy,
...rest
}: DateInputProps,
ref,
Expand Down Expand Up @@ -541,6 +547,8 @@ export const DateInput = React.forwardRef<HTMLInputElement, DateInputProps>(
setOpen={setOpen}
pickerTabGuardId={pickerTabGuardId.current}
onPickerClose={onPickerClose}
ariaLabel={datePickerAriaLabel}
ariaLabelledBy={datePickerAriaLabelledBy}
/>
</StyledDateInput>
);
Expand Down

0 comments on commit 1b031d4

Please sign in to comment.