{
{withYearPicker ? (
/**
- * A button to render in the navigation header. The recommendation is to
- * compose it with the [IconButton](Button) component by setting the `size`
- * prop to `small`, `withBorder` and `withBackground` to `false`, and setting
- * `renderIcon` to [IconArrowOpenStart](icons).
+ * A button to render in the navigation header.
+ * When passed as a function, receives `{ targetMonthSrLabel }` —
+ * a pre-formatted screen reader label for the target month (e.g. "November 2023").
+ * The recommendation is to compose it with the [IconButton](Button) component
+ * by setting the `size` prop to `small`, `withBorder` and `withBackground` to `false`,
+ * and setting `renderIcon` to [IconArrowOpenStart](icons).
*/
- renderPrevMonthButton?: Renderable
+ renderPrevMonthButton?: Renderable<{ targetMonthSrLabel: string }>
/**
* An array of labels containing the name of each day of the week. The visible
* portion of the label should be abbreviated (no longer than three characters).
@@ -182,7 +186,11 @@ type CalendarProps = CalendarOwnProps &
WithDeterministicIdProps
type CalendarStyle = ComponentStyle<
- 'navigation' | 'navigationWithButtons' | 'weekdayHeader' | 'yearPicker'
+ | 'navigation'
+ | 'navigationWithButtons'
+ | 'navigationLabel'
+ | 'weekdayHeader'
+ | 'yearPicker'
>
const allowedProps: AllowedPropKeys = [
'as',
diff --git a/packages/ui-calendar/src/Calendar/v2/styles.ts b/packages/ui-calendar/src/Calendar/v2/styles.ts
index eba9f9f3a6..6d3335c85e 100644
--- a/packages/ui-calendar/src/Calendar/v2/styles.ts
+++ b/packages/ui-calendar/src/Calendar/v2/styles.ts
@@ -63,6 +63,15 @@ const generateStyle = (
maxWidth: componentTheme.maxHeaderWidth,
lineHeight: componentTheme.lineHeight
},
+ navigationLabel: {
+ label: 'calendar__navigation-label',
+ margin: 0,
+ fontSize: 'inherit',
+ fontWeight: 'inherit',
+ '& span': {
+ display: 'block'
+ }
+ },
yearPicker: {
display: 'flex',
justifyContent: 'center',
diff --git a/packages/ui-date-input/src/DateInput/__tests__/DateInput.test.tsx b/packages/ui-date-input/src/DateInput/__tests__/DateInput.test.tsx
index 3005ea69a4..94c65a3cde 100644
--- a/packages/ui-date-input/src/DateInput/__tests__/DateInput.test.tsx
+++ b/packages/ui-date-input/src/DateInput/__tests__/DateInput.test.tsx
@@ -220,21 +220,15 @@ describe('', () => {
await waitFor(() => {
const prevMonthButton = screen.getByRole('button', {
- name: prevMonthLabel
+ name: new RegExp(`^${prevMonthLabel}`)
})
const nextMonthButton = screen.getByRole('button', {
- name: nextMonthLabel
+ name: new RegExp(`^${nextMonthLabel}`)
})
expect(prevMonthButton).toBeInTheDocument()
expect(nextMonthButton).toBeInTheDocument()
- const prevButtonLabel = screen.getByText(prevMonthLabel)
- const nextButtonLabel = screen.getByText(nextMonthLabel)
-
- expect(prevButtonLabel).toBeInTheDocument()
- expect(nextButtonLabel).toBeInTheDocument()
-
const prevMonthIcon = prevMonthButton.querySelector(
'svg[name="ChevronLeft"]'
)
diff --git a/packages/ui-date-input/src/DateInput/v2/index.tsx b/packages/ui-date-input/src/DateInput/v2/index.tsx
index 792f6df884..ee2bef3181 100644
--- a/packages/ui-date-input/src/DateInput/v2/index.tsx
+++ b/packages/ui-date-input/src/DateInput/v2/index.tsx
@@ -311,24 +311,24 @@ const DateInput = forwardRef(
visibleMonth={selectedDate}
locale={userLocale}
timezone={userTimezone}
- renderNextMonthButton={
+ renderNextMonthButton={({ targetMonthSrLabel }) => (
}
- screenReaderLabel={screenReaderLabels.nextMonthButton}
+ screenReaderLabel={`${screenReaderLabels.nextMonthButton}, ${targetMonthSrLabel}`}
/>
- }
- renderPrevMonthButton={
+ )}
+ renderPrevMonthButton={({ targetMonthSrLabel }) => (
}
- screenReaderLabel={screenReaderLabels.prevMonthButton}
+ screenReaderLabel={`${screenReaderLabels.prevMonthButton}, ${targetMonthSrLabel}`}
/>
- }
+ )}
/>
}
diff --git a/packages/ui-dialog/src/Dialog/index.tsx b/packages/ui-dialog/src/Dialog/index.tsx
index 09e0243766..8fdc15db9f 100644
--- a/packages/ui-dialog/src/Dialog/index.tsx
+++ b/packages/ui-dialog/src/Dialog/index.tsx
@@ -168,6 +168,9 @@ class Dialog extends Component {
{...omitProps(this.props, Dialog.allowedProps)}
role={role}
aria-label={this.props.label}
+ aria-modal={
+ role === 'dialog' && this.props.shouldContainFocus ? true : undefined
+ }
className={this.props.className} // TODO in V2 remove className, there is no usage of it.
style={{ borderRadius: 'inherit' }} // ensure the dialog inherits border radius from View
ref={this.getRef}