diff --git a/src/generic/datepicker-control/DatepickerControl.jsx b/src/generic/datepicker-control/DatepickerControl.jsx
index 91306f2f11..84329f65de 100644
--- a/src/generic/datepicker-control/DatepickerControl.jsx
+++ b/src/generic/datepicker-control/DatepickerControl.jsx
@@ -32,6 +32,22 @@ const DatepickerControl = ({
[DATEPICKER_TYPES.date]: DATE_FORMAT,
[DATEPICKER_TYPES.time]: TIME_FORMAT,
};
+ const isTimePicker = type === DATEPICKER_TYPES.time;
+
+ let describedByIds;
+ if (isTimePicker) {
+ const ids = [`${controlName}-timehint`];
+ if (helpText) {
+ ids.push(`${controlName}-helptext`);
+ }
+ describedByIds = ids.filter(Boolean).join(' ') || undefined;
+ } else if (helpText) {
+ describedByIds = `${controlName}-helptext`;
+ }
+
+ const ariaLabel = isTimePicker
+ ? intl.formatMessage(messages.timepickerAriaLabel)
+ : undefined;
return (
@@ -67,6 +83,8 @@ const DatepickerControl = ({
showTimeSelectOnly={type === DATEPICKER_TYPES.time}
placeholderText={inputFormat[type].toLocaleUpperCase()}
showPopperArrow={false}
+ ariaLabel={ariaLabel}
+ ariaDescribedBy={describedByIds}
onChange={(date) => {
if (isValidDate(date)) {
onChange(convertToStringFromDate(date));
@@ -74,7 +92,18 @@ const DatepickerControl = ({
}}
/>
- {helpText && {helpText}}
+ {isTimePicker && (
+
+ {intl.formatMessage(messages.timepickerScreenreaderHint, {
+ timeFormat: inputFormat[type].toLocaleUpperCase(),
+ })}
+
+ )}
+ {helpText && (
+
+ {helpText}
+
+ )}
);
};
diff --git a/src/generic/datepicker-control/DatepickerControl.test.jsx b/src/generic/datepicker-control/DatepickerControl.test.jsx
index 509fc0cf8b..df158cc2b6 100644
--- a/src/generic/datepicker-control/DatepickerControl.test.jsx
+++ b/src/generic/datepicker-control/DatepickerControl.test.jsx
@@ -48,4 +48,21 @@ describe('', () => {
convertToStringFromDate('06/16/2023'),
);
});
+
+ it('renders time picker with accessibility hint', () => {
+ const { getByText, getByPlaceholderText } = render(
+ ,
+ );
+ const input = getByPlaceholderText('HH:MM');
+
+ expect(
+ getByText('Enter time in HH:MM or twelve-hour format, for example 6:00 PM.'),
+ ).toBeInTheDocument();
+ expect(input.getAttribute('aria-describedby')).toContain('fooControlName-timehint');
+ });
});
diff --git a/src/generic/datepicker-control/messages.js b/src/generic/datepicker-control/messages.js
index b6139f7b57..38446a69ac 100644
--- a/src/generic/datepicker-control/messages.js
+++ b/src/generic/datepicker-control/messages.js
@@ -9,6 +9,14 @@ const messages = defineMessages({
id: 'course-authoring.schedule.schedule-section.datepicker.utc',
defaultMessage: 'UTC',
},
+ timepickerAriaLabel: {
+ id: 'course-authoring.schedule.schedule-section.timepicker.aria-label',
+ defaultMessage: 'Time input field. Enter a time or use the arrow keys to adjust.',
+ },
+ timepickerScreenreaderHint: {
+ id: 'course-authoring.schedule.schedule-section.timepicker.screenreader-hint',
+ defaultMessage: 'Enter time in {timeFormat} or twelve-hour format, for example 6:00 PM.',
+ },
});
export default messages;