@simplybusiness/mobius-datepicker 4.5.4 → 5.0.1
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/CHANGELOG.md +24 -0
- package/dist/cjs/components/DatePicker/DatePickerModal.js +39 -9
- package/dist/cjs/components/DatePicker/DatePickerModal.js.map +1 -1
- package/dist/cjs/components/DatePicker/utils/weekdayAsOneLetter.js +2 -3
- package/dist/cjs/components/DatePicker/utils/weekdayAsOneLetter.js.map +1 -1
- package/dist/esm/components/DatePicker/DatePickerModal.js +39 -9
- package/dist/esm/components/DatePicker/DatePickerModal.js.map +1 -1
- package/dist/esm/components/DatePicker/utils/weekdayAsOneLetter.js +2 -3
- package/dist/esm/components/DatePicker/utils/weekdayAsOneLetter.js.map +1 -1
- package/dist/types/components/DatePicker/DatePicker.stories.d.ts +1 -1
- package/dist/types/components/DatePicker/utils/weekdayAsOneLetter.d.ts +1 -7
- package/package.json +4 -4
- package/src/components/DatePicker/DatePicker.mdx +91 -64
- package/src/components/DatePicker/DatePicker.stories.tsx +1 -1
- package/src/components/DatePicker/DatePickerModal.test.tsx +12 -8
- package/src/components/DatePicker/DatePickerModal.tsx +38 -8
- package/src/components/DatePicker/utils/weekdayAsOneLetter.test.ts +1 -2
- package/src/components/DatePicker/utils/weekdayAsOneLetter.ts +2 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 5.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- d1d1631: Allow `<Container>` `elementType` to be a range of HTML element tags; allow `style` prop
|
|
8
|
+
- Updated dependencies [5ab68d0]
|
|
9
|
+
- Updated dependencies [d1d1631]
|
|
10
|
+
- Updated dependencies [6f7a0ea]
|
|
11
|
+
- Updated dependencies [5979683]
|
|
12
|
+
- Updated dependencies [45e9667]
|
|
13
|
+
- @simplybusiness/icons@4.13.0
|
|
14
|
+
- @simplybusiness/mobius@4.16.0
|
|
15
|
+
|
|
16
|
+
## 5.0.0
|
|
17
|
+
|
|
18
|
+
### Major Changes
|
|
19
|
+
|
|
20
|
+
- 93d8a75: Bump react-day-picker to latest; improve accessibility
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- Updated dependencies [de269a5]
|
|
25
|
+
- @simplybusiness/mobius@4.15.1
|
|
26
|
+
|
|
3
27
|
## 4.5.4
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
|
@@ -10,10 +10,10 @@ Object.defineProperty(exports, "default", {
|
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
12
|
const _jsxruntime = require("react/jsx-runtime");
|
|
13
|
-
const _icons = require("@simplybusiness/icons");
|
|
14
13
|
const _mobius = require("@simplybusiness/mobius");
|
|
15
14
|
const _dedupe = /*#__PURE__*/ _interop_require_default(require("classnames/dedupe"));
|
|
16
15
|
const _react = require("react");
|
|
16
|
+
const _icons = require("@simplybusiness/icons");
|
|
17
17
|
const _reactdaypicker = require("react-day-picker");
|
|
18
18
|
const _useFocusTrap = /*#__PURE__*/ _interop_require_default(require("../../hooks/useFocusTrap/useFocusTrap"));
|
|
19
19
|
const _utils = require("./utils");
|
|
@@ -25,12 +25,16 @@ function _interop_require_default(obj) {
|
|
|
25
25
|
}
|
|
26
26
|
var _navigator;
|
|
27
27
|
const PARENT_NODE = typeof document !== "undefined" && document.body;
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
const ChevronComponent = ({ orientation })=>{
|
|
29
|
+
if (orientation === "left") {
|
|
30
|
+
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_mobius.Icon, {
|
|
31
|
+
icon: _icons.chevronLeft
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_mobius.Icon, {
|
|
32
35
|
icon: _icons.chevronRight
|
|
33
36
|
});
|
|
37
|
+
};
|
|
34
38
|
const startWeekday = (0, _getStartWeekday.getStartWeekday)((_navigator = navigator) === null || _navigator === void 0 ? void 0 : _navigator.language);
|
|
35
39
|
const DatePickerModal = ({ date, isOpen, onSelected, top, min, max })=>{
|
|
36
40
|
const modalRef = (0, _react.useRef)(null);
|
|
@@ -75,8 +79,12 @@ const DatePickerModal = ({ date, isOpen, onSelected, top, min, max })=>{
|
|
|
75
79
|
}),
|
|
76
80
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(_reactdaypicker.DayPicker, {
|
|
77
81
|
mode: "single",
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
...minDate && {
|
|
83
|
+
startMonth: minDate
|
|
84
|
+
},
|
|
85
|
+
...maxDate && {
|
|
86
|
+
endMonth: maxDate
|
|
87
|
+
},
|
|
80
88
|
selected: initialDate,
|
|
81
89
|
defaultMonth: initialDate,
|
|
82
90
|
onSelect: handleDayPickerSelect,
|
|
@@ -87,8 +95,30 @@ const DatePickerModal = ({ date, isOpen, onSelected, top, min, max })=>{
|
|
|
87
95
|
formatWeekdayName: _utils.weekdayAsOneLetter
|
|
88
96
|
},
|
|
89
97
|
components: {
|
|
90
|
-
|
|
91
|
-
|
|
98
|
+
Chevron: ChevronComponent
|
|
99
|
+
},
|
|
100
|
+
classNames: {
|
|
101
|
+
root: "mobius/DatePickerRoot",
|
|
102
|
+
months: "mobius/DatePickerMonths",
|
|
103
|
+
month: "mobius/DatePickerMonth",
|
|
104
|
+
nav: "mobius/DatePickerNav",
|
|
105
|
+
button_previous: "mobius/DatePickerNavButton --previous",
|
|
106
|
+
button_next: "mobius/DatePickerNavButton --next",
|
|
107
|
+
month_caption: "mobius/DatePickerCaption",
|
|
108
|
+
caption_label: "mobius/DatePickerCaptionLabel",
|
|
109
|
+
month_grid: "mobius/DatePickerMonthGrid",
|
|
110
|
+
weekdays: "mobius/DatePickerWeekdays",
|
|
111
|
+
weekday: "mobius/DatePickerWeekday",
|
|
112
|
+
weeks: "mobius/DatePickerWeeks",
|
|
113
|
+
week: "mobius/DatePickerWeek",
|
|
114
|
+
day: "mobius/DatePickerDay",
|
|
115
|
+
day_button: "mobius/DatePickerDayButton",
|
|
116
|
+
selected: "--is-selected",
|
|
117
|
+
disabled: "--is-disabled",
|
|
118
|
+
outside: "--is-outside",
|
|
119
|
+
hidden: "--is-hidden",
|
|
120
|
+
today: "--is-today",
|
|
121
|
+
focused: "--is-focused"
|
|
92
122
|
}
|
|
93
123
|
})
|
|
94
124
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/DatePicker/DatePickerModal.tsx"],"sourcesContent":["\"use client\";\n\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/DatePicker/DatePickerModal.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n Icon,\n VisuallyHidden,\n useOnClickOutside,\n} from \"@simplybusiness/mobius\";\nimport classNames from \"classnames/dedupe\";\nimport { useId, useRef } from \"react\";\nimport { chevronLeft, chevronRight } from \"@simplybusiness/icons\";\nimport { DayPicker } from \"react-day-picker\";\nimport FocusTrap from \"../../hooks/useFocusTrap/useFocusTrap\";\nimport { dateObjToString, weekdayAsOneLetter } from \"./utils\";\nimport { getStartWeekday } from \"./utils/getStartWeekday\";\n\nconst PARENT_NODE = typeof document !== \"undefined\" && document.body;\n\nexport type DatePickerModalProps = {\n date?: string; // yyyy-mm-dd\n isOpen: boolean;\n top: number;\n onSelected: (date?: string | undefined) => void;\n min?: string;\n max?: string;\n};\n\nconst ChevronComponent = ({\n orientation,\n}: {\n orientation?: \"up\" | \"down\" | \"left\" | \"right\";\n}) => {\n if (orientation === \"left\") {\n return <Icon icon={chevronLeft} />;\n }\n return <Icon icon={chevronRight} />;\n};\n\nconst startWeekday = getStartWeekday(navigator?.language);\n\nconst DatePickerModal = ({\n date,\n isOpen,\n onSelected,\n top,\n min,\n max,\n}: DatePickerModalProps) => {\n const modalRef = useRef<HTMLDivElement>(null);\n const initialDate = date ? new Date(date) : undefined;\n const minDate = min ? new Date(min) : undefined;\n const maxDate = max ? new Date(max) : undefined;\n const hiddenId = `screen-reader-title-${useId()}`;\n\n if (isOpen && PARENT_NODE) {\n PARENT_NODE?.setAttribute(\"aria-hidden\", \"true\");\n }\n\n const handleSelected = (selectedDate?: string | undefined) => {\n if (PARENT_NODE) PARENT_NODE?.removeAttribute(\"aria-hidden\");\n onSelected(selectedDate);\n };\n\n const handleDayPickerSelect = (selectedDate: Date | undefined) => {\n if (!selectedDate) return;\n\n handleSelected(dateObjToString(selectedDate));\n };\n\n useOnClickOutside(modalRef, () => {\n if (modalRef.current && isOpen) {\n handleSelected();\n }\n });\n\n const modalClasses = classNames(\"mobius/DatePickerModal\", {\n \"--is-open\": isOpen,\n });\n\n return (\n <FocusTrap>\n <div\n ref={modalRef}\n className={modalClasses}\n style={{ top }}\n aria-describedby={hiddenId}\n data-testid=\"modal-container\"\n >\n <VisuallyHidden>\n <div id={hiddenId}>Please select a date from the calendar</div>\n </VisuallyHidden>\n <DayPicker\n mode=\"single\"\n {...(minDate && { startMonth: minDate })}\n {...(maxDate && { endMonth: maxDate })}\n selected={initialDate}\n defaultMonth={initialDate}\n onSelect={handleDayPickerSelect}\n pagedNavigation\n showOutsideDays\n weekStartsOn={startWeekday}\n formatters={{ formatWeekdayName: weekdayAsOneLetter }}\n components={{\n Chevron: ChevronComponent,\n }}\n classNames={{\n root: \"mobius/DatePickerRoot\",\n months: \"mobius/DatePickerMonths\",\n month: \"mobius/DatePickerMonth\",\n nav: \"mobius/DatePickerNav\",\n button_previous: \"mobius/DatePickerNavButton --previous\",\n button_next: \"mobius/DatePickerNavButton --next\",\n month_caption: \"mobius/DatePickerCaption\",\n caption_label: \"mobius/DatePickerCaptionLabel\",\n month_grid: \"mobius/DatePickerMonthGrid\",\n weekdays: \"mobius/DatePickerWeekdays\",\n weekday: \"mobius/DatePickerWeekday\",\n weeks: \"mobius/DatePickerWeeks\",\n week: \"mobius/DatePickerWeek\",\n day: \"mobius/DatePickerDay\",\n day_button: \"mobius/DatePickerDayButton\",\n selected: \"--is-selected\",\n disabled: \"--is-disabled\",\n outside: \"--is-outside\",\n hidden: \"--is-hidden\",\n today: \"--is-today\",\n focused: \"--is-focused\",\n }}\n />\n </div>\n </FocusTrap>\n );\n};\n\nexport default DatePickerModal;\n"],"names":["navigator","PARENT_NODE","document","body","ChevronComponent","orientation","Icon","icon","chevronLeft","chevronRight","startWeekday","getStartWeekday","language","DatePickerModal","date","isOpen","onSelected","top","min","max","modalRef","useRef","initialDate","Date","undefined","minDate","maxDate","hiddenId","useId","setAttribute","handleSelected","selectedDate","removeAttribute","handleDayPickerSelect","dateObjToString","useOnClickOutside","current","modalClasses","classNames","FocusTrap","div","ref","className","style","aria-describedby","data-testid","VisuallyHidden","id","DayPicker","mode","startMonth","endMonth","selected","defaultMonth","onSelect","pagedNavigation","showOutsideDays","weekStartsOn","formatters","formatWeekdayName","weekdayAsOneLetter","components","Chevron","root","months","month","nav","button_previous","button_next","month_caption","caption_label","month_grid","weekdays","weekday","weeks","week","day","day_button","disabled","outside","hidden","today","focused"],"mappings":"AAAA;;;;;+BAqIA;;;eAAA;;;;wBA/HO;+DACgB;uBACO;uBACY;gCAChB;qEACJ;uBAC8B;iCACpB;;;;;;IAwBKA;AAtBrC,MAAMC,cAAc,OAAOC,aAAa,eAAeA,SAASC,IAAI;AAWpE,MAAMC,mBAAmB,CAAC,EACxBC,WAAW,EAGZ;IACC,IAAIA,gBAAgB,QAAQ;QAC1B,qBAAO,qBAACC,YAAI;YAACC,MAAMC,kBAAW;;IAChC;IACA,qBAAO,qBAACF,YAAI;QAACC,MAAME,mBAAY;;AACjC;AAEA,MAAMC,eAAeC,IAAAA,gCAAe,GAACX,aAAAA,uBAAAA,iCAAAA,WAAWY,QAAQ;AAExD,MAAMC,kBAAkB,CAAC,EACvBC,IAAI,EACJC,MAAM,EACNC,UAAU,EACVC,GAAG,EACHC,GAAG,EACHC,GAAG,EACkB;IACrB,MAAMC,WAAWC,IAAAA,aAAM,EAAiB;IACxC,MAAMC,cAAcR,OAAO,IAAIS,KAAKT,QAAQU;IAC5C,MAAMC,UAAUP,MAAM,IAAIK,KAAKL,OAAOM;IACtC,MAAME,UAAUP,MAAM,IAAII,KAAKJ,OAAOK;IACtC,MAAMG,WAAW,CAAC,oBAAoB,EAAEC,IAAAA,YAAK,IAAG,CAAC;IAEjD,IAAIb,UAAUd,aAAa;QACzBA,wBAAAA,kCAAAA,YAAa4B,YAAY,CAAC,eAAe;IAC3C;IAEA,MAAMC,iBAAiB,CAACC;QACtB,IAAI9B,aAAaA,wBAAAA,kCAAAA,YAAa+B,eAAe,CAAC;QAC9ChB,WAAWe;IACb;IAEA,MAAME,wBAAwB,CAACF;QAC7B,IAAI,CAACA,cAAc;QAEnBD,eAAeI,IAAAA,sBAAe,EAACH;IACjC;IAEAI,IAAAA,yBAAiB,EAACf,UAAU;QAC1B,IAAIA,SAASgB,OAAO,IAAIrB,QAAQ;YAC9Be;QACF;IACF;IAEA,MAAMO,eAAeC,IAAAA,eAAU,EAAC,0BAA0B;QACxD,aAAavB;IACf;IAEA,qBACE,qBAACwB,qBAAS;kBACR,cAAA,sBAACC;YACCC,KAAKrB;YACLsB,WAAWL;YACXM,OAAO;gBAAE1B;YAAI;YACb2B,oBAAkBjB;YAClBkB,eAAY;;8BAEZ,qBAACC,sBAAc;8BACb,cAAA,qBAACN;wBAAIO,IAAIpB;kCAAU;;;8BAErB,qBAACqB,yBAAS;oBACRC,MAAK;oBACJ,GAAIxB,WAAW;wBAAEyB,YAAYzB;oBAAQ,CAAC;oBACtC,GAAIC,WAAW;wBAAEyB,UAAUzB;oBAAQ,CAAC;oBACrC0B,UAAU9B;oBACV+B,cAAc/B;oBACdgC,UAAUrB;oBACVsB,eAAe;oBACfC,eAAe;oBACfC,cAAc/C;oBACdgD,YAAY;wBAAEC,mBAAmBC,yBAAkB;oBAAC;oBACpDC,YAAY;wBACVC,SAAS1D;oBACX;oBACAkC,YAAY;wBACVyB,MAAM;wBACNC,QAAQ;wBACRC,OAAO;wBACPC,KAAK;wBACLC,iBAAiB;wBACjBC,aAAa;wBACbC,eAAe;wBACfC,eAAe;wBACfC,YAAY;wBACZC,UAAU;wBACVC,SAAS;wBACTC,OAAO;wBACPC,MAAM;wBACNC,KAAK;wBACLC,YAAY;wBACZzB,UAAU;wBACV0B,UAAU;wBACVC,SAAS;wBACTC,QAAQ;wBACRC,OAAO;wBACPC,SAAS;oBACX;;;;;AAKV;MAEA,WAAerE"}
|
|
@@ -9,9 +9,8 @@ Object.defineProperty(exports, "weekdayAsOneLetter", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
const _constants = require("../constants");
|
|
12
|
-
const weekdayAsOneLetter = (date
|
|
13
|
-
|
|
14
|
-
const locale = (options === null || options === void 0 ? void 0 : (_options_locale = options.locale) === null || _options_locale === void 0 ? void 0 : _options_locale.code) || _constants.DEFAULT_LOCALE;
|
|
12
|
+
const weekdayAsOneLetter = (date)=>{
|
|
13
|
+
const locale = navigator.language || _constants.DEFAULT_LOCALE;
|
|
15
14
|
const oneLetter = date.toLocaleString(locale, {
|
|
16
15
|
weekday: "narrow"
|
|
17
16
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/components/DatePicker/utils/weekdayAsOneLetter.ts"],"sourcesContent":["import { DEFAULT_LOCALE } from \"../constants\";\n\
|
|
1
|
+
{"version":3,"sources":["../../../../../src/components/DatePicker/utils/weekdayAsOneLetter.ts"],"sourcesContent":["import { DEFAULT_LOCALE } from \"../constants\";\n\nexport const weekdayAsOneLetter = (date: Date) => {\n const locale = navigator.language || DEFAULT_LOCALE;\n const oneLetter = date.toLocaleString(locale, {\n weekday: \"narrow\",\n });\n\n return oneLetter;\n};\n"],"names":["weekdayAsOneLetter","date","locale","navigator","language","DEFAULT_LOCALE","oneLetter","toLocaleString","weekday"],"mappings":";;;;+BAEaA;;;eAAAA;;;2BAFkB;AAExB,MAAMA,qBAAqB,CAACC;IACjC,MAAMC,SAASC,UAAUC,QAAQ,IAAIC,yBAAc;IACnD,MAAMC,YAAYL,KAAKM,cAAc,CAACL,QAAQ;QAC5CM,SAAS;IACX;IAEA,OAAOF;AACT"}
|
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
var _navigator;
|
|
3
3
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
4
|
-
import { chevronLeft, chevronRight } from "@simplybusiness/icons";
|
|
5
4
|
import { Icon, VisuallyHidden, useOnClickOutside } from "@simplybusiness/mobius";
|
|
6
5
|
import classNames from "classnames/dedupe";
|
|
7
6
|
import { useId, useRef } from "react";
|
|
7
|
+
import { chevronLeft, chevronRight } from "@simplybusiness/icons";
|
|
8
8
|
import { DayPicker } from "react-day-picker";
|
|
9
9
|
import FocusTrap from "../../hooks/useFocusTrap/useFocusTrap";
|
|
10
10
|
import { dateObjToString, weekdayAsOneLetter } from "./utils";
|
|
11
11
|
import { getStartWeekday } from "./utils/getStartWeekday";
|
|
12
12
|
const PARENT_NODE = typeof document !== "undefined" && document.body;
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
const ChevronComponent = ({ orientation })=>{
|
|
14
|
+
if (orientation === "left") {
|
|
15
|
+
return /*#__PURE__*/ _jsx(Icon, {
|
|
16
|
+
icon: chevronLeft
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
return /*#__PURE__*/ _jsx(Icon, {
|
|
17
20
|
icon: chevronRight
|
|
18
21
|
});
|
|
22
|
+
};
|
|
19
23
|
const startWeekday = getStartWeekday((_navigator = navigator) === null || _navigator === void 0 ? void 0 : _navigator.language);
|
|
20
24
|
const DatePickerModal = ({ date, isOpen, onSelected, top, min, max })=>{
|
|
21
25
|
const modalRef = useRef(null);
|
|
@@ -60,8 +64,12 @@ const DatePickerModal = ({ date, isOpen, onSelected, top, min, max })=>{
|
|
|
60
64
|
}),
|
|
61
65
|
/*#__PURE__*/ _jsx(DayPicker, {
|
|
62
66
|
mode: "single",
|
|
63
|
-
|
|
64
|
-
|
|
67
|
+
...minDate && {
|
|
68
|
+
startMonth: minDate
|
|
69
|
+
},
|
|
70
|
+
...maxDate && {
|
|
71
|
+
endMonth: maxDate
|
|
72
|
+
},
|
|
65
73
|
selected: initialDate,
|
|
66
74
|
defaultMonth: initialDate,
|
|
67
75
|
onSelect: handleDayPickerSelect,
|
|
@@ -72,8 +80,30 @@ const DatePickerModal = ({ date, isOpen, onSelected, top, min, max })=>{
|
|
|
72
80
|
formatWeekdayName: weekdayAsOneLetter
|
|
73
81
|
},
|
|
74
82
|
components: {
|
|
75
|
-
|
|
76
|
-
|
|
83
|
+
Chevron: ChevronComponent
|
|
84
|
+
},
|
|
85
|
+
classNames: {
|
|
86
|
+
root: "mobius/DatePickerRoot",
|
|
87
|
+
months: "mobius/DatePickerMonths",
|
|
88
|
+
month: "mobius/DatePickerMonth",
|
|
89
|
+
nav: "mobius/DatePickerNav",
|
|
90
|
+
button_previous: "mobius/DatePickerNavButton --previous",
|
|
91
|
+
button_next: "mobius/DatePickerNavButton --next",
|
|
92
|
+
month_caption: "mobius/DatePickerCaption",
|
|
93
|
+
caption_label: "mobius/DatePickerCaptionLabel",
|
|
94
|
+
month_grid: "mobius/DatePickerMonthGrid",
|
|
95
|
+
weekdays: "mobius/DatePickerWeekdays",
|
|
96
|
+
weekday: "mobius/DatePickerWeekday",
|
|
97
|
+
weeks: "mobius/DatePickerWeeks",
|
|
98
|
+
week: "mobius/DatePickerWeek",
|
|
99
|
+
day: "mobius/DatePickerDay",
|
|
100
|
+
day_button: "mobius/DatePickerDayButton",
|
|
101
|
+
selected: "--is-selected",
|
|
102
|
+
disabled: "--is-disabled",
|
|
103
|
+
outside: "--is-outside",
|
|
104
|
+
hidden: "--is-hidden",
|
|
105
|
+
today: "--is-today",
|
|
106
|
+
focused: "--is-focused"
|
|
77
107
|
}
|
|
78
108
|
})
|
|
79
109
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/DatePicker/DatePickerModal.tsx"],"sourcesContent":["\"use client\";\n\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/DatePicker/DatePickerModal.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n Icon,\n VisuallyHidden,\n useOnClickOutside,\n} from \"@simplybusiness/mobius\";\nimport classNames from \"classnames/dedupe\";\nimport { useId, useRef } from \"react\";\nimport { chevronLeft, chevronRight } from \"@simplybusiness/icons\";\nimport { DayPicker } from \"react-day-picker\";\nimport FocusTrap from \"../../hooks/useFocusTrap/useFocusTrap\";\nimport { dateObjToString, weekdayAsOneLetter } from \"./utils\";\nimport { getStartWeekday } from \"./utils/getStartWeekday\";\n\nconst PARENT_NODE = typeof document !== \"undefined\" && document.body;\n\nexport type DatePickerModalProps = {\n date?: string; // yyyy-mm-dd\n isOpen: boolean;\n top: number;\n onSelected: (date?: string | undefined) => void;\n min?: string;\n max?: string;\n};\n\nconst ChevronComponent = ({\n orientation,\n}: {\n orientation?: \"up\" | \"down\" | \"left\" | \"right\";\n}) => {\n if (orientation === \"left\") {\n return <Icon icon={chevronLeft} />;\n }\n return <Icon icon={chevronRight} />;\n};\n\nconst startWeekday = getStartWeekday(navigator?.language);\n\nconst DatePickerModal = ({\n date,\n isOpen,\n onSelected,\n top,\n min,\n max,\n}: DatePickerModalProps) => {\n const modalRef = useRef<HTMLDivElement>(null);\n const initialDate = date ? new Date(date) : undefined;\n const minDate = min ? new Date(min) : undefined;\n const maxDate = max ? new Date(max) : undefined;\n const hiddenId = `screen-reader-title-${useId()}`;\n\n if (isOpen && PARENT_NODE) {\n PARENT_NODE?.setAttribute(\"aria-hidden\", \"true\");\n }\n\n const handleSelected = (selectedDate?: string | undefined) => {\n if (PARENT_NODE) PARENT_NODE?.removeAttribute(\"aria-hidden\");\n onSelected(selectedDate);\n };\n\n const handleDayPickerSelect = (selectedDate: Date | undefined) => {\n if (!selectedDate) return;\n\n handleSelected(dateObjToString(selectedDate));\n };\n\n useOnClickOutside(modalRef, () => {\n if (modalRef.current && isOpen) {\n handleSelected();\n }\n });\n\n const modalClasses = classNames(\"mobius/DatePickerModal\", {\n \"--is-open\": isOpen,\n });\n\n return (\n <FocusTrap>\n <div\n ref={modalRef}\n className={modalClasses}\n style={{ top }}\n aria-describedby={hiddenId}\n data-testid=\"modal-container\"\n >\n <VisuallyHidden>\n <div id={hiddenId}>Please select a date from the calendar</div>\n </VisuallyHidden>\n <DayPicker\n mode=\"single\"\n {...(minDate && { startMonth: minDate })}\n {...(maxDate && { endMonth: maxDate })}\n selected={initialDate}\n defaultMonth={initialDate}\n onSelect={handleDayPickerSelect}\n pagedNavigation\n showOutsideDays\n weekStartsOn={startWeekday}\n formatters={{ formatWeekdayName: weekdayAsOneLetter }}\n components={{\n Chevron: ChevronComponent,\n }}\n classNames={{\n root: \"mobius/DatePickerRoot\",\n months: \"mobius/DatePickerMonths\",\n month: \"mobius/DatePickerMonth\",\n nav: \"mobius/DatePickerNav\",\n button_previous: \"mobius/DatePickerNavButton --previous\",\n button_next: \"mobius/DatePickerNavButton --next\",\n month_caption: \"mobius/DatePickerCaption\",\n caption_label: \"mobius/DatePickerCaptionLabel\",\n month_grid: \"mobius/DatePickerMonthGrid\",\n weekdays: \"mobius/DatePickerWeekdays\",\n weekday: \"mobius/DatePickerWeekday\",\n weeks: \"mobius/DatePickerWeeks\",\n week: \"mobius/DatePickerWeek\",\n day: \"mobius/DatePickerDay\",\n day_button: \"mobius/DatePickerDayButton\",\n selected: \"--is-selected\",\n disabled: \"--is-disabled\",\n outside: \"--is-outside\",\n hidden: \"--is-hidden\",\n today: \"--is-today\",\n focused: \"--is-focused\",\n }}\n />\n </div>\n </FocusTrap>\n );\n};\n\nexport default DatePickerModal;\n"],"names":["navigator","Icon","VisuallyHidden","useOnClickOutside","classNames","useId","useRef","chevronLeft","chevronRight","DayPicker","FocusTrap","dateObjToString","weekdayAsOneLetter","getStartWeekday","PARENT_NODE","document","body","ChevronComponent","orientation","icon","startWeekday","language","DatePickerModal","date","isOpen","onSelected","top","min","max","modalRef","initialDate","Date","undefined","minDate","maxDate","hiddenId","setAttribute","handleSelected","selectedDate","removeAttribute","handleDayPickerSelect","current","modalClasses","div","ref","className","style","aria-describedby","data-testid","id","mode","startMonth","endMonth","selected","defaultMonth","onSelect","pagedNavigation","showOutsideDays","weekStartsOn","formatters","formatWeekdayName","components","Chevron","root","months","month","nav","button_previous","button_next","month_caption","caption_label","month_grid","weekdays","weekday","weeks","week","day","day_button","disabled","outside","hidden","today","focused"],"mappings":"AAAA;IAqCqCA;;AAnCrC,SACEC,IAAI,EACJC,cAAc,EACdC,iBAAiB,QACZ,yBAAyB;AAChC,OAAOC,gBAAgB,oBAAoB;AAC3C,SAASC,KAAK,EAAEC,MAAM,QAAQ,QAAQ;AACtC,SAASC,WAAW,EAAEC,YAAY,QAAQ,wBAAwB;AAClE,SAASC,SAAS,QAAQ,mBAAmB;AAC7C,OAAOC,eAAe,wCAAwC;AAC9D,SAASC,eAAe,EAAEC,kBAAkB,QAAQ,UAAU;AAC9D,SAASC,eAAe,QAAQ,0BAA0B;AAE1D,MAAMC,cAAc,OAAOC,aAAa,eAAeA,SAASC,IAAI;AAWpE,MAAMC,mBAAmB,CAAC,EACxBC,WAAW,EAGZ;IACC,IAAIA,gBAAgB,QAAQ;QAC1B,qBAAO,KAACjB;YAAKkB,MAAMZ;;IACrB;IACA,qBAAO,KAACN;QAAKkB,MAAMX;;AACrB;AAEA,MAAMY,eAAeP,iBAAgBb,aAAAA,uBAAAA,iCAAAA,WAAWqB,QAAQ;AAExD,MAAMC,kBAAkB,CAAC,EACvBC,IAAI,EACJC,MAAM,EACNC,UAAU,EACVC,GAAG,EACHC,GAAG,EACHC,GAAG,EACkB;IACrB,MAAMC,WAAWvB,OAAuB;IACxC,MAAMwB,cAAcP,OAAO,IAAIQ,KAAKR,QAAQS;IAC5C,MAAMC,UAAUN,MAAM,IAAII,KAAKJ,OAAOK;IACtC,MAAME,UAAUN,MAAM,IAAIG,KAAKH,OAAOI;IACtC,MAAMG,WAAW,CAAC,oBAAoB,EAAE9B,QAAQ,CAAC;IAEjD,IAAImB,UAAUV,aAAa;QACzBA,wBAAAA,kCAAAA,YAAasB,YAAY,CAAC,eAAe;IAC3C;IAEA,MAAMC,iBAAiB,CAACC;QACtB,IAAIxB,aAAaA,wBAAAA,kCAAAA,YAAayB,eAAe,CAAC;QAC9Cd,WAAWa;IACb;IAEA,MAAME,wBAAwB,CAACF;QAC7B,IAAI,CAACA,cAAc;QAEnBD,eAAe1B,gBAAgB2B;IACjC;IAEAnC,kBAAkB0B,UAAU;QAC1B,IAAIA,SAASY,OAAO,IAAIjB,QAAQ;YAC9Ba;QACF;IACF;IAEA,MAAMK,eAAetC,WAAW,0BAA0B;QACxD,aAAaoB;IACf;IAEA,qBACE,KAACd;kBACC,cAAA,MAACiC;YACCC,KAAKf;YACLgB,WAAWH;YACXI,OAAO;gBAAEpB;YAAI;YACbqB,oBAAkBZ;YAClBa,eAAY;;8BAEZ,KAAC9C;8BACC,cAAA,KAACyC;wBAAIM,IAAId;kCAAU;;;8BAErB,KAAC1B;oBACCyC,MAAK;oBACJ,GAAIjB,WAAW;wBAAEkB,YAAYlB;oBAAQ,CAAC;oBACtC,GAAIC,WAAW;wBAAEkB,UAAUlB;oBAAQ,CAAC;oBACrCmB,UAAUvB;oBACVwB,cAAcxB;oBACdyB,UAAUf;oBACVgB,eAAe;oBACfC,eAAe;oBACfC,cAActC;oBACduC,YAAY;wBAAEC,mBAAmBhD;oBAAmB;oBACpDiD,YAAY;wBACVC,SAAS7C;oBACX;oBACAb,YAAY;wBACV2D,MAAM;wBACNC,QAAQ;wBACRC,OAAO;wBACPC,KAAK;wBACLC,iBAAiB;wBACjBC,aAAa;wBACbC,eAAe;wBACfC,eAAe;wBACfC,YAAY;wBACZC,UAAU;wBACVC,SAAS;wBACTC,OAAO;wBACPC,MAAM;wBACNC,KAAK;wBACLC,YAAY;wBACZxB,UAAU;wBACVyB,UAAU;wBACVC,SAAS;wBACTC,QAAQ;wBACRC,OAAO;wBACPC,SAAS;oBACX;;;;;AAKV;AAEA,eAAe5D,gBAAgB"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_LOCALE } from "../constants";
|
|
2
|
-
export const weekdayAsOneLetter = (date
|
|
3
|
-
|
|
4
|
-
const locale = (options === null || options === void 0 ? void 0 : (_options_locale = options.locale) === null || _options_locale === void 0 ? void 0 : _options_locale.code) || DEFAULT_LOCALE;
|
|
2
|
+
export const weekdayAsOneLetter = (date)=>{
|
|
3
|
+
const locale = navigator.language || DEFAULT_LOCALE;
|
|
5
4
|
const oneLetter = date.toLocaleString(locale, {
|
|
6
5
|
weekday: "narrow"
|
|
7
6
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/components/DatePicker/utils/weekdayAsOneLetter.ts"],"sourcesContent":["import { DEFAULT_LOCALE } from \"../constants\";\n\
|
|
1
|
+
{"version":3,"sources":["../../../../../src/components/DatePicker/utils/weekdayAsOneLetter.ts"],"sourcesContent":["import { DEFAULT_LOCALE } from \"../constants\";\n\nexport const weekdayAsOneLetter = (date: Date) => {\n const locale = navigator.language || DEFAULT_LOCALE;\n const oneLetter = date.toLocaleString(locale, {\n weekday: \"narrow\",\n });\n\n return oneLetter;\n};\n"],"names":["DEFAULT_LOCALE","weekdayAsOneLetter","date","locale","navigator","language","oneLetter","toLocaleString","weekday"],"mappings":"AAAA,SAASA,cAAc,QAAQ,eAAe;AAE9C,OAAO,MAAMC,qBAAqB,CAACC;IACjC,MAAMC,SAASC,UAAUC,QAAQ,IAAIL;IACrC,MAAMM,YAAYJ,KAAKK,cAAc,CAACJ,QAAQ;QAC5CK,SAAS;IACX;IAEA,OAAOF;AACT,EAAE"}
|
|
@@ -2,7 +2,7 @@ import type { Meta, StoryObj } from "@storybook/react";
|
|
|
2
2
|
import { DatePicker } from "./DatePicker";
|
|
3
3
|
type StoryType = StoryObj<typeof DatePicker>;
|
|
4
4
|
declare const meta: Meta<typeof DatePicker>;
|
|
5
|
-
export declare const
|
|
5
|
+
export declare const Default: StoryType;
|
|
6
6
|
export declare const WithMinValue: StoryType;
|
|
7
7
|
export declare const WithMaxValue: StoryType;
|
|
8
8
|
export declare const Disabled: StoryType;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplybusiness/mobius-datepicker",
|
|
3
3
|
"license": "UNLICENSED",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "5.0.1",
|
|
5
5
|
"description": "Mobius date picker component",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -74,11 +74,11 @@
|
|
|
74
74
|
"react-dom": "^18.2.0"
|
|
75
75
|
},
|
|
76
76
|
"dependencies": {
|
|
77
|
-
"@simplybusiness/icons": "^4.
|
|
78
|
-
"@simplybusiness/mobius": "^4.
|
|
77
|
+
"@simplybusiness/icons": "^4.13.0",
|
|
78
|
+
"@simplybusiness/mobius": "^4.16.0",
|
|
79
79
|
"classnames": "^2.5.1",
|
|
80
80
|
"date-fns": "^3.6.0",
|
|
81
|
-
"react-day-picker": "^
|
|
81
|
+
"react-day-picker": "^9.0.6"
|
|
82
82
|
},
|
|
83
83
|
"lint-staged": {
|
|
84
84
|
"*.{js,ts,jsx,tsx}": "eslint --ext .tsx,.ts,.js,.jsx,.mjs --fix"
|
|
@@ -28,9 +28,9 @@ import { DatePicker } from "@simplybusiness/mobius-datepicker";
|
|
|
28
28
|
|
|
29
29
|
## Examples
|
|
30
30
|
|
|
31
|
-
###
|
|
31
|
+
### Default
|
|
32
32
|
|
|
33
|
-
<Story of={DatePickerStories.
|
|
33
|
+
<Story of={DatePickerStories.Default} />
|
|
34
34
|
|
|
35
35
|
{/* prettier-ignore */}
|
|
36
36
|
```jsx
|
|
@@ -74,72 +74,99 @@ The following HTML is rendered for a DatePicker:
|
|
|
74
74
|
|
|
75
75
|
```html
|
|
76
76
|
<div class="mobius/DatePickerContainer">
|
|
77
|
-
<div class="mobius
|
|
78
|
-
<label class="mobius
|
|
79
|
-
<div class="mobius/
|
|
80
|
-
<
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
77
|
+
<div class="mobius/DatePicker">
|
|
78
|
+
<label class="mobius/Label">Start date</label>
|
|
79
|
+
<div class="mobius/TextFieldInnerContainer">
|
|
80
|
+
<div class="mobius/DatePicker">
|
|
81
|
+
<input type="date" class="mobius/DatePicker" />
|
|
82
|
+
</div>
|
|
83
|
+
<button class="mobius/DateFieldButton">
|
|
84
|
+
<svg class="mobius/Icon">
|
|
85
|
+
<title>Calendar day icon</title>
|
|
86
|
+
...
|
|
87
|
+
</svg>
|
|
88
|
+
<div>Pick date</div>
|
|
89
|
+
</button>
|
|
85
90
|
</div>
|
|
86
91
|
</div>
|
|
87
|
-
<
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
<
|
|
102
|
-
|
|
103
|
-
class="rdp-nav_button_previous"
|
|
104
|
-
></button
|
|
105
|
-
><button
|
|
106
|
-
aria-label="Go to next month"
|
|
107
|
-
class="rdp-nav_button_next"
|
|
108
|
-
></button>
|
|
109
|
-
</div>
|
|
110
|
-
</div>
|
|
111
|
-
<table class="rdp-table">
|
|
112
|
-
<thead class="rdp-head">
|
|
113
|
-
<tr class="rdp-head_row">
|
|
114
|
-
<th class="rdp-head_cell" aria-label="Monday">M</th>
|
|
115
|
-
<th class="rdp-head_cell" aria-label="Tuesday">T</th>
|
|
116
|
-
<th class="rdp-head_cell" aria-label="Wednesday">W</th>
|
|
117
|
-
<th class="rdp-head_cell" aria-label="Thursday">T</th>
|
|
118
|
-
<th class="rdp-head_cell" aria-label="Friday">F</th>
|
|
119
|
-
<th class="rdp-head_cell" aria-label="Saturday">S</th>
|
|
120
|
-
<th class="rdp-head_cell" aria-label="Sunday">S</th>
|
|
121
|
-
</tr>
|
|
122
|
-
</thead>
|
|
123
|
-
<tbody class="rdp-tbody">
|
|
124
|
-
<tr class="rdp-row">
|
|
125
|
-
<td class="rdp-cell" role="presentation">
|
|
126
|
-
<button name="day" class="rdp-day_outside" tabindex="-1">
|
|
127
|
-
30
|
|
128
|
-
</button>
|
|
129
|
-
</td>
|
|
92
|
+
<div class="trap">
|
|
93
|
+
<div class="mobius/DatePickerModal --is-open">
|
|
94
|
+
<div>
|
|
95
|
+
<div id="screen-reader-title-:rs:">
|
|
96
|
+
Please select a date from the calendar
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
<div class="mobius/DatePickerRoot" data-mode="single">
|
|
100
|
+
<div class="mobius/DatePickerMonths">
|
|
101
|
+
<nav role="navigation" class="mobius/DatePickerNav">
|
|
102
|
+
<button
|
|
103
|
+
class="mobius/DatePickerNavButton --previous"
|
|
104
|
+
aria-label="Go to the Previous Month"
|
|
105
|
+
>
|
|
106
|
+
<svg class="mobius/Icon">
|
|
107
|
+
<title>Chevron left icon</title>
|
|
130
108
|
...
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
109
|
+
</svg>
|
|
110
|
+
</button>
|
|
111
|
+
<button
|
|
112
|
+
class="mobius/DatePickerNavButton --next"
|
|
113
|
+
aria-label="Go to the Next Month"
|
|
114
|
+
>
|
|
115
|
+
<svg class="mobius/Icon">
|
|
116
|
+
<title>Chevron right icon</title>
|
|
134
117
|
...
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
118
|
+
</svg>
|
|
119
|
+
</button>
|
|
120
|
+
</nav>
|
|
121
|
+
<div class="mobius/DatePickerMonth">
|
|
122
|
+
<div class="mobius/DatePickerCaption">
|
|
123
|
+
<span
|
|
124
|
+
class="mobius/DatePickerCaptionLabel"
|
|
125
|
+
role="status"
|
|
126
|
+
aria-live="polite"
|
|
127
|
+
>August 2024</span
|
|
128
|
+
>
|
|
129
|
+
</div>
|
|
130
|
+
<table
|
|
131
|
+
role="grid"
|
|
132
|
+
aria-multiselectable="false"
|
|
133
|
+
aria-label="August 2024"
|
|
134
|
+
class="mobius/DatePickerMonthGrid"
|
|
135
|
+
>
|
|
136
|
+
<thead>
|
|
137
|
+
<tr class="mobius/DatePickerWeekdays" role="row">
|
|
138
|
+
<th
|
|
139
|
+
aria-label="Monday"
|
|
140
|
+
class="mobius/DatePickerWeekday"
|
|
141
|
+
role="columnheader"
|
|
142
|
+
>
|
|
143
|
+
M
|
|
144
|
+
</th>
|
|
145
|
+
...
|
|
146
|
+
</tr>
|
|
147
|
+
</thead>
|
|
148
|
+
<tbody class="mobius/DatePickerWeeks" role="rowgroup">
|
|
149
|
+
<tr class="mobius/DatePickerWeek" role="row">
|
|
150
|
+
<td
|
|
151
|
+
role="gridcell"
|
|
152
|
+
class="mobius/DatePickerDay --is-outside"
|
|
153
|
+
data-day="2024-07-29"
|
|
154
|
+
data-month="2024-07"
|
|
155
|
+
data-outside="true"
|
|
156
|
+
>
|
|
157
|
+
<button
|
|
158
|
+
class="mobius/DatePickerDayButton"
|
|
159
|
+
tabindex="-1"
|
|
160
|
+
aria-label="Monday, July 29th, 2024"
|
|
161
|
+
>
|
|
162
|
+
29
|
|
163
|
+
</button>
|
|
164
|
+
</td>
|
|
165
|
+
...
|
|
166
|
+
</tr>
|
|
167
|
+
</tbody>
|
|
168
|
+
</table>
|
|
169
|
+
</div>
|
|
143
170
|
</div>
|
|
144
171
|
</div>
|
|
145
172
|
</div>
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { render, screen } from "@testing-library/react";
|
|
2
2
|
import { userEvent } from "@testing-library/user-event";
|
|
3
|
+
import { format } from "date-fns";
|
|
3
4
|
import { useState } from "react";
|
|
4
5
|
import DatePickerModal from "./DatePickerModal";
|
|
5
6
|
|
|
7
|
+
const TODAY_CLASS_NAME = "--is-today";
|
|
8
|
+
const SELECTED_CLASS_NAME = "--is-selected";
|
|
9
|
+
|
|
6
10
|
const getYear = (date: Date) =>
|
|
7
11
|
date.toLocaleString("en-GB", {
|
|
8
12
|
year: "numeric",
|
|
@@ -32,7 +36,7 @@ describe("DatePickerModal", () => {
|
|
|
32
36
|
|
|
33
37
|
const modal = screen.getByTestId("modal-container");
|
|
34
38
|
const label = screen.getByText(`${getMonth(date)} ${getYear(date)}`);
|
|
35
|
-
const today = container.getElementsByClassName(
|
|
39
|
+
const today = container.getElementsByClassName(TODAY_CLASS_NAME);
|
|
36
40
|
|
|
37
41
|
const day = today[0];
|
|
38
42
|
|
|
@@ -50,7 +54,7 @@ describe("DatePickerModal", () => {
|
|
|
50
54
|
|
|
51
55
|
const modal = screen.getByTestId("modal-container");
|
|
52
56
|
const label = screen.getByText(`${getMonth(date)} ${getYear(date)}`);
|
|
53
|
-
const today = container.getElementsByClassName(
|
|
57
|
+
const today = container.getElementsByClassName(TODAY_CLASS_NAME);
|
|
54
58
|
|
|
55
59
|
const day = today[0];
|
|
56
60
|
|
|
@@ -72,14 +76,14 @@ describe("DatePickerModal", () => {
|
|
|
72
76
|
it("calls onSelected when a day is picked", async () => {
|
|
73
77
|
const onSelected = jest.fn();
|
|
74
78
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
);
|
|
79
|
+
render(<DatePickerModal isOpen top={30} onSelected={onSelected} />);
|
|
80
|
+
|
|
81
|
+
const todayFormatted = format(new Date(), "EEEE, MMMM do, yyyy");
|
|
78
82
|
|
|
79
|
-
const today =
|
|
83
|
+
const today = screen.getByLabelText(`Today, ${todayFormatted}`);
|
|
80
84
|
const dateToday = new Date().toISOString().split("T")[0];
|
|
81
85
|
|
|
82
|
-
await userEvent.click(today
|
|
86
|
+
await userEvent.click(today);
|
|
83
87
|
|
|
84
88
|
expect(onSelected).toHaveBeenCalled();
|
|
85
89
|
expect(onSelected).toHaveBeenCalledWith(dateToday);
|
|
@@ -93,7 +97,7 @@ describe("DatePickerModal", () => {
|
|
|
93
97
|
<DatePickerModal isOpen top={30} date={date} onSelected={onSelected} />,
|
|
94
98
|
);
|
|
95
99
|
|
|
96
|
-
const day = container.getElementsByClassName(
|
|
100
|
+
const day = container.getElementsByClassName(SELECTED_CLASS_NAME);
|
|
97
101
|
|
|
98
102
|
await userEvent.click(day[0]);
|
|
99
103
|
expect(day[0]).toHaveTextContent("31");
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { chevronLeft, chevronRight } from "@simplybusiness/icons";
|
|
4
3
|
import {
|
|
5
4
|
Icon,
|
|
6
5
|
VisuallyHidden,
|
|
@@ -8,6 +7,7 @@ import {
|
|
|
8
7
|
} from "@simplybusiness/mobius";
|
|
9
8
|
import classNames from "classnames/dedupe";
|
|
10
9
|
import { useId, useRef } from "react";
|
|
10
|
+
import { chevronLeft, chevronRight } from "@simplybusiness/icons";
|
|
11
11
|
import { DayPicker } from "react-day-picker";
|
|
12
12
|
import FocusTrap from "../../hooks/useFocusTrap/useFocusTrap";
|
|
13
13
|
import { dateObjToString, weekdayAsOneLetter } from "./utils";
|
|
@@ -15,9 +15,6 @@ import { getStartWeekday } from "./utils/getStartWeekday";
|
|
|
15
15
|
|
|
16
16
|
const PARENT_NODE = typeof document !== "undefined" && document.body;
|
|
17
17
|
|
|
18
|
-
const IconLeft = () => <Icon icon={chevronLeft} />;
|
|
19
|
-
const IconRight = () => <Icon icon={chevronRight} />;
|
|
20
|
-
|
|
21
18
|
export type DatePickerModalProps = {
|
|
22
19
|
date?: string; // yyyy-mm-dd
|
|
23
20
|
isOpen: boolean;
|
|
@@ -27,6 +24,17 @@ export type DatePickerModalProps = {
|
|
|
27
24
|
max?: string;
|
|
28
25
|
};
|
|
29
26
|
|
|
27
|
+
const ChevronComponent = ({
|
|
28
|
+
orientation,
|
|
29
|
+
}: {
|
|
30
|
+
orientation?: "up" | "down" | "left" | "right";
|
|
31
|
+
}) => {
|
|
32
|
+
if (orientation === "left") {
|
|
33
|
+
return <Icon icon={chevronLeft} />;
|
|
34
|
+
}
|
|
35
|
+
return <Icon icon={chevronRight} />;
|
|
36
|
+
};
|
|
37
|
+
|
|
30
38
|
const startWeekday = getStartWeekday(navigator?.language);
|
|
31
39
|
|
|
32
40
|
const DatePickerModal = ({
|
|
@@ -82,8 +90,8 @@ const DatePickerModal = ({
|
|
|
82
90
|
</VisuallyHidden>
|
|
83
91
|
<DayPicker
|
|
84
92
|
mode="single"
|
|
85
|
-
|
|
86
|
-
|
|
93
|
+
{...(minDate && { startMonth: minDate })}
|
|
94
|
+
{...(maxDate && { endMonth: maxDate })}
|
|
87
95
|
selected={initialDate}
|
|
88
96
|
defaultMonth={initialDate}
|
|
89
97
|
onSelect={handleDayPickerSelect}
|
|
@@ -92,8 +100,30 @@ const DatePickerModal = ({
|
|
|
92
100
|
weekStartsOn={startWeekday}
|
|
93
101
|
formatters={{ formatWeekdayName: weekdayAsOneLetter }}
|
|
94
102
|
components={{
|
|
95
|
-
|
|
96
|
-
|
|
103
|
+
Chevron: ChevronComponent,
|
|
104
|
+
}}
|
|
105
|
+
classNames={{
|
|
106
|
+
root: "mobius/DatePickerRoot",
|
|
107
|
+
months: "mobius/DatePickerMonths",
|
|
108
|
+
month: "mobius/DatePickerMonth",
|
|
109
|
+
nav: "mobius/DatePickerNav",
|
|
110
|
+
button_previous: "mobius/DatePickerNavButton --previous",
|
|
111
|
+
button_next: "mobius/DatePickerNavButton --next",
|
|
112
|
+
month_caption: "mobius/DatePickerCaption",
|
|
113
|
+
caption_label: "mobius/DatePickerCaptionLabel",
|
|
114
|
+
month_grid: "mobius/DatePickerMonthGrid",
|
|
115
|
+
weekdays: "mobius/DatePickerWeekdays",
|
|
116
|
+
weekday: "mobius/DatePickerWeekday",
|
|
117
|
+
weeks: "mobius/DatePickerWeeks",
|
|
118
|
+
week: "mobius/DatePickerWeek",
|
|
119
|
+
day: "mobius/DatePickerDay",
|
|
120
|
+
day_button: "mobius/DatePickerDayButton",
|
|
121
|
+
selected: "--is-selected",
|
|
122
|
+
disabled: "--is-disabled",
|
|
123
|
+
outside: "--is-outside",
|
|
124
|
+
hidden: "--is-hidden",
|
|
125
|
+
today: "--is-today",
|
|
126
|
+
focused: "--is-focused",
|
|
97
127
|
}}
|
|
98
128
|
/>
|
|
99
129
|
</div>
|
|
@@ -4,9 +4,8 @@ describe("weekdayAsOneLetter", () => {
|
|
|
4
4
|
describe("given a Date object and a locale", () => {
|
|
5
5
|
it("returns weekday as a single letter", () => {
|
|
6
6
|
const randomMonday = new Date("2023-11-13");
|
|
7
|
-
const locale = { locale: { code: "en-GB" } };
|
|
8
7
|
|
|
9
|
-
const actual = weekdayAsOneLetter(randomMonday
|
|
8
|
+
const actual = weekdayAsOneLetter(randomMonday);
|
|
10
9
|
|
|
11
10
|
const expected = "M";
|
|
12
11
|
|
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
import { DEFAULT_LOCALE } from "../constants";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
locale
|
|
5
|
-
code: string;
|
|
6
|
-
};
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export const weekdayAsOneLetter = (date: Date, options?: OptionProps) => {
|
|
10
|
-
const locale = options?.locale?.code || DEFAULT_LOCALE;
|
|
3
|
+
export const weekdayAsOneLetter = (date: Date) => {
|
|
4
|
+
const locale = navigator.language || DEFAULT_LOCALE;
|
|
11
5
|
const oneLetter = date.toLocaleString(locale, {
|
|
12
6
|
weekday: "narrow",
|
|
13
7
|
});
|