Skip to content

Commit cb03690

Browse files
committed
Merge branch 'main' into at/wizard-integration
2 parents f201865 + dbf5b75 commit cb03690

File tree

13 files changed

+128
-49
lines changed

13 files changed

+128
-49
lines changed

.changeset/red-years-bet.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.github/workflows/release.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,12 +196,18 @@ jobs:
196196
uses: changesets/action@v1
197197
with:
198198
version: pnpm run version # Rebuild packages to ensure any uncommitted pre-build artifacts
199-
publish: pnpm publish -r --no-git-checks # Use `pnpm publish` directly to resolve `workspace` dependencies
199+
publish: pnpm run publish
200200
createGithubReleases: true
201201
env:
202202
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
203203
NPM_TOKEN: '${{ secrets.NPM_TOKEN }}'
204204

205+
- name: Debug changesets output
206+
run: |
207+
echo "Changesets output: ${{ steps.changesets.outputs }}"
208+
echo "Changesets output type: ${{ toJSON(steps.changesets.outputs) }}"
209+
echo "--------------------------------"
210+
205211
release-aws:
206212
name: Publish to AWS CodeArtifact
207213
runs-on: ubuntu-latest

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
"link": "lg link",
3333
"lint": "lg lint",
3434
"prepublishOnly": "pnpm run build && pnpm build:ts-downlevel && pnpm build:docs",
35-
"publish": "pnpm changeset publish --public",
35+
"publish": "pnpm publish --recursive --no-git-checks",
3636
"reset:react17": "npx node ./scripts/react17/reset.mjs; pnpm run init",
3737
"slackbot": "lg slackbot",
3838
"start": "npx storybook dev -p 9001 --no-version-updates --no-open",

packages/date-picker/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# @leafygreen-ui/date-picker
22

3+
## 4.1.1
4+
5+
### Patch Changes
6+
7+
- 0c42aba: [LG-3879](https://jira.mongodb.org/browse/LG-3879)
8+
Updates ARIA labels for DatePicker menu previous/next buttons, and year/month select elements.
9+
Hides calendar cell text, so screen-readers only read the cell's `aria-value`.
10+
311
## 4.1.0
412

513
### Minor Changes

packages/date-picker/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@leafygreen-ui/date-picker",
3-
"version": "4.1.0",
3+
"version": "4.1.1",
44
"description": "LeafyGreen UI Kit Date Picker",
55
"license": "Apache-2.0",
66
"main": "./dist/umd/index.js",

packages/date-picker/src/DatePicker/DatePicker.testutils.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,14 @@ export const renderDatePicker = (
114114
const calendarGrid = withinElement(menuContainerEl)?.queryByRole('grid');
115115
const calendarCells =
116116
withinElement(menuContainerEl)?.getAllByRole('gridcell');
117-
const leftChevron =
118-
withinElement(menuContainerEl)?.queryByLabelText('Previous month') ||
119-
withinElement(menuContainerEl)?.queryByLabelText('Previous valid month');
120-
const rightChevron =
121-
withinElement(menuContainerEl)?.queryByLabelText('Next month') ||
122-
withinElement(menuContainerEl)?.queryByLabelText('Next valid month');
117+
118+
// TODO: date-picker test harnesses https://jira.mongodb.org/browse/LG-4176
119+
const leftChevron = withinElement(menuContainerEl)?.queryByTestId(
120+
'lg-date_picker-menu-prev_month_button',
121+
);
122+
const rightChevron = withinElement(menuContainerEl)?.queryByTestId(
123+
'lg-date_picker-menu-next_month_button',
124+
);
123125
const monthSelect = withinElement(menuContainerEl)?.queryByLabelText(
124126
'Select month',
125127
{

packages/date-picker/src/DatePicker/DatePickerMenu/DatePickerMenu.spec.tsx

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,16 +123,32 @@ describe('packages/date-picker/date-picker-menu', () => {
123123
expect(grid).toHaveAttribute('aria-label', 'September 2023');
124124
});
125125
test('chevrons have aria labels', () => {
126-
const { getByLabelText } = renderDatePickerMenu();
127-
const leftChevron = getByLabelText('Previous month');
128-
const rightChevron = getByLabelText('Next month');
126+
const { getByTestId } = renderDatePickerMenu();
127+
const leftChevron = getByTestId('lg-date_picker-menu-prev_month_button');
128+
const rightChevron = getByTestId('lg-date_picker-menu-next_month_button');
129129
expect(leftChevron).toBeInTheDocument();
130130
expect(rightChevron).toBeInTheDocument();
131+
expect(leftChevron).toHaveAttribute(
132+
'aria-label',
133+
expect.stringContaining('Previous month'),
134+
);
135+
expect(rightChevron).toHaveAttribute(
136+
'aria-label',
137+
expect.stringContaining('Next month'),
138+
);
131139
});
132140
test('select menu triggers have aria labels', () => {
133141
const { monthSelect, yearSelect } = renderDatePickerMenu();
134142
expect(monthSelect).toBeInTheDocument();
135143
expect(yearSelect).toBeInTheDocument();
144+
expect(monthSelect).toHaveAttribute(
145+
'aria-label',
146+
expect.stringContaining('Select month'),
147+
);
148+
expect(yearSelect).toHaveAttribute(
149+
'aria-label',
150+
expect.stringContaining('Select year'),
151+
);
136152
});
137153
test('select menus have correct values', () => {
138154
const { monthSelect, yearSelect } = renderDatePickerMenu();

packages/date-picker/src/DatePicker/DatePickerMenu/DatePickerMenuHeader/DatePickerMenuHeader.tsx

Lines changed: 60 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import React, { forwardRef, MouseEventHandler } from 'react';
22

3-
import { isSameUTCMonth, setUTCMonth } from '@leafygreen-ui/date-utils';
3+
import {
4+
getMonthName,
5+
isSameUTCMonth,
6+
setUTCMonth,
7+
} from '@leafygreen-ui/date-utils';
48
import { SupportedLocales } from '@leafygreen-ui/date-utils';
59
import { Icon } from '@leafygreen-ui/icon';
610
import { IconButton } from '@leafygreen-ui/icon-button';
11+
import { isDefined } from '@leafygreen-ui/lib';
712

813
import { useSharedDatePickerContext } from '../../../shared/context';
914
import { useDatePickerContext } from '../../DatePickerContext';
@@ -42,6 +47,12 @@ export const DatePickerMenuHeader = forwardRef<
4247

4348
const isIsoFormat = locale === SupportedLocales.ISO_8601;
4449

50+
const formatMonth = (date: Date) => {
51+
const monthName = getMonthName(date.getUTCMonth(), locale);
52+
const year = date.getUTCFullYear().toString();
53+
return `${monthName.long} ${year}`;
54+
};
55+
4556
/**
4657
* If the month is not in range and is not the last valid month
4758
* e.g.
@@ -63,6 +74,48 @@ export const DatePickerMenuHeader = forwardRef<
6374
return !isDateInRange && !isOnLastValidMonth;
6475
};
6576

77+
/**
78+
* Given a direction (left/right), computes the nearest valid adjacent month
79+
*
80+
* @example
81+
* max: new Date(Date.UTC(2038, Month.January, 19));
82+
* current month date: new Date(Date.UTC(2038, Month.March, 19));
83+
* `left` chevron will change the month back to January 2038
84+
*
85+
* @example
86+
* min: new Date(Date.UTC(1970, Month.January, 1));
87+
* current month date: new Date(Date.UTC(1969, Month.November, 19));
88+
* "right" chevron will change the month back to January 1970
89+
*/
90+
const getNewMonth = (dir: 'left' | 'right'): Date => {
91+
if (isMonthInvalid(dir)) {
92+
const closestValidDate = dir === 'left' ? max : min;
93+
const newMonthIndex = closestValidDate.getUTCMonth();
94+
const newMonth = setUTCMonth(closestValidDate, newMonthIndex);
95+
return newMonth;
96+
} else {
97+
const increment = dir === 'left' ? -1 : 1;
98+
const newMonthIndex = month.getUTCMonth() + increment;
99+
const newMonth = setUTCMonth(month, newMonthIndex);
100+
return newMonth;
101+
}
102+
};
103+
104+
const getChevronButtonLabel = (dir: 'left' | 'right') => {
105+
const dirLabel = dir === 'left' ? 'Previous' : 'Next';
106+
const isNewMonthInvalid = isMonthInvalid(dir);
107+
const newMonth = getNewMonth(dir);
108+
const newMonthString = formatMonth(newMonth);
109+
return [
110+
dirLabel,
111+
isNewMonthInvalid ? 'valid' : undefined,
112+
'month',
113+
`(${newMonthString})`,
114+
]
115+
.filter(isDefined)
116+
.join(' ');
117+
};
118+
66119
/**
67120
* Calls the `updateMonth` helper with the appropriate month when a Chevron is clicked
68121
*/
@@ -71,35 +124,16 @@ export const DatePickerMenuHeader = forwardRef<
71124
e => {
72125
e.stopPropagation();
73126
e.preventDefault();
74-
75-
// e.g.
76-
// max: new Date(Date.UTC(2038, Month.January, 19));
77-
// current month date: new Date(Date.UTC(2038, Month.March, 19));
78-
// left chevron will change the month back to January 2038
79-
// e.g.
80-
// min: new Date(Date.UTC(1970, Month.January, 1));
81-
// current month date: new Date(Date.UTC(1969, Month.November, 19));
82-
// right chevron will change the month back to January 1970
83-
if (isMonthInvalid(dir)) {
84-
const closestValidDate = dir === 'left' ? max : min;
85-
const newMonthIndex = closestValidDate.getUTCMonth();
86-
const newMonth = setUTCMonth(closestValidDate, newMonthIndex);
87-
updateMonth(newMonth);
88-
} else {
89-
const increment = dir === 'left' ? -1 : 1;
90-
const newMonthIndex = month.getUTCMonth() + increment;
91-
const newMonth = setUTCMonth(month, newMonthIndex);
92-
updateMonth(newMonth);
93-
}
127+
const newMonth = getNewMonth(dir);
128+
updateMonth(newMonth);
94129
};
95130

96131
return (
97132
<div ref={fwdRef} className={menuHeaderStyles} {...rest}>
98133
<IconButton
99134
ref={refs.chevronButtonRefs.left}
100-
aria-label={
101-
isMonthInvalid('left') ? 'Previous valid month' : 'Previous month'
102-
}
135+
data-testid="lg-date_picker-menu-prev_month_button"
136+
aria-label={getChevronButtonLabel('left')}
103137
disabled={shouldChevronBeDisabled('left', month, min)}
104138
onClick={handleChevronClick('left')}
105139
>
@@ -120,7 +154,8 @@ export const DatePickerMenuHeader = forwardRef<
120154
</div>
121155
<IconButton
122156
ref={refs.chevronButtonRefs.right}
123-
aria-label={isMonthInvalid('right') ? 'Next valid month' : 'Next month'}
157+
data-testid="lg-date_picker-menu-next_month_button"
158+
aria-label={getChevronButtonLabel('right')}
124159
disabled={shouldChevronBeDisabled('right', month, max)}
125160
onClick={handleChevronClick('right')}
126161
>

packages/date-picker/src/DatePicker/DatePickerMenu/DatePickerMenuSelect/DatePickerMenuSelectMonth.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import React, { useCallback } from 'react';
22

3-
import { getLocaleMonths, setUTCMonth } from '@leafygreen-ui/date-utils';
3+
import {
4+
getLocaleMonths,
5+
getMonthName,
6+
setUTCMonth,
7+
} from '@leafygreen-ui/date-utils';
48
import { cx } from '@leafygreen-ui/emotion';
59
import { Option, Select } from '@leafygreen-ui/select';
610

@@ -40,16 +44,18 @@ export const DatePickerMenuSelectMonth = ({
4044
updateMonth(newMonth);
4145
};
4246

47+
const monthString = getMonthName(month.getUTCMonth(), locale);
48+
4349
return (
4450
<Select
4551
{...selectElementProps}
46-
aria-label="select month"
52+
aria-label={`Select month (${monthString.long} selected)`}
4753
value={month.getUTCMonth().toString()}
4854
onChange={handleMonthOnChange}
4955
className={cx(selectTruncateStyles, selectInputWidthStyles)}
5056
onEntered={() => setIsSelectOpen(true)}
5157
onExited={() => setIsSelectOpen(false)}
52-
placeholder={monthOptions[month.getUTCMonth()].short}
58+
placeholder={monthString.short}
5359
>
5460
{monthOptions.map((m, i) => (
5561
<Option

packages/date-picker/src/DatePicker/DatePickerMenu/DatePickerMenuSelect/DatePickerMenuSelectYear.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,18 @@ export const DatePickerMenuSelectYear = ({
3333
updateMonth(newMonth);
3434
};
3535

36+
const yearString = month.getUTCFullYear().toString();
37+
3638
return (
3739
<Select
3840
{...selectElementProps}
39-
aria-label="select year"
40-
value={month.getUTCFullYear().toString()}
41+
aria-label={`Select year (${yearString} selected)`}
42+
value={yearString}
4143
onChange={handleYearOnChange}
4244
className={cx(selectTruncateStyles, selectInputWidthStyles)}
4345
onEntered={() => setIsSelectOpen(true)}
4446
onExited={() => setIsSelectOpen(false)}
45-
placeholder={month.getUTCFullYear().toString()}
47+
placeholder={yearString}
4648
>
4749
{yearOptions.map(y => (
4850
<Option value={y.toString()} key={y} aria-label={y.toString()}>

0 commit comments

Comments
 (0)