Skip to content

Commit

Permalink
LG-3878: Date Picker add current year/month selection to aria-label (#…
Browse files Browse the repository at this point in the history
…2183)

* add current selection to aria label

* add changeset

* fix tests

* address comments

---------

Co-authored-by: Brooke Scarlett Yalof <[email protected]>
  • Loading branch information
shaneeza and bruugey authored Jan 26, 2024
1 parent a3d8d17 commit ae0e362
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 41 deletions.
5 changes: 5 additions & 0 deletions .changeset/tough-goats-jam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@leafygreen-ui/date-picker': patch
---

Dynamically update the `aria-label` for the year/month select to include the current selection, enabling screen readers to announce the current selection.
16 changes: 12 additions & 4 deletions packages/date-picker/src/DatePicker/DatePicker.testutils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,18 @@ export const renderDatePicker = (
const rightChevron =
withinElement(menuContainerEl)?.queryByLabelText('Next month') ||
withinElement(menuContainerEl)?.queryByLabelText('Next valid month');
const monthSelect =
withinElement(menuContainerEl)?.queryByLabelText('Select month');
const yearSelect =
withinElement(menuContainerEl)?.queryByLabelText('Select year');
const monthSelect = withinElement(menuContainerEl)?.queryByLabelText(
'Select month',
{
exact: false,
},
);
const yearSelect = withinElement(menuContainerEl)?.queryByLabelText(
'Select year',
{
exact: false,
},
);

const queryCellByDate = (date: Date): HTMLTableCellElement | null => {
const cell = calendarGrid?.querySelector(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ const renderDatePickerMenu = (
const rightChevron =
result.queryByLabelText('Next month') ||
result.queryByLabelText('Next valid month');
const monthSelect = result.queryByLabelText('Select month');
const yearSelect = result.queryByLabelText('Select year');
const monthSelect = result.queryByLabelText('Select month', { exact: false });
const yearSelect = result.queryByLabelText('Select year', { exact: false });

return {
...result,
Expand Down Expand Up @@ -127,23 +127,19 @@ describe('packages/date-picker/date-picker-menu', () => {
expect(grid).toHaveAttribute('aria-label', 'September 2023');
});
test('chevrons have aria labels', () => {
const result = renderDatePickerMenu();
const leftChevron = result.getByLabelText('Previous month');
const rightChevron = result.getByLabelText('Next month');
const { getByLabelText } = renderDatePickerMenu();
const leftChevron = getByLabelText('Previous month');
const rightChevron = getByLabelText('Next month');
expect(leftChevron).toBeInTheDocument();
expect(rightChevron).toBeInTheDocument();
});
test('select menu triggers have aria labels', () => {
const result = renderDatePickerMenu();
const monthSelect = result.getByLabelText('Select month');
const yearSelect = result.getByLabelText('Select year');
const { monthSelect, yearSelect } = renderDatePickerMenu();
expect(monthSelect).toBeInTheDocument();
expect(yearSelect).toBeInTheDocument();
});
test('select menus have correct values', () => {
const result = renderDatePickerMenu();
const monthSelect = result.getByLabelText('Select month');
const yearSelect = result.getByLabelText('Select year');
const { monthSelect, yearSelect } = renderDatePickerMenu();
expect(monthSelect).toHaveValue(Month.September.toString());
expect(yearSelect).toHaveValue('2023');
});
Expand All @@ -169,14 +165,11 @@ describe('packages/date-picker/date-picker-menu', () => {
expect(grid).toHaveAttribute('aria-label', 'March 2024');
});
test('select menus have correct values', () => {
const { getByLabelText, rerenderDatePickerMenu } =
const { rerenderDatePickerMenu, monthSelect, yearSelect } =
renderDatePickerMenu();
rerenderDatePickerMenu(null, {
value: newUTC(2024, Month.March, 10),
});

const monthSelect = getByLabelText('Select month');
const yearSelect = getByLabelText('Select year');
expect(monthSelect).toHaveValue(Month.March.toString());
expect(yearSelect).toHaveValue('2024');
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,9 @@ export const OpenMonthMenu: DatePickerMenuInteractionTestType = {
play: async ctx => {
const canvas = within(ctx.canvasElement.parentElement!);
await canvas.findByRole('listbox');
const monthMenu = await canvas.findByLabelText('Select month');
const monthMenu = await canvas.findByLabelText('Select month', {
exact: false,
});
userEvent.click(monthMenu);
},
};
Expand All @@ -242,7 +244,9 @@ export const OpenYearMenu: DatePickerMenuInteractionTestType = {
play: async ctx => {
const canvas = within(ctx.canvasElement.parentElement!);
await canvas.findByRole('listbox');
const monthMenu = await canvas.findByLabelText('Select year');
const monthMenu = await canvas.findByLabelText('Select year', {
exact: false,
});
userEvent.click(monthMenu);
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ describe('packages/date-picker/menu/header', () => {
</MockSharedDatePickerProvider>,
);

const monthSelect = getByLabelText('Select month');
const monthSelect = getByLabelText('Select month', {
exact: false,
});

userEvent.click(monthSelect);

Expand Down Expand Up @@ -87,7 +89,9 @@ describe('packages/date-picker/menu/header', () => {
</MockSharedDatePickerProvider>,
);

const monthSelect = getByLabelText('Select month');
const monthSelect = getByLabelText('Select month', {
exact: false,
});

userEvent.click(monthSelect);

Expand Down Expand Up @@ -125,7 +129,9 @@ describe('packages/date-picker/menu/header', () => {
</MockSharedDatePickerProvider>,
);

const monthSelect = getByLabelText('Select month');
const monthSelect = getByLabelText('Select month', {
exact: false,
});

userEvent.click(monthSelect);

Expand Down Expand Up @@ -161,7 +167,9 @@ describe('packages/date-picker/menu/header', () => {
</MockSharedDatePickerProvider>,
);

const monthSelect = getByLabelText('Select month');
const monthSelect = getByLabelText('Select month', {
exact: false,
});

userEvent.click(monthSelect);

Expand Down Expand Up @@ -196,8 +204,12 @@ describe('packages/date-picker/menu/header', () => {
</MockSharedDatePickerProvider>,
);

const monthSelect = getByLabelText('Select month');
const yearSelect = getByLabelText('Select year');
const monthSelect = getByLabelText('Select month', {
exact: false,
});
const yearSelect = getByLabelText('Select year', {
exact: false,
});

expect(monthSelect).toHaveTextContent('Jul');
expect(yearSelect).toHaveTextContent('2025');
Expand Down Expand Up @@ -227,7 +239,9 @@ describe('packages/date-picker/menu/header', () => {
</MockSharedDatePickerProvider>,
);

const monthSelect = getByLabelText('Select month');
const monthSelect = getByLabelText('Select month', {
exact: false,
});

userEvent.click(monthSelect);

Expand Down Expand Up @@ -262,8 +276,12 @@ describe('packages/date-picker/menu/header', () => {
</MockSharedDatePickerProvider>,
);

const monthSelect = getByLabelText('Select month');
const yearSelect = getByLabelText('Select year');
const monthSelect = getByLabelText('Select month', {
exact: false,
});
const yearSelect = getByLabelText('Select year', {
exact: false,
});

expect(monthSelect).toHaveTextContent('Jul');
expect(yearSelect).toHaveTextContent('2021');
Expand Down Expand Up @@ -317,7 +335,9 @@ describe('packages/date-picker/menu/header', () => {
</AllMockProviders>,
);

const monthSelect = getByLabelText('Select month');
const monthSelect = getByLabelText('Select month', {
exact: false,
});
userEvent.click(monthSelect);
await waitFor(() => {
jest.advanceTimersByTime(transitionDuration.default);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@ export const DatePickerMenuHeader = forwardRef<
<div className={menuHeaderSelectContainerStyles}>
<Select
{...selectElementProps}
aria-label="Select month"
aria-label={`Select month - ${
monthOptions[month.getUTCMonth()].long
} selected`}
value={month.getUTCMonth().toString()}
onChange={m => {
const newMonth = setUTCMonth(month, Number(m));
Expand All @@ -147,7 +149,9 @@ export const DatePickerMenuHeader = forwardRef<
</Select>
<Select
{...selectElementProps}
aria-label="Select year"
aria-label={`Select year - ${month
.getUTCFullYear()
.toString()} selected`}
value={month.getUTCFullYear().toString()}
onChange={y => {
const newMonth = setUTCYear(month, Number(y));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ describe('packages/date-picker/shared/date-input-box', () => {
describe('Rendering', () => {
describe.each(['day', 'month', 'year'])('%p', segment => {
test('renders the correct aria attributes', () => {
const result = renderDateInputBox();
const input = result.getByLabelText(segment);
const { getByLabelText } = renderDateInputBox();
const input = getByLabelText(segment);

// each segment has appropriate aria label
expect(input).toHaveAttribute('aria-label', segment);
Expand All @@ -76,24 +76,30 @@ describe('packages/date-picker/shared/date-input-box', () => {

describe('renders segments in the correct order', () => {
test('iso8601', () => {
const result = renderDateInputBox(undefined, { locale: 'iso8601' });
const segments = result.getAllByRole('spinbutton');
const { getAllByRole } = renderDateInputBox(undefined, {
locale: 'iso8601',
});
const segments = getAllByRole('spinbutton');
expect(segments[0]).toHaveAttribute('aria-label', 'year');
expect(segments[1]).toHaveAttribute('aria-label', 'month');
expect(segments[2]).toHaveAttribute('aria-label', 'day');
});

test('en-US', () => {
const result = renderDateInputBox(undefined, { locale: 'en-US' });
const segments = result.getAllByRole('spinbutton');
const { getAllByRole } = renderDateInputBox(undefined, {
locale: 'en-US',
});
const segments = getAllByRole('spinbutton');
expect(segments[0]).toHaveAttribute('aria-label', 'month');
expect(segments[1]).toHaveAttribute('aria-label', 'day');
expect(segments[2]).toHaveAttribute('aria-label', 'year');
});

test('en-UK', () => {
const result = renderDateInputBox(undefined, { locale: 'en-UK' });
const segments = result.getAllByRole('spinbutton');
const { getAllByRole } = renderDateInputBox(undefined, {
locale: 'en-UK',
});
const segments = getAllByRole('spinbutton');
expect(segments[0]).toHaveAttribute('aria-label', 'day');
expect(segments[1]).toHaveAttribute('aria-label', 'month');
expect(segments[2]).toHaveAttribute('aria-label', 'year');
Expand Down

0 comments on commit ae0e362

Please sign in to comment.