fix: keyboard accessibility for time picker (#2613)
This commit is contained in:
@@ -32,9 +32,21 @@ 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`;
|
||||
}
|
||||
|
||||
return (
|
||||
<Form.Group className="form-group-custom datepicker-custom">
|
||||
<Form.Group controlId={controlName} className="form-group-custom datepicker-custom">
|
||||
<Form.Label className="d-flex justify-content-between">
|
||||
{label}
|
||||
{showUTC && (
|
||||
@@ -52,6 +64,7 @@ const DatepickerControl = ({
|
||||
/>
|
||||
)}
|
||||
<DatePicker
|
||||
id={controlName}
|
||||
name={controlName}
|
||||
selected={formattedDate}
|
||||
disabled={readonly}
|
||||
@@ -67,6 +80,7 @@ const DatepickerControl = ({
|
||||
showTimeSelectOnly={type === DATEPICKER_TYPES.time}
|
||||
placeholderText={inputFormat[type].toLocaleUpperCase()}
|
||||
showPopperArrow={false}
|
||||
aria-describedby={describedByIds}
|
||||
onChange={(date) => {
|
||||
if (isValidDate(date)) {
|
||||
onChange(convertToStringFromDate(date));
|
||||
@@ -74,7 +88,18 @@ const DatepickerControl = ({
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{helpText && <Form.Control.Feedback>{helpText}</Form.Control.Feedback>}
|
||||
{isTimePicker && (
|
||||
<Form.Text id={`${controlName}-timehint`} className="sr-only">
|
||||
{intl.formatMessage(messages.timepickerScreenreaderHint, {
|
||||
timeFormat: inputFormat[type].toLocaleUpperCase(),
|
||||
})}
|
||||
</Form.Text>
|
||||
)}
|
||||
{helpText && (
|
||||
<Form.Control.Feedback id={`${controlName}-helptext`}>
|
||||
{helpText}
|
||||
</Form.Control.Feedback>
|
||||
)}
|
||||
</Form.Group>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -48,4 +48,40 @@ describe('<DatepickerControl />', () => {
|
||||
convertToStringFromDate('06/16/2023'),
|
||||
);
|
||||
});
|
||||
|
||||
it('renders time picker with accessibility hint', () => {
|
||||
const { getByText, getByPlaceholderText } = render(
|
||||
<RootWrapper
|
||||
{...props}
|
||||
type={DATEPICKER_TYPES.time}
|
||||
value="2025-01-01T10:00:00Z"
|
||||
helpText=""
|
||||
/>,
|
||||
);
|
||||
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');
|
||||
});
|
||||
|
||||
it('renders time picker with accessibility hint and help text', () => {
|
||||
const { getByText, getByPlaceholderText } = render(
|
||||
<RootWrapper
|
||||
{...props}
|
||||
type={DATEPICKER_TYPES.time}
|
||||
value="2025-01-01T10:00:00Z"
|
||||
helpText="This is help text"
|
||||
/>,
|
||||
);
|
||||
const input = getByPlaceholderText('HH:MM');
|
||||
|
||||
expect(
|
||||
getByText('Enter time in HH:MM or twelve-hour format, for example 6:00 PM.'),
|
||||
).toBeInTheDocument();
|
||||
expect(getByText('This is help text')).toBeInTheDocument();
|
||||
expect(input.getAttribute('aria-describedby')).toContain('fooControlName-timehint');
|
||||
expect(input.getAttribute('aria-describedby')).toContain('fooControlName-helptext');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user