Skip to content

Commit

Permalink
fix: Reannounce validation error in date range picker on apply (#3210)
Browse files Browse the repository at this point in the history
Co-authored-by: Joan Perals <[email protected]>
  • Loading branch information
abdhalees and jperals authored Feb 4, 2025
1 parent ddd4f97 commit 3f666b4
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 3 deletions.
59 changes: 58 additions & 1 deletion src/date-range-picker/__tests__/date-range-picker.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import * as React from 'react';
import { render } from '@testing-library/react';
import { render, waitFor } from '@testing-library/react';
import Mockdate from 'mockdate';

import { warnOnce } from '@cloudscape-design/component-toolkit/internal';
Expand Down Expand Up @@ -313,6 +313,63 @@ describe('Date range picker', () => {
changeMode(wrapper, 'relative');
expect(wrapper.findDropdown()!.findValidationError()).toBeNull();
});

test('reannounces error text when apply is clicked', async () => {
Mockdate.set(new Date('2020-01-01T12:30:20'));
({ wrapper } = renderDateRangePicker({
...defaultProps,
isValidRange: value => {
if (value === null) {
return {
valid: false,
errorMessage: 'No range selected',
};
}
if (value.type === 'relative' && value.amount === 10) {
return { valid: false, errorMessage: '10 is not allowed.' };
}
if (value.type === 'absolute') {
const [endDateWithoutTime] = value.endDate.split('T');

if (!endDateWithoutTime) {
return {
valid: false,
errorMessage: 'You must provide an end date',
};
}

if (value.startDate < '2020-01-01T00:00:00') {
return {
valid: false,
errorMessage: 'The range cannot start before 2020',
};
}
}
return { valid: true };
},
}));
wrapper.openDropdown();
changeMode(wrapper, 'absolute');
wrapper.findDropdown()?.findDateAt('left', 1, 1).click();
wrapper.findDropdown()!.findApplyButton().click();

const liveRegion = document.querySelectorAll('[aria-live=polite]')![3];

// announces first validation error
await waitFor(() => expect(liveRegion).toHaveTextContent('You must provide an end date'));

wrapper.findDropdown()?.findDateAt('left', 1, 3).click();

// announces different validation error
await waitFor(() => expect(liveRegion).toHaveTextContent('The range cannot start before 2020'));

wrapper.findDropdown()!.findApplyButton().click();

// reannounces second validation error
await waitFor(() => expect(liveRegion).toHaveTextContent('The range cannot start before 2020.'));

Mockdate.reset();
});
});

describe('change event', () => {
Expand Down
6 changes: 4 additions & 2 deletions src/date-range-picker/dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { ButtonProps } from '../button/interfaces';
import { InternalButton } from '../button/internal';
import { useInternalI18n } from '../i18n/context';
import FocusLock from '../internal/components/focus-lock';
import InternalLiveRegion from '../live-region/internal';
import InternalLiveRegion, { InternalLiveRegionRef } from '../live-region/internal';
import InternalSpaceBetween from '../space-between/internal';
import Calendar from './calendar';
import { DateRangePickerProps } from './interfaces';
Expand Down Expand Up @@ -84,6 +84,7 @@ export function DateRangePickerDropdown({
const i18n = useInternalI18n('date-range-picker');
const isMonthPicker = granularity === 'month';
const hideTime = dateOnly || isMonthPicker;
const liveRegionRef = useRef<InternalLiveRegionRef>(null);

const [rangeSelectionMode, setRangeSelectionMode] = useState<'absolute' | 'relative'>(
getDefaultMode(value, relativeOptions, rangeSelectorMode)
Expand Down Expand Up @@ -123,6 +124,7 @@ export function DateRangePickerDropdown({
if (newValidationResult.valid === false) {
setApplyClicked(true);
setValidationResult(newValidationResult);
liveRegionRef.current?.reannounce();
} else {
setApplyClicked(false);
closeDropdown();
Expand Down Expand Up @@ -230,7 +232,7 @@ export function DateRangePickerDropdown({
>
<span className={testutilStyles['validation-error']}>{validationResult.errorMessage}</span>
</InternalAlert>
<InternalLiveRegion hidden={true} tagName="span">
<InternalLiveRegion hidden={true} tagName="span" ref={liveRegionRef}>
{validationResult.errorMessage}
</InternalLiveRegion>
</>
Expand Down

0 comments on commit 3f666b4

Please sign in to comment.