react-day-picker 8.0.3 → 8.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/hooks/useDayRender/useDayRender.d.ts +1 -1
- package/dist/hooks/useInput/useInput.d.ts +2 -2
- package/dist/index.esm.js +3 -3
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/react-day-picker.min.js +1 -0
- package/dist/style.css +11 -10
- package/dist/style.module.css +11 -10
- package/dist/types/Styles.d.ts +8 -2
- package/package.json +15 -13
- package/src/DayPicker.tsx +113 -0
- package/src/components/Button/Button.test.tsx +47 -0
- package/src/components/Button/Button.tsx +36 -0
- package/src/components/Button/index.ts +1 -0
- package/src/components/Caption/Caption.test.tsx +86 -0
- package/src/components/Caption/Caption.tsx +54 -0
- package/src/components/Caption/index.ts +1 -0
- package/src/components/CaptionDropdowns/CaptionDropdowns.test.tsx +123 -0
- package/src/components/CaptionDropdowns/CaptionDropdowns.tsx +43 -0
- package/src/components/CaptionDropdowns/index.ts +1 -0
- package/src/components/CaptionLabel/CaptionLabel.test.tsx +29 -0
- package/src/components/CaptionLabel/CaptionLabel.tsx +32 -0
- package/src/components/CaptionLabel/index.ts +1 -0
- package/src/components/CaptionNavigation/CaptionNavigation.test.tsx +172 -0
- package/src/components/CaptionNavigation/CaptionNavigation.tsx +63 -0
- package/src/components/CaptionNavigation/index.ts +1 -0
- package/src/components/Day/Day.test.tsx +84 -0
- package/src/components/Day/Day.tsx +30 -0
- package/src/components/Day/index.ts +1 -0
- package/src/components/DayContent/DayContent.test.tsx +51 -0
- package/src/components/DayContent/DayContent.tsx +36 -0
- package/src/components/DayContent/index.ts +1 -0
- package/src/components/Dropdown/Dropdown.test.tsx +73 -0
- package/src/components/Dropdown/Dropdown.tsx +56 -0
- package/src/components/Dropdown/index.ts +1 -0
- package/src/components/Footer/Footer.test.tsx +29 -0
- package/src/components/Footer/Footer.tsx +20 -0
- package/src/components/Footer/index.ts +1 -0
- package/src/components/Head/Head.test.tsx +117 -0
- package/src/components/Head/Head.tsx +51 -0
- package/src/components/Head/index.ts +1 -0
- package/src/components/Head/utils/getWeekdays.test.ts +36 -0
- package/src/components/Head/utils/getWeekdays.ts +22 -0
- package/src/components/Head/utils/index.ts +1 -0
- package/src/components/IconDropdown/IconDropdown.test.tsx +20 -0
- package/src/components/IconDropdown/IconDropdown.tsx +24 -0
- package/src/components/IconDropdown/index.ts +1 -0
- package/src/components/IconLeft/IconLeft.test.tsx +20 -0
- package/src/components/IconLeft/IconLeft.tsx +18 -0
- package/src/components/IconLeft/index.ts +1 -0
- package/src/components/IconRight/IconRight.test.tsx +20 -0
- package/src/components/IconRight/IconRight.tsx +17 -0
- package/src/components/IconRight/index.ts +1 -0
- package/src/components/Month/Month.test.tsx +216 -0
- package/src/components/Month/Month.tsx +53 -0
- package/src/components/Month/index.ts +1 -0
- package/src/components/MonthsDropdown/MonthsDropdown.test.tsx +99 -0
- package/src/components/MonthsDropdown/MonthsDropdown.tsx +75 -0
- package/src/components/MonthsDropdown/index.ts +1 -0
- package/src/components/Navigation/Navigation.test.tsx +129 -0
- package/src/components/Navigation/Navigation.tsx +102 -0
- package/src/components/Navigation/index.ts +1 -0
- package/src/components/Root/Root.test.tsx +123 -0
- package/src/components/Root/Root.tsx +58 -0
- package/src/components/Root/index.ts +1 -0
- package/src/components/Row/Row.test.tsx +69 -0
- package/src/components/Row/Row.tsx +51 -0
- package/src/components/Row/index.ts +1 -0
- package/src/components/Table/Table.test.tsx +42 -0
- package/src/components/Table/Table.tsx +60 -0
- package/src/components/Table/__snapshots__/Table.test.tsx.snap +1453 -0
- package/src/components/Table/index.ts +1 -0
- package/src/components/Table/utils/daysToMonthWeeks.ts +47 -0
- package/src/components/Table/utils/getMonthWeeks.test.ts +68 -0
- package/src/components/Table/utils/getMonthWeeks.ts +55 -0
- package/src/components/WeekNumber/WeekNumber.test.tsx +46 -0
- package/src/components/WeekNumber/WeekNumber.tsx +58 -0
- package/src/components/WeekNumber/__snapshots__/WeekNumber.test.tsx.snap +11 -0
- package/src/components/WeekNumber/index.ts +1 -0
- package/src/components/YearsDropdown/YearsDropdown.test.tsx +98 -0
- package/src/components/YearsDropdown/YearsDropdown.tsx +76 -0
- package/src/components/YearsDropdown/index.ts +1 -0
- package/src/contexts/DayPicker/DayPickerContext.tsx +156 -0
- package/src/contexts/DayPicker/defaultClassNames.ts +58 -0
- package/src/contexts/DayPicker/defaultContextValue.ts +37 -0
- package/src/contexts/DayPicker/formatters/formatCaption.test.ts +15 -0
- package/src/contexts/DayPicker/formatters/formatCaption.ts +12 -0
- package/src/contexts/DayPicker/formatters/formatDay.test.ts +7 -0
- package/src/contexts/DayPicker/formatters/formatDay.ts +9 -0
- package/src/contexts/DayPicker/formatters/formatMonthCaption.test.ts +15 -0
- package/src/contexts/DayPicker/formatters/formatMonthCaption.ts +12 -0
- package/src/contexts/DayPicker/formatters/formatWeekNumber.test.ts +5 -0
- package/src/contexts/DayPicker/formatters/formatWeekNumber.ts +6 -0
- package/src/contexts/DayPicker/formatters/formatWeekdayName.test.ts +15 -0
- package/src/contexts/DayPicker/formatters/formatWeekdayName.ts +12 -0
- package/src/contexts/DayPicker/formatters/formatYearCaption.test.ts +7 -0
- package/src/contexts/DayPicker/formatters/formatYearCaption.ts +11 -0
- package/src/contexts/DayPicker/formatters/index.ts +6 -0
- package/src/contexts/DayPicker/index.ts +2 -0
- package/src/contexts/DayPicker/labels/index.ts +7 -0
- package/src/contexts/DayPicker/labels/labelDay.test.ts +7 -0
- package/src/contexts/DayPicker/labels/labelDay.ts +10 -0
- package/src/contexts/DayPicker/labels/labelMonthDropdown.test.ts +5 -0
- package/src/contexts/DayPicker/labels/labelMonthDropdown.ts +6 -0
- package/src/contexts/DayPicker/labels/labelNext.test.ts +5 -0
- package/src/contexts/DayPicker/labels/labelNext.ts +8 -0
- package/src/contexts/DayPicker/labels/labelPrevious.test.ts +5 -0
- package/src/contexts/DayPicker/labels/labelPrevious.ts +8 -0
- package/src/contexts/DayPicker/labels/labelWeekNumber.test.ts +5 -0
- package/src/contexts/DayPicker/labels/labelWeekNumber.ts +8 -0
- package/src/contexts/DayPicker/labels/labelWeekday.test.ts +15 -0
- package/src/contexts/DayPicker/labels/labelWeekday.ts +10 -0
- package/src/contexts/DayPicker/labels/labelYearDropdown.test.ts +5 -0
- package/src/contexts/DayPicker/labels/labelYearDropdown.ts +6 -0
- package/src/contexts/DayPicker/useDayPicker.test.ts +297 -0
- package/src/contexts/DayPicker/useDayPicker.ts +17 -0
- package/src/contexts/DayPicker/utils/index.ts +1 -0
- package/src/contexts/DayPicker/utils/parseFromToProps.test.ts +47 -0
- package/src/contexts/DayPicker/utils/parseFromToProps.ts +32 -0
- package/src/contexts/Focus/FocusContext.tsx +174 -0
- package/src/contexts/Focus/index.ts +2 -0
- package/src/contexts/Focus/useFocusContext.test.ts +183 -0
- package/src/contexts/Focus/useFocusContext.ts +12 -0
- package/src/contexts/Focus/utils/getInitialFocusTarget.test.tsx +12 -0
- package/src/contexts/Focus/utils/getInitialFocusTarget.tsx +44 -0
- package/src/contexts/Modifiers/ModifiersContext.tsx +44 -0
- package/src/contexts/Modifiers/index.ts +2 -0
- package/src/contexts/Modifiers/useModifiers.test.ts +46 -0
- package/src/contexts/Modifiers/useModifiers.ts +17 -0
- package/src/contexts/Modifiers/utils/getActiveModifiers.test.ts +53 -0
- package/src/contexts/Modifiers/utils/getActiveModifiers.ts +33 -0
- package/src/contexts/Modifiers/utils/getCustomModifiers.test.ts +14 -0
- package/src/contexts/Modifiers/utils/getCustomModifiers.ts +14 -0
- package/src/contexts/Modifiers/utils/getInternalModifiers.test.ts +146 -0
- package/src/contexts/Modifiers/utils/getInternalModifiers.ts +58 -0
- package/src/contexts/Modifiers/utils/isDateInRange.test.ts +28 -0
- package/src/contexts/Modifiers/utils/isDateInRange.ts +27 -0
- package/src/contexts/Modifiers/utils/isMatch.test.ts +92 -0
- package/src/contexts/Modifiers/utils/isMatch.ts +76 -0
- package/src/contexts/Modifiers/utils/matcherToArray.test.ts +22 -0
- package/src/contexts/Modifiers/utils/matcherToArray.ts +14 -0
- package/src/contexts/Navigation/NavigationContext.tsx +84 -0
- package/src/contexts/Navigation/index.ts +2 -0
- package/src/contexts/Navigation/useNavigation.test.ts +126 -0
- package/src/contexts/Navigation/useNavigation.ts +12 -0
- package/src/contexts/Navigation/useNavigationState.test.ts +36 -0
- package/src/contexts/Navigation/useNavigationState.ts +25 -0
- package/src/contexts/Navigation/utils/getDisplayMonths.ts +31 -0
- package/src/contexts/Navigation/utils/getInitialMonth.test.ts +56 -0
- package/src/contexts/Navigation/utils/getInitialMonth.ts +24 -0
- package/src/contexts/Navigation/utils/getNextMonth.test.ts +75 -0
- package/src/contexts/Navigation/utils/getNextMonth.ts +45 -0
- package/src/contexts/Navigation/utils/getPreviousMonth.test.ts +55 -0
- package/src/contexts/Navigation/utils/getPreviousMonth.ts +44 -0
- package/src/contexts/RootProvider.tsx +37 -0
- package/src/contexts/SelectMultiple/SelectMultipleContext.tsx +135 -0
- package/src/contexts/SelectMultiple/index.ts +2 -0
- package/src/contexts/SelectMultiple/useSelectMultiple.test.ts +191 -0
- package/src/contexts/SelectMultiple/useSelectMultiple.ts +17 -0
- package/src/contexts/SelectRange/SelectRangeContext.tsx +158 -0
- package/src/contexts/SelectRange/index.ts +2 -0
- package/src/contexts/SelectRange/useSelectRange.test.ts +282 -0
- package/src/contexts/SelectRange/useSelectRange.ts +15 -0
- package/src/contexts/SelectRange/utils/addToRange.test.ts +119 -0
- package/src/contexts/SelectRange/utils/addToRange.ts +43 -0
- package/src/contexts/SelectSingle/SelectSingleContext.tsx +80 -0
- package/src/contexts/SelectSingle/index.ts +2 -0
- package/src/contexts/SelectSingle/useSelectSingle.test.ts +81 -0
- package/src/contexts/SelectSingle/useSelectSingle.ts +17 -0
- package/src/hooks/useActiveModifiers/index.ts +1 -0
- package/src/hooks/useActiveModifiers/useActiveModifiers.test.tsx +36 -0
- package/src/hooks/useActiveModifiers/useActiveModifiers.tsx +18 -0
- package/src/hooks/useControlledValue/index.ts +1 -0
- package/src/hooks/useControlledValue/useControlledValue.test.ts +68 -0
- package/src/hooks/useControlledValue/useControlledValue.ts +24 -0
- package/src/hooks/useDayEventHandlers/index.ts +1 -0
- package/src/hooks/useDayEventHandlers/useDayEventHandlers.test.tsx +213 -0
- package/src/hooks/useDayEventHandlers/useDayEventHandlers.tsx +195 -0
- package/src/hooks/useDayRender/index.ts +1 -0
- package/src/hooks/useDayRender/useDayRender.test.tsx +304 -0
- package/src/hooks/useDayRender/useDayRender.tsx +123 -0
- package/src/hooks/useDayRender/utils/getDayClassNames.test.ts +63 -0
- package/src/hooks/useDayRender/utils/getDayClassNames.ts +32 -0
- package/src/hooks/useDayRender/utils/getDayStyle.ts +19 -0
- package/src/hooks/useInput/index.ts +1 -0
- package/src/hooks/useInput/useInput.ts +175 -0
- package/src/hooks/useInput/utils/isValidDate.tsx +4 -0
- package/src/hooks/useSelectedDays/index.ts +1 -0
- package/src/hooks/useSelectedDays/useSelectedDays.test.ts +72 -0
- package/src/hooks/useSelectedDays/useSelectedDays.ts +32 -0
- package/src/index.ts +43 -0
- package/src/style.css +311 -0
- package/src/style.css.d.ts +38 -0
- package/src/types/DayPickerBase.ts +267 -0
- package/src/types/DayPickerDefault.ts +15 -0
- package/src/types/DayPickerMultiple.ts +26 -0
- package/src/types/DayPickerRange.ts +27 -0
- package/src/types/DayPickerSingle.ts +24 -0
- package/src/types/EventHandlers.ts +87 -0
- package/src/types/Formatters.ts +29 -0
- package/src/types/Labels.ts +36 -0
- package/src/types/Matchers.ts +106 -0
- package/src/types/Modifiers.ts +62 -0
- package/src/types/Styles.ts +125 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { CaptionProps } from 'components/Caption/Caption';
|
|
4
|
+
import { CaptionLabel } from 'components/CaptionLabel';
|
|
5
|
+
import { MonthsDropdown } from 'components/MonthsDropdown';
|
|
6
|
+
import { YearsDropdown } from 'components/YearsDropdown';
|
|
7
|
+
import { useDayPicker } from 'contexts/DayPicker';
|
|
8
|
+
import { useNavigation } from 'contexts/Navigation';
|
|
9
|
+
import { MonthChangeEventHandler } from 'types/EventHandlers';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Render a caption with the dropdowns to navigate between months and years.
|
|
13
|
+
*/
|
|
14
|
+
export function CaptionDropdowns(props: CaptionProps): JSX.Element {
|
|
15
|
+
const { classNames, styles, onMonthChange, components } = useDayPicker();
|
|
16
|
+
const { goToMonth } = useNavigation();
|
|
17
|
+
|
|
18
|
+
const handleMonthChange: MonthChangeEventHandler = (newMonth) => {
|
|
19
|
+
goToMonth(newMonth);
|
|
20
|
+
onMonthChange?.(newMonth);
|
|
21
|
+
};
|
|
22
|
+
const CaptionLabelComponent = components?.CaptionLabel ?? CaptionLabel;
|
|
23
|
+
const captionLabel = (
|
|
24
|
+
<CaptionLabelComponent id={props.id} displayMonth={props.displayMonth} />
|
|
25
|
+
);
|
|
26
|
+
return (
|
|
27
|
+
<div
|
|
28
|
+
className={classNames.caption_dropdowns}
|
|
29
|
+
style={styles.caption_dropdowns}
|
|
30
|
+
>
|
|
31
|
+
{/* Caption label is visually hidden but for a11y. */}
|
|
32
|
+
<div className={classNames.vhidden}>{captionLabel}</div>
|
|
33
|
+
<MonthsDropdown
|
|
34
|
+
onChange={handleMonthChange}
|
|
35
|
+
displayMonth={props.displayMonth}
|
|
36
|
+
/>
|
|
37
|
+
<YearsDropdown
|
|
38
|
+
onChange={handleMonthChange}
|
|
39
|
+
displayMonth={props.displayMonth}
|
|
40
|
+
/>
|
|
41
|
+
</div>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './CaptionDropdowns';
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { getMonthCaption } from 'test/po';
|
|
4
|
+
import { customRender } from 'test/render';
|
|
5
|
+
import { freezeBeforeAll } from 'test/utils';
|
|
6
|
+
|
|
7
|
+
import { CaptionLabel } from './CaptionLabel';
|
|
8
|
+
|
|
9
|
+
const today = new Date(1979, 8);
|
|
10
|
+
freezeBeforeAll(today);
|
|
11
|
+
|
|
12
|
+
test('should render the formatted display month', () => {
|
|
13
|
+
customRender(<CaptionLabel displayMonth={today} />);
|
|
14
|
+
expect(getMonthCaption()).toHaveTextContent('September 1979');
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('should apply the `caption_label` class name', () => {
|
|
18
|
+
customRender(<CaptionLabel displayMonth={today} />, {
|
|
19
|
+
classNames: { caption_label: 'foo' }
|
|
20
|
+
});
|
|
21
|
+
expect(getMonthCaption()).toHaveClass('foo');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('should apply the `caption_label` style', () => {
|
|
25
|
+
customRender(<CaptionLabel displayMonth={today} />, {
|
|
26
|
+
styles: { caption_label: { color: 'red' } }
|
|
27
|
+
});
|
|
28
|
+
expect(getMonthCaption()).toHaveStyle({ color: 'red' });
|
|
29
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { useDayPicker } from 'contexts/DayPicker';
|
|
4
|
+
|
|
5
|
+
/** The props for the [[CaptionLabel]] component. */
|
|
6
|
+
export interface CaptionLabelProps {
|
|
7
|
+
/** The ID for the heading element. Must be the same as the labelled-by in Table. */
|
|
8
|
+
id?: string;
|
|
9
|
+
/** The month where the caption is displayed. */
|
|
10
|
+
displayMonth: Date;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Render the caption for the displayed month. This component is used when `captionLayout="buttons"`. */
|
|
14
|
+
export function CaptionLabel(props: CaptionLabelProps): JSX.Element {
|
|
15
|
+
const {
|
|
16
|
+
locale,
|
|
17
|
+
classNames,
|
|
18
|
+
styles,
|
|
19
|
+
formatters: { formatCaption }
|
|
20
|
+
} = useDayPicker();
|
|
21
|
+
return (
|
|
22
|
+
<h2
|
|
23
|
+
className={classNames.caption_label}
|
|
24
|
+
style={styles.caption_label}
|
|
25
|
+
aria-live="polite"
|
|
26
|
+
aria-atomic="true"
|
|
27
|
+
id={props.id}
|
|
28
|
+
>
|
|
29
|
+
{formatCaption(props.displayMonth, { locale })}
|
|
30
|
+
</h2>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './CaptionLabel';
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { screen } from '@testing-library/react';
|
|
4
|
+
import userEvent from '@testing-library/user-event';
|
|
5
|
+
import { addMonths } from 'date-fns';
|
|
6
|
+
import { DayPickerProps } from 'DayPicker';
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
getMonthCaption,
|
|
10
|
+
getNextButton,
|
|
11
|
+
getPrevButton,
|
|
12
|
+
queryNextButton,
|
|
13
|
+
queryPrevButton
|
|
14
|
+
} from 'test/po';
|
|
15
|
+
import { customRender } from 'test/render';
|
|
16
|
+
import { freezeBeforeAll } from 'test/utils';
|
|
17
|
+
|
|
18
|
+
import { CaptionProps } from 'components/Caption';
|
|
19
|
+
import { CustomComponents } from 'types/DayPickerBase';
|
|
20
|
+
|
|
21
|
+
import { CaptionNavigation } from './CaptionNavigation';
|
|
22
|
+
|
|
23
|
+
const today = new Date(2021, 8);
|
|
24
|
+
|
|
25
|
+
freezeBeforeAll(today);
|
|
26
|
+
|
|
27
|
+
function setup(props: CaptionProps, dayPickerProps?: DayPickerProps) {
|
|
28
|
+
customRender(<CaptionNavigation {...props} />, dayPickerProps);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
describe('when using a custom CaptionLabel component', () => {
|
|
32
|
+
const components: CustomComponents = {
|
|
33
|
+
CaptionLabel: () => <>custom label foo</>
|
|
34
|
+
};
|
|
35
|
+
const props = { displayMonth: today };
|
|
36
|
+
beforeEach(() => {
|
|
37
|
+
setup(props, { components });
|
|
38
|
+
});
|
|
39
|
+
test('it should render the custom component instead', () => {
|
|
40
|
+
expect(screen.getByText('custom label foo')).toBeInTheDocument();
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
describe('when rendered', () => {
|
|
45
|
+
const dayPickerProps: DayPickerProps = {
|
|
46
|
+
captionLayout: 'buttons'
|
|
47
|
+
};
|
|
48
|
+
test('should render the caption label', () => {
|
|
49
|
+
customRender(<CaptionNavigation displayMonth={today} />, dayPickerProps);
|
|
50
|
+
expect(getMonthCaption()).toHaveTextContent('September 2021');
|
|
51
|
+
});
|
|
52
|
+
test('should render the next month button', () => {
|
|
53
|
+
customRender(<CaptionNavigation displayMonth={today} />, dayPickerProps);
|
|
54
|
+
expect(getNextButton()).toBeInTheDocument();
|
|
55
|
+
});
|
|
56
|
+
test('should render the previous month button', () => {
|
|
57
|
+
customRender(<CaptionNavigation displayMonth={today} />, dayPickerProps);
|
|
58
|
+
expect(getPrevButton()).toBeInTheDocument();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe('when displaying the first of multiple months', () => {
|
|
62
|
+
const numberOfMonths = 3;
|
|
63
|
+
beforeEach(() => {
|
|
64
|
+
customRender(<CaptionNavigation displayMonth={today} />, {
|
|
65
|
+
...dayPickerProps,
|
|
66
|
+
numberOfMonths
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
test('should not display the next month button', () => {
|
|
70
|
+
expect(queryNextButton()).toBeNull();
|
|
71
|
+
});
|
|
72
|
+
test('should show the previous month button', () => {
|
|
73
|
+
expect(getPrevButton()).toBeInTheDocument();
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
describe('when displaying the last of multiple months', () => {
|
|
78
|
+
const numberOfMonths = 3;
|
|
79
|
+
beforeEach(() => {
|
|
80
|
+
const lastMonth = addMonths(today, numberOfMonths - 1);
|
|
81
|
+
customRender(<CaptionNavigation displayMonth={lastMonth} />, {
|
|
82
|
+
...dayPickerProps,
|
|
83
|
+
numberOfMonths
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
test('should hide the previous month button', () => {
|
|
87
|
+
expect(queryPrevButton()).toBeNull();
|
|
88
|
+
});
|
|
89
|
+
test('should show the next month button', () => {
|
|
90
|
+
expect(getNextButton()).toBeInTheDocument();
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe('when displaying a month in the middle of multiple months', () => {
|
|
95
|
+
const numberOfMonths = 3;
|
|
96
|
+
beforeEach(() => {
|
|
97
|
+
const lastMonth = addMonths(today, numberOfMonths - 2);
|
|
98
|
+
customRender(<CaptionNavigation displayMonth={lastMonth} />, {
|
|
99
|
+
...dayPickerProps,
|
|
100
|
+
numberOfMonths
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
test('should not render the previous month button', () => {
|
|
104
|
+
expect(queryPrevButton()).toBeNull();
|
|
105
|
+
});
|
|
106
|
+
test('should not render the next month button', () => {
|
|
107
|
+
expect(queryNextButton()).toBeNull();
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
describe('when clicking the previous button', () => {
|
|
112
|
+
describe('and a previous month is defined', () => {
|
|
113
|
+
const testContext = {
|
|
114
|
+
...dayPickerProps,
|
|
115
|
+
onMonthChange: jest.fn()
|
|
116
|
+
};
|
|
117
|
+
const previousMonth = addMonths(today, -1);
|
|
118
|
+
beforeEach(() => {
|
|
119
|
+
customRender(<CaptionNavigation displayMonth={today} />, testContext);
|
|
120
|
+
userEvent.click(getPrevButton());
|
|
121
|
+
});
|
|
122
|
+
test('should call the `onMonthChange` callback', () => {
|
|
123
|
+
expect(testContext.onMonthChange).toHaveBeenCalledWith(previousMonth);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
describe('and the previous month is not defined', () => {
|
|
127
|
+
const testContext = {
|
|
128
|
+
...dayPickerProps,
|
|
129
|
+
fromDate: today,
|
|
130
|
+
onMonthChange: jest.fn()
|
|
131
|
+
};
|
|
132
|
+
beforeEach(() => {
|
|
133
|
+
customRender(<CaptionNavigation displayMonth={today} />, testContext);
|
|
134
|
+
userEvent.click(getPrevButton());
|
|
135
|
+
});
|
|
136
|
+
test('should call the `onMonthChange` callback', () => {
|
|
137
|
+
expect(testContext.onMonthChange).not.toHaveBeenCalled();
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
describe('when clicking the next month button', () => {
|
|
143
|
+
describe('and the next month is defined', () => {
|
|
144
|
+
const testContext = {
|
|
145
|
+
...dayPickerProps,
|
|
146
|
+
onMonthChange: jest.fn()
|
|
147
|
+
};
|
|
148
|
+
const nextMonth = addMonths(today, 1);
|
|
149
|
+
beforeEach(() => {
|
|
150
|
+
customRender(<CaptionNavigation displayMonth={today} />, testContext);
|
|
151
|
+
userEvent.click(getNextButton());
|
|
152
|
+
});
|
|
153
|
+
test('should call the `onMonthChange` callback', () => {
|
|
154
|
+
expect(testContext.onMonthChange).toHaveBeenCalledWith(nextMonth);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
describe('and the next month is not defined', () => {
|
|
158
|
+
const testContext = {
|
|
159
|
+
...dayPickerProps,
|
|
160
|
+
toDate: today,
|
|
161
|
+
onMonthChange: jest.fn()
|
|
162
|
+
};
|
|
163
|
+
beforeEach(() => {
|
|
164
|
+
customRender(<CaptionNavigation displayMonth={today} />, testContext);
|
|
165
|
+
userEvent.click(getNextButton());
|
|
166
|
+
});
|
|
167
|
+
test('should call the `onMonthChange` callback', () => {
|
|
168
|
+
expect(testContext.onMonthChange).not.toHaveBeenCalled();
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import isSameMonth from 'date-fns/isSameMonth';
|
|
4
|
+
|
|
5
|
+
import { CaptionProps } from 'components/Caption/Caption';
|
|
6
|
+
import { CaptionLabel } from 'components/CaptionLabel';
|
|
7
|
+
import { Navigation } from 'components/Navigation';
|
|
8
|
+
import { useDayPicker } from 'contexts/DayPicker';
|
|
9
|
+
import { useNavigation } from 'contexts/Navigation';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Render a caption with a button-based navigation.
|
|
13
|
+
*/
|
|
14
|
+
export function CaptionNavigation(props: CaptionProps): JSX.Element {
|
|
15
|
+
const { numberOfMonths, onMonthChange, dir, components } = useDayPicker();
|
|
16
|
+
const { previousMonth, nextMonth, goToMonth, displayMonths } =
|
|
17
|
+
useNavigation();
|
|
18
|
+
|
|
19
|
+
const displayIndex = displayMonths.findIndex((month) =>
|
|
20
|
+
isSameMonth(props.displayMonth, month)
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
let isFirst = displayIndex === 0;
|
|
24
|
+
let isLast = displayIndex === displayMonths.length - 1;
|
|
25
|
+
if (dir === 'rtl') {
|
|
26
|
+
[isLast, isFirst] = [isFirst, isLast];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const hideNext = numberOfMonths > 1 && (isFirst || !isLast);
|
|
30
|
+
const hidePrevious = numberOfMonths > 1 && (isLast || !isFirst);
|
|
31
|
+
|
|
32
|
+
const handlePreviousClick: React.MouseEventHandler = () => {
|
|
33
|
+
if (!previousMonth) return;
|
|
34
|
+
goToMonth(previousMonth);
|
|
35
|
+
onMonthChange?.(previousMonth);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const handleNextClick: React.MouseEventHandler = () => {
|
|
39
|
+
if (!nextMonth) return;
|
|
40
|
+
goToMonth(nextMonth);
|
|
41
|
+
onMonthChange?.(nextMonth);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const CaptionLabelComponent = components?.CaptionLabel ?? CaptionLabel;
|
|
45
|
+
const captionLabel = (
|
|
46
|
+
<CaptionLabelComponent id={props.id} displayMonth={props.displayMonth} />
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<>
|
|
51
|
+
{captionLabel}
|
|
52
|
+
<Navigation
|
|
53
|
+
displayMonth={props.displayMonth}
|
|
54
|
+
hideNext={hideNext}
|
|
55
|
+
hidePrevious={hidePrevious}
|
|
56
|
+
nextMonth={nextMonth}
|
|
57
|
+
previousMonth={previousMonth}
|
|
58
|
+
onPreviousClick={handlePreviousClick}
|
|
59
|
+
onNextClick={handleNextClick}
|
|
60
|
+
/>
|
|
61
|
+
</>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './CaptionNavigation';
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { screen } from '@testing-library/react';
|
|
4
|
+
import { DayPickerProps } from 'DayPicker';
|
|
5
|
+
|
|
6
|
+
import { customRender } from 'test/render';
|
|
7
|
+
import { freezeBeforeAll } from 'test/utils';
|
|
8
|
+
|
|
9
|
+
import { CustomComponents } from 'types/DayPickerBase';
|
|
10
|
+
|
|
11
|
+
import { Day, DayProps } from './Day';
|
|
12
|
+
|
|
13
|
+
const today = new Date(2021, 8);
|
|
14
|
+
|
|
15
|
+
freezeBeforeAll(today);
|
|
16
|
+
let container: HTMLElement;
|
|
17
|
+
function setup(props: DayProps, dayPickerProps?: DayPickerProps) {
|
|
18
|
+
const view = customRender(<Day {...props} />, dayPickerProps);
|
|
19
|
+
container = view.container;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const date = today;
|
|
23
|
+
const displayMonth = today;
|
|
24
|
+
const props: DayProps = {
|
|
25
|
+
date: date,
|
|
26
|
+
displayMonth
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
describe('when the day to render has an hidden modifier', () => {
|
|
30
|
+
const dayPickerProps: DayPickerProps = {
|
|
31
|
+
modifiers: { hidden: date }
|
|
32
|
+
};
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
setup(props, dayPickerProps);
|
|
35
|
+
});
|
|
36
|
+
test('should render an empty element', () => {
|
|
37
|
+
expect(container).toBeEmptyDOMElement();
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
describe('when a no selection mode and no "onDayClick"', () => {
|
|
41
|
+
const dayPickerProps: DayPickerProps = { mode: 'default' };
|
|
42
|
+
beforeEach(() => {
|
|
43
|
+
setup(props, dayPickerProps);
|
|
44
|
+
});
|
|
45
|
+
test('should render a div', () => {
|
|
46
|
+
expect(container.firstChild?.nodeName).toBe('DIV');
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe('when a selection mode is set', () => {
|
|
51
|
+
const dayPickerProps: DayPickerProps = {
|
|
52
|
+
mode: 'single'
|
|
53
|
+
};
|
|
54
|
+
beforeEach(() => {
|
|
55
|
+
setup(props, dayPickerProps);
|
|
56
|
+
});
|
|
57
|
+
test('should render a button', () => {
|
|
58
|
+
expect(container.firstChild?.nodeName).toBe('BUTTON');
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe('when "onDayClick" is present', () => {
|
|
63
|
+
const dayPickerProps: DayPickerProps = {
|
|
64
|
+
onDayClick: jest.fn()
|
|
65
|
+
};
|
|
66
|
+
beforeEach(() => {
|
|
67
|
+
setup(props, dayPickerProps);
|
|
68
|
+
});
|
|
69
|
+
test('should render a button', () => {
|
|
70
|
+
expect(container.firstChild?.nodeName).toBe('BUTTON');
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
describe('when using a custom DayContent component', () => {
|
|
75
|
+
const components: CustomComponents = {
|
|
76
|
+
DayContent: () => <>Custom DayContent</>
|
|
77
|
+
};
|
|
78
|
+
beforeEach(() => {
|
|
79
|
+
setup(props, { components });
|
|
80
|
+
});
|
|
81
|
+
test('it should render the custom component instead', () => {
|
|
82
|
+
expect(screen.getByText('Custom DayContent')).toBeInTheDocument();
|
|
83
|
+
});
|
|
84
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React, { useRef } from 'react';
|
|
2
|
+
|
|
3
|
+
import { useDayRender } from 'hooks/useDayRender';
|
|
4
|
+
|
|
5
|
+
import { Button } from '../Button';
|
|
6
|
+
|
|
7
|
+
/** Represent the props used by the [[Day]] component. */
|
|
8
|
+
export interface DayProps {
|
|
9
|
+
/** The month where the date is displayed. */
|
|
10
|
+
displayMonth: Date;
|
|
11
|
+
/** The date to render. */
|
|
12
|
+
date: Date;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The content of a day cell – as a button or span element according to its
|
|
17
|
+
* modifiers.
|
|
18
|
+
*/
|
|
19
|
+
export function Day(props: DayProps): JSX.Element {
|
|
20
|
+
const buttonRef = useRef<HTMLButtonElement>(null);
|
|
21
|
+
const dayRender = useDayRender(props.date, props.displayMonth, buttonRef);
|
|
22
|
+
|
|
23
|
+
if (dayRender.isHidden) {
|
|
24
|
+
return <></>;
|
|
25
|
+
}
|
|
26
|
+
if (!dayRender.isButton) {
|
|
27
|
+
return <div {...dayRender.divProps} />;
|
|
28
|
+
}
|
|
29
|
+
return <Button ref={buttonRef} {...dayRender.buttonProps} />;
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Day';
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import es from 'date-fns/locale/es';
|
|
4
|
+
import { DayPickerProps } from 'DayPicker';
|
|
5
|
+
|
|
6
|
+
import { customRender } from 'test/render';
|
|
7
|
+
import { freezeBeforeAll } from 'test/utils';
|
|
8
|
+
|
|
9
|
+
import { DayContent, DayContentProps } from 'components/DayContent';
|
|
10
|
+
import { defaultClassNames } from 'contexts/DayPicker/defaultClassNames';
|
|
11
|
+
|
|
12
|
+
const today = new Date(2021, 8);
|
|
13
|
+
|
|
14
|
+
freezeBeforeAll(today);
|
|
15
|
+
let container: HTMLElement;
|
|
16
|
+
function setup(props: DayContentProps, dayPickerProps?: DayPickerProps) {
|
|
17
|
+
const view = customRender(<DayContent {...props} />, dayPickerProps);
|
|
18
|
+
container = view.container;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const date = today;
|
|
22
|
+
const displayMonth = today;
|
|
23
|
+
const props: DayContentProps = {
|
|
24
|
+
date: date,
|
|
25
|
+
displayMonth,
|
|
26
|
+
activeModifiers: {}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const dayPickerProps: DayPickerProps = {
|
|
30
|
+
locale: es
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
describe('when rendered', () => {
|
|
34
|
+
beforeEach(() => {
|
|
35
|
+
setup(props, dayPickerProps);
|
|
36
|
+
});
|
|
37
|
+
test('the first element is an aria-hidden element with the formatted day', () => {
|
|
38
|
+
expect(container.firstChild).toHaveAttribute('aria-hidden', 'true');
|
|
39
|
+
});
|
|
40
|
+
test('the first element contains the formatted day', () => {
|
|
41
|
+
expect(container.firstChild).toHaveTextContent('1');
|
|
42
|
+
});
|
|
43
|
+
test('the second element is visually hidden', () => {
|
|
44
|
+
expect(container.childNodes[1]).toHaveClass(defaultClassNames.vhidden);
|
|
45
|
+
});
|
|
46
|
+
test('the second element contains the formatted day', () => {
|
|
47
|
+
expect(container.childNodes[1]).toHaveTextContent(
|
|
48
|
+
'1º septiembre (miércoles)'
|
|
49
|
+
);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { useDayPicker } from 'contexts/DayPicker';
|
|
4
|
+
import { ActiveModifiers } from 'types/Modifiers';
|
|
5
|
+
|
|
6
|
+
/** Represent the props for the [[DayContent]] component. */
|
|
7
|
+
export interface DayContentProps {
|
|
8
|
+
/** The date representing the day. */
|
|
9
|
+
date: Date;
|
|
10
|
+
/** The month where the day is displayed. */
|
|
11
|
+
displayMonth: Date;
|
|
12
|
+
/** The active modifiers for the given date. */
|
|
13
|
+
activeModifiers: ActiveModifiers;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Render the content of the day cell.
|
|
18
|
+
*/
|
|
19
|
+
export function DayContent(props: DayContentProps): JSX.Element {
|
|
20
|
+
const {
|
|
21
|
+
locale,
|
|
22
|
+
classNames,
|
|
23
|
+
styles,
|
|
24
|
+
labels: { labelDay },
|
|
25
|
+
formatters: { formatDay }
|
|
26
|
+
} = useDayPicker();
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<>
|
|
30
|
+
<span aria-hidden="true">{formatDay(props.date, { locale })}</span>
|
|
31
|
+
<span className={classNames.vhidden} style={styles.vhidden}>
|
|
32
|
+
{labelDay(props.date, props.activeModifiers, { locale })}
|
|
33
|
+
</span>
|
|
34
|
+
</>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DayContent';
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { fireEvent, screen } from '@testing-library/react';
|
|
4
|
+
import { DayPickerProps } from 'DayPicker';
|
|
5
|
+
|
|
6
|
+
import { customRender } from 'test/render';
|
|
7
|
+
import { freezeBeforeAll } from 'test/utils';
|
|
8
|
+
|
|
9
|
+
import { Dropdown, DropdownProps } from 'components/Dropdown';
|
|
10
|
+
import { defaultClassNames } from 'contexts/DayPicker/defaultClassNames';
|
|
11
|
+
import { CustomComponents } from 'types/DayPickerBase';
|
|
12
|
+
|
|
13
|
+
const today = new Date(2021, 8);
|
|
14
|
+
|
|
15
|
+
freezeBeforeAll(today);
|
|
16
|
+
|
|
17
|
+
function setup(props: DropdownProps, dayPickerProps?: DayPickerProps) {
|
|
18
|
+
customRender(<Dropdown {...props} />, dayPickerProps);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const props: Required<DropdownProps> = {
|
|
22
|
+
'aria-label': 'foo',
|
|
23
|
+
onChange: jest.fn(),
|
|
24
|
+
caption: 'Some caption',
|
|
25
|
+
className: 'test',
|
|
26
|
+
value: 'bar',
|
|
27
|
+
children: <option value={'bar'} />,
|
|
28
|
+
style: {}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
describe('when rendered', () => {
|
|
32
|
+
let combobox: HTMLElement;
|
|
33
|
+
let label: HTMLElement;
|
|
34
|
+
|
|
35
|
+
beforeEach(() => {
|
|
36
|
+
setup(props);
|
|
37
|
+
combobox = screen.getByRole('combobox');
|
|
38
|
+
label = screen.getByText(props['aria-label']);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('should render the vhidden aria label', () => {
|
|
42
|
+
expect(label).toHaveClass(defaultClassNames.vhidden);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('should render the combobox', () => {
|
|
46
|
+
expect(combobox).toBeInTheDocument();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe('when the combobox changes', () => {
|
|
50
|
+
beforeEach(() => {
|
|
51
|
+
fireEvent.change(combobox);
|
|
52
|
+
});
|
|
53
|
+
test('should call the "onChange" eve, nt handler', () => {
|
|
54
|
+
expect(props.onChange).toHaveBeenCalled();
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test('should render the combobox with the given value', () => {
|
|
59
|
+
expect(combobox).toHaveValue(props.value);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe('when using a custom IconDropdown component', () => {
|
|
64
|
+
const components: CustomComponents = {
|
|
65
|
+
IconDropdown: () => <div>Custom IconDropdown</div>
|
|
66
|
+
};
|
|
67
|
+
beforeEach(() => {
|
|
68
|
+
setup(props, { components });
|
|
69
|
+
});
|
|
70
|
+
test('it should render the custom component instead', () => {
|
|
71
|
+
expect(screen.getByText('Custom IconDropdown')).toBeInTheDocument();
|
|
72
|
+
});
|
|
73
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { IconDropdown } from 'components/IconDropdown';
|
|
4
|
+
import { useDayPicker } from 'contexts/DayPicker';
|
|
5
|
+
|
|
6
|
+
/** The props for the [[Dropdown]] component. */
|
|
7
|
+
export interface DropdownProps {
|
|
8
|
+
caption?: React.ReactNode;
|
|
9
|
+
children?: React.SelectHTMLAttributes<HTMLSelectElement>['children'];
|
|
10
|
+
className?: string;
|
|
11
|
+
['aria-label']?: string;
|
|
12
|
+
style?: React.CSSProperties;
|
|
13
|
+
value?: string | number;
|
|
14
|
+
onChange?: React.ChangeEventHandler<HTMLSelectElement>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Render a styled select component – displaying a caption and a custom
|
|
19
|
+
* drop-down icon.
|
|
20
|
+
*/
|
|
21
|
+
export function Dropdown(props: DropdownProps): JSX.Element {
|
|
22
|
+
const { onChange, value, children, caption, className, style } = props;
|
|
23
|
+
const dayPicker = useDayPicker();
|
|
24
|
+
|
|
25
|
+
const IconDropdownComponent =
|
|
26
|
+
dayPicker.components?.IconDropdown ?? IconDropdown;
|
|
27
|
+
return (
|
|
28
|
+
<div className={className} style={style}>
|
|
29
|
+
<span className={dayPicker.classNames.vhidden}>
|
|
30
|
+
{props['aria-label']}
|
|
31
|
+
</span>
|
|
32
|
+
<select
|
|
33
|
+
aria-label={props['aria-label']}
|
|
34
|
+
className={dayPicker.classNames.dropdown}
|
|
35
|
+
style={dayPicker.styles.dropdown}
|
|
36
|
+
value={value}
|
|
37
|
+
onChange={onChange}
|
|
38
|
+
>
|
|
39
|
+
{children}
|
|
40
|
+
</select>
|
|
41
|
+
<div
|
|
42
|
+
className={dayPicker.classNames.caption_label}
|
|
43
|
+
style={dayPicker.styles.caption_label}
|
|
44
|
+
aria-hidden="true"
|
|
45
|
+
>
|
|
46
|
+
{caption}
|
|
47
|
+
{
|
|
48
|
+
<IconDropdownComponent
|
|
49
|
+
className={dayPicker.classNames.dropdown_icon}
|
|
50
|
+
style={dayPicker.styles.dropdown_icon}
|
|
51
|
+
/>
|
|
52
|
+
}
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
);
|
|
56
|
+
}
|