const intl = useIntl();
+ const formatChevronLabel = (date?: Date) => {
+ if (date === undefined) {
+ return intl.formatMessage({ id: 'disabled_' });
+ }
+ return `${intl.formatDate(date, { month: 'long', format: 'M' })} ${intl.formatDate(date, {
+ year: 'numeric',
+ format: 'y',
+ })}`;
+ };
+
const baseDate = startOfMonth(displayMonth); // reference date
const months = range(MONTHS_IN_A_YEAR).map((month) => {
<nav className="sw-flex sw-items-center sw-justify-between sw-py-1">
<InteractiveIcon
Icon={ChevronLeftIcon}
- aria-label={intl.formatMessage({ id: 'previous_' })}
+ aria-label={intl.formatMessage(
+ { id: 'previous_month_x' },
+ { month: formatChevronLabel(previousMonth) },
+ )}
className="sw-mr-2"
+ disabled={previousMonth === undefined}
onClick={() => {
if (previousMonth) {
goToMonth(previousMonth);
<InteractiveIcon
Icon={ChevronRightIcon}
- aria-label={intl.formatMessage({ id: 'next_' })}
+ aria-label={intl.formatMessage(
+ { id: 'next_month_x' },
+ {
+ month: formatChevronLabel(nextMonth),
+ },
+ )}
className="sw-ml-2"
+ disabled={nextMonth === undefined}
onClick={() => {
if (nextMonth) {
goToMonth(nextMonth);
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { screen, within } from '@testing-library/react';
+import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { getMonth, getYear, parseISO } from 'date-fns';
+import { byRole } from '../../../../../src/main/js/helpers/testSelector';
import { renderWithContext } from '../../../helpers/testUtils';
import { DatePicker } from '../DatePicker';
const nav = screen.getByRole('navigation');
expect(nav).toBeInTheDocument();
- await user.click(within(nav).getByRole('button', { name: 'previous_' }));
+ await user.click(byRole('navigation').byRole('button', { name: 'previous_month_x' }).get());
await user.click(screen.getByText('7'));
expect(onChange).toHaveBeenCalled();
* Then check that onChange was correctly called with a date in the following month
*/
await user.click(screen.getByRole('textbox'));
- await user.click(screen.getByRole('button', { name: 'next_' }));
+ await user.click(screen.getByRole('button', { name: 'next_month_x' }));
await user.click(screen.getByText('12'));
expect(onChange).toHaveBeenCalled();
expect(getYear(newDate3)).toBe(2019);
});
+it('should disable next navigation when not in the accepted range', async () => {
+ const user = userEvent.setup();
+
+ const currentDate = parseISO('2022-11-13');
+
+ renderDatePicker({
+ currentMonth: currentDate,
+ maxDate: parseISO('2022-12-30'),
+ value: currentDate,
+ // eslint-disable-next-line jest/no-conditional-in-test
+ valueFormatter: (date?: Date) => (date ? 'formatted date' : 'no date'),
+ });
+
+ await user.click(screen.getByRole('textbox'));
+ await user.click(screen.getByRole('button', { name: 'next_month_x' }));
+
+ expect(screen.getByRole('button', { name: 'next_month_x' })).toBeDisabled();
+});
+
it('should clear the value', async () => {
const user = userEvent.setup();
placeholder="placeholder"
valueFormatter={defaultFormatter}
{...overrides}
- />
+ />,
);
}
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { screen, within } from '@testing-library/react';
+import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { formatISO, parseISO } from 'date-fns';
+import { byRole } from '../../../../../src/main/js/helpers/testSelector';
import { IntlWrapper, render } from '../../../helpers/testUtils';
import { DateRangePicker } from '../DateRangePicker';
});
it('behaves correctly', async () => {
+ const nav = byRole('navigation');
// Remove delay to play nice with fake timers
const user = userEvent.setup({ delay: null });
await user.click(screen.getByRole('textbox', { name: 'from' }));
- const fromDateNav = screen.getByRole('navigation');
- expect(fromDateNav).toBeInTheDocument();
+ expect(nav.get()).toBeInTheDocument();
- await user.click(within(fromDateNav).getByRole('button', { name: 'previous' }));
+ await user.click(nav.byRole('button', { name: 'previous_month_x' }).get());
await user.click(screen.getByText('7'));
- expect(screen.queryByRole('navigation')).not.toBeInTheDocument();
+ expect(nav.query()).not.toBeInTheDocument();
expect(onChange).toHaveBeenCalled();
const { from } = onChange.mock.calls[0][0]; // first argument
jest.runAllTimers();
- const toDateNav = await screen.findByRole('navigation');
- const previousButton = within(toDateNav).getByRole('button', { name: 'previous' });
- const nextButton = within(toDateNav).getByRole('button', { name: 'next' });
- await user.click(previousButton);
- await user.click(nextButton);
- await user.click(previousButton);
+ const previousButton = nav.byRole('button', { name: 'previous_month_x' });
+ const nextButton = nav.byRole('button', { name: 'next_month_x' });
+ await user.click(previousButton.get());
+ await user.click(nextButton.get());
+ await user.click(previousButton.get());
await user.click(screen.getByText('12'));
- expect(screen.queryByRole('navigation')).not.toBeInTheDocument();
+ expect(nav.query()).not.toBeInTheDocument();
expect(onChange).toHaveBeenCalled();
const { to } = onChange.mock.calls[0][0]; // first argument
valueFormatter={defaultFormatter}
{...overrides}
/>
- </IntlWrapper>
+ </IntlWrapper>,
);
}
export function render(
ui: React.ReactElement,
options?: RenderOptions,
- userEventOptions?: UserEventsOptions
+ userEventOptions?: UserEventsOptions,
) {
return { ...rtlRender(ui, options), user: userEvent.setup(userEventOptions) };
}
export function renderWithContext(
ui: React.ReactElement,
- { userEventOptions, ...options }: RenderContextOptions = {}
+ { userEventOptions, ...options }: RenderContextOptions = {},
) {
return render(ui, { ...options, wrapper: getContextWrapper() }, userEventOptions);
}
export function renderWithRouter(
ui: React.ReactElement,
- options: RenderContextOptions & RenderRouterOptions = {}
+ options: RenderContextOptions & RenderRouterOptions = {},
) {
const { additionalRoutes, userEventOptions, ...renderOptions } = options;
messages={messages}
onError={(e) => {
// ignore missing translations, there are none!
- if (e.code !== ReactIntlErrorCode.MISSING_TRANSLATION) {
+ if (
+ e.code !== ReactIntlErrorCode.MISSING_TRANSLATION &&
+ e.code !== ReactIntlErrorCode.UNSUPPORTED_FORMATTER
+ ) {
// eslint-disable-next-line no-console
console.error(e);
}
description=Description
directories=Directories
directory=Directory
+disabled_=disabled
dismiss=Dismiss
dismiss_permanently=Dismiss permanently
display=Display
never=Never
new=New
next=Next
+next_month_x=next month {month}
new_name=New name
next_=next
none=None
permalink=Permanent Link
plugin=Plugin
previous_=previous
+previous_month_x=previous month {month}
project=Project
project_x=Project: {0}
projects=Projects