v1.0 with SW PWA enabled
This commit is contained in:
1
frontend/node_modules/react-day-picker/src/.eslintignore
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/.eslintignore
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
style.css.d.ts
|
||||
114
frontend/node_modules/react-day-picker/src/DayPicker.tsx
generated
vendored
Normal file
114
frontend/node_modules/react-day-picker/src/DayPicker.tsx
generated
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
import { DayPickerDefaultProps } from 'types/DayPickerDefault';
|
||||
import { DayPickerMultipleProps } from 'types/DayPickerMultiple';
|
||||
import { DayPickerRangeProps } from 'types/DayPickerRange';
|
||||
import { DayPickerSingleProps } from 'types/DayPickerSingle';
|
||||
|
||||
import { Root } from './components/Root';
|
||||
import { RootProvider } from './contexts/RootProvider';
|
||||
|
||||
export type DayPickerProps =
|
||||
| DayPickerDefaultProps
|
||||
| DayPickerSingleProps
|
||||
| DayPickerMultipleProps
|
||||
| DayPickerRangeProps;
|
||||
|
||||
/**
|
||||
* DayPicker render a date picker component to let users pick dates from a
|
||||
* calendar. See http://react-day-picker.js.org for updated documentation and
|
||||
* examples.
|
||||
*
|
||||
* ### Customization
|
||||
*
|
||||
* DayPicker offers different customization props. For example,
|
||||
*
|
||||
* - show multiple months using `numberOfMonths`
|
||||
* - display a dropdown to navigate the months via `captionLayout`
|
||||
* - display the week numbers with `showWeekNumbers`
|
||||
* - disable or hide days with `disabled` or `hidden`
|
||||
*
|
||||
* ### Controlling the months
|
||||
*
|
||||
* Change the initially displayed month using the `defaultMonth` prop. The
|
||||
* displayed months are controlled by DayPicker and stored in its internal
|
||||
* state. To control the months yourself, use `month` instead of `defaultMonth`
|
||||
* and use the `onMonthChange` event to set it.
|
||||
*
|
||||
* To limit the months the user can navigate to, use
|
||||
* `fromDate`/`fromMonth`/`fromYear` or `toDate`/`toMonth`/`toYear`.
|
||||
*
|
||||
* ### Selection modes
|
||||
*
|
||||
* DayPicker supports different selection mode that can be toggled using the
|
||||
* `mode` prop:
|
||||
*
|
||||
* - `mode="single"`: only one day can be selected. Use `required` to make the
|
||||
* selection required. Use the `onSelect` event handler to get the selected
|
||||
* days.
|
||||
* - `mode="multiple"`: users can select one or more days. Limit the amount of
|
||||
* days that can be selected with the `min` or the `max` props.
|
||||
* - `mode="range"`: users can select a range of days. Limit the amount of days
|
||||
* in the range with the `min` or the `max` props.
|
||||
* - `mode="default"` (default): the built-in selections are disabled. Implement
|
||||
* your own selection mode with `onDayClick`.
|
||||
*
|
||||
* The selection modes should cover the most common use cases. In case you
|
||||
* need a more refined way of selecting days, use `mode="default"`. Use the
|
||||
* `selected` props and add the day event handlers to add/remove days from the
|
||||
* selection.
|
||||
*
|
||||
* ### Modifiers
|
||||
*
|
||||
* A _modifier_ represents different styles or states for the days displayed in
|
||||
* the calendar (like "selected" or "disabled"). Define custom modifiers using
|
||||
* the `modifiers` prop.
|
||||
*
|
||||
* ### Formatters and custom component
|
||||
*
|
||||
* You can customize how the content is displayed in the date picker by using
|
||||
* either the formatters or replacing the internal components.
|
||||
*
|
||||
* For the most common cases you want to use the `formatters` prop to change how
|
||||
* the content is formatted in the calendar. Use the `components` prop to
|
||||
* replace the internal components, like the navigation icons.
|
||||
*
|
||||
* ### Styling
|
||||
*
|
||||
* DayPicker comes with a default, basic style in `react-day-picker/style` – use
|
||||
* it as template for your own style.
|
||||
*
|
||||
* If you are using CSS modules, pass the imported styles object the
|
||||
* `classNames` props.
|
||||
*
|
||||
* You can also style the elements via inline styles using the `styles` prop.
|
||||
*
|
||||
* ### Form fields
|
||||
*
|
||||
* If you need to bind the date picker to a form field, you can use the
|
||||
* `useInput` hooks for a basic behavior. See the `useInput` source as an
|
||||
* example to bind the date picker with form fields.
|
||||
*
|
||||
* ### Localization
|
||||
*
|
||||
* To localize DayPicker, import the locale from `date-fns` package and use the
|
||||
* `locale` prop.
|
||||
*
|
||||
* For example, to use Spanish locale:
|
||||
*
|
||||
* ```
|
||||
* import { es } from 'date-fns/locale';
|
||||
* <DayPicker locale={es} />
|
||||
* ```
|
||||
*/
|
||||
export function DayPicker(
|
||||
props:
|
||||
| DayPickerDefaultProps
|
||||
| DayPickerSingleProps
|
||||
| DayPickerMultipleProps
|
||||
| DayPickerRangeProps
|
||||
): JSX.Element {
|
||||
return (
|
||||
<RootProvider {...props}>
|
||||
<Root initialProps={props} />
|
||||
</RootProvider>
|
||||
);
|
||||
}
|
||||
45
frontend/node_modules/react-day-picker/src/components/Button/Button.test.tsx
generated
vendored
Normal file
45
frontend/node_modules/react-day-picker/src/components/Button/Button.test.tsx
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
import { screen } from '@testing-library/react';
|
||||
|
||||
import { customRender } from 'test/render';
|
||||
|
||||
import { Button } from './Button';
|
||||
|
||||
let button: HTMLButtonElement;
|
||||
|
||||
describe('when rendered without props', () => {
|
||||
beforeEach(() => {
|
||||
customRender(<Button className="foo" style={{ color: 'blue' }} />);
|
||||
button = screen.getByRole('button');
|
||||
});
|
||||
test('should render a button with type "button"', () => {
|
||||
expect(button).toHaveAttribute('type', 'button');
|
||||
});
|
||||
test('should render a button with the button class name', () => {
|
||||
expect(button).toHaveClass('rdp-button');
|
||||
});
|
||||
test('should render a button with the reset class name', () => {
|
||||
expect(button).toHaveClass('rdp-button_reset');
|
||||
});
|
||||
test('should add the class name', () => {
|
||||
expect(button).toHaveClass('foo');
|
||||
});
|
||||
test('should apply the style', () => {
|
||||
expect(button).toHaveStyle({ color: 'blue' });
|
||||
});
|
||||
});
|
||||
|
||||
describe('when using class names and styles from context', () => {
|
||||
beforeEach(() => {
|
||||
customRender(<Button />, {
|
||||
classNames: { button: 'foo' },
|
||||
styles: { button: { color: 'red' } }
|
||||
});
|
||||
button = screen.getByRole('button');
|
||||
});
|
||||
test('should apply the style', () => {
|
||||
expect(button).toHaveStyle({ color: 'red' });
|
||||
});
|
||||
test('should apply the class name', () => {
|
||||
expect(button).toHaveClass('foo');
|
||||
});
|
||||
});
|
||||
34
frontend/node_modules/react-day-picker/src/components/Button/Button.tsx
generated
vendored
Normal file
34
frontend/node_modules/react-day-picker/src/components/Button/Button.tsx
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
import { forwardRef } from 'react';
|
||||
|
||||
import { useDayPicker } from 'contexts/DayPicker';
|
||||
|
||||
/** The props for the {@link Button} component. */
|
||||
export type ButtonProps = JSX.IntrinsicElements['button'];
|
||||
|
||||
/** Render a button HTML element applying the reset class name. */
|
||||
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
(props, ref) => {
|
||||
const { classNames, styles } = useDayPicker();
|
||||
|
||||
const classNamesArr = [classNames.button_reset, classNames.button];
|
||||
if (props.className) {
|
||||
classNamesArr.push(props.className);
|
||||
}
|
||||
const className = classNamesArr.join(' ');
|
||||
|
||||
const style = { ...styles.button_reset, ...styles.button };
|
||||
if (props.style) {
|
||||
Object.assign(style, props.style);
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
{...props}
|
||||
ref={ref}
|
||||
type="button"
|
||||
className={className}
|
||||
style={style}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
1
frontend/node_modules/react-day-picker/src/components/Button/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/Button/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './Button';
|
||||
108
frontend/node_modules/react-day-picker/src/components/Caption/Caption.test.tsx
generated
vendored
Normal file
108
frontend/node_modules/react-day-picker/src/components/Caption/Caption.test.tsx
generated
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
import { screen } from '@testing-library/react';
|
||||
import { DayPickerProps } from 'DayPicker';
|
||||
|
||||
import { customRender } from 'test/render';
|
||||
import {
|
||||
getMonthCaption,
|
||||
getMonthDropdown,
|
||||
getNextButton,
|
||||
getPrevButton,
|
||||
getYearDropdown,
|
||||
queryNextButton,
|
||||
queryPrevButton
|
||||
} from 'test/selectors';
|
||||
import { freezeBeforeAll } from 'test/utils';
|
||||
|
||||
import { CustomComponents } from 'types/DayPickerBase';
|
||||
|
||||
import { Caption, CaptionProps } from './Caption';
|
||||
|
||||
const today = new Date(2021, 8);
|
||||
|
||||
freezeBeforeAll(today);
|
||||
|
||||
function setup(props: CaptionProps, dayPickerProps?: DayPickerProps) {
|
||||
customRender(<Caption {...props} />, dayPickerProps);
|
||||
}
|
||||
|
||||
describe('when navigation is disabled', () => {
|
||||
const props = { displayMonth: today };
|
||||
const dayPickerProps = { disableNavigation: true };
|
||||
beforeEach(() => setup(props, dayPickerProps));
|
||||
test('should display the caption label', () => {
|
||||
expect(getMonthCaption()).toHaveTextContent('September 2021');
|
||||
});
|
||||
test('should not render the navigation', () => {
|
||||
expect(queryPrevButton()).toBeNull();
|
||||
expect(queryNextButton()).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when using a custom CaptionLabel component', () => {
|
||||
const components: CustomComponents = {
|
||||
CaptionLabel: () => <>custom label foo</>
|
||||
};
|
||||
const props = { displayMonth: today };
|
||||
beforeEach(() => {
|
||||
setup(props, { components });
|
||||
});
|
||||
test('it should render the custom component instead', () => {
|
||||
expect(screen.getByText('custom label foo')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the caption layout is "dropdown"', () => {
|
||||
const dayPickerProps: DayPickerProps = {
|
||||
captionLayout: 'dropdown',
|
||||
fromYear: 2020,
|
||||
toYear: 2025
|
||||
};
|
||||
const props = { displayMonth: today };
|
||||
beforeEach(() => {
|
||||
setup(props, dayPickerProps);
|
||||
});
|
||||
test('should render the month drop-down', () => {
|
||||
expect(getMonthDropdown()).toBeInTheDocument();
|
||||
});
|
||||
test('should render the year drop-down', () => {
|
||||
expect(getYearDropdown()).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the caption layout is "buttons"', () => {
|
||||
const dayPickerProps: DayPickerProps = {
|
||||
captionLayout: 'buttons'
|
||||
};
|
||||
test('should render the next month button', () => {
|
||||
customRender(<Caption displayMonth={today} />, dayPickerProps);
|
||||
expect(getNextButton()).toBeInTheDocument();
|
||||
});
|
||||
test('should render the previous month button', () => {
|
||||
customRender(<Caption displayMonth={today} />, dayPickerProps);
|
||||
expect(getPrevButton()).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the caption layout is "dropdown-buttons"', () => {
|
||||
const dayPickerProps: DayPickerProps = {
|
||||
captionLayout: 'dropdown-buttons',
|
||||
fromYear: 2020,
|
||||
toYear: 2025
|
||||
};
|
||||
const props = { displayMonth: today };
|
||||
beforeEach(() => {
|
||||
setup(props, dayPickerProps);
|
||||
});
|
||||
test('should render the month drop-down', () => {
|
||||
expect(getMonthDropdown()).toBeInTheDocument();
|
||||
});
|
||||
test('should render the year drop-down', () => {
|
||||
expect(getYearDropdown()).toBeInTheDocument();
|
||||
});
|
||||
test('should render the next month button', () => {
|
||||
expect(getNextButton()).toBeInTheDocument();
|
||||
});
|
||||
test('should render the previous month button', () => {
|
||||
expect(getPrevButton()).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
77
frontend/node_modules/react-day-picker/src/components/Caption/Caption.tsx
generated
vendored
Normal file
77
frontend/node_modules/react-day-picker/src/components/Caption/Caption.tsx
generated
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
import { CaptionDropdowns } from 'components/CaptionDropdowns';
|
||||
import { CaptionLabel } from 'components/CaptionLabel';
|
||||
import { CaptionNavigation } from 'components/CaptionNavigation';
|
||||
import { useDayPicker } from 'contexts/DayPicker';
|
||||
|
||||
/** Represent the props of the {@link Caption} component. */
|
||||
export interface CaptionProps {
|
||||
/** The ID for the heading element. Must be the same as the labelled-by in Table. */
|
||||
id?: string;
|
||||
/** The month where the caption is displayed. */
|
||||
displayMonth: Date;
|
||||
/** The index of the month where the caption is displayed. Older custom components may miss this prop. */
|
||||
displayIndex?: number | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* The layout of the caption:
|
||||
*
|
||||
* - `dropdown`: display dropdowns for choosing the month and the year.
|
||||
* - `buttons`: display previous month / next month buttons.
|
||||
* - `dropdown-buttons`: display both month / year dropdowns and previous month / next month buttons.
|
||||
*/
|
||||
export type CaptionLayout = 'dropdown' | 'buttons' | 'dropdown-buttons';
|
||||
|
||||
/**
|
||||
* Render the caption of a month. The caption has a different layout when
|
||||
* setting the {@link DayPickerBase.captionLayout} prop.
|
||||
*/
|
||||
export function Caption(props: CaptionProps): JSX.Element {
|
||||
const { classNames, disableNavigation, styles, captionLayout, components } =
|
||||
useDayPicker();
|
||||
|
||||
const CaptionLabelComponent = components?.CaptionLabel ?? CaptionLabel;
|
||||
|
||||
let caption: JSX.Element;
|
||||
if (disableNavigation) {
|
||||
caption = (
|
||||
<CaptionLabelComponent id={props.id} displayMonth={props.displayMonth} />
|
||||
);
|
||||
} else if (captionLayout === 'dropdown') {
|
||||
caption = (
|
||||
<CaptionDropdowns displayMonth={props.displayMonth} id={props.id} />
|
||||
);
|
||||
} else if (captionLayout === 'dropdown-buttons') {
|
||||
caption = (
|
||||
<>
|
||||
<CaptionDropdowns
|
||||
displayMonth={props.displayMonth}
|
||||
displayIndex={props.displayIndex}
|
||||
id={props.id}
|
||||
/>
|
||||
<CaptionNavigation
|
||||
displayMonth={props.displayMonth}
|
||||
displayIndex={props.displayIndex}
|
||||
id={props.id}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
} else {
|
||||
caption = (
|
||||
<>
|
||||
<CaptionLabelComponent
|
||||
id={props.id}
|
||||
displayMonth={props.displayMonth}
|
||||
displayIndex={props.displayIndex}
|
||||
/>
|
||||
<CaptionNavigation displayMonth={props.displayMonth} id={props.id} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classNames.caption} style={styles.caption}>
|
||||
{caption}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
1
frontend/node_modules/react-day-picker/src/components/Caption/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/Caption/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './Caption';
|
||||
121
frontend/node_modules/react-day-picker/src/components/CaptionDropdowns/CaptionDropdowns.test.tsx
generated
vendored
Normal file
121
frontend/node_modules/react-day-picker/src/components/CaptionDropdowns/CaptionDropdowns.test.tsx
generated
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
import { screen } from '@testing-library/react';
|
||||
import { setMonth, setYear } from 'date-fns';
|
||||
import { DayPickerProps } from 'DayPicker';
|
||||
|
||||
import { customRender } from 'test/render';
|
||||
import {
|
||||
getMonthDropdown,
|
||||
getYearDropdown,
|
||||
queryMonthDropdown,
|
||||
queryYearDropdown
|
||||
} from 'test/selectors';
|
||||
import { user } from 'test/user';
|
||||
import { freezeBeforeAll } from 'test/utils';
|
||||
|
||||
import { CaptionProps } from 'components/Caption';
|
||||
import { CustomComponents } from 'types/DayPickerBase';
|
||||
|
||||
import { CaptionDropdowns } from './CaptionDropdowns';
|
||||
|
||||
const today = new Date(2021, 8);
|
||||
const fromYear = 2020;
|
||||
const toYear = 2025;
|
||||
|
||||
freezeBeforeAll(today);
|
||||
|
||||
function setup(props: CaptionProps, dayPickerProps?: DayPickerProps) {
|
||||
customRender(<CaptionDropdowns {...props} />, dayPickerProps);
|
||||
}
|
||||
|
||||
describe('when using a custom CaptionLabel component', () => {
|
||||
const components: CustomComponents = {
|
||||
CaptionLabel: () => <>custom label foo</>
|
||||
};
|
||||
const props = { displayMonth: today };
|
||||
beforeEach(() => {
|
||||
setup(props, { components });
|
||||
});
|
||||
test('it should render the custom component instead', () => {
|
||||
expect(screen.getByText('custom label foo')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when rendered with custom styles or classnames', () => {
|
||||
let container: HTMLElement;
|
||||
|
||||
beforeEach(() => {
|
||||
const dayPickerProps: DayPickerProps = {
|
||||
captionLayout: 'dropdown',
|
||||
fromYear,
|
||||
toYear,
|
||||
classNames: { caption_dropdowns: 'foo_dropdowns' },
|
||||
styles: { caption_dropdowns: { color: 'red' } }
|
||||
};
|
||||
const view = customRender(
|
||||
<CaptionDropdowns displayMonth={today} />,
|
||||
dayPickerProps
|
||||
);
|
||||
container = view.container;
|
||||
});
|
||||
test('should use the `caption_dropdowns` class name', () => {
|
||||
expect(container.firstChild).toHaveClass('foo_dropdowns');
|
||||
});
|
||||
test('should use the `caption_dropdowns` style', () => {
|
||||
expect(container.firstChild).toHaveStyle({ color: 'red' });
|
||||
});
|
||||
test('should render the month drop-down', () => {
|
||||
expect(getMonthDropdown()).toBeInTheDocument();
|
||||
});
|
||||
test('should render the year drop-down', () => {
|
||||
expect(getYearDropdown()).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when a month is selected', () => {
|
||||
const dayPickerProps: DayPickerProps = {
|
||||
captionLayout: 'dropdown',
|
||||
fromYear,
|
||||
toYear,
|
||||
onMonthChange: jest.fn()
|
||||
};
|
||||
beforeEach(() => {
|
||||
customRender(<CaptionDropdowns displayMonth={today} />, dayPickerProps);
|
||||
});
|
||||
describe('from the months drop-down', () => {
|
||||
const newMonth = setMonth(today, 0);
|
||||
beforeEach(async () => {
|
||||
await user.selectOptions(
|
||||
getMonthDropdown(),
|
||||
newMonth.getMonth().toString()
|
||||
);
|
||||
});
|
||||
test('should call the `onMonthChange` callback', () => {
|
||||
expect(dayPickerProps.onMonthChange).toHaveBeenCalledWith(newMonth);
|
||||
});
|
||||
});
|
||||
describe('from the years drop-down', () => {
|
||||
const newYear = setYear(today, 2022);
|
||||
beforeEach(async () => {
|
||||
await user.selectOptions(
|
||||
getYearDropdown(),
|
||||
newYear.getFullYear().toString()
|
||||
);
|
||||
});
|
||||
test('should call the `onMonthChange` callback', () => {
|
||||
expect(dayPickerProps.onMonthChange).toHaveBeenCalledWith(newYear);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when no date limits are set', () => {
|
||||
const dayPickerProps: DayPickerProps = {
|
||||
captionLayout: 'dropdown'
|
||||
};
|
||||
beforeEach(() => {
|
||||
customRender(<CaptionDropdowns displayMonth={today} />, dayPickerProps);
|
||||
});
|
||||
test('should not render the drop-downs', () => {
|
||||
expect(queryMonthDropdown()).toBeNull();
|
||||
expect(queryYearDropdown()).toBeNull();
|
||||
});
|
||||
});
|
||||
44
frontend/node_modules/react-day-picker/src/components/CaptionDropdowns/CaptionDropdowns.tsx
generated
vendored
Normal file
44
frontend/node_modules/react-day-picker/src/components/CaptionDropdowns/CaptionDropdowns.tsx
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
import { addMonths } from 'date-fns';
|
||||
|
||||
import { CaptionProps } from 'components/Caption/Caption';
|
||||
import { CaptionLabel } from 'components/CaptionLabel';
|
||||
import { MonthsDropdown } from 'components/MonthsDropdown';
|
||||
import { YearsDropdown } from 'components/YearsDropdown';
|
||||
import { useDayPicker } from 'contexts/DayPicker';
|
||||
import { useNavigation } from 'contexts/Navigation';
|
||||
import { MonthChangeEventHandler } from 'types/EventHandlers';
|
||||
|
||||
/**
|
||||
* Render a caption with the dropdowns to navigate between months and years.
|
||||
*/
|
||||
export function CaptionDropdowns(props: CaptionProps): JSX.Element {
|
||||
const { classNames, styles, components } = useDayPicker();
|
||||
const { goToMonth } = useNavigation();
|
||||
|
||||
const handleMonthChange: MonthChangeEventHandler = (newMonth) => {
|
||||
goToMonth(
|
||||
addMonths(newMonth, props.displayIndex ? -props.displayIndex : 0)
|
||||
);
|
||||
};
|
||||
const CaptionLabelComponent = components?.CaptionLabel ?? CaptionLabel;
|
||||
const captionLabel = (
|
||||
<CaptionLabelComponent id={props.id} displayMonth={props.displayMonth} />
|
||||
);
|
||||
return (
|
||||
<div
|
||||
className={classNames.caption_dropdowns}
|
||||
style={styles.caption_dropdowns}
|
||||
>
|
||||
{/* Caption label is visually hidden but for a11y. */}
|
||||
<div className={classNames.vhidden}>{captionLabel}</div>
|
||||
<MonthsDropdown
|
||||
onChange={handleMonthChange}
|
||||
displayMonth={props.displayMonth}
|
||||
/>
|
||||
<YearsDropdown
|
||||
onChange={handleMonthChange}
|
||||
displayMonth={props.displayMonth}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
1
frontend/node_modules/react-day-picker/src/components/CaptionDropdowns/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/CaptionDropdowns/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './CaptionDropdowns';
|
||||
27
frontend/node_modules/react-day-picker/src/components/CaptionLabel/CaptionLabel.test.tsx
generated
vendored
Normal file
27
frontend/node_modules/react-day-picker/src/components/CaptionLabel/CaptionLabel.test.tsx
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
import { customRender } from 'test/render';
|
||||
import { getMonthCaption } from 'test/selectors';
|
||||
import { freezeBeforeAll } from 'test/utils';
|
||||
|
||||
import { CaptionLabel } from './CaptionLabel';
|
||||
|
||||
const today = new Date(1979, 8);
|
||||
freezeBeforeAll(today);
|
||||
|
||||
test('should render the formatted display month', () => {
|
||||
customRender(<CaptionLabel displayMonth={today} />);
|
||||
expect(getMonthCaption()).toHaveTextContent('September 1979');
|
||||
});
|
||||
|
||||
test('should apply the `caption_label` class name', () => {
|
||||
customRender(<CaptionLabel displayMonth={today} />, {
|
||||
classNames: { caption_label: 'foo' }
|
||||
});
|
||||
expect(getMonthCaption()).toHaveClass('foo');
|
||||
});
|
||||
|
||||
test('should apply the `caption_label` style', () => {
|
||||
customRender(<CaptionLabel displayMonth={today} />, {
|
||||
styles: { caption_label: { color: 'red' } }
|
||||
});
|
||||
expect(getMonthCaption()).toHaveStyle({ color: 'red' });
|
||||
});
|
||||
32
frontend/node_modules/react-day-picker/src/components/CaptionLabel/CaptionLabel.tsx
generated
vendored
Normal file
32
frontend/node_modules/react-day-picker/src/components/CaptionLabel/CaptionLabel.tsx
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
import { useDayPicker } from 'contexts/DayPicker';
|
||||
|
||||
/** The props for the {@link CaptionLabel} component. */
|
||||
export interface CaptionLabelProps {
|
||||
/** The ID for the heading element. Must be the same as the labelled-by in Table. */
|
||||
id?: string;
|
||||
/** The month where the caption is displayed. */
|
||||
displayMonth: Date;
|
||||
/** The index of the month where the caption is displayed. Older custom components may miss this prop. */
|
||||
displayIndex?: number | undefined;
|
||||
}
|
||||
|
||||
/** Render the caption for the displayed month. This component is used when `captionLayout="buttons"`. */
|
||||
export function CaptionLabel(props: CaptionLabelProps): JSX.Element {
|
||||
const {
|
||||
locale,
|
||||
classNames,
|
||||
styles,
|
||||
formatters: { formatCaption }
|
||||
} = useDayPicker();
|
||||
return (
|
||||
<div
|
||||
className={classNames.caption_label}
|
||||
style={styles.caption_label}
|
||||
aria-live="polite"
|
||||
role="presentation"
|
||||
id={props.id}
|
||||
>
|
||||
{formatCaption(props.displayMonth, { locale })}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
1
frontend/node_modules/react-day-picker/src/components/CaptionLabel/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/CaptionLabel/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './CaptionLabel';
|
||||
144
frontend/node_modules/react-day-picker/src/components/CaptionNavigation/CaptionNavigation.test.tsx
generated
vendored
Normal file
144
frontend/node_modules/react-day-picker/src/components/CaptionNavigation/CaptionNavigation.test.tsx
generated
vendored
Normal file
@ -0,0 +1,144 @@
|
||||
import { addMonths } from 'date-fns';
|
||||
import { DayPickerProps } from 'DayPicker';
|
||||
|
||||
import { customRender } from 'test/render';
|
||||
import {
|
||||
getNextButton,
|
||||
getPrevButton,
|
||||
queryNextButton,
|
||||
queryPrevButton
|
||||
} from 'test/selectors';
|
||||
import { user } from 'test/user';
|
||||
import { freezeBeforeAll } from 'test/utils';
|
||||
|
||||
import { CaptionNavigation } from './CaptionNavigation';
|
||||
|
||||
const today = new Date(2021, 8);
|
||||
|
||||
freezeBeforeAll(today);
|
||||
|
||||
describe('when rendered', () => {
|
||||
const dayPickerProps: DayPickerProps = {
|
||||
captionLayout: 'buttons'
|
||||
};
|
||||
test('should render the next month button', () => {
|
||||
customRender(<CaptionNavigation displayMonth={today} />, dayPickerProps);
|
||||
expect(getNextButton()).toBeInTheDocument();
|
||||
});
|
||||
test('should render the previous month button', () => {
|
||||
customRender(<CaptionNavigation displayMonth={today} />, dayPickerProps);
|
||||
expect(getPrevButton()).toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe('when displaying the first of multiple months', () => {
|
||||
const numberOfMonths = 3;
|
||||
beforeEach(() => {
|
||||
customRender(<CaptionNavigation displayMonth={today} />, {
|
||||
...dayPickerProps,
|
||||
numberOfMonths
|
||||
});
|
||||
});
|
||||
test('should not display the next month button', () => {
|
||||
expect(queryNextButton()).toBeNull();
|
||||
});
|
||||
test('should show the previous month button', () => {
|
||||
expect(getPrevButton()).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when displaying the last of multiple months', () => {
|
||||
const numberOfMonths = 3;
|
||||
beforeEach(() => {
|
||||
const lastMonth = addMonths(today, numberOfMonths - 1);
|
||||
customRender(<CaptionNavigation displayMonth={lastMonth} />, {
|
||||
...dayPickerProps,
|
||||
numberOfMonths
|
||||
});
|
||||
});
|
||||
test('should hide the previous month button', () => {
|
||||
expect(queryPrevButton()).toBeNull();
|
||||
});
|
||||
test('should show the next month button', () => {
|
||||
expect(getNextButton()).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when displaying a month in the middle of multiple months', () => {
|
||||
const numberOfMonths = 3;
|
||||
beforeEach(() => {
|
||||
const lastMonth = addMonths(today, numberOfMonths - 2);
|
||||
customRender(<CaptionNavigation displayMonth={lastMonth} />, {
|
||||
...dayPickerProps,
|
||||
numberOfMonths
|
||||
});
|
||||
});
|
||||
test('should not render the previous month button', () => {
|
||||
expect(queryPrevButton()).toBeNull();
|
||||
});
|
||||
test('should not render the next month button', () => {
|
||||
expect(queryNextButton()).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when clicking the previous button', () => {
|
||||
describe('and a previous month is defined', () => {
|
||||
const testContext = {
|
||||
...dayPickerProps,
|
||||
onMonthChange: jest.fn()
|
||||
};
|
||||
const previousMonth = addMonths(today, -1);
|
||||
beforeEach(async () => {
|
||||
customRender(<CaptionNavigation displayMonth={today} />, testContext);
|
||||
await user.click(getPrevButton());
|
||||
});
|
||||
test('should call the `onMonthChange` callback', () => {
|
||||
expect(testContext.onMonthChange).toHaveBeenCalledWith(previousMonth);
|
||||
});
|
||||
});
|
||||
describe('and the previous month is not defined', () => {
|
||||
const testContext = {
|
||||
...dayPickerProps,
|
||||
fromDate: today,
|
||||
onMonthChange: jest.fn()
|
||||
};
|
||||
beforeEach(async () => {
|
||||
customRender(<CaptionNavigation displayMonth={today} />, testContext);
|
||||
await user.click(getPrevButton());
|
||||
});
|
||||
test('should call the `onMonthChange` callback', () => {
|
||||
expect(testContext.onMonthChange).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when clicking the next month button', () => {
|
||||
describe('and the next month is defined', () => {
|
||||
const testContext = {
|
||||
...dayPickerProps,
|
||||
onMonthChange: jest.fn()
|
||||
};
|
||||
const nextMonth = addMonths(today, 1);
|
||||
beforeEach(async () => {
|
||||
customRender(<CaptionNavigation displayMonth={today} />, testContext);
|
||||
await user.click(getNextButton());
|
||||
});
|
||||
test('should call the `onMonthChange` callback', () => {
|
||||
expect(testContext.onMonthChange).toHaveBeenCalledWith(nextMonth);
|
||||
});
|
||||
});
|
||||
describe('and the next month is not defined', () => {
|
||||
const testContext = {
|
||||
...dayPickerProps,
|
||||
toDate: today,
|
||||
onMonthChange: jest.fn()
|
||||
};
|
||||
beforeEach(async () => {
|
||||
customRender(<CaptionNavigation displayMonth={today} />, testContext);
|
||||
await user.click(getNextButton());
|
||||
});
|
||||
test('should call the `onMonthChange` callback', () => {
|
||||
expect(testContext.onMonthChange).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
49
frontend/node_modules/react-day-picker/src/components/CaptionNavigation/CaptionNavigation.tsx
generated
vendored
Normal file
49
frontend/node_modules/react-day-picker/src/components/CaptionNavigation/CaptionNavigation.tsx
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
import { MouseEventHandler } from 'react';
|
||||
|
||||
import { isSameMonth } from 'date-fns';
|
||||
|
||||
import { CaptionProps } from 'components/Caption/Caption';
|
||||
import { Navigation } from 'components/Navigation';
|
||||
import { useDayPicker } from 'contexts/DayPicker';
|
||||
import { useNavigation } from 'contexts/Navigation';
|
||||
|
||||
/**
|
||||
* Render a caption with a button-based navigation.
|
||||
*/
|
||||
export function CaptionNavigation(props: CaptionProps): JSX.Element {
|
||||
const { numberOfMonths } = useDayPicker();
|
||||
const { previousMonth, nextMonth, goToMonth, displayMonths } =
|
||||
useNavigation();
|
||||
|
||||
const displayIndex = displayMonths.findIndex((month) =>
|
||||
isSameMonth(props.displayMonth, month)
|
||||
);
|
||||
|
||||
const isFirst = displayIndex === 0;
|
||||
const isLast = displayIndex === displayMonths.length - 1;
|
||||
|
||||
const hideNext = numberOfMonths > 1 && (isFirst || !isLast);
|
||||
const hidePrevious = numberOfMonths > 1 && (isLast || !isFirst);
|
||||
|
||||
const handlePreviousClick: MouseEventHandler = () => {
|
||||
if (!previousMonth) return;
|
||||
goToMonth(previousMonth);
|
||||
};
|
||||
|
||||
const handleNextClick: MouseEventHandler = () => {
|
||||
if (!nextMonth) return;
|
||||
goToMonth(nextMonth);
|
||||
};
|
||||
|
||||
return (
|
||||
<Navigation
|
||||
displayMonth={props.displayMonth}
|
||||
hideNext={hideNext}
|
||||
hidePrevious={hidePrevious}
|
||||
nextMonth={nextMonth}
|
||||
previousMonth={previousMonth}
|
||||
onPreviousClick={handlePreviousClick}
|
||||
onNextClick={handleNextClick}
|
||||
/>
|
||||
);
|
||||
}
|
||||
1
frontend/node_modules/react-day-picker/src/components/CaptionNavigation/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/CaptionNavigation/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './CaptionNavigation';
|
||||
82
frontend/node_modules/react-day-picker/src/components/Day/Day.test.tsx
generated
vendored
Normal file
82
frontend/node_modules/react-day-picker/src/components/Day/Day.test.tsx
generated
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
import { screen } from '@testing-library/react';
|
||||
import { DayPickerProps } from 'DayPicker';
|
||||
|
||||
import { customRender } from 'test/render';
|
||||
import { freezeBeforeAll } from 'test/utils';
|
||||
|
||||
import { CustomComponents } from 'types/DayPickerBase';
|
||||
|
||||
import { Day, DayProps } from './Day';
|
||||
|
||||
const today = new Date(2021, 8);
|
||||
|
||||
freezeBeforeAll(today);
|
||||
|
||||
const date = today;
|
||||
const displayMonth = today;
|
||||
const props: DayProps = {
|
||||
date: date,
|
||||
displayMonth
|
||||
};
|
||||
|
||||
describe('when the day to render has an hidden modifier', () => {
|
||||
const dayPickerProps: DayPickerProps = {
|
||||
modifiers: { hidden: date }
|
||||
};
|
||||
beforeEach(() => {
|
||||
customRender(<Day {...props} />, dayPickerProps);
|
||||
});
|
||||
test('should render an empty grid cell', () => {
|
||||
const cell = screen.getByRole('gridcell');
|
||||
expect(cell).toBeEmptyDOMElement();
|
||||
});
|
||||
});
|
||||
describe('when a no selection mode and no "onDayClick"', () => {
|
||||
const dayPickerProps: DayPickerProps = { mode: 'default' };
|
||||
beforeEach(() => {
|
||||
customRender(<Day {...props} />, dayPickerProps);
|
||||
});
|
||||
test('should render a div', () => {
|
||||
const cell = screen.getByRole('gridcell');
|
||||
expect(cell.nodeName).toBe('DIV');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when a selection mode is set', () => {
|
||||
const dayPickerProps: DayPickerProps = {
|
||||
mode: 'single'
|
||||
};
|
||||
beforeEach(() => {
|
||||
customRender(<Day {...props} />, dayPickerProps);
|
||||
});
|
||||
test('should render a button named "day"', () => {
|
||||
const cell = screen.getByRole('gridcell');
|
||||
expect(cell.nodeName).toBe('BUTTON');
|
||||
expect(cell).toHaveAttribute('name', 'day');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when "onDayClick" is present', () => {
|
||||
const dayPickerProps: DayPickerProps = {
|
||||
onDayClick: jest.fn()
|
||||
};
|
||||
beforeEach(() => {
|
||||
customRender(<Day {...props} />, dayPickerProps);
|
||||
});
|
||||
test('should render a button', () => {
|
||||
const cell = screen.getByRole('gridcell');
|
||||
expect(cell.nodeName).toBe('BUTTON');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when using a custom DayContent component', () => {
|
||||
const components: CustomComponents = {
|
||||
DayContent: () => <>Custom DayContent</>
|
||||
};
|
||||
beforeEach(() => {
|
||||
customRender(<Day {...props} />, { components });
|
||||
});
|
||||
test('it should render the custom component instead', () => {
|
||||
expect(screen.getByText('Custom DayContent')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
30
frontend/node_modules/react-day-picker/src/components/Day/Day.tsx
generated
vendored
Normal file
30
frontend/node_modules/react-day-picker/src/components/Day/Day.tsx
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
import { useRef } from 'react';
|
||||
|
||||
import { useDayRender } from 'hooks/useDayRender';
|
||||
|
||||
import { Button } from '../Button';
|
||||
|
||||
/** Represent the props used by the {@link Day} component. */
|
||||
export interface DayProps {
|
||||
/** The month where the date is displayed. */
|
||||
displayMonth: Date;
|
||||
/** The date to render. */
|
||||
date: Date;
|
||||
}
|
||||
|
||||
/**
|
||||
* The content of a day cell – as a button or span element according to its
|
||||
* modifiers.
|
||||
*/
|
||||
export function Day(props: DayProps): JSX.Element {
|
||||
const buttonRef = useRef<HTMLButtonElement>(null);
|
||||
const dayRender = useDayRender(props.date, props.displayMonth, buttonRef);
|
||||
|
||||
if (dayRender.isHidden) {
|
||||
return <div role="gridcell"></div>;
|
||||
}
|
||||
if (!dayRender.isButton) {
|
||||
return <div {...dayRender.divProps} />;
|
||||
}
|
||||
return <Button name="day" ref={buttonRef} {...dayRender.buttonProps} />;
|
||||
}
|
||||
1
frontend/node_modules/react-day-picker/src/components/Day/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/Day/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './Day';
|
||||
37
frontend/node_modules/react-day-picker/src/components/DayContent/DayContent.test.tsx
generated
vendored
Normal file
37
frontend/node_modules/react-day-picker/src/components/DayContent/DayContent.test.tsx
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
import { es } from 'date-fns/locale';
|
||||
import { DayPickerProps } from 'DayPicker';
|
||||
|
||||
import { customRender } from 'test/render';
|
||||
import { freezeBeforeAll } from 'test/utils';
|
||||
|
||||
import { DayContent, DayContentProps } from 'components/DayContent';
|
||||
|
||||
const today = new Date(2021, 8);
|
||||
|
||||
freezeBeforeAll(today);
|
||||
let container: HTMLElement;
|
||||
function setup(props: DayContentProps, dayPickerProps?: DayPickerProps) {
|
||||
const view = customRender(<DayContent {...props} />, dayPickerProps);
|
||||
container = view.container;
|
||||
}
|
||||
|
||||
const date = today;
|
||||
const displayMonth = today;
|
||||
const props: DayContentProps = {
|
||||
date: date,
|
||||
displayMonth,
|
||||
activeModifiers: {}
|
||||
};
|
||||
|
||||
const dayPickerProps: DayPickerProps = {
|
||||
locale: es
|
||||
};
|
||||
|
||||
describe('when rendered', () => {
|
||||
beforeEach(() => {
|
||||
setup(props, dayPickerProps);
|
||||
});
|
||||
test('contains the formatted day', () => {
|
||||
expect(container.firstChild).toHaveTextContent('1');
|
||||
});
|
||||
});
|
||||
22
frontend/node_modules/react-day-picker/src/components/DayContent/DayContent.tsx
generated
vendored
Normal file
22
frontend/node_modules/react-day-picker/src/components/DayContent/DayContent.tsx
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
import { useDayPicker } from 'contexts/DayPicker';
|
||||
import { ActiveModifiers } from 'types/Modifiers';
|
||||
|
||||
/** Represent the props for the {@link DayContent} component. */
|
||||
export interface DayContentProps {
|
||||
/** The date representing the day. */
|
||||
date: Date;
|
||||
/** The month where the day is displayed. */
|
||||
displayMonth: Date;
|
||||
/** The active modifiers for the given date. */
|
||||
activeModifiers: ActiveModifiers;
|
||||
}
|
||||
|
||||
/** Render the content of the day cell. */
|
||||
export function DayContent(props: DayContentProps): JSX.Element {
|
||||
const {
|
||||
locale,
|
||||
formatters: { formatDay }
|
||||
} = useDayPicker();
|
||||
|
||||
return <>{formatDay(props.date, { locale })}</>;
|
||||
}
|
||||
1
frontend/node_modules/react-day-picker/src/components/DayContent/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/DayContent/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './DayContent';
|
||||
72
frontend/node_modules/react-day-picker/src/components/Dropdown/Dropdown.test.tsx
generated
vendored
Normal file
72
frontend/node_modules/react-day-picker/src/components/Dropdown/Dropdown.test.tsx
generated
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
import { fireEvent, screen } from '@testing-library/react';
|
||||
import { DayPickerProps } from 'DayPicker';
|
||||
|
||||
import { customRender } from 'test/render';
|
||||
import { freezeBeforeAll } from 'test/utils';
|
||||
|
||||
import { Dropdown, DropdownProps } from 'components/Dropdown';
|
||||
import { defaultClassNames } from 'contexts/DayPicker/defaultClassNames';
|
||||
import { CustomComponents } from 'types/DayPickerBase';
|
||||
|
||||
const today = new Date(2021, 8);
|
||||
|
||||
freezeBeforeAll(today);
|
||||
|
||||
function setup(props: DropdownProps, dayPickerProps?: DayPickerProps) {
|
||||
customRender(<Dropdown {...props} />, dayPickerProps);
|
||||
}
|
||||
|
||||
const props: Required<DropdownProps> = {
|
||||
name: 'dropdown',
|
||||
'aria-label': 'foo',
|
||||
onChange: jest.fn(),
|
||||
caption: 'Some caption',
|
||||
className: 'test',
|
||||
value: 'bar',
|
||||
children: <option value={'bar'} />,
|
||||
style: {}
|
||||
};
|
||||
|
||||
describe('when rendered', () => {
|
||||
let combobox: HTMLElement;
|
||||
let label: HTMLElement;
|
||||
|
||||
beforeEach(() => {
|
||||
setup(props);
|
||||
combobox = screen.getByRole('combobox');
|
||||
label = screen.getByText(props['aria-label']);
|
||||
});
|
||||
|
||||
test('should render the vhidden aria label', () => {
|
||||
expect(label).toHaveClass(defaultClassNames.vhidden);
|
||||
});
|
||||
|
||||
test('should render the combobox', () => {
|
||||
expect(combobox).toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe('when the combobox changes', () => {
|
||||
beforeEach(() => {
|
||||
fireEvent.change(combobox);
|
||||
});
|
||||
test('should call the "onChange" eve, nt handler', () => {
|
||||
expect(props.onChange).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
test('should render the combobox with the given value', () => {
|
||||
expect(combobox).toHaveValue(props.value);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when using a custom IconDropdown component', () => {
|
||||
const components: CustomComponents = {
|
||||
IconDropdown: () => <div>Custom IconDropdown</div>
|
||||
};
|
||||
beforeEach(() => {
|
||||
setup(props, { components });
|
||||
});
|
||||
test('it should render the custom component instead', () => {
|
||||
expect(screen.getByText('Custom IconDropdown')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
66
frontend/node_modules/react-day-picker/src/components/Dropdown/Dropdown.tsx
generated
vendored
Normal file
66
frontend/node_modules/react-day-picker/src/components/Dropdown/Dropdown.tsx
generated
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
import {
|
||||
ChangeEventHandler,
|
||||
CSSProperties,
|
||||
ReactNode,
|
||||
SelectHTMLAttributes
|
||||
} from 'react';
|
||||
|
||||
import { IconDropdown } from 'components/IconDropdown';
|
||||
import { useDayPicker } from 'contexts/DayPicker';
|
||||
|
||||
/** The props for the {@link Dropdown} component. */
|
||||
export interface DropdownProps {
|
||||
/** The name attribute of the element. */
|
||||
name?: string;
|
||||
/** The caption displayed to replace the hidden select. */
|
||||
caption?: ReactNode;
|
||||
children?: SelectHTMLAttributes<HTMLSelectElement>['children'];
|
||||
className?: string;
|
||||
['aria-label']?: string;
|
||||
style?: CSSProperties;
|
||||
/** The selected value. */
|
||||
value?: string | number;
|
||||
onChange?: ChangeEventHandler<HTMLSelectElement>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a styled select component – displaying a caption and a custom
|
||||
* drop-down icon.
|
||||
*/
|
||||
export function Dropdown(props: DropdownProps): JSX.Element {
|
||||
const { onChange, value, children, caption, className, style } = props;
|
||||
const dayPicker = useDayPicker();
|
||||
|
||||
const IconDropdownComponent =
|
||||
dayPicker.components?.IconDropdown ?? IconDropdown;
|
||||
return (
|
||||
<div className={className} style={style}>
|
||||
<span className={dayPicker.classNames.vhidden}>
|
||||
{props['aria-label']}
|
||||
</span>
|
||||
<select
|
||||
name={props.name}
|
||||
aria-label={props['aria-label']}
|
||||
className={dayPicker.classNames.dropdown}
|
||||
style={dayPicker.styles.dropdown}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
>
|
||||
{children}
|
||||
</select>
|
||||
<div
|
||||
className={dayPicker.classNames.caption_label}
|
||||
style={dayPicker.styles.caption_label}
|
||||
aria-hidden="true"
|
||||
>
|
||||
{caption}
|
||||
{
|
||||
<IconDropdownComponent
|
||||
className={dayPicker.classNames.dropdown_icon}
|
||||
style={dayPicker.styles.dropdown_icon}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
1
frontend/node_modules/react-day-picker/src/components/Dropdown/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/Dropdown/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './Dropdown';
|
||||
27
frontend/node_modules/react-day-picker/src/components/Footer/Footer.test.tsx
generated
vendored
Normal file
27
frontend/node_modules/react-day-picker/src/components/Footer/Footer.test.tsx
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
import { customRender } from 'test/render';
|
||||
import { getTableFooter, queryTableFooter } from 'test/selectors';
|
||||
|
||||
import { Footer } from './Footer';
|
||||
|
||||
customRender(
|
||||
<table role="grid">
|
||||
<Footer />
|
||||
</table>
|
||||
);
|
||||
test('should not render anything as default', () => {
|
||||
expect(queryTableFooter()).toBeNull();
|
||||
});
|
||||
|
||||
describe('when using the `footer` prop', () => {
|
||||
beforeEach(() => {
|
||||
customRender(
|
||||
<table role="grid">
|
||||
<Footer />
|
||||
</table>,
|
||||
{ footer: 'footer_foo' }
|
||||
);
|
||||
});
|
||||
test('should render the table footer', () => {
|
||||
expect(getTableFooter()).toHaveTextContent('footer_foo');
|
||||
});
|
||||
});
|
||||
23
frontend/node_modules/react-day-picker/src/components/Footer/Footer.tsx
generated
vendored
Normal file
23
frontend/node_modules/react-day-picker/src/components/Footer/Footer.tsx
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
import { useDayPicker } from 'contexts/DayPicker';
|
||||
|
||||
export interface FooterProps {
|
||||
/** The month where the footer is displayed. */
|
||||
displayMonth?: Date;
|
||||
}
|
||||
/** Render the Footer component (empty as default).*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function Footer(props: FooterProps): JSX.Element {
|
||||
const {
|
||||
footer,
|
||||
styles,
|
||||
classNames: { tfoot }
|
||||
} = useDayPicker();
|
||||
if (!footer) return <></>;
|
||||
return (
|
||||
<tfoot className={tfoot} style={styles.tfoot}>
|
||||
<tr>
|
||||
<td colSpan={8}>{footer}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
);
|
||||
}
|
||||
1
frontend/node_modules/react-day-picker/src/components/Footer/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/Footer/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './Footer';
|
||||
65
frontend/node_modules/react-day-picker/src/components/Head/Head.test.tsx
generated
vendored
Normal file
65
frontend/node_modules/react-day-picker/src/components/Head/Head.test.tsx
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
import { RenderResult, screen } from '@testing-library/react';
|
||||
import { DayPickerProps } from 'DayPicker';
|
||||
|
||||
import { customRender } from 'test/render';
|
||||
|
||||
import { Head } from './Head';
|
||||
|
||||
let container: HTMLElement;
|
||||
let view: RenderResult;
|
||||
|
||||
function setup(dayPickerProps: DayPickerProps = {}) {
|
||||
view = customRender(
|
||||
<table>
|
||||
<Head />
|
||||
</table>,
|
||||
dayPickerProps
|
||||
);
|
||||
container = view.container.firstChild as HTMLTableCellElement;
|
||||
}
|
||||
|
||||
const dayPickerProps = {
|
||||
styles: {
|
||||
head: { color: 'red' },
|
||||
head_row: { color: 'blue' },
|
||||
head_cell: { color: 'green' }
|
||||
},
|
||||
classNames: {
|
||||
head: 'foo',
|
||||
head_row: 'foo_row',
|
||||
head_cell: 'foo_head-cell'
|
||||
}
|
||||
};
|
||||
|
||||
describe('when rendered', () => {
|
||||
beforeEach(() => {
|
||||
setup(dayPickerProps);
|
||||
});
|
||||
|
||||
test('thead should have the `head` style', () => {
|
||||
expect(container.firstChild).toHaveStyle(dayPickerProps.styles.head);
|
||||
});
|
||||
|
||||
test('thead should have the `head` class', () => {
|
||||
expect(container.firstChild).toHaveClass(dayPickerProps.classNames.head);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when using a custom HeadRow component', () => {
|
||||
beforeEach(() => {
|
||||
setup({
|
||||
...dayPickerProps,
|
||||
components: {
|
||||
HeadRow: () => (
|
||||
<tr>
|
||||
<td>custom head</td>
|
||||
</tr>
|
||||
)
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('should render the custom component', () => {
|
||||
expect(screen.getByText('custom head')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
13
frontend/node_modules/react-day-picker/src/components/Head/Head.tsx
generated
vendored
Normal file
13
frontend/node_modules/react-day-picker/src/components/Head/Head.tsx
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
import { HeadRow } from 'components/HeadRow';
|
||||
import { useDayPicker } from 'contexts/DayPicker';
|
||||
|
||||
/** Render the table head. */
|
||||
export function Head(): JSX.Element {
|
||||
const { classNames, styles, components } = useDayPicker();
|
||||
const HeadRowComponent = components?.HeadRow ?? HeadRow;
|
||||
return (
|
||||
<thead style={styles.head} className={classNames.head}>
|
||||
<HeadRowComponent />
|
||||
</thead>
|
||||
);
|
||||
}
|
||||
1
frontend/node_modules/react-day-picker/src/components/Head/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/Head/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './Head';
|
||||
85
frontend/node_modules/react-day-picker/src/components/HeadRow/HeadRow.test.tsx
generated
vendored
Normal file
85
frontend/node_modules/react-day-picker/src/components/HeadRow/HeadRow.test.tsx
generated
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
import { RenderResult } from '@testing-library/react';
|
||||
import { DayPickerProps } from 'DayPicker';
|
||||
|
||||
import { customRender } from 'test/render';
|
||||
|
||||
import { HeadRow } from './HeadRow';
|
||||
|
||||
let container: HTMLElement;
|
||||
let view: RenderResult;
|
||||
|
||||
let thElements: HTMLTableCellElement[];
|
||||
|
||||
function setup(dayPickerProps: DayPickerProps = {}) {
|
||||
view = customRender(
|
||||
<table>
|
||||
<thead>
|
||||
<HeadRow />
|
||||
</thead>
|
||||
</table>,
|
||||
dayPickerProps
|
||||
);
|
||||
container = view.container.firstChild?.firstChild as HTMLTableRowElement;
|
||||
thElements = Array.from(container.getElementsByTagName('th'));
|
||||
}
|
||||
|
||||
const dayPickerProps = {
|
||||
styles: {
|
||||
head: { color: 'red' },
|
||||
head_row: { color: 'blue' },
|
||||
head_cell: { color: 'green' }
|
||||
},
|
||||
classNames: {
|
||||
head: 'foo',
|
||||
head_row: 'foo_row',
|
||||
head_cell: 'foo_head-cell'
|
||||
}
|
||||
};
|
||||
|
||||
describe('when rendered', () => {
|
||||
beforeEach(() => {
|
||||
setup(dayPickerProps);
|
||||
});
|
||||
|
||||
test('tr element should have the `head_row` style', () => {
|
||||
expect(container.firstChild).toHaveStyle(dayPickerProps.styles.head_row);
|
||||
});
|
||||
|
||||
test('tr element should have the `head_row` class', () => {
|
||||
expect(container.firstChild).toHaveClass(
|
||||
dayPickerProps.classNames.head_row
|
||||
);
|
||||
});
|
||||
test('should render 7 head elements', () => {
|
||||
expect(thElements).toHaveLength(7);
|
||||
});
|
||||
test('should render the head elements with the "head_cell" class name', () => {
|
||||
thElements.forEach((el) => {
|
||||
expect(el).toHaveClass(dayPickerProps.classNames.head_cell);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when showing the week numbers', () => {
|
||||
beforeEach(() => {
|
||||
setup({ ...dayPickerProps, showWeekNumber: true });
|
||||
});
|
||||
test('should render 8 head elements', () => {
|
||||
expect(thElements).toHaveLength(7);
|
||||
});
|
||||
test('should render the head elements with the "head_cell" class name', () => {
|
||||
thElements.forEach((el) => {
|
||||
expect(el).toHaveClass(dayPickerProps.classNames.head_cell);
|
||||
});
|
||||
});
|
||||
test('should render the head elements with the "head_cell" style', () => {
|
||||
thElements.forEach((el) => {
|
||||
expect(el).toHaveStyle(dayPickerProps.styles.head_cell);
|
||||
});
|
||||
});
|
||||
test('should render the head elements with the "col" scope', () => {
|
||||
thElements.forEach((el) => {
|
||||
expect(el).toHaveAttribute('scope', 'col');
|
||||
});
|
||||
});
|
||||
});
|
||||
40
frontend/node_modules/react-day-picker/src/components/HeadRow/HeadRow.tsx
generated
vendored
Normal file
40
frontend/node_modules/react-day-picker/src/components/HeadRow/HeadRow.tsx
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
import { useDayPicker } from 'contexts/DayPicker';
|
||||
|
||||
import { getWeekdays } from './utils';
|
||||
|
||||
/**
|
||||
* Render the HeadRow component - i.e. the table head row with the weekday names.
|
||||
*/
|
||||
export function HeadRow(): JSX.Element {
|
||||
const {
|
||||
classNames,
|
||||
styles,
|
||||
showWeekNumber,
|
||||
locale,
|
||||
weekStartsOn,
|
||||
ISOWeek,
|
||||
formatters: { formatWeekdayName },
|
||||
labels: { labelWeekday }
|
||||
} = useDayPicker();
|
||||
|
||||
const weekdays = getWeekdays(locale, weekStartsOn, ISOWeek);
|
||||
|
||||
return (
|
||||
<tr style={styles.head_row} className={classNames.head_row}>
|
||||
{showWeekNumber && (
|
||||
<td style={styles.head_cell} className={classNames.head_cell}></td>
|
||||
)}
|
||||
{weekdays.map((weekday, i) => (
|
||||
<th
|
||||
key={i}
|
||||
scope="col"
|
||||
className={classNames.head_cell}
|
||||
style={styles.head_cell}
|
||||
aria-label={labelWeekday(weekday, { locale })}
|
||||
>
|
||||
{formatWeekdayName(weekday, { locale })}
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
1
frontend/node_modules/react-day-picker/src/components/HeadRow/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/HeadRow/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './HeadRow';
|
||||
46
frontend/node_modules/react-day-picker/src/components/HeadRow/utils/getWeekdays.test.ts
generated
vendored
Normal file
46
frontend/node_modules/react-day-picker/src/components/HeadRow/utils/getWeekdays.test.ts
generated
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
import { es } from 'date-fns/locale';
|
||||
|
||||
import { freezeBeforeAll } from 'test/utils';
|
||||
|
||||
import { getWeekdays } from './getWeekdays';
|
||||
|
||||
const today = new Date(2022, 1, 12);
|
||||
const prevSunday = new Date(2022, 1, 6);
|
||||
const prevMonday = new Date(2022, 1, 7);
|
||||
|
||||
freezeBeforeAll(today);
|
||||
|
||||
let result: Date[];
|
||||
|
||||
describe('when rendered without a locale', () => {
|
||||
beforeEach(() => {
|
||||
result = getWeekdays();
|
||||
});
|
||||
test('should return 7 days', () => {
|
||||
expect(result).toHaveLength(7);
|
||||
});
|
||||
test('should return Sunday as first day', () => {
|
||||
expect(result[0]).toEqual(prevSunday);
|
||||
});
|
||||
});
|
||||
|
||||
describe.each<0 | 1 | 2 | 3 | 4 | 5 | 6>([0, 1, 2, 3, 4, 5, 6])(
|
||||
'when week start on %s',
|
||||
(weekStartsOn) => {
|
||||
beforeEach(() => {
|
||||
result = getWeekdays(es, weekStartsOn);
|
||||
});
|
||||
test('the first date should be weekStartsOn', () => {
|
||||
expect(result[0].getDay()).toBe(weekStartsOn);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
describe('when using ISO week', () => {
|
||||
beforeEach(() => {
|
||||
result = getWeekdays(es, 3, true);
|
||||
});
|
||||
test('should return Monday as first day', () => {
|
||||
expect(result[0]).toEqual(prevMonday);
|
||||
});
|
||||
});
|
||||
24
frontend/node_modules/react-day-picker/src/components/HeadRow/utils/getWeekdays.ts
generated
vendored
Normal file
24
frontend/node_modules/react-day-picker/src/components/HeadRow/utils/getWeekdays.ts
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
import { addDays, Locale, startOfISOWeek, startOfWeek } from 'date-fns';
|
||||
|
||||
/**
|
||||
* Generate a series of 7 days, starting from the week, to use for formatting
|
||||
* the weekday names (Monday, Tuesday, etc.).
|
||||
*/
|
||||
export function getWeekdays(
|
||||
locale?: Locale,
|
||||
/** The index of the first day of the week (0 - Sunday). */
|
||||
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6,
|
||||
/** Use ISOWeek instead of locale/ */
|
||||
ISOWeek?: boolean
|
||||
): Date[] {
|
||||
const start = ISOWeek
|
||||
? startOfISOWeek(new Date())
|
||||
: startOfWeek(new Date(), { locale, weekStartsOn });
|
||||
|
||||
const days = [];
|
||||
for (let i = 0; i < 7; i++) {
|
||||
const day = addDays(start, i);
|
||||
days.push(day);
|
||||
}
|
||||
return days;
|
||||
}
|
||||
1
frontend/node_modules/react-day-picker/src/components/HeadRow/utils/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/HeadRow/utils/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './getWeekdays';
|
||||
18
frontend/node_modules/react-day-picker/src/components/IconDropdown/IconDropdown.test.tsx
generated
vendored
Normal file
18
frontend/node_modules/react-day-picker/src/components/IconDropdown/IconDropdown.test.tsx
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
import { customRender } from 'test/render';
|
||||
|
||||
import { IconDropdown } from './IconDropdown';
|
||||
|
||||
let root: HTMLElement;
|
||||
|
||||
beforeEach(() => {
|
||||
const view = customRender(
|
||||
<IconDropdown className="foo" style={{ color: 'red' }} />
|
||||
);
|
||||
root = view.container.firstChild as HTMLElement;
|
||||
});
|
||||
test('should add the class name', () => {
|
||||
expect(root).toHaveClass('foo');
|
||||
});
|
||||
test('should apply the style', () => {
|
||||
expect(root).toHaveStyle({ color: 'red' });
|
||||
});
|
||||
22
frontend/node_modules/react-day-picker/src/components/IconDropdown/IconDropdown.tsx
generated
vendored
Normal file
22
frontend/node_modules/react-day-picker/src/components/IconDropdown/IconDropdown.tsx
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
import { StyledComponent } from 'types/Styles';
|
||||
|
||||
/**
|
||||
* Render the icon in the styled drop-down.
|
||||
*/
|
||||
export function IconDropdown(props: StyledComponent): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
width="8px"
|
||||
height="8px"
|
||||
viewBox="0 0 120 120"
|
||||
data-testid="iconDropdown"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M4.22182541,48.2218254 C8.44222828,44.0014225 15.2388494,43.9273804 19.5496459,47.9996989 L19.7781746,48.2218254 L60,88.443 L100.221825,48.2218254 C104.442228,44.0014225 111.238849,43.9273804 115.549646,47.9996989 L115.778175,48.2218254 C119.998577,52.4422283 120.07262,59.2388494 116.000301,63.5496459 L115.778175,63.7781746 L67.7781746,111.778175 C63.5577717,115.998577 56.7611506,116.07262 52.4503541,112.000301 L52.2218254,111.778175 L4.22182541,63.7781746 C-0.0739418023,59.4824074 -0.0739418023,52.5175926 4.22182541,48.2218254 Z"
|
||||
fill="currentColor"
|
||||
fillRule="nonzero"
|
||||
></path>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
1
frontend/node_modules/react-day-picker/src/components/IconDropdown/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/IconDropdown/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './IconDropdown';
|
||||
18
frontend/node_modules/react-day-picker/src/components/IconLeft/IconLeft.test.tsx
generated
vendored
Normal file
18
frontend/node_modules/react-day-picker/src/components/IconLeft/IconLeft.test.tsx
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
import { customRender } from 'test/render';
|
||||
|
||||
import { IconLeft } from './IconLeft';
|
||||
|
||||
let root: HTMLElement;
|
||||
|
||||
beforeEach(() => {
|
||||
const view = customRender(
|
||||
<IconLeft className="foo" style={{ color: 'red' }} />
|
||||
);
|
||||
root = view.container.firstChild as HTMLElement;
|
||||
});
|
||||
test('should add the class name', () => {
|
||||
expect(root).toHaveClass('foo');
|
||||
});
|
||||
test('should apply the style', () => {
|
||||
expect(root).toHaveStyle({ color: 'red' });
|
||||
});
|
||||
16
frontend/node_modules/react-day-picker/src/components/IconLeft/IconLeft.tsx
generated
vendored
Normal file
16
frontend/node_modules/react-day-picker/src/components/IconLeft/IconLeft.tsx
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
import { StyledComponent } from 'types/Styles';
|
||||
|
||||
/**
|
||||
* Render the "previous month" button in the navigation.
|
||||
*/
|
||||
export function IconLeft(props: StyledComponent): JSX.Element {
|
||||
return (
|
||||
<svg width="16px" height="16px" viewBox="0 0 120 120" {...props}>
|
||||
<path
|
||||
d="M69.490332,3.34314575 C72.6145263,0.218951416 77.6798462,0.218951416 80.8040405,3.34314575 C83.8617626,6.40086786 83.9268205,11.3179931 80.9992143,14.4548388 L80.8040405,14.6568542 L35.461,60 L80.8040405,105.343146 C83.8617626,108.400868 83.9268205,113.317993 80.9992143,116.454839 L80.8040405,116.656854 C77.7463184,119.714576 72.8291931,119.779634 69.6923475,116.852028 L69.490332,116.656854 L18.490332,65.6568542 C15.4326099,62.5991321 15.367552,57.6820069 18.2951583,54.5451612 L18.490332,54.3431458 L69.490332,3.34314575 Z"
|
||||
fill="currentColor"
|
||||
fillRule="nonzero"
|
||||
></path>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
1
frontend/node_modules/react-day-picker/src/components/IconLeft/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/IconLeft/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './IconLeft';
|
||||
18
frontend/node_modules/react-day-picker/src/components/IconRight/IconRight.test.tsx
generated
vendored
Normal file
18
frontend/node_modules/react-day-picker/src/components/IconRight/IconRight.test.tsx
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
import { customRender } from 'test/render';
|
||||
|
||||
import { IconRight } from './IconRight';
|
||||
|
||||
let root: HTMLElement;
|
||||
|
||||
beforeEach(() => {
|
||||
const view = customRender(
|
||||
<IconRight className="foo" style={{ color: 'red' }} />
|
||||
);
|
||||
root = view.container.firstChild as HTMLElement;
|
||||
});
|
||||
test('should add the class name', () => {
|
||||
expect(root).toHaveClass('foo');
|
||||
});
|
||||
test('should apply the style', () => {
|
||||
expect(root).toHaveStyle({ color: 'red' });
|
||||
});
|
||||
15
frontend/node_modules/react-day-picker/src/components/IconRight/IconRight.tsx
generated
vendored
Normal file
15
frontend/node_modules/react-day-picker/src/components/IconRight/IconRight.tsx
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
import { StyledComponent } from 'types/Styles';
|
||||
|
||||
/**
|
||||
* Render the "next month" button in the navigation.
|
||||
*/
|
||||
export function IconRight(props: StyledComponent): JSX.Element {
|
||||
return (
|
||||
<svg width="16px" height="16px" viewBox="0 0 120 120" {...props}>
|
||||
<path
|
||||
d="M49.8040405,3.34314575 C46.6798462,0.218951416 41.6145263,0.218951416 38.490332,3.34314575 C35.4326099,6.40086786 35.367552,11.3179931 38.2951583,14.4548388 L38.490332,14.6568542 L83.8333725,60 L38.490332,105.343146 C35.4326099,108.400868 35.367552,113.317993 38.2951583,116.454839 L38.490332,116.656854 C41.5480541,119.714576 46.4651794,119.779634 49.602025,116.852028 L49.8040405,116.656854 L100.804041,65.6568542 C103.861763,62.5991321 103.926821,57.6820069 100.999214,54.5451612 L100.804041,54.3431458 L49.8040405,3.34314575 Z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
1
frontend/node_modules/react-day-picker/src/components/IconRight/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/IconRight/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './IconRight';
|
||||
230
frontend/node_modules/react-day-picker/src/components/Month/Month.test.tsx
generated
vendored
Normal file
230
frontend/node_modules/react-day-picker/src/components/Month/Month.test.tsx
generated
vendored
Normal file
@ -0,0 +1,230 @@
|
||||
import { screen } from '@testing-library/react';
|
||||
import { DayPickerProps } from 'DayPicker';
|
||||
|
||||
import { customRender } from 'test/render';
|
||||
import { getMonthCaption, getMonthGrid } from 'test/selectors';
|
||||
|
||||
import { CustomComponents } from 'types/DayPickerBase';
|
||||
|
||||
import { Month, MonthProps } from './Month';
|
||||
|
||||
let root: HTMLDivElement;
|
||||
|
||||
const displayMonth = new Date(2022, 10, 4);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const testStyles: Record<string, any> = {
|
||||
caption_start: { color: 'red' },
|
||||
caption_end: { background: 'blue' },
|
||||
caption_between: { fontSize: 20 }
|
||||
};
|
||||
|
||||
const testClassNames: Record<string, string> = {
|
||||
caption_start: 'caption_start',
|
||||
caption_end: 'caption_end',
|
||||
caption_between: 'caption_between'
|
||||
};
|
||||
|
||||
type Test = {
|
||||
monthProps: MonthProps;
|
||||
dayPickerProps: DayPickerProps;
|
||||
expected: string[];
|
||||
notExpected: string[];
|
||||
};
|
||||
|
||||
function setup(props: MonthProps, dayPickerProps?: DayPickerProps) {
|
||||
const view = customRender(<Month {...props} />, dayPickerProps);
|
||||
root = view.container.firstChild as HTMLDivElement;
|
||||
}
|
||||
describe('when rendered', () => {
|
||||
beforeEach(() => {
|
||||
setup({ displayIndex: 0, displayMonth });
|
||||
});
|
||||
test('the caption id should be the aria-labelledby of the grid', () => {
|
||||
const captionId = getMonthCaption().getAttribute('id');
|
||||
const gridLabelledBy = getMonthGrid().getAttribute('aria-labelledby');
|
||||
expect(captionId).toEqual(gridLabelledBy);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when rendered with a custom id', () => {
|
||||
const id = 'custom-id';
|
||||
beforeEach(() => {
|
||||
setup({ displayIndex: 0, displayMonth }, { id });
|
||||
});
|
||||
test('the caption id should include the display index', () => {
|
||||
const captionId = getMonthCaption().getAttribute('id');
|
||||
expect(captionId).toEqual('custom-id-0');
|
||||
});
|
||||
|
||||
test('the table id should include the display index', () => {
|
||||
const tableId = getMonthGrid().getAttribute('id');
|
||||
expect(tableId).toEqual('custom-id-grid-0');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when using a custom Caption component', () => {
|
||||
const components: CustomComponents = {
|
||||
Caption: () => <>custom caption foo</>
|
||||
};
|
||||
beforeEach(() => {
|
||||
setup({ displayIndex: 0, displayMonth }, { components });
|
||||
});
|
||||
test('it should render the custom component instead', () => {
|
||||
expect(screen.getByText('custom caption foo')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when dir is ltr', () => {
|
||||
const testLtr: Test[] = [
|
||||
{
|
||||
monthProps: {
|
||||
displayIndex: 0,
|
||||
displayMonth
|
||||
},
|
||||
dayPickerProps: {
|
||||
numberOfMonths: 1,
|
||||
styles: testStyles,
|
||||
classNames: testClassNames
|
||||
},
|
||||
expected: ['caption_start', 'caption_end'],
|
||||
notExpected: ['caption_between']
|
||||
},
|
||||
{
|
||||
monthProps: {
|
||||
displayIndex: 0,
|
||||
displayMonth
|
||||
},
|
||||
dayPickerProps: {
|
||||
numberOfMonths: 2,
|
||||
styles: testStyles,
|
||||
classNames: testClassNames
|
||||
},
|
||||
expected: ['caption_start'],
|
||||
notExpected: ['caption_between', 'caption_end']
|
||||
},
|
||||
{
|
||||
monthProps: {
|
||||
displayIndex: 1,
|
||||
displayMonth
|
||||
},
|
||||
dayPickerProps: {
|
||||
numberOfMonths: 2,
|
||||
styles: testStyles,
|
||||
classNames: testClassNames
|
||||
},
|
||||
expected: ['caption_end'],
|
||||
notExpected: ['caption_start', 'caption_between']
|
||||
},
|
||||
{
|
||||
monthProps: {
|
||||
displayIndex: 1,
|
||||
displayMonth
|
||||
},
|
||||
dayPickerProps: {
|
||||
numberOfMonths: 3,
|
||||
styles: testStyles,
|
||||
classNames: testClassNames
|
||||
},
|
||||
expected: ['caption_between'],
|
||||
notExpected: ['caption_start', 'caption_end']
|
||||
}
|
||||
];
|
||||
|
||||
describe.each(testLtr)(
|
||||
'when displayIndex is $monthProps.displayIndex and numberOfMonths is $dayPickerProps.numberOfMonths',
|
||||
({ monthProps, dayPickerProps, expected, notExpected }) => {
|
||||
beforeEach(() => {
|
||||
setup(monthProps, dayPickerProps);
|
||||
});
|
||||
test.each(expected)(`the root should have the %s class`, (name) =>
|
||||
expect(root).toHaveClass(testClassNames[name])
|
||||
);
|
||||
test.each(expected)(`the root should have the %s style`, (name) =>
|
||||
expect(root).toHaveStyle(testStyles[name])
|
||||
);
|
||||
test.each(notExpected)(`the root should not have the %s class`, (name) =>
|
||||
expect(root).not.toHaveClass(testClassNames[name])
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
describe('when dir is rtl', () => {
|
||||
const testRtl: Test[] = [
|
||||
{
|
||||
monthProps: {
|
||||
displayIndex: 0,
|
||||
displayMonth
|
||||
},
|
||||
dayPickerProps: {
|
||||
dir: 'rtl',
|
||||
numberOfMonths: 1,
|
||||
styles: testStyles,
|
||||
classNames: testClassNames
|
||||
},
|
||||
expected: ['caption_start', 'caption_end'],
|
||||
notExpected: ['caption_between']
|
||||
},
|
||||
{
|
||||
monthProps: {
|
||||
displayIndex: 0,
|
||||
displayMonth
|
||||
},
|
||||
dayPickerProps: {
|
||||
dir: 'rtl',
|
||||
numberOfMonths: 2,
|
||||
styles: testStyles,
|
||||
classNames: testClassNames
|
||||
},
|
||||
expected: ['caption_end'],
|
||||
notExpected: ['caption_between', 'caption_start']
|
||||
},
|
||||
{
|
||||
monthProps: {
|
||||
displayIndex: 1,
|
||||
displayMonth
|
||||
},
|
||||
dayPickerProps: {
|
||||
dir: 'rtl',
|
||||
numberOfMonths: 2,
|
||||
styles: testStyles,
|
||||
classNames: testClassNames
|
||||
},
|
||||
expected: ['caption_start'],
|
||||
notExpected: ['caption_end', 'caption_between']
|
||||
},
|
||||
{
|
||||
monthProps: {
|
||||
displayIndex: 1,
|
||||
displayMonth
|
||||
},
|
||||
dayPickerProps: {
|
||||
dir: 'rtl',
|
||||
numberOfMonths: 3,
|
||||
styles: testStyles,
|
||||
classNames: testClassNames
|
||||
},
|
||||
expected: ['caption_between'],
|
||||
notExpected: ['caption_start', 'caption_end']
|
||||
}
|
||||
];
|
||||
|
||||
describe.each(testRtl)(
|
||||
'when displayIndex is $monthProps.displayIndex and numberOfMonths is $dayPickerProps.numberOfMonths',
|
||||
({ monthProps, dayPickerProps, expected, notExpected }) => {
|
||||
beforeEach(() => {
|
||||
setup(monthProps, dayPickerProps);
|
||||
});
|
||||
test.each(expected)(`the root should have the %s class`, (name) =>
|
||||
expect(root).toHaveClass(testClassNames[name])
|
||||
);
|
||||
test.each(expected)(`the root should have the %s style`, (name) =>
|
||||
expect(root).toHaveStyle(testStyles[name])
|
||||
);
|
||||
test.each(notExpected)(`the root should not have the %s class`, (name) =>
|
||||
expect(root).not.toHaveClass(testClassNames[name])
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
66
frontend/node_modules/react-day-picker/src/components/Month/Month.tsx
generated
vendored
Normal file
66
frontend/node_modules/react-day-picker/src/components/Month/Month.tsx
generated
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
import { Caption } from 'components/Caption';
|
||||
import { Table } from 'components/Table';
|
||||
import { useDayPicker } from 'contexts/DayPicker';
|
||||
import { useNavigation } from 'contexts/Navigation';
|
||||
import { useId } from 'hooks/useId';
|
||||
|
||||
/** The props for the {@link Month} component. */
|
||||
export interface MonthProps {
|
||||
displayIndex: number;
|
||||
displayMonth: Date;
|
||||
}
|
||||
|
||||
/** Render a month. */
|
||||
export function Month(props: MonthProps) {
|
||||
const dayPicker = useDayPicker();
|
||||
const { dir, classNames, styles, components } = dayPicker;
|
||||
const { displayMonths } = useNavigation();
|
||||
|
||||
const captionId = useId(
|
||||
dayPicker.id ? `${dayPicker.id}-${props.displayIndex}` : undefined
|
||||
);
|
||||
|
||||
const tableId = dayPicker.id
|
||||
? `${dayPicker.id}-grid-${props.displayIndex}`
|
||||
: undefined;
|
||||
|
||||
const className = [classNames.month];
|
||||
let style = styles.month;
|
||||
|
||||
let isStart = props.displayIndex === 0;
|
||||
let isEnd = props.displayIndex === displayMonths.length - 1;
|
||||
const isCenter = !isStart && !isEnd;
|
||||
if (dir === 'rtl') {
|
||||
[isEnd, isStart] = [isStart, isEnd];
|
||||
}
|
||||
|
||||
if (isStart) {
|
||||
className.push(classNames.caption_start);
|
||||
style = { ...style, ...styles.caption_start };
|
||||
}
|
||||
if (isEnd) {
|
||||
className.push(classNames.caption_end);
|
||||
style = { ...style, ...styles.caption_end };
|
||||
}
|
||||
if (isCenter) {
|
||||
className.push(classNames.caption_between);
|
||||
style = { ...style, ...styles.caption_between };
|
||||
}
|
||||
|
||||
const CaptionComponent = components?.Caption ?? Caption;
|
||||
|
||||
return (
|
||||
<div key={props.displayIndex} className={className.join(' ')} style={style}>
|
||||
<CaptionComponent
|
||||
id={captionId}
|
||||
displayMonth={props.displayMonth}
|
||||
displayIndex={props.displayIndex}
|
||||
/>
|
||||
<Table
|
||||
id={tableId}
|
||||
aria-labelledby={captionId}
|
||||
displayMonth={props.displayMonth}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
1
frontend/node_modules/react-day-picker/src/components/Month/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/Month/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './Month';
|
||||
27
frontend/node_modules/react-day-picker/src/components/Months/Months.test.tsx
generated
vendored
Normal file
27
frontend/node_modules/react-day-picker/src/components/Months/Months.test.tsx
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
import { customRender } from 'test/render';
|
||||
|
||||
import { Months } from './Months';
|
||||
|
||||
let root: HTMLElement;
|
||||
|
||||
test('should use the default class name', () => {
|
||||
const view = customRender(<Months>foo</Months>, {});
|
||||
root = view.container.firstChild as HTMLElement;
|
||||
expect(root).toHaveClass('rdp-months');
|
||||
});
|
||||
|
||||
test('should use a custom class name', () => {
|
||||
const view = customRender(<Months>foo</Months>, {
|
||||
classNames: { months: 'foo' }
|
||||
});
|
||||
root = view.container.firstChild as HTMLElement;
|
||||
expect(root).toHaveClass('foo');
|
||||
});
|
||||
|
||||
test('should use a custom style', () => {
|
||||
const view = customRender(<Months>foo</Months>, {
|
||||
styles: { months: { color: 'red' } }
|
||||
});
|
||||
root = view.container.firstChild as HTMLElement;
|
||||
expect(root).toHaveStyle({ color: 'red' });
|
||||
});
|
||||
19
frontend/node_modules/react-day-picker/src/components/Months/Months.tsx
generated
vendored
Normal file
19
frontend/node_modules/react-day-picker/src/components/Months/Months.tsx
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
import { useDayPicker } from 'contexts/DayPicker';
|
||||
|
||||
/** The props for the {@link Months} component. */
|
||||
export type MonthsProps = { children: ReactNode };
|
||||
|
||||
/**
|
||||
* Render the wrapper for the month grids.
|
||||
*/
|
||||
export function Months(props: MonthsProps): JSX.Element {
|
||||
const { classNames, styles } = useDayPicker();
|
||||
|
||||
return (
|
||||
<div className={classNames.months} style={styles.months}>
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
1
frontend/node_modules/react-day-picker/src/components/Months/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/Months/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './Months';
|
||||
107
frontend/node_modules/react-day-picker/src/components/MonthsDropdown/MonthsDropdown.test.tsx
generated
vendored
Normal file
107
frontend/node_modules/react-day-picker/src/components/MonthsDropdown/MonthsDropdown.test.tsx
generated
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
import { screen } from '@testing-library/react';
|
||||
import { addMonths, differenceInMonths } from 'date-fns';
|
||||
import { DayPickerProps } from 'DayPicker';
|
||||
|
||||
import { customRender } from 'test/render';
|
||||
import { user } from 'test/user';
|
||||
import { freezeBeforeAll } from 'test/utils';
|
||||
|
||||
import { MonthsDropdown, MonthsDropdownProps } from './MonthsDropdown';
|
||||
|
||||
const today = new Date(2020, 12, 22);
|
||||
|
||||
freezeBeforeAll(today);
|
||||
|
||||
let root: HTMLDivElement;
|
||||
let options: HTMLCollectionOf<HTMLOptionElement> | undefined;
|
||||
let select: HTMLSelectElement | null;
|
||||
|
||||
function setup(props: MonthsDropdownProps, dayPickerProps?: DayPickerProps) {
|
||||
const view = customRender(<MonthsDropdown {...props} />, dayPickerProps);
|
||||
root = view.container.firstChild as HTMLDivElement;
|
||||
select = screen.queryByRole('combobox', { name: 'Month:' });
|
||||
options = select?.getElementsByTagName('option');
|
||||
}
|
||||
|
||||
const props: MonthsDropdownProps = {
|
||||
displayMonth: today,
|
||||
onChange: jest.fn()
|
||||
};
|
||||
|
||||
describe('when fromDate and toDate are passed in', () => {
|
||||
beforeEach(() => {
|
||||
setup(props, { fromDate: new Date(), toDate: addMonths(new Date(), 1) });
|
||||
});
|
||||
test('should render the dropdown element', () => {
|
||||
expect(root).toMatchSnapshot();
|
||||
expect(select).toHaveAttribute('name', 'months');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when "fromDate" is not set', () => {
|
||||
beforeEach(() => {
|
||||
setup(props, { fromDate: undefined });
|
||||
});
|
||||
test('should return nothing', () => {
|
||||
expect(root).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when "toDate" is not set', () => {
|
||||
beforeEach(() => {
|
||||
setup(props, { toDate: undefined });
|
||||
});
|
||||
test('should return nothing', () => {
|
||||
expect(root).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when "fromDate" and "toDate" are in the same year', () => {
|
||||
const fromDate = new Date(2012, 0, 22);
|
||||
const toDate = new Date(2012, 10, 22);
|
||||
beforeEach(() => {
|
||||
setup(props, { fromDate, toDate });
|
||||
});
|
||||
test('should display the months included between the two dates', () => {
|
||||
expect(options).toHaveLength(differenceInMonths(toDate, fromDate) + 1);
|
||||
});
|
||||
test('the first month should be the fromDate month', () => {
|
||||
expect(options?.[0]).toHaveValue(String(fromDate.getMonth()));
|
||||
});
|
||||
test('the last month should be the toMonth month', () => {
|
||||
expect(options?.[options.length - 1]).toHaveValue(
|
||||
String(toDate.getMonth())
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when "fromDate" and "toDate" are not in the same year', () => {
|
||||
const fromDate = new Date(2012, 0, 22);
|
||||
const toDate = new Date(2015, 10, 22);
|
||||
const displayMonth = new Date(2015, 7, 0);
|
||||
beforeEach(() => {
|
||||
setup({ ...props, displayMonth }, { fromDate, toDate });
|
||||
});
|
||||
test('should display the 12 months', () => {
|
||||
expect(options).toHaveLength(12);
|
||||
});
|
||||
test('the first month should be January', () => {
|
||||
expect(options?.[0]).toHaveValue('0');
|
||||
});
|
||||
test('the last month should be December', () => {
|
||||
expect(options?.[options.length - 1]).toHaveValue('11');
|
||||
});
|
||||
test('should select the displayed month', () => {
|
||||
expect(select).toHaveValue(`${displayMonth.getMonth()}`);
|
||||
});
|
||||
|
||||
describe('when the dropdown changes', () => {
|
||||
beforeEach(async () => {
|
||||
if (select) await user.selectOptions(select, 'February');
|
||||
});
|
||||
test('should fire the "onChange" event handler', () => {
|
||||
const expectedMonth = new Date(2015, 1, 1);
|
||||
expect(props.onChange).toHaveBeenCalledWith(expectedMonth);
|
||||
});
|
||||
});
|
||||
});
|
||||
74
frontend/node_modules/react-day-picker/src/components/MonthsDropdown/MonthsDropdown.tsx
generated
vendored
Normal file
74
frontend/node_modules/react-day-picker/src/components/MonthsDropdown/MonthsDropdown.tsx
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
import { ChangeEventHandler } from 'react';
|
||||
|
||||
import { isSameYear, setMonth, startOfMonth } from 'date-fns';
|
||||
|
||||
import { Dropdown } from 'components/Dropdown';
|
||||
import { useDayPicker } from 'contexts/DayPicker';
|
||||
import { MonthChangeEventHandler } from 'types/EventHandlers';
|
||||
|
||||
/** The props for the {@link MonthsDropdown} component. */
|
||||
export interface MonthsDropdownProps {
|
||||
/** The month where the dropdown is displayed. */
|
||||
displayMonth: Date;
|
||||
onChange: MonthChangeEventHandler;
|
||||
}
|
||||
|
||||
/** Render the dropdown to navigate between months. */
|
||||
export function MonthsDropdown(props: MonthsDropdownProps): JSX.Element {
|
||||
const {
|
||||
fromDate,
|
||||
toDate,
|
||||
styles,
|
||||
locale,
|
||||
formatters: { formatMonthCaption },
|
||||
classNames,
|
||||
components,
|
||||
labels: { labelMonthDropdown }
|
||||
} = useDayPicker();
|
||||
|
||||
// Dropdown should appear only when both from/toDate is set
|
||||
if (!fromDate) return <></>;
|
||||
if (!toDate) return <></>;
|
||||
|
||||
const dropdownMonths: Date[] = [];
|
||||
|
||||
if (isSameYear(fromDate, toDate)) {
|
||||
// only display the months included in the range
|
||||
const date = startOfMonth(fromDate);
|
||||
for (let month = fromDate.getMonth(); month <= toDate.getMonth(); month++) {
|
||||
dropdownMonths.push(setMonth(date, month));
|
||||
}
|
||||
} else {
|
||||
// display all the 12 months
|
||||
const date = startOfMonth(new Date()); // Any date should be OK, as we just need the year
|
||||
for (let month = 0; month <= 11; month++) {
|
||||
dropdownMonths.push(setMonth(date, month));
|
||||
}
|
||||
}
|
||||
|
||||
const handleChange: ChangeEventHandler<HTMLSelectElement> = (e) => {
|
||||
const selectedMonth = Number(e.target.value);
|
||||
const newMonth = setMonth(startOfMonth(props.displayMonth), selectedMonth);
|
||||
props.onChange(newMonth);
|
||||
};
|
||||
|
||||
const DropdownComponent = components?.Dropdown ?? Dropdown;
|
||||
|
||||
return (
|
||||
<DropdownComponent
|
||||
name="months"
|
||||
aria-label={labelMonthDropdown()}
|
||||
className={classNames.dropdown_month}
|
||||
style={styles.dropdown_month}
|
||||
onChange={handleChange}
|
||||
value={props.displayMonth.getMonth()}
|
||||
caption={formatMonthCaption(props.displayMonth, { locale })}
|
||||
>
|
||||
{dropdownMonths.map((m) => (
|
||||
<option key={m.getMonth()} value={m.getMonth()}>
|
||||
{formatMonthCaption(m, { locale })}
|
||||
</option>
|
||||
))}
|
||||
</DropdownComponent>
|
||||
);
|
||||
}
|
||||
48
frontend/node_modules/react-day-picker/src/components/MonthsDropdown/__snapshots__/MonthsDropdown.test.tsx.snap
generated
vendored
Normal file
48
frontend/node_modules/react-day-picker/src/components/MonthsDropdown/__snapshots__/MonthsDropdown.test.tsx.snap
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`when fromDate and toDate are passed in should render the dropdown element 1`] = `
|
||||
<div
|
||||
class="rdp-dropdown_month"
|
||||
>
|
||||
<span
|
||||
class="rdp-vhidden"
|
||||
>
|
||||
Month:
|
||||
</span>
|
||||
<select
|
||||
aria-label="Month: "
|
||||
class="rdp-dropdown"
|
||||
name="months"
|
||||
>
|
||||
<option
|
||||
value="0"
|
||||
>
|
||||
January
|
||||
</option>
|
||||
<option
|
||||
value="1"
|
||||
>
|
||||
February
|
||||
</option>
|
||||
</select>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="rdp-caption_label"
|
||||
>
|
||||
January
|
||||
<svg
|
||||
class="rdp-dropdown_icon"
|
||||
data-testid="iconDropdown"
|
||||
height="8px"
|
||||
viewBox="0 0 120 120"
|
||||
width="8px"
|
||||
>
|
||||
<path
|
||||
d="M4.22182541,48.2218254 C8.44222828,44.0014225 15.2388494,43.9273804 19.5496459,47.9996989 L19.7781746,48.2218254 L60,88.443 L100.221825,48.2218254 C104.442228,44.0014225 111.238849,43.9273804 115.549646,47.9996989 L115.778175,48.2218254 C119.998577,52.4422283 120.07262,59.2388494 116.000301,63.5496459 L115.778175,63.7781746 L67.7781746,111.778175 C63.5577717,115.998577 56.7611506,116.07262 52.4503541,112.000301 L52.2218254,111.778175 L4.22182541,63.7781746 C-0.0739418023,59.4824074 -0.0739418023,52.5175926 4.22182541,48.2218254 Z"
|
||||
fill="currentColor"
|
||||
fill-rule="nonzero"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
1
frontend/node_modules/react-day-picker/src/components/MonthsDropdown/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/MonthsDropdown/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './MonthsDropdown';
|
||||
133
frontend/node_modules/react-day-picker/src/components/Navigation/Navigation.test.tsx
generated
vendored
Normal file
133
frontend/node_modules/react-day-picker/src/components/Navigation/Navigation.test.tsx
generated
vendored
Normal file
@ -0,0 +1,133 @@
|
||||
import { DayPickerProps } from 'DayPicker';
|
||||
|
||||
import { customRender } from 'test/render';
|
||||
import { getNextButton, getPrevButton } from 'test/selectors';
|
||||
import { user } from 'test/user';
|
||||
|
||||
import { Navigation, NavigationProps } from './Navigation';
|
||||
|
||||
let root: HTMLElement;
|
||||
|
||||
function setup(props: NavigationProps, dayPickerProps?: DayPickerProps) {
|
||||
const view = customRender(<Navigation {...props} />, dayPickerProps);
|
||||
root = view.container.firstChild as HTMLElement;
|
||||
}
|
||||
|
||||
const props: NavigationProps = {
|
||||
previousMonth: new Date(2021, 3),
|
||||
nextMonth: new Date(2021, 5),
|
||||
displayMonth: new Date(2021, 4),
|
||||
hidePrevious: false,
|
||||
hideNext: false,
|
||||
onNextClick: jest.fn(),
|
||||
onPreviousClick: jest.fn()
|
||||
};
|
||||
|
||||
const dayPickerProps = {
|
||||
classNames: {
|
||||
nav: 'foo'
|
||||
},
|
||||
styles: {
|
||||
nav: { color: 'red' }
|
||||
},
|
||||
components: {
|
||||
IconRight: () => <svg>IconRight</svg>,
|
||||
IconLeft: () => <svg>IconLeft</svg>
|
||||
}
|
||||
};
|
||||
|
||||
describe('when rendered', () => {
|
||||
beforeEach(() => {
|
||||
setup(props, dayPickerProps);
|
||||
});
|
||||
test('should add the class name', () => {
|
||||
expect(root).toHaveClass(dayPickerProps.classNames.nav);
|
||||
});
|
||||
test('should apply the style', () => {
|
||||
expect(root).toHaveStyle(dayPickerProps.styles.nav);
|
||||
});
|
||||
test('the previous button should display the left icon', () => {
|
||||
const icons = root.getElementsByTagName('svg');
|
||||
expect(icons[0]).toHaveTextContent('IconLeft');
|
||||
});
|
||||
test('the next button should display the right icon', () => {
|
||||
const icons = root.getElementsByTagName('svg');
|
||||
expect(icons[1]).toHaveTextContent('IconRight');
|
||||
});
|
||||
test('the previous button should be named "previous-month"', () => {
|
||||
expect(getPrevButton()).toHaveAttribute('name', 'previous-month');
|
||||
});
|
||||
test('the next button should be named "next-month"', () => {
|
||||
expect(getNextButton()).toHaveAttribute('name', 'next-month');
|
||||
});
|
||||
beforeEach(async () => {
|
||||
await user.click(getPrevButton());
|
||||
});
|
||||
test('should call "onPreviousClick"', () => {
|
||||
expect(props.onPreviousClick).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('when clicking the next button', () => {
|
||||
beforeEach(async () => {
|
||||
await user.click(getNextButton());
|
||||
});
|
||||
test('should call "onNextClick"', () => {
|
||||
expect(props.onNextClick).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when in right-to-left direction', () => {
|
||||
beforeEach(() => {
|
||||
setup(props, { ...dayPickerProps, dir: 'rtl' });
|
||||
});
|
||||
test('the previous button should display the right icon', () => {
|
||||
const icons = root.getElementsByTagName('svg');
|
||||
expect(icons[0]).toHaveTextContent('IconRight');
|
||||
});
|
||||
test('the next button should display the left icon', () => {
|
||||
const icons = root.getElementsByTagName('svg');
|
||||
expect(icons[1]).toHaveTextContent('IconLeft');
|
||||
});
|
||||
|
||||
describe('when clicking the previous button', () => {
|
||||
beforeEach(async () => {
|
||||
await user.click(getPrevButton());
|
||||
});
|
||||
test('should call "onPreviousClick"', () => {
|
||||
expect(props.onPreviousClick).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
describe('when clicking the next button', () => {
|
||||
beforeEach(async () => {
|
||||
await user.click(getNextButton());
|
||||
});
|
||||
test('should call "onNextClick"', () => {
|
||||
expect(props.onNextClick).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the previous month is undefined', () => {
|
||||
beforeEach(() => {
|
||||
setup({ ...props, previousMonth: undefined }, dayPickerProps);
|
||||
});
|
||||
test('the previous button should be disabled', () => {
|
||||
expect(getPrevButton()).toBeDisabled();
|
||||
});
|
||||
test('the next button should be enabled', () => {
|
||||
expect(getNextButton()).toBeEnabled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the next month is undefined', () => {
|
||||
beforeEach(() => {
|
||||
setup({ ...props, nextMonth: undefined }, dayPickerProps);
|
||||
});
|
||||
test('the previous button should be enabled', () => {
|
||||
expect(getPrevButton()).toBeEnabled();
|
||||
});
|
||||
test('the next button should be disabled', () => {
|
||||
expect(getNextButton()).toBeDisabled();
|
||||
});
|
||||
});
|
||||
104
frontend/node_modules/react-day-picker/src/components/Navigation/Navigation.tsx
generated
vendored
Normal file
104
frontend/node_modules/react-day-picker/src/components/Navigation/Navigation.tsx
generated
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
import { MouseEventHandler } from 'react';
|
||||
|
||||
import { IconLeft } from 'components/IconLeft';
|
||||
import { IconRight } from 'components/IconRight';
|
||||
import { useDayPicker } from 'contexts/DayPicker';
|
||||
|
||||
import { Button } from '../Button';
|
||||
|
||||
/** The props for the {@link Navigation} component. */
|
||||
export interface NavigationProps {
|
||||
/** The month where the caption is displayed. */
|
||||
displayMonth: Date;
|
||||
/** The previous month. */
|
||||
previousMonth?: Date;
|
||||
/** The next month. */
|
||||
nextMonth?: Date;
|
||||
/** Hide the previous button. */
|
||||
hidePrevious: boolean;
|
||||
/** Hide the next button. */
|
||||
hideNext: boolean;
|
||||
/** Event handler when the next button is clicked. */
|
||||
onNextClick: MouseEventHandler<HTMLButtonElement>;
|
||||
/** Event handler when the previous button is clicked. */
|
||||
onPreviousClick: MouseEventHandler<HTMLButtonElement>;
|
||||
}
|
||||
|
||||
/** A component rendering the navigation buttons or the drop-downs. */
|
||||
export function Navigation(props: NavigationProps): JSX.Element {
|
||||
const {
|
||||
dir,
|
||||
locale,
|
||||
classNames,
|
||||
styles,
|
||||
labels: { labelPrevious, labelNext },
|
||||
components
|
||||
} = useDayPicker();
|
||||
|
||||
if (!props.nextMonth && !props.previousMonth) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
const previousLabel = labelPrevious(props.previousMonth, { locale });
|
||||
const previousClassName = [
|
||||
classNames.nav_button,
|
||||
classNames.nav_button_previous
|
||||
].join(' ');
|
||||
|
||||
const nextLabel = labelNext(props.nextMonth, { locale });
|
||||
const nextClassName = [
|
||||
classNames.nav_button,
|
||||
classNames.nav_button_next
|
||||
].join(' ');
|
||||
|
||||
const IconRightComponent = components?.IconRight ?? IconRight;
|
||||
const IconLeftComponent = components?.IconLeft ?? IconLeft;
|
||||
return (
|
||||
<div className={classNames.nav} style={styles.nav}>
|
||||
{!props.hidePrevious && (
|
||||
<Button
|
||||
name="previous-month"
|
||||
aria-label={previousLabel}
|
||||
className={previousClassName}
|
||||
style={styles.nav_button_previous}
|
||||
disabled={!props.previousMonth}
|
||||
onClick={props.onPreviousClick}
|
||||
>
|
||||
{dir === 'rtl' ? (
|
||||
<IconRightComponent
|
||||
className={classNames.nav_icon}
|
||||
style={styles.nav_icon}
|
||||
/>
|
||||
) : (
|
||||
<IconLeftComponent
|
||||
className={classNames.nav_icon}
|
||||
style={styles.nav_icon}
|
||||
/>
|
||||
)}
|
||||
</Button>
|
||||
)}
|
||||
{!props.hideNext && (
|
||||
<Button
|
||||
name="next-month"
|
||||
aria-label={nextLabel}
|
||||
className={nextClassName}
|
||||
style={styles.nav_button_next}
|
||||
disabled={!props.nextMonth}
|
||||
onClick={props.onNextClick}
|
||||
>
|
||||
{dir === 'rtl' ? (
|
||||
<IconLeftComponent
|
||||
className={classNames.nav_icon}
|
||||
style={styles.nav_icon}
|
||||
/>
|
||||
) : (
|
||||
<IconRightComponent
|
||||
className={classNames.nav_icon}
|
||||
style={styles.nav_icon}
|
||||
/>
|
||||
)}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
1
frontend/node_modules/react-day-picker/src/components/Navigation/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/Navigation/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './Navigation';
|
||||
173
frontend/node_modules/react-day-picker/src/components/Root/Root.test.tsx
generated
vendored
Normal file
173
frontend/node_modules/react-day-picker/src/components/Root/Root.test.tsx
generated
vendored
Normal file
@ -0,0 +1,173 @@
|
||||
import { RenderResult, screen } from '@testing-library/react';
|
||||
import { addDays } from 'date-fns';
|
||||
import { DayPickerProps } from 'DayPicker';
|
||||
|
||||
import { customRender } from 'test/render';
|
||||
import { getDayButton, queryMonthGrids } from 'test/selectors';
|
||||
import { freezeBeforeAll } from 'test/utils';
|
||||
|
||||
import { MonthsProps } from 'components/Months';
|
||||
import { defaultClassNames } from 'contexts/DayPicker/defaultClassNames';
|
||||
import { ClassNames } from 'types/Styles';
|
||||
|
||||
import { Root } from './Root';
|
||||
|
||||
const today = new Date(2020, 10, 4);
|
||||
freezeBeforeAll(today);
|
||||
|
||||
let container: HTMLElement;
|
||||
let view: RenderResult;
|
||||
|
||||
function render(dayPickerProps: DayPickerProps = {}) {
|
||||
view = customRender(<Root initialProps={dayPickerProps} />, dayPickerProps);
|
||||
container = view.container;
|
||||
}
|
||||
|
||||
describe('when the number of months is 1', () => {
|
||||
const props: DayPickerProps = { numberOfMonths: 1 };
|
||||
beforeEach(() => {
|
||||
render(props);
|
||||
});
|
||||
test('should display one month grid', () => {
|
||||
expect(queryMonthGrids()).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the number of months is greater than 1', () => {
|
||||
const props: DayPickerProps = { numberOfMonths: 3 };
|
||||
beforeEach(() => {
|
||||
render(props);
|
||||
});
|
||||
test('should display the specified number of month grids', () => {
|
||||
expect(queryMonthGrids()).toHaveLength(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when using the "classNames" prop', () => {
|
||||
const classNames: ClassNames = {
|
||||
root: 'foo'
|
||||
};
|
||||
beforeEach(() => {
|
||||
render({ classNames });
|
||||
});
|
||||
test('should add the class to the container', () => {
|
||||
expect(container.firstChild).toHaveClass('foo');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when using a custom "Months" component', () => {
|
||||
function CustomMonths(props: MonthsProps) {
|
||||
return (
|
||||
<div>
|
||||
<div data-testid="foo" />
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
beforeEach(() => {
|
||||
render({ numberOfMonths: 3, components: { Months: CustomMonths } });
|
||||
});
|
||||
test('should render the custom component', () => {
|
||||
expect(screen.getByTestId('foo')).toBeInTheDocument();
|
||||
});
|
||||
test('should still display the specified number of months', () => {
|
||||
expect(queryMonthGrids()).toHaveLength(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when using the "id" prop', () => {
|
||||
const testId = 'foo';
|
||||
beforeEach(() => render({ id: testId }));
|
||||
test('should add the "id" attribute', () => {
|
||||
expect(container.firstChild).toHaveAttribute('id', testId);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when using the "nonce" prop', () => {
|
||||
const nonce = 'foo';
|
||||
beforeEach(() => render({ nonce }));
|
||||
test('should add the "nonce" attribute', () => {
|
||||
expect(container.firstChild).toHaveAttribute('nonce', nonce);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when using the "title" prop', () => {
|
||||
const title = 'foo';
|
||||
beforeEach(() => render({ title }));
|
||||
test('should add the "title" attribute', () => {
|
||||
expect(container.firstChild).toHaveAttribute('title', title);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when using the "lang" prop', () => {
|
||||
const lang = 'en-US';
|
||||
beforeEach(() => render({ lang }));
|
||||
test('should add the "lang" attribute', () => {
|
||||
expect(container.firstChild).toHaveAttribute('lang', lang);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when using the "className" prop', () => {
|
||||
const props: DayPickerProps = { className: 'foo' };
|
||||
beforeEach(() => {
|
||||
render(props);
|
||||
});
|
||||
test('should append the class name to the root element', () => {
|
||||
expect(container.firstChild).toHaveClass('rdp foo');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the "numberOfMonths" is greater than 1', () => {
|
||||
const props: DayPickerProps = { numberOfMonths: 3 };
|
||||
const expectedClassName = defaultClassNames.multiple_months;
|
||||
beforeEach(() => {
|
||||
render(props);
|
||||
});
|
||||
test(`should have the ${expectedClassName} class name`, () => {
|
||||
expect(container.firstChild).toHaveClass(expectedClassName);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when showing the week numbers', () => {
|
||||
const props: DayPickerProps = { showWeekNumber: true };
|
||||
const expectedClassName = defaultClassNames.with_weeknumber;
|
||||
beforeEach(() => {
|
||||
render(props);
|
||||
});
|
||||
test(`should have the ${expectedClassName} class name`, () => {
|
||||
expect(container.firstChild).toHaveClass(expectedClassName);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when "initialFocus" is set', () => {
|
||||
const baseProps: DayPickerProps = {
|
||||
initialFocus: true,
|
||||
mode: 'single'
|
||||
};
|
||||
describe('when a day is not selected', () => {
|
||||
beforeEach(() => {
|
||||
render(baseProps);
|
||||
});
|
||||
test('should focus today', () => {
|
||||
expect(getDayButton(today)).toHaveFocus();
|
||||
});
|
||||
describe('when a new day is focused', () => {
|
||||
beforeEach(() => {
|
||||
getDayButton(addDays(today, 1)).focus();
|
||||
});
|
||||
describe('and the calendar is rerendered', () => {
|
||||
test.todo('should focus the new day');
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('when a day is selected', () => {
|
||||
const selected = addDays(today, 1);
|
||||
const props: DayPickerProps = { ...baseProps, selected };
|
||||
beforeEach(() => {
|
||||
render(props);
|
||||
});
|
||||
test('should focus the selected day', () => {
|
||||
expect(getDayButton(selected)).toHaveFocus();
|
||||
});
|
||||
});
|
||||
});
|
||||
89
frontend/node_modules/react-day-picker/src/components/Root/Root.tsx
generated
vendored
Normal file
89
frontend/node_modules/react-day-picker/src/components/Root/Root.tsx
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { DayPickerProps } from 'DayPicker';
|
||||
|
||||
import { Month } from 'components/Month';
|
||||
import { Months } from 'components/Months';
|
||||
import { useDayPicker } from 'contexts/DayPicker';
|
||||
import { useFocusContext } from 'contexts/Focus';
|
||||
import { useNavigation } from 'contexts/Navigation';
|
||||
|
||||
function isDataAttributes(attrs: DayPickerProps): attrs is {
|
||||
[key: string]: string | boolean | number | undefined;
|
||||
} {
|
||||
return true;
|
||||
}
|
||||
|
||||
export interface RootProps {
|
||||
initialProps: DayPickerProps;
|
||||
}
|
||||
|
||||
/** Render the container with the months according to the number of months to display. */
|
||||
export function Root({ initialProps }: RootProps): JSX.Element {
|
||||
const dayPicker = useDayPicker();
|
||||
const focusContext = useFocusContext();
|
||||
const navigation = useNavigation();
|
||||
|
||||
const [hasInitialFocus, setHasInitialFocus] = useState(false);
|
||||
|
||||
// Focus the focus target when initialFocus is passed in
|
||||
useEffect(() => {
|
||||
if (!dayPicker.initialFocus) return;
|
||||
if (!focusContext.focusTarget) return;
|
||||
if (hasInitialFocus) return;
|
||||
|
||||
focusContext.focus(focusContext.focusTarget);
|
||||
setHasInitialFocus(true);
|
||||
}, [
|
||||
dayPicker.initialFocus,
|
||||
hasInitialFocus,
|
||||
focusContext.focus,
|
||||
focusContext.focusTarget,
|
||||
focusContext
|
||||
]);
|
||||
|
||||
// Apply classnames according to props
|
||||
const classNames = [dayPicker.classNames.root, dayPicker.className];
|
||||
if (dayPicker.numberOfMonths > 1) {
|
||||
classNames.push(dayPicker.classNames.multiple_months);
|
||||
}
|
||||
if (dayPicker.showWeekNumber) {
|
||||
classNames.push(dayPicker.classNames.with_weeknumber);
|
||||
}
|
||||
|
||||
const style = {
|
||||
...dayPicker.styles.root,
|
||||
...dayPicker.style
|
||||
};
|
||||
|
||||
const dataAttributes = Object.keys(initialProps)
|
||||
.filter((key) => key.startsWith('data-'))
|
||||
.reduce((attrs, key) => {
|
||||
if (!isDataAttributes(initialProps)) return attrs;
|
||||
return {
|
||||
...attrs,
|
||||
[key]: initialProps[key]
|
||||
};
|
||||
}, {});
|
||||
|
||||
const MonthsComponent = initialProps.components?.Months ?? Months;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames.join(' ')}
|
||||
style={style}
|
||||
dir={dayPicker.dir}
|
||||
id={dayPicker.id}
|
||||
nonce={initialProps.nonce}
|
||||
title={initialProps.title}
|
||||
lang={initialProps.lang}
|
||||
{...dataAttributes}
|
||||
>
|
||||
<MonthsComponent>
|
||||
{navigation.displayMonths.map((month, i) => (
|
||||
<Month key={i} displayIndex={i} displayMonth={month} />
|
||||
))}
|
||||
</MonthsComponent>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
1
frontend/node_modules/react-day-picker/src/components/Root/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/Root/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './Root';
|
||||
67
frontend/node_modules/react-day-picker/src/components/Row/Row.test.tsx
generated
vendored
Normal file
67
frontend/node_modules/react-day-picker/src/components/Row/Row.test.tsx
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
import { screen } from '@testing-library/react';
|
||||
import { DayPickerProps } from 'DayPicker';
|
||||
|
||||
import { customRender } from 'test/render/customRender';
|
||||
|
||||
import { CustomComponents } from 'types/DayPickerBase';
|
||||
|
||||
import { Row, RowProps } from './Row';
|
||||
|
||||
function setup(props: RowProps, dayPickerProps?: DayPickerProps) {
|
||||
customRender(<Row {...props} />, dayPickerProps);
|
||||
}
|
||||
|
||||
const props: RowProps = {
|
||||
displayMonth: new Date(2020, 1),
|
||||
weekNumber: 4,
|
||||
dates: [new Date(2020, 1, 1), new Date(2020, 1, 2), new Date(2020, 1, 3)]
|
||||
};
|
||||
|
||||
describe('when "showWeekNumber" is set', () => {
|
||||
const dayPickerProps = {
|
||||
showWeekNumber: true,
|
||||
classNames: { cell: 'cell' },
|
||||
styles: { cell: { background: 'red' } }
|
||||
};
|
||||
beforeEach(() => {
|
||||
setup(props, dayPickerProps);
|
||||
});
|
||||
test('should display the cell with the week number', () => {
|
||||
const cell = screen.getByRole('cell', { name: `${props.weekNumber}` });
|
||||
expect(cell).toBeInTheDocument();
|
||||
});
|
||||
test('the cell should have the "cell" class name', () => {
|
||||
const cell = screen.getByRole('cell', { name: `${props.weekNumber}` });
|
||||
expect(cell).toHaveClass(dayPickerProps.classNames.cell);
|
||||
});
|
||||
test('the cell should have the "cell" style', () => {
|
||||
const cell = screen.getByRole('cell', { name: `${props.weekNumber}` });
|
||||
expect(cell).toHaveStyle(dayPickerProps.styles.cell);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when using a custom Day component', () => {
|
||||
const components: CustomComponents = {
|
||||
Day: () => <div>CustomDay</div>
|
||||
};
|
||||
const dayPickerProps = { components };
|
||||
beforeEach(() => {
|
||||
setup(props, dayPickerProps);
|
||||
});
|
||||
test('it should render the custom component instead', () => {
|
||||
expect(screen.getAllByText('CustomDay')).toHaveLength(props.dates.length);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when using a custom WeekNumber component', () => {
|
||||
const components: CustomComponents = {
|
||||
WeekNumber: () => <div>WeekNumber</div>
|
||||
};
|
||||
const dayPickerProps: DayPickerProps = { components, showWeekNumber: true };
|
||||
beforeEach(() => {
|
||||
setup(props, dayPickerProps);
|
||||
});
|
||||
test('it should render the custom component instead', () => {
|
||||
expect(screen.getByText('WeekNumber')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
50
frontend/node_modules/react-day-picker/src/components/Row/Row.tsx
generated
vendored
Normal file
50
frontend/node_modules/react-day-picker/src/components/Row/Row.tsx
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
import { getUnixTime } from 'date-fns';
|
||||
|
||||
import { Day } from 'components/Day';
|
||||
import { WeekNumber } from 'components/WeekNumber';
|
||||
import { useDayPicker } from 'contexts/DayPicker';
|
||||
|
||||
/**
|
||||
* The props for the {@link Row} component.
|
||||
*/
|
||||
export interface RowProps {
|
||||
/** The month where the row is displayed. */
|
||||
displayMonth: Date;
|
||||
/** The number of the week to render. */
|
||||
weekNumber: number;
|
||||
/** The days contained in the week. */
|
||||
dates: Date[];
|
||||
}
|
||||
|
||||
/** Render a row in the calendar, with the days and the week number. */
|
||||
export function Row(props: RowProps): JSX.Element {
|
||||
const { styles, classNames, showWeekNumber, components } = useDayPicker();
|
||||
|
||||
const DayComponent = components?.Day ?? Day;
|
||||
const WeeknumberComponent = components?.WeekNumber ?? WeekNumber;
|
||||
|
||||
let weekNumberCell;
|
||||
if (showWeekNumber) {
|
||||
weekNumberCell = (
|
||||
<td className={classNames.cell} style={styles.cell}>
|
||||
<WeeknumberComponent number={props.weekNumber} dates={props.dates} />
|
||||
</td>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<tr className={classNames.row} style={styles.row}>
|
||||
{weekNumberCell}
|
||||
{props.dates.map((date) => (
|
||||
<td
|
||||
className={classNames.cell}
|
||||
style={styles.cell}
|
||||
key={getUnixTime(date)}
|
||||
role="presentation"
|
||||
>
|
||||
<DayComponent displayMonth={props.displayMonth} date={date} />
|
||||
</td>
|
||||
))}
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
1
frontend/node_modules/react-day-picker/src/components/Row/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/Row/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './Row';
|
||||
62
frontend/node_modules/react-day-picker/src/components/Table/Table.test.tsx
generated
vendored
Normal file
62
frontend/node_modules/react-day-picker/src/components/Table/Table.test.tsx
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
import { DayPickerProps } from 'DayPicker';
|
||||
|
||||
import { customRender } from 'test/render/customRender';
|
||||
import { freezeBeforeAll } from 'test/utils';
|
||||
|
||||
import { FooterProps } from 'components/Footer';
|
||||
|
||||
import { Table, TableProps } from './Table';
|
||||
|
||||
function setup(props: TableProps, dayPickerProps?: DayPickerProps) {
|
||||
return customRender(<Table {...props} />, dayPickerProps);
|
||||
}
|
||||
|
||||
const today = new Date(2021, 11, 8);
|
||||
freezeBeforeAll(today);
|
||||
|
||||
const props: TableProps = {
|
||||
displayMonth: new Date(2020, 1)
|
||||
};
|
||||
|
||||
test('should render correctly', () => {
|
||||
const { container } = setup(props);
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe('when showing the week numbers', () => {
|
||||
const dayPickerProps = { showWeekNumber: true };
|
||||
test('should render correctly', () => {
|
||||
const { container } = setup(props, dayPickerProps);
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when using custom components', () => {
|
||||
const dayPickerProps: DayPickerProps = {
|
||||
components: {
|
||||
Head: () => (
|
||||
<thead>
|
||||
<tr>
|
||||
<td>CustomHead</td>
|
||||
</tr>
|
||||
</thead>
|
||||
),
|
||||
Row: () => (
|
||||
<tr>
|
||||
<td>CustomRow</td>
|
||||
</tr>
|
||||
),
|
||||
Footer: (props: FooterProps) => (
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td>{props.displayMonth?.toDateString()}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
)
|
||||
}
|
||||
};
|
||||
test('should render correctly', () => {
|
||||
const { container } = setup(props, dayPickerProps);
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
65
frontend/node_modules/react-day-picker/src/components/Table/Table.tsx
generated
vendored
Normal file
65
frontend/node_modules/react-day-picker/src/components/Table/Table.tsx
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
import { Footer } from 'components/Footer';
|
||||
import { Head } from 'components/Head';
|
||||
import { Row } from 'components/Row';
|
||||
import { useDayPicker } from 'contexts/DayPicker';
|
||||
|
||||
import { getMonthWeeks } from './utils/getMonthWeeks';
|
||||
|
||||
/** The props for the {@link Table} component. */
|
||||
export interface TableProps {
|
||||
/** ID of table element */
|
||||
id?: string;
|
||||
/** The ID of the label of the table (the same given to the Caption). */
|
||||
['aria-labelledby']?: string;
|
||||
/** The month where the table is displayed. */
|
||||
displayMonth: Date;
|
||||
}
|
||||
|
||||
/** Render the table with the calendar. */
|
||||
export function Table(props: TableProps): JSX.Element {
|
||||
const {
|
||||
locale,
|
||||
classNames,
|
||||
styles,
|
||||
hideHead,
|
||||
fixedWeeks,
|
||||
components,
|
||||
weekStartsOn,
|
||||
firstWeekContainsDate,
|
||||
ISOWeek
|
||||
} = useDayPicker();
|
||||
|
||||
const weeks = getMonthWeeks(props.displayMonth, {
|
||||
useFixedWeeks: Boolean(fixedWeeks),
|
||||
ISOWeek,
|
||||
locale,
|
||||
weekStartsOn,
|
||||
firstWeekContainsDate
|
||||
});
|
||||
|
||||
const HeadComponent = components?.Head ?? Head;
|
||||
const RowComponent = components?.Row ?? Row;
|
||||
const FooterComponent = components?.Footer ?? Footer;
|
||||
return (
|
||||
<table
|
||||
id={props.id}
|
||||
className={classNames.table}
|
||||
style={styles.table}
|
||||
role="grid"
|
||||
aria-labelledby={props['aria-labelledby']}
|
||||
>
|
||||
{!hideHead && <HeadComponent />}
|
||||
<tbody className={classNames.tbody} style={styles.tbody}>
|
||||
{weeks.map((week) => (
|
||||
<RowComponent
|
||||
displayMonth={props.displayMonth}
|
||||
key={week.weekNumber}
|
||||
dates={week.dates}
|
||||
weekNumber={week.weekNumber}
|
||||
/>
|
||||
))}
|
||||
</tbody>
|
||||
<FooterComponent displayMonth={props.displayMonth} />
|
||||
</table>
|
||||
);
|
||||
}
|
||||
1012
frontend/node_modules/react-day-picker/src/components/Table/__snapshots__/Table.test.tsx.snap
generated
vendored
Normal file
1012
frontend/node_modules/react-day-picker/src/components/Table/__snapshots__/Table.test.tsx.snap
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
frontend/node_modules/react-day-picker/src/components/Table/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/Table/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './Table';
|
||||
60
frontend/node_modules/react-day-picker/src/components/Table/utils/daysToMonthWeeks.ts
generated
vendored
Normal file
60
frontend/node_modules/react-day-picker/src/components/Table/utils/daysToMonthWeeks.ts
generated
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
import {
|
||||
addDays,
|
||||
differenceInCalendarDays,
|
||||
endOfISOWeek,
|
||||
endOfWeek,
|
||||
getISOWeek,
|
||||
getWeek,
|
||||
Locale,
|
||||
startOfISOWeek,
|
||||
startOfWeek
|
||||
} from 'date-fns';
|
||||
|
||||
import { MonthWeek } from './getMonthWeeks';
|
||||
|
||||
/** Return the weeks between two dates. */
|
||||
export function daysToMonthWeeks(
|
||||
fromDate: Date,
|
||||
toDate: Date,
|
||||
options?: {
|
||||
ISOWeek?: boolean;
|
||||
locale?: Locale;
|
||||
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
||||
firstWeekContainsDate?: 1 | 4;
|
||||
}
|
||||
): MonthWeek[] {
|
||||
const toWeek = options?.ISOWeek
|
||||
? endOfISOWeek(toDate)
|
||||
: endOfWeek(toDate, options);
|
||||
const fromWeek = options?.ISOWeek
|
||||
? startOfISOWeek(fromDate)
|
||||
: startOfWeek(fromDate, options);
|
||||
|
||||
const nOfDays = differenceInCalendarDays(toWeek, fromWeek);
|
||||
const days: Date[] = [];
|
||||
|
||||
for (let i = 0; i <= nOfDays; i++) {
|
||||
days.push(addDays(fromWeek, i));
|
||||
}
|
||||
|
||||
const weeksInMonth = days.reduce((result: MonthWeek[], date) => {
|
||||
const weekNumber = options?.ISOWeek
|
||||
? getISOWeek(date)
|
||||
: getWeek(date, options);
|
||||
|
||||
const existingWeek = result.find(
|
||||
(value) => value.weekNumber === weekNumber
|
||||
);
|
||||
if (existingWeek) {
|
||||
existingWeek.dates.push(date);
|
||||
return result;
|
||||
}
|
||||
result.push({
|
||||
weekNumber,
|
||||
dates: [date]
|
||||
});
|
||||
return result;
|
||||
}, []);
|
||||
|
||||
return weeksInMonth;
|
||||
}
|
||||
100
frontend/node_modules/react-day-picker/src/components/Table/utils/getMonthWeeks.test.ts
generated
vendored
Normal file
100
frontend/node_modules/react-day-picker/src/components/Table/utils/getMonthWeeks.test.ts
generated
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
import { enGB, enUS } from 'date-fns/locale';
|
||||
|
||||
import { getMonthWeeks } from './getMonthWeeks';
|
||||
|
||||
describe('when using the "enUS" locale', () => {
|
||||
const locale = enUS;
|
||||
describe('when using fixed weeks', () => {
|
||||
const useFixedWeeks = true;
|
||||
describe('when getting the weeks for December 2022', () => {
|
||||
const date = new Date(2022, 11);
|
||||
const weeks = getMonthWeeks(date, { useFixedWeeks, locale });
|
||||
test('should return 49 - 1 week numbers', () => {
|
||||
const weekNumbers = weeks.map((week) => week.weekNumber);
|
||||
const expectedResult = [49, 50, 51, 52, 53, 1];
|
||||
expect(weekNumbers).toEqual(expectedResult);
|
||||
});
|
||||
test('the last week should be the one in the next year', () => {
|
||||
const lastWeek = weeks[weeks.length - 1];
|
||||
const lastWeekDates = lastWeek.dates.map((date) => date.getDate());
|
||||
const expectedResult = [1, 2, 3, 4, 5, 6, 7];
|
||||
expect(lastWeekDates).toEqual(expectedResult);
|
||||
});
|
||||
});
|
||||
describe('when getting the weeks for December 2021', () => {
|
||||
const weeks = getMonthWeeks(new Date(2021, 11), {
|
||||
useFixedWeeks: false,
|
||||
locale: enUS
|
||||
});
|
||||
test('should return 49 - 1 week numbers', () => {
|
||||
const weekNumbers = weeks.map((week) => week.weekNumber);
|
||||
const expectedResult = [49, 50, 51, 52, 1];
|
||||
expect(weekNumbers).toEqual(expectedResult);
|
||||
});
|
||||
test('the last week should be the last in the year', () => {
|
||||
const lastWeek = weeks[weeks.length - 1];
|
||||
const lastWeekDates = lastWeek.dates.map((date) => date.getDate());
|
||||
const expectedResult = [26, 27, 28, 29, 30, 31, 1];
|
||||
expect(lastWeekDates).toEqual(expectedResult);
|
||||
});
|
||||
test('week 1 contains the first day of the new year', () => {
|
||||
expect(weeks[4].dates.map((date) => date.getDate())).toEqual([
|
||||
26, 27, 28, 29, 30, 31, 1
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when using the "enGB" locale', () => {
|
||||
const locale = enGB;
|
||||
describe('when getting the weeks for January 2022', () => {
|
||||
const date = new Date(2022, 0);
|
||||
const weeks = getMonthWeeks(date, { locale });
|
||||
test('the first week should be the last of the previous year', () => {
|
||||
const weekNumbers = weeks.map((week) => week.weekNumber);
|
||||
expect(weekNumbers[0]).toEqual(52);
|
||||
});
|
||||
test('the first week should contain days from previous year', () => {
|
||||
expect(weeks[0].dates.map((date) => date.getDate())).toEqual([
|
||||
27, 28, 29, 30, 31, 1, 2
|
||||
]);
|
||||
});
|
||||
test('the last week should be the last of January', () => {
|
||||
const weekNumbers = weeks.map((week) => week.weekNumber);
|
||||
expect(weekNumbers[weekNumbers.length - 1]).toEqual(5);
|
||||
});
|
||||
});
|
||||
describe('when setting thursday as first day of year', () => {
|
||||
const date = new Date(2022, 0);
|
||||
const weeks = getMonthWeeks(date, { locale, firstWeekContainsDate: 4 });
|
||||
test('the number of week should have number 52', () => {
|
||||
const weekNumbers = weeks.map((week) => week.weekNumber);
|
||||
expect(weekNumbers[0]).toEqual(52);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when using the ISOWeek numbers', () => {
|
||||
const locale = enUS;
|
||||
describe('when getting the weeks for September 2022', () => {
|
||||
const date = new Date(2022, 8);
|
||||
const weeks = getMonthWeeks(date, { locale, ISOWeek: true });
|
||||
test('the last week should have number 39', () => {
|
||||
const weekNumbers = weeks.map((week) => week.weekNumber);
|
||||
expect(weekNumbers[weekNumbers.length - 1]).toEqual(39);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when not using the ISOWeek numbers', () => {
|
||||
const locale = enUS;
|
||||
describe('when getting the weeks for September 2022', () => {
|
||||
const date = new Date(2022, 8);
|
||||
const weeks = getMonthWeeks(date, { locale, ISOWeek: false });
|
||||
test('the last week should have number 40', () => {
|
||||
const weekNumbers = weeks.map((week) => week.weekNumber);
|
||||
expect(weekNumbers[weekNumbers.length - 1]).toEqual(40);
|
||||
});
|
||||
});
|
||||
});
|
||||
55
frontend/node_modules/react-day-picker/src/components/Table/utils/getMonthWeeks.ts
generated
vendored
Normal file
55
frontend/node_modules/react-day-picker/src/components/Table/utils/getMonthWeeks.ts
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
import {
|
||||
addWeeks,
|
||||
endOfMonth,
|
||||
getWeeksInMonth,
|
||||
Locale,
|
||||
startOfMonth
|
||||
} from 'date-fns';
|
||||
|
||||
import { daysToMonthWeeks } from './daysToMonthWeeks';
|
||||
|
||||
/** Represents a week in the month.*/
|
||||
export type MonthWeek = {
|
||||
/** The week number from the start of the year. */
|
||||
weekNumber: number;
|
||||
/** The dates in the week. */
|
||||
dates: Date[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the weeks belonging to the given month, adding the "outside days" to
|
||||
* the first and last week.
|
||||
*/
|
||||
export function getMonthWeeks(
|
||||
month: Date,
|
||||
options: {
|
||||
locale: Locale;
|
||||
useFixedWeeks?: boolean;
|
||||
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
||||
firstWeekContainsDate?: 1 | 4;
|
||||
ISOWeek?: boolean;
|
||||
}
|
||||
): MonthWeek[] {
|
||||
const weeksInMonth: MonthWeek[] = daysToMonthWeeks(
|
||||
startOfMonth(month),
|
||||
endOfMonth(month),
|
||||
options
|
||||
);
|
||||
|
||||
if (options?.useFixedWeeks) {
|
||||
// Add extra weeks to the month, up to 6 weeks
|
||||
const nrOfMonthWeeks = getWeeksInMonth(month, options);
|
||||
if (nrOfMonthWeeks < 6) {
|
||||
const lastWeek = weeksInMonth[weeksInMonth.length - 1];
|
||||
const lastDate = lastWeek.dates[lastWeek.dates.length - 1];
|
||||
const toDate = addWeeks(lastDate, 6 - nrOfMonthWeeks);
|
||||
const extraWeeks = daysToMonthWeeks(
|
||||
addWeeks(lastDate, 1),
|
||||
toDate,
|
||||
options
|
||||
);
|
||||
weeksInMonth.push(...extraWeeks);
|
||||
}
|
||||
}
|
||||
return weeksInMonth;
|
||||
}
|
||||
49
frontend/node_modules/react-day-picker/src/components/WeekNumber/WeekNumber.test.tsx
generated
vendored
Normal file
49
frontend/node_modules/react-day-picker/src/components/WeekNumber/WeekNumber.test.tsx
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
import { screen } from '@testing-library/react';
|
||||
import { userEvent } from '@testing-library/user-event';
|
||||
import { DayPickerProps } from 'DayPicker';
|
||||
|
||||
import { customRender } from 'test/render/customRender';
|
||||
|
||||
import { WeekNumber, WeekNumberProps } from './WeekNumber';
|
||||
|
||||
function setup(props: WeekNumberProps, dayPickerProps?: DayPickerProps) {
|
||||
return customRender(<WeekNumber {...props} />, dayPickerProps);
|
||||
}
|
||||
|
||||
const props: WeekNumberProps = {
|
||||
number: 10,
|
||||
dates: [new Date(), new Date()]
|
||||
};
|
||||
|
||||
describe('without "onWeekNumberClick" prop', () => {
|
||||
const dayPickerProps: DayPickerProps = { onWeekNumberClick: undefined };
|
||||
test('it should return a span element', () => {
|
||||
const { container } = setup(props, dayPickerProps);
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('with "onWeekNumberClick" prop', () => {
|
||||
const dayPickerProps: DayPickerProps = { onWeekNumberClick: jest.fn() };
|
||||
let container: HTMLElement;
|
||||
beforeEach(() => {
|
||||
container = setup(props, dayPickerProps).container;
|
||||
});
|
||||
test('it should return a button element', () => {
|
||||
expect(screen.getByRole('button')).toBeInTheDocument();
|
||||
expect(container.firstChild).toHaveAttribute('name', 'week-number');
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
});
|
||||
describe('when the button element is clicked', () => {
|
||||
beforeEach(async () => {
|
||||
await userEvent.click(screen.getByRole('button'));
|
||||
});
|
||||
test('should call onWeekNumberClick', () => {
|
||||
expect(dayPickerProps.onWeekNumberClick).toHaveBeenCalledWith(
|
||||
props.number,
|
||||
props.dates,
|
||||
expect.anything()
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
59
frontend/node_modules/react-day-picker/src/components/WeekNumber/WeekNumber.tsx
generated
vendored
Normal file
59
frontend/node_modules/react-day-picker/src/components/WeekNumber/WeekNumber.tsx
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
import { MouseEventHandler } from 'react';
|
||||
|
||||
import { useDayPicker } from 'contexts/DayPicker';
|
||||
|
||||
import { Button } from '../Button';
|
||||
|
||||
/**
|
||||
* The props for the {@link WeekNumber} component.
|
||||
*/
|
||||
export interface WeekNumberProps {
|
||||
/** The number of the week. */
|
||||
number: number;
|
||||
/** The dates in the week. */
|
||||
dates: Date[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the week number element. If `onWeekNumberClick` is passed to DayPicker, it
|
||||
* renders a button, otherwise a span element.
|
||||
*/
|
||||
export function WeekNumber(props: WeekNumberProps): JSX.Element {
|
||||
const { number: weekNumber, dates } = props;
|
||||
const {
|
||||
onWeekNumberClick,
|
||||
styles,
|
||||
classNames,
|
||||
locale,
|
||||
labels: { labelWeekNumber },
|
||||
formatters: { formatWeekNumber }
|
||||
} = useDayPicker();
|
||||
|
||||
const content = formatWeekNumber(Number(weekNumber), { locale });
|
||||
|
||||
if (!onWeekNumberClick) {
|
||||
return (
|
||||
<span className={classNames.weeknumber} style={styles.weeknumber}>
|
||||
{content}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
const label = labelWeekNumber(Number(weekNumber), { locale });
|
||||
|
||||
const handleClick: MouseEventHandler = function (e) {
|
||||
onWeekNumberClick(weekNumber, dates, e);
|
||||
};
|
||||
|
||||
return (
|
||||
<Button
|
||||
name="week-number"
|
||||
aria-label={label}
|
||||
className={classNames.weeknumber}
|
||||
style={styles.weeknumber}
|
||||
onClick={handleClick}
|
||||
>
|
||||
{content}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
20
frontend/node_modules/react-day-picker/src/components/WeekNumber/__snapshots__/WeekNumber.test.tsx.snap
generated
vendored
Normal file
20
frontend/node_modules/react-day-picker/src/components/WeekNumber/__snapshots__/WeekNumber.test.tsx.snap
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`with "onWeekNumberClick" prop it should return a button element 1`] = `
|
||||
<button
|
||||
aria-label="Week n. 10"
|
||||
class="rdp-button_reset rdp-button rdp-weeknumber"
|
||||
name="week-number"
|
||||
type="button"
|
||||
>
|
||||
10
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`without "onWeekNumberClick" prop it should return a span element 1`] = `
|
||||
<span
|
||||
class="rdp-weeknumber"
|
||||
>
|
||||
10
|
||||
</span>
|
||||
`;
|
||||
1
frontend/node_modules/react-day-picker/src/components/WeekNumber/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/WeekNumber/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './WeekNumber';
|
||||
106
frontend/node_modules/react-day-picker/src/components/YearsDropdown/YearsDropdown.test.tsx
generated
vendored
Normal file
106
frontend/node_modules/react-day-picker/src/components/YearsDropdown/YearsDropdown.test.tsx
generated
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
import { screen } from '@testing-library/react';
|
||||
import { addMonths, differenceInYears } from 'date-fns';
|
||||
import { DayPickerProps } from 'DayPicker';
|
||||
|
||||
import { customRender } from 'test/render';
|
||||
import { user } from 'test/user';
|
||||
import { freezeBeforeAll } from 'test/utils';
|
||||
|
||||
import { YearsDropdown, YearsDropdownProps } from './YearsDropdown';
|
||||
|
||||
const today = new Date(2020, 12, 22);
|
||||
|
||||
freezeBeforeAll(today);
|
||||
|
||||
let root: HTMLDivElement;
|
||||
let options: HTMLCollectionOf<HTMLOptionElement> | undefined;
|
||||
let select: HTMLSelectElement | null;
|
||||
|
||||
function setup(props: YearsDropdownProps, dayPickerProps?: DayPickerProps) {
|
||||
const view = customRender(<YearsDropdown {...props} />, dayPickerProps);
|
||||
root = view.container.firstChild as HTMLDivElement;
|
||||
select = screen.queryByRole('combobox', { name: 'Year:' });
|
||||
options = select?.getElementsByTagName('option');
|
||||
}
|
||||
|
||||
const props: YearsDropdownProps = {
|
||||
displayMonth: today,
|
||||
onChange: jest.fn()
|
||||
};
|
||||
|
||||
describe('when fromDate and toDate are passed in', () => {
|
||||
beforeEach(() => {
|
||||
setup(props, { fromDate: new Date(), toDate: addMonths(new Date(), 1) });
|
||||
});
|
||||
test('should render the dropdown element', () => {
|
||||
expect(root).toMatchSnapshot();
|
||||
expect(select).toHaveAttribute('name', 'years');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when "fromDate" is not set', () => {
|
||||
beforeEach(() => {
|
||||
setup(props, { fromDate: undefined });
|
||||
});
|
||||
test('should return nothing', () => {
|
||||
expect(root).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when "toDate" is not set', () => {
|
||||
beforeEach(() => {
|
||||
setup(props, { toDate: undefined });
|
||||
});
|
||||
test('should return nothing', () => {
|
||||
expect(root).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when "fromDate" and "toDate" are in the same year', () => {
|
||||
const fromDate = new Date(2012, 0, 22);
|
||||
const toDate = new Date(2012, 10, 22);
|
||||
beforeEach(() => {
|
||||
setup(props, { fromDate, toDate });
|
||||
});
|
||||
test('should display the months included between the two dates', () => {
|
||||
expect(select).toBeInTheDocument();
|
||||
expect(options).toHaveLength(differenceInYears(toDate, fromDate) + 1);
|
||||
});
|
||||
test('the month should be the same month', () => {
|
||||
expect(options?.[0]).toHaveValue(`${fromDate.getFullYear()}`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when "fromDate" and "toDate" are not in the same year', () => {
|
||||
const fromDate = new Date(2012, 0, 22);
|
||||
const toDate = new Date(2015, 10, 22);
|
||||
const displayMonth = new Date(2013, 7, 0);
|
||||
beforeEach(() => {
|
||||
setup({ ...props, displayMonth }, { fromDate, toDate });
|
||||
});
|
||||
test('should display the full years', () => {
|
||||
expect(options).toHaveLength(differenceInYears(toDate, fromDate) + 1);
|
||||
});
|
||||
test('the first option should be fromDates year', () => {
|
||||
expect(options?.[0]).toHaveValue(`${fromDate.getFullYear()}`);
|
||||
});
|
||||
test('the last option should be "toDate"s year', () => {
|
||||
expect(options?.[options.length - 1]).toHaveValue(
|
||||
`${toDate.getFullYear()}`
|
||||
);
|
||||
});
|
||||
test('should select the displayed year', () => {
|
||||
expect(select).toHaveValue(`${displayMonth.getFullYear()}`);
|
||||
});
|
||||
|
||||
describe('when the dropdown changes', () => {
|
||||
const newYear = fromDate.getFullYear();
|
||||
beforeEach(async () => {
|
||||
if (select) await user.selectOptions(select, `${newYear}`);
|
||||
});
|
||||
test('should fire the "onChange" event handler', () => {
|
||||
const expectedYear = new Date(newYear, displayMonth.getMonth(), 1);
|
||||
expect(props.onChange).toHaveBeenCalledWith(expectedYear);
|
||||
});
|
||||
});
|
||||
});
|
||||
75
frontend/node_modules/react-day-picker/src/components/YearsDropdown/YearsDropdown.tsx
generated
vendored
Normal file
75
frontend/node_modules/react-day-picker/src/components/YearsDropdown/YearsDropdown.tsx
generated
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
import { ChangeEventHandler } from 'react';
|
||||
|
||||
import { setYear, startOfMonth, startOfYear } from 'date-fns';
|
||||
|
||||
import { Dropdown } from 'components/Dropdown';
|
||||
import { useDayPicker } from 'contexts/DayPicker';
|
||||
import { MonthChangeEventHandler } from 'types/EventHandlers';
|
||||
|
||||
/**
|
||||
* The props for the {@link YearsDropdown} component.
|
||||
*/
|
||||
export interface YearsDropdownProps {
|
||||
/** The month where the drop-down is displayed. */
|
||||
displayMonth: Date;
|
||||
/** Callback to handle the `change` event. */
|
||||
onChange: MonthChangeEventHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a dropdown to change the year. Take in account the `nav.fromDate` and
|
||||
* `toDate` from context.
|
||||
*/
|
||||
export function YearsDropdown(props: YearsDropdownProps): JSX.Element {
|
||||
const { displayMonth } = props;
|
||||
const {
|
||||
fromDate,
|
||||
toDate,
|
||||
locale,
|
||||
styles,
|
||||
classNames,
|
||||
components,
|
||||
formatters: { formatYearCaption },
|
||||
labels: { labelYearDropdown }
|
||||
} = useDayPicker();
|
||||
|
||||
const years: Date[] = [];
|
||||
|
||||
// Dropdown should appear only when both from/toDate is set
|
||||
if (!fromDate) return <></>;
|
||||
if (!toDate) return <></>;
|
||||
|
||||
const fromYear = fromDate.getFullYear();
|
||||
const toYear = toDate.getFullYear();
|
||||
for (let year = fromYear; year <= toYear; year++) {
|
||||
years.push(setYear(startOfYear(new Date()), year));
|
||||
}
|
||||
|
||||
const handleChange: ChangeEventHandler<HTMLSelectElement> = (e) => {
|
||||
const newMonth = setYear(
|
||||
startOfMonth(displayMonth),
|
||||
Number(e.target.value)
|
||||
);
|
||||
props.onChange(newMonth);
|
||||
};
|
||||
|
||||
const DropdownComponent = components?.Dropdown ?? Dropdown;
|
||||
|
||||
return (
|
||||
<DropdownComponent
|
||||
name="years"
|
||||
aria-label={labelYearDropdown()}
|
||||
className={classNames.dropdown_year}
|
||||
style={styles.dropdown_year}
|
||||
onChange={handleChange}
|
||||
value={displayMonth.getFullYear()}
|
||||
caption={formatYearCaption(displayMonth, { locale })}
|
||||
>
|
||||
{years.map((year) => (
|
||||
<option key={year.getFullYear()} value={year.getFullYear()}>
|
||||
{formatYearCaption(year, { locale })}
|
||||
</option>
|
||||
))}
|
||||
</DropdownComponent>
|
||||
);
|
||||
}
|
||||
43
frontend/node_modules/react-day-picker/src/components/YearsDropdown/__snapshots__/YearsDropdown.test.tsx.snap
generated
vendored
Normal file
43
frontend/node_modules/react-day-picker/src/components/YearsDropdown/__snapshots__/YearsDropdown.test.tsx.snap
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`when fromDate and toDate are passed in should render the dropdown element 1`] = `
|
||||
<div
|
||||
class="rdp-dropdown_year"
|
||||
>
|
||||
<span
|
||||
class="rdp-vhidden"
|
||||
>
|
||||
Year:
|
||||
</span>
|
||||
<select
|
||||
aria-label="Year: "
|
||||
class="rdp-dropdown"
|
||||
name="years"
|
||||
>
|
||||
<option
|
||||
value="2021"
|
||||
>
|
||||
2021
|
||||
</option>
|
||||
</select>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="rdp-caption_label"
|
||||
>
|
||||
2021
|
||||
<svg
|
||||
class="rdp-dropdown_icon"
|
||||
data-testid="iconDropdown"
|
||||
height="8px"
|
||||
viewBox="0 0 120 120"
|
||||
width="8px"
|
||||
>
|
||||
<path
|
||||
d="M4.22182541,48.2218254 C8.44222828,44.0014225 15.2388494,43.9273804 19.5496459,47.9996989 L19.7781746,48.2218254 L60,88.443 L100.221825,48.2218254 C104.442228,44.0014225 111.238849,43.9273804 115.549646,47.9996989 L115.778175,48.2218254 C119.998577,52.4422283 120.07262,59.2388494 116.000301,63.5496459 L115.778175,63.7781746 L67.7781746,111.778175 C63.5577717,115.998577 56.7611506,116.07262 52.4503541,112.000301 L52.2218254,111.778175 L4.22182541,63.7781746 C-0.0739418023,59.4824074 -0.0739418023,52.5175926 4.22182541,48.2218254 Z"
|
||||
fill="currentColor"
|
||||
fill-rule="nonzero"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
1
frontend/node_modules/react-day-picker/src/components/YearsDropdown/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/components/YearsDropdown/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './YearsDropdown';
|
||||
210
frontend/node_modules/react-day-picker/src/contexts/DayPicker/DayPickerContext.test.ts
generated
vendored
Normal file
210
frontend/node_modules/react-day-picker/src/contexts/DayPicker/DayPickerContext.test.ts
generated
vendored
Normal file
@ -0,0 +1,210 @@
|
||||
/* eslint-disable testing-library/render-result-naming-convention */
|
||||
|
||||
import { es } from 'date-fns/locale';
|
||||
import { DayPickerProps } from 'DayPicker';
|
||||
|
||||
import { renderDayPickerHook } from 'test/render';
|
||||
import { freezeBeforeAll } from 'test/utils';
|
||||
|
||||
import { CaptionLayout } from 'components/Caption';
|
||||
import { DayPickerContextValue, useDayPicker } from 'contexts/DayPicker';
|
||||
import {
|
||||
DefaultContextProps,
|
||||
getDefaultContextValues
|
||||
} from 'contexts/DayPicker/defaultContextValues';
|
||||
import { DaySelectionMode } from 'types/DayPickerBase';
|
||||
import { Formatters } from 'types/Formatters';
|
||||
import { Labels } from 'types/Labels';
|
||||
import { DayModifiers, ModifiersClassNames } from 'types/Modifiers';
|
||||
import { ClassNames, Styles } from 'types/Styles';
|
||||
|
||||
const today = new Date(2022, 5, 13);
|
||||
const defaults = getDefaultContextValues();
|
||||
|
||||
freezeBeforeAll(today);
|
||||
|
||||
function renderHook(props?: DayPickerProps) {
|
||||
return renderDayPickerHook<DayPickerContextValue>(useDayPicker, props);
|
||||
}
|
||||
|
||||
describe('when rendered without props', () => {
|
||||
const testPropNames = Object.keys(defaults).filter(
|
||||
(key) => key !== 'today'
|
||||
) as DefaultContextProps[];
|
||||
test.each(testPropNames)('should use the %s default value', (propName) => {
|
||||
const result = renderHook();
|
||||
expect(result.current[propName]).toEqual(defaults[propName]);
|
||||
});
|
||||
});
|
||||
describe('when passing "locale" from props', () => {
|
||||
const locale = es;
|
||||
test('should return the custom locale', () => {
|
||||
const result = renderHook({ locale });
|
||||
expect(result.current.locale).toBe(locale);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when passing "numberOfMonths" from props', () => {
|
||||
const numberOfMonths = 4;
|
||||
test('should return the custom numberOfMonths', () => {
|
||||
const result = renderHook({ numberOfMonths });
|
||||
expect(result.current.numberOfMonths).toBe(4);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when passing "today" from props', () => {
|
||||
const today = new Date(2010, 9, 11);
|
||||
test('should return the custom "today"', () => {
|
||||
const result = renderHook({ today });
|
||||
expect(result.current.today).toBe(today);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when passing "captionLayout" from props', () => {
|
||||
const captionLayout: CaptionLayout = 'dropdown';
|
||||
const fromYear = 2000;
|
||||
const toYear = 2010;
|
||||
const dayPickerProps: DayPickerProps = { captionLayout, fromYear, toYear };
|
||||
test('should return the custom "captionLayout"', () => {
|
||||
const result = renderHook(dayPickerProps);
|
||||
expect(result.current.captionLayout).toBe(captionLayout);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when "fromDate" and "toDate" are undefined', () => {
|
||||
const fromDate = undefined;
|
||||
const toDate = undefined;
|
||||
describe('when using "dropdown" as "captionLayout"', () => {
|
||||
const captionLayout: CaptionLayout = 'dropdown';
|
||||
test('should return "buttons" as "captionLayout"', () => {
|
||||
const result = renderHook({
|
||||
fromDate,
|
||||
toDate,
|
||||
captionLayout
|
||||
});
|
||||
expect(result.current.captionLayout).toBe('buttons');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when "fromDate" is undefined, but not "toDate"', () => {
|
||||
const fromDate = undefined;
|
||||
const toDate = new Date();
|
||||
|
||||
describe('when using "dropdown" as "captionLayout"', () => {
|
||||
const captionLayout: CaptionLayout = 'dropdown';
|
||||
test('should return "buttons" as "captionLayout"', () => {
|
||||
const result = renderHook({
|
||||
fromDate,
|
||||
toDate,
|
||||
captionLayout
|
||||
});
|
||||
expect(result.current.captionLayout).toBe('buttons');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when "toDate" is undefined, but not "fromDate"', () => {
|
||||
const fromDate = new Date();
|
||||
const toDate = undefined;
|
||||
|
||||
describe('when using "dropdown" as "captionLayout"', () => {
|
||||
const captionLayout: CaptionLayout = 'dropdown';
|
||||
test('should return "buttons" as "captionLayout"', () => {
|
||||
const result = renderHook({
|
||||
fromDate,
|
||||
toDate,
|
||||
captionLayout
|
||||
});
|
||||
expect(result.current.captionLayout).toBe('buttons');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when using "dropdown" as "captionLayout"', () => {
|
||||
const captionLayout: CaptionLayout = 'dropdown';
|
||||
const fromYear = 2000;
|
||||
const toYear = 2010;
|
||||
test('should return the custom "captionLayout"', () => {
|
||||
const result = renderHook({ captionLayout, fromYear, toYear });
|
||||
expect(result.current.captionLayout).toBe(captionLayout);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when passing "modifiers" from props', () => {
|
||||
const modifiers: DayModifiers = { foo: new Date() };
|
||||
test('should return the custom "modifiers"', () => {
|
||||
const result = renderHook({ modifiers });
|
||||
expect(result.current.modifiers).toStrictEqual(modifiers);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when passing "modifiersClassNames" from props', () => {
|
||||
const modifiersClassNames: ModifiersClassNames = { foo: 'bar' };
|
||||
test('should return the custom "modifiersClassNames"', () => {
|
||||
const result = renderHook({ modifiersClassNames });
|
||||
expect(result.current.modifiersClassNames).toStrictEqual(
|
||||
modifiersClassNames
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when passing "styles" from props', () => {
|
||||
const styles: Styles = { caption: { color: 'red ' } };
|
||||
test('should include the custom "styles"', () => {
|
||||
const result = renderHook({ styles });
|
||||
expect(result.current.styles).toStrictEqual({
|
||||
...defaults.styles,
|
||||
...styles
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when passing "classNames" from props', () => {
|
||||
const classNames: ClassNames = { caption: 'foo' };
|
||||
test('should include the custom "classNames"', () => {
|
||||
const result = renderHook({ classNames });
|
||||
expect(result.current.classNames).toStrictEqual({
|
||||
...defaults.classNames,
|
||||
...classNames
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when passing "formatters" from props', () => {
|
||||
const formatters: Partial<Formatters> = { formatCaption: jest.fn() };
|
||||
test('should include the custom "formatters"', () => {
|
||||
const result = renderHook({ formatters });
|
||||
expect(result.current.formatters).toStrictEqual({
|
||||
...defaults.formatters,
|
||||
...formatters
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when passing "labels" from props', () => {
|
||||
const labels: Partial<Labels> = { labelDay: jest.fn() };
|
||||
test('should include the custom "labels"', () => {
|
||||
const result = renderHook({ labels });
|
||||
expect(result.current.labels).toStrictEqual({
|
||||
...defaults.labels,
|
||||
...labels
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when passing an "id" from props', () => {
|
||||
test('should return the id', () => {
|
||||
const result = renderHook({ id: 'foo' });
|
||||
expect(result.current.id).toBe('foo');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when in selection mode', () => {
|
||||
const mode: DaySelectionMode = 'multiple';
|
||||
const onSelect = jest.fn();
|
||||
test('should return the "onSelect" event handler', () => {
|
||||
const result = renderHook({ mode, onSelect });
|
||||
expect(result.current.onSelect).toBe(onSelect);
|
||||
});
|
||||
});
|
||||
150
frontend/node_modules/react-day-picker/src/contexts/DayPicker/DayPickerContext.tsx
generated
vendored
Normal file
150
frontend/node_modules/react-day-picker/src/contexts/DayPicker/DayPickerContext.tsx
generated
vendored
Normal file
@ -0,0 +1,150 @@
|
||||
import { createContext, ReactNode, useContext } from 'react';
|
||||
|
||||
import { Locale } from 'date-fns';
|
||||
import { DayPickerProps } from 'DayPicker';
|
||||
|
||||
import { CaptionLayout } from 'components/Caption';
|
||||
import { DayPickerBase, DaySelectionMode } from 'types/DayPickerBase';
|
||||
import {
|
||||
DayPickerMultipleProps,
|
||||
isDayPickerMultiple
|
||||
} from 'types/DayPickerMultiple';
|
||||
import { DayPickerRangeProps, isDayPickerRange } from 'types/DayPickerRange';
|
||||
import { DayPickerSingleProps, isDayPickerSingle } from 'types/DayPickerSingle';
|
||||
import { Formatters } from 'types/Formatters';
|
||||
import { Labels } from 'types/Labels';
|
||||
import { Matcher } from 'types/Matchers';
|
||||
import { DayModifiers, ModifiersClassNames } from 'types/Modifiers';
|
||||
import { ClassNames, Styles } from 'types/Styles';
|
||||
|
||||
import { getDefaultContextValues } from './defaultContextValues';
|
||||
import { parseFromToProps } from './utils';
|
||||
|
||||
/**
|
||||
* The value of the {@link DayPickerContext} extends the props from DayPicker
|
||||
* with default and cleaned up values.
|
||||
*/
|
||||
export interface DayPickerContextValue extends DayPickerBase {
|
||||
mode: DaySelectionMode;
|
||||
onSelect?:
|
||||
| DayPickerSingleProps['onSelect']
|
||||
| DayPickerMultipleProps['onSelect']
|
||||
| DayPickerRangeProps['onSelect'];
|
||||
required?: boolean;
|
||||
min?: number;
|
||||
max?: number;
|
||||
selected?: Matcher | Matcher[];
|
||||
|
||||
captionLayout: CaptionLayout;
|
||||
classNames: Required<ClassNames>;
|
||||
formatters: Formatters;
|
||||
labels: Labels;
|
||||
locale: Locale;
|
||||
modifiersClassNames: ModifiersClassNames;
|
||||
modifiers: DayModifiers;
|
||||
numberOfMonths: number;
|
||||
styles: Styles;
|
||||
today: Date;
|
||||
}
|
||||
|
||||
/**
|
||||
* The DayPicker context shares the props passed to DayPicker within internal
|
||||
* and custom components. It is used to set the default values and perform
|
||||
* one-time calculations required to render the days.
|
||||
*
|
||||
* Access to this context from the {@link useDayPicker} hook.
|
||||
*/
|
||||
export const DayPickerContext = createContext<
|
||||
DayPickerContextValue | undefined
|
||||
>(undefined);
|
||||
|
||||
/** The props for the {@link DayPickerProvider}. */
|
||||
export interface DayPickerProviderProps {
|
||||
/** The initial props from the DayPicker component. */
|
||||
initialProps: DayPickerProps;
|
||||
children?: ReactNode;
|
||||
}
|
||||
/**
|
||||
* The provider for the {@link DayPickerContext}, assigning the defaults from the
|
||||
* initial DayPicker props.
|
||||
*/
|
||||
export function DayPickerProvider(props: DayPickerProviderProps): JSX.Element {
|
||||
const { initialProps } = props;
|
||||
|
||||
const defaultContextValues = getDefaultContextValues();
|
||||
|
||||
const { fromDate, toDate } = parseFromToProps(initialProps);
|
||||
|
||||
let captionLayout =
|
||||
initialProps.captionLayout ?? defaultContextValues.captionLayout;
|
||||
if (captionLayout !== 'buttons' && (!fromDate || !toDate)) {
|
||||
// When no from/to dates are set, the caption is always buttons
|
||||
captionLayout = 'buttons';
|
||||
}
|
||||
|
||||
let onSelect;
|
||||
if (
|
||||
isDayPickerSingle(initialProps) ||
|
||||
isDayPickerMultiple(initialProps) ||
|
||||
isDayPickerRange(initialProps)
|
||||
) {
|
||||
onSelect = initialProps.onSelect;
|
||||
}
|
||||
|
||||
const value: DayPickerContextValue = {
|
||||
...defaultContextValues,
|
||||
...initialProps,
|
||||
captionLayout,
|
||||
classNames: {
|
||||
...defaultContextValues.classNames,
|
||||
...initialProps.classNames
|
||||
},
|
||||
components: {
|
||||
...initialProps.components
|
||||
},
|
||||
formatters: {
|
||||
...defaultContextValues.formatters,
|
||||
...initialProps.formatters
|
||||
},
|
||||
fromDate,
|
||||
labels: {
|
||||
...defaultContextValues.labels,
|
||||
...initialProps.labels
|
||||
},
|
||||
mode: initialProps.mode || defaultContextValues.mode,
|
||||
modifiers: {
|
||||
...defaultContextValues.modifiers,
|
||||
...initialProps.modifiers
|
||||
},
|
||||
modifiersClassNames: {
|
||||
...defaultContextValues.modifiersClassNames,
|
||||
...initialProps.modifiersClassNames
|
||||
},
|
||||
onSelect,
|
||||
styles: {
|
||||
...defaultContextValues.styles,
|
||||
...initialProps.styles
|
||||
},
|
||||
toDate
|
||||
};
|
||||
|
||||
return (
|
||||
<DayPickerContext.Provider value={value}>
|
||||
{props.children}
|
||||
</DayPickerContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to access the {@link DayPickerContextValue}.
|
||||
*
|
||||
* Use the DayPicker context to access to the props passed to DayPicker inside
|
||||
* internal or custom components.
|
||||
*/
|
||||
export function useDayPicker(): DayPickerContextValue {
|
||||
const context = useContext(DayPickerContext);
|
||||
if (!context) {
|
||||
throw new Error(`useDayPicker must be used within a DayPickerProvider.`);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
58
frontend/node_modules/react-day-picker/src/contexts/DayPicker/defaultClassNames.ts
generated
vendored
Normal file
58
frontend/node_modules/react-day-picker/src/contexts/DayPicker/defaultClassNames.ts
generated
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
import { ClassNames } from 'types/Styles';
|
||||
|
||||
/**
|
||||
* The name of the default CSS classes.
|
||||
*/
|
||||
export const defaultClassNames: Required<ClassNames> = {
|
||||
root: 'rdp',
|
||||
multiple_months: 'rdp-multiple_months',
|
||||
with_weeknumber: 'rdp-with_weeknumber',
|
||||
vhidden: 'rdp-vhidden',
|
||||
button_reset: 'rdp-button_reset',
|
||||
button: 'rdp-button',
|
||||
|
||||
caption: 'rdp-caption',
|
||||
|
||||
caption_start: 'rdp-caption_start',
|
||||
caption_end: 'rdp-caption_end',
|
||||
caption_between: 'rdp-caption_between',
|
||||
caption_label: 'rdp-caption_label',
|
||||
|
||||
caption_dropdowns: 'rdp-caption_dropdowns',
|
||||
|
||||
dropdown: 'rdp-dropdown',
|
||||
dropdown_month: 'rdp-dropdown_month',
|
||||
dropdown_year: 'rdp-dropdown_year',
|
||||
dropdown_icon: 'rdp-dropdown_icon',
|
||||
|
||||
months: 'rdp-months',
|
||||
month: 'rdp-month',
|
||||
table: 'rdp-table',
|
||||
tbody: 'rdp-tbody',
|
||||
tfoot: 'rdp-tfoot',
|
||||
|
||||
head: 'rdp-head',
|
||||
head_row: 'rdp-head_row',
|
||||
head_cell: 'rdp-head_cell',
|
||||
|
||||
nav: 'rdp-nav',
|
||||
nav_button: 'rdp-nav_button',
|
||||
nav_button_previous: 'rdp-nav_button_previous',
|
||||
nav_button_next: 'rdp-nav_button_next',
|
||||
|
||||
nav_icon: 'rdp-nav_icon',
|
||||
|
||||
row: 'rdp-row',
|
||||
weeknumber: 'rdp-weeknumber',
|
||||
cell: 'rdp-cell',
|
||||
|
||||
day: 'rdp-day',
|
||||
day_today: 'rdp-day_today',
|
||||
day_outside: 'rdp-day_outside',
|
||||
day_selected: 'rdp-day_selected',
|
||||
day_disabled: 'rdp-day_disabled',
|
||||
day_hidden: 'rdp-day_hidden',
|
||||
day_range_start: 'rdp-day_range_start',
|
||||
day_range_end: 'rdp-day_range_end',
|
||||
day_range_middle: 'rdp-day_range_middle'
|
||||
};
|
||||
54
frontend/node_modules/react-day-picker/src/contexts/DayPicker/defaultContextValues.ts
generated
vendored
Normal file
54
frontend/node_modules/react-day-picker/src/contexts/DayPicker/defaultContextValues.ts
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
import { enUS } from 'date-fns/locale';
|
||||
|
||||
import { CaptionLayout } from 'components/Caption';
|
||||
import { DayPickerContextValue } from 'contexts/DayPicker';
|
||||
|
||||
import { defaultClassNames } from './defaultClassNames';
|
||||
import * as formatters from './formatters';
|
||||
import * as labels from './labels';
|
||||
|
||||
export type DefaultContextProps =
|
||||
| 'captionLayout'
|
||||
| 'classNames'
|
||||
| 'formatters'
|
||||
| 'locale'
|
||||
| 'labels'
|
||||
| 'modifiersClassNames'
|
||||
| 'modifiers'
|
||||
| 'numberOfMonths'
|
||||
| 'styles'
|
||||
| 'today'
|
||||
| 'mode';
|
||||
|
||||
export type DefaultContextValues = Pick<
|
||||
DayPickerContextValue,
|
||||
DefaultContextProps
|
||||
>;
|
||||
/**
|
||||
* Returns the default values to use in the DayPickerContext, in case they are
|
||||
* not passed down with the DayPicker initial props.
|
||||
*/
|
||||
export function getDefaultContextValues(): DefaultContextValues {
|
||||
const captionLayout: CaptionLayout = 'buttons';
|
||||
const classNames = defaultClassNames;
|
||||
const locale = enUS;
|
||||
const modifiersClassNames = {};
|
||||
const modifiers = {};
|
||||
const numberOfMonths = 1;
|
||||
const styles = {};
|
||||
const today = new Date();
|
||||
|
||||
return {
|
||||
captionLayout,
|
||||
classNames,
|
||||
formatters,
|
||||
labels,
|
||||
locale,
|
||||
modifiersClassNames,
|
||||
modifiers,
|
||||
numberOfMonths,
|
||||
styles,
|
||||
today,
|
||||
mode: 'default'
|
||||
};
|
||||
}
|
||||
15
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatCaption.test.ts
generated
vendored
Normal file
15
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatCaption.test.ts
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
import { es } from 'date-fns/locale';
|
||||
|
||||
import { formatCaption } from './formatCaption';
|
||||
|
||||
const date = new Date(2022, 10, 21);
|
||||
|
||||
test('should return the formatted caption', () => {
|
||||
expect(formatCaption(date)).toEqual('November 2022');
|
||||
});
|
||||
|
||||
describe('when a locale is passed in', () => {
|
||||
test('should format using the locale', () => {
|
||||
expect(formatCaption(date, { locale: es })).toEqual('noviembre 2022');
|
||||
});
|
||||
});
|
||||
11
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatCaption.ts
generated
vendored
Normal file
11
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatCaption.ts
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
import { format, Locale } from 'date-fns';
|
||||
|
||||
/**
|
||||
* The default formatter for the caption.
|
||||
*/
|
||||
export function formatCaption(
|
||||
month: Date,
|
||||
options?: { locale?: Locale }
|
||||
): string {
|
||||
return format(month, 'LLLL y', options);
|
||||
}
|
||||
7
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatDay.test.ts
generated
vendored
Normal file
7
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatDay.test.ts
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
import { formatDay } from './formatDay';
|
||||
|
||||
const date = new Date(2022, 10, 21);
|
||||
|
||||
test('should return the formatted day', () => {
|
||||
expect(formatDay(date)).toEqual('21');
|
||||
});
|
||||
8
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatDay.ts
generated
vendored
Normal file
8
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatDay.ts
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
import { format, Locale } from 'date-fns';
|
||||
|
||||
/**
|
||||
* The default formatter for the Day button.
|
||||
*/
|
||||
export function formatDay(day: Date, options?: { locale?: Locale }): string {
|
||||
return format(day, 'd', options);
|
||||
}
|
||||
15
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatMonthCaption.test.ts
generated
vendored
Normal file
15
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatMonthCaption.test.ts
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
import { es } from 'date-fns/locale';
|
||||
|
||||
import { formatMonthCaption } from './formatMonthCaption';
|
||||
|
||||
const date = new Date(2022, 10, 21);
|
||||
|
||||
test('should return the formatted month caption', () => {
|
||||
expect(formatMonthCaption(date)).toEqual('November');
|
||||
});
|
||||
|
||||
describe('when a locale is passed in', () => {
|
||||
test('should format using the locale', () => {
|
||||
expect(formatMonthCaption(date, { locale: es })).toEqual('noviembre');
|
||||
});
|
||||
});
|
||||
11
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatMonthCaption.ts
generated
vendored
Normal file
11
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatMonthCaption.ts
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
import { format, Locale } from 'date-fns';
|
||||
|
||||
/**
|
||||
* The default formatter for the Month caption.
|
||||
*/
|
||||
export function formatMonthCaption(
|
||||
month: Date,
|
||||
options?: { locale?: Locale }
|
||||
): string {
|
||||
return format(month, 'LLLL', options);
|
||||
}
|
||||
5
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatWeekNumber.test.ts
generated
vendored
Normal file
5
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatWeekNumber.test.ts
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
import { formatWeekNumber } from './formatWeekNumber';
|
||||
|
||||
test('should return the formatted week number', () => {
|
||||
expect(formatWeekNumber(10)).toEqual('10');
|
||||
});
|
||||
6
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatWeekNumber.ts
generated
vendored
Normal file
6
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatWeekNumber.ts
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* The default formatter for the week number.
|
||||
*/
|
||||
export function formatWeekNumber(weekNumber: number): string {
|
||||
return `${weekNumber}`;
|
||||
}
|
||||
15
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatWeekdayName.test.ts
generated
vendored
Normal file
15
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatWeekdayName.test.ts
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
import { es } from 'date-fns/locale';
|
||||
|
||||
import { formatWeekdayName } from './formatWeekdayName';
|
||||
|
||||
const date = new Date(2022, 10, 21);
|
||||
|
||||
test('should return the formatted weekday name', () => {
|
||||
expect(formatWeekdayName(date)).toEqual('Mo');
|
||||
});
|
||||
|
||||
describe('when a locale is passed in', () => {
|
||||
test('should format using the locale', () => {
|
||||
expect(formatWeekdayName(date, { locale: es })).toEqual('lu');
|
||||
});
|
||||
});
|
||||
11
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatWeekdayName.ts
generated
vendored
Normal file
11
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatWeekdayName.ts
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
import { format, Locale } from 'date-fns';
|
||||
|
||||
/**
|
||||
* The default formatter for the name of the weekday.
|
||||
*/
|
||||
export function formatWeekdayName(
|
||||
weekday: Date,
|
||||
options?: { locale?: Locale }
|
||||
): string {
|
||||
return format(weekday, 'cccccc', options);
|
||||
}
|
||||
7
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatYearCaption.test.ts
generated
vendored
Normal file
7
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatYearCaption.test.ts
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
import { formatYearCaption } from './formatYearCaption';
|
||||
|
||||
const date = new Date(2022, 10, 21);
|
||||
|
||||
test('should return the formatted weekday name', () => {
|
||||
expect(formatYearCaption(date)).toEqual('2022');
|
||||
});
|
||||
13
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatYearCaption.ts
generated
vendored
Normal file
13
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/formatYearCaption.ts
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
import { format, Locale } from 'date-fns';
|
||||
|
||||
/**
|
||||
* The default formatter for the Year caption.
|
||||
*/
|
||||
export function formatYearCaption(
|
||||
year: Date,
|
||||
options?: {
|
||||
locale?: Locale;
|
||||
}
|
||||
): string {
|
||||
return format(year, 'yyyy', options);
|
||||
}
|
||||
6
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/index.ts
generated
vendored
Normal file
6
frontend/node_modules/react-day-picker/src/contexts/DayPicker/formatters/index.ts
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
export * from './formatCaption';
|
||||
export * from './formatDay';
|
||||
export * from './formatMonthCaption';
|
||||
export * from './formatWeekNumber';
|
||||
export * from './formatWeekdayName';
|
||||
export * from './formatYearCaption';
|
||||
1
frontend/node_modules/react-day-picker/src/contexts/DayPicker/index.ts
generated
vendored
Normal file
1
frontend/node_modules/react-day-picker/src/contexts/DayPicker/index.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './DayPickerContext';
|
||||
7
frontend/node_modules/react-day-picker/src/contexts/DayPicker/labels/index.ts
generated
vendored
Normal file
7
frontend/node_modules/react-day-picker/src/contexts/DayPicker/labels/index.ts
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
export * from './labelDay';
|
||||
export * from './labelMonthDropdown';
|
||||
export * from './labelNext';
|
||||
export * from './labelPrevious';
|
||||
export * from './labelWeekday';
|
||||
export * from './labelWeekNumber';
|
||||
export * from './labelYearDropdown';
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user