@simplybusiness/mobius-datepicker 9.0.0 → 9.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 +9 -0
- package/dist/esm/index.js +363 -54
- package/dist/esm/index.js.map +4 -4
- package/dist/esm/meta.json +51 -66
- package/package.json +6 -7
- package/dist/esm/DatePickerModal-WRMRIQDP.js +0 -208
- package/dist/esm/DatePickerModal-WRMRIQDP.js.map +0 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 9.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 6621ab0: Rebuild packages to pick up latest build-scripts changes.
|
|
8
|
+
- Updated dependencies [6621ab0]
|
|
9
|
+
- @simplybusiness/mobius@8.0.1
|
|
10
|
+
- @simplybusiness/icons@5.0.1
|
|
11
|
+
|
|
3
12
|
## 9.0.0
|
|
4
13
|
|
|
5
14
|
### Major Changes
|
package/dist/esm/index.js
CHANGED
|
@@ -1,19 +1,360 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __esm = (fn, res) => function __init() {
|
|
4
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
5
|
+
};
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// src/components/DatePicker/utils/dateObjToString.ts
|
|
12
|
+
var dateObjToString;
|
|
13
|
+
var init_dateObjToString = __esm({
|
|
14
|
+
"src/components/DatePicker/utils/dateObjToString.ts"() {
|
|
15
|
+
"use strict";
|
|
16
|
+
dateObjToString = (date) => {
|
|
17
|
+
const year = date.getFullYear();
|
|
18
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
19
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
20
|
+
return `${year}-${month}-${day}`;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// src/components/DatePicker/utils/formatErrorMessageText.ts
|
|
26
|
+
import { isAfter, isBefore } from "date-fns";
|
|
27
|
+
var DEFAULT_INVALID_DATE_MESSAGE, DEFAULT_BEFORE_MIN, DEFAULT_AFTER_MAX, formatErrorMessageText;
|
|
28
|
+
var init_formatErrorMessageText = __esm({
|
|
29
|
+
"src/components/DatePicker/utils/formatErrorMessageText.ts"() {
|
|
30
|
+
"use strict";
|
|
31
|
+
DEFAULT_INVALID_DATE_MESSAGE = "Please enter a valid date";
|
|
32
|
+
DEFAULT_BEFORE_MIN = "The date you selected is before the earliest allowed date";
|
|
33
|
+
DEFAULT_AFTER_MAX = "The date you selected is after the latest allowed date";
|
|
34
|
+
formatErrorMessageText = (actual, min, max) => {
|
|
35
|
+
const actualDate = new Date(actual);
|
|
36
|
+
const minDate = min && new Date(min);
|
|
37
|
+
const maxDate = max && new Date(max);
|
|
38
|
+
if (minDate && isBefore(actualDate, minDate)) {
|
|
39
|
+
return DEFAULT_BEFORE_MIN;
|
|
40
|
+
}
|
|
41
|
+
if (maxDate && isAfter(actualDate, maxDate)) {
|
|
42
|
+
return DEFAULT_AFTER_MAX;
|
|
43
|
+
}
|
|
44
|
+
return DEFAULT_INVALID_DATE_MESSAGE;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// src/components/DatePicker/utils/validateDateFormat.ts
|
|
50
|
+
import { isMatch } from "date-fns";
|
|
51
|
+
var DATE_FORMAT, validateDateFormat;
|
|
52
|
+
var init_validateDateFormat = __esm({
|
|
53
|
+
"src/components/DatePicker/utils/validateDateFormat.ts"() {
|
|
54
|
+
"use strict";
|
|
55
|
+
DATE_FORMAT = "yyyy-MM-dd";
|
|
56
|
+
validateDateFormat = (date) => {
|
|
57
|
+
if (date === "") {
|
|
58
|
+
return "";
|
|
59
|
+
}
|
|
60
|
+
if (isMatch(date, DATE_FORMAT)) {
|
|
61
|
+
return date;
|
|
62
|
+
}
|
|
63
|
+
throw Error(
|
|
64
|
+
`DatePicker defaultValue '${date}' is invalid. The expected format is '${DATE_FORMAT}' `
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// src/components/DatePicker/constants.ts
|
|
71
|
+
var SUNDAY_AS_NUMBER, MONDAY_AS_NUMBER, DEFAULT_LOCALE;
|
|
72
|
+
var init_constants = __esm({
|
|
73
|
+
"src/components/DatePicker/constants.ts"() {
|
|
74
|
+
"use strict";
|
|
75
|
+
SUNDAY_AS_NUMBER = 0;
|
|
76
|
+
MONDAY_AS_NUMBER = 1;
|
|
77
|
+
DEFAULT_LOCALE = "en-GB";
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// src/components/DatePicker/utils/weekdayAsOneLetter.ts
|
|
82
|
+
var weekdayAsOneLetter;
|
|
83
|
+
var init_weekdayAsOneLetter = __esm({
|
|
84
|
+
"src/components/DatePicker/utils/weekdayAsOneLetter.ts"() {
|
|
85
|
+
"use strict";
|
|
86
|
+
init_constants();
|
|
87
|
+
weekdayAsOneLetter = (date) => {
|
|
88
|
+
const locale = navigator.language || DEFAULT_LOCALE;
|
|
89
|
+
const oneLetter = date.toLocaleString(locale, {
|
|
90
|
+
weekday: "narrow"
|
|
91
|
+
});
|
|
92
|
+
return oneLetter;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// src/components/DatePicker/utils/index.ts
|
|
98
|
+
var init_utils = __esm({
|
|
99
|
+
"src/components/DatePicker/utils/index.ts"() {
|
|
100
|
+
"use strict";
|
|
101
|
+
init_dateObjToString();
|
|
102
|
+
init_formatErrorMessageText();
|
|
103
|
+
init_validateDateFormat();
|
|
104
|
+
init_weekdayAsOneLetter();
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// src/hooks/useFocusTrap/useFocusTrap.tsx
|
|
109
|
+
import { useEffect, useRef } from "react";
|
|
110
|
+
import { jsx } from "react/jsx-runtime";
|
|
111
|
+
function FocusTrap({ children }) {
|
|
112
|
+
const focusRef = useFocusTrap();
|
|
113
|
+
return /* @__PURE__ */ jsx("div", { className: "trap", ref: focusRef, children });
|
|
114
|
+
}
|
|
115
|
+
var useFocusTrap;
|
|
116
|
+
var init_useFocusTrap = __esm({
|
|
117
|
+
"src/hooks/useFocusTrap/useFocusTrap.tsx"() {
|
|
118
|
+
"use strict";
|
|
119
|
+
useFocusTrap = () => {
|
|
120
|
+
const containerRef = useRef(null);
|
|
121
|
+
useEffect(() => {
|
|
122
|
+
if (containerRef.current) {
|
|
123
|
+
const element = containerRef.current;
|
|
124
|
+
const focusableElements = containerRef.current.querySelectorAll(
|
|
125
|
+
'[tabindex="0"], .mobius-date-picker__nav-button'
|
|
126
|
+
);
|
|
127
|
+
const firstElement = focusableElements[0];
|
|
128
|
+
const lastElement = focusableElements[focusableElements.length - 1];
|
|
129
|
+
const handleTabKeyPress = (event) => {
|
|
130
|
+
if (event.key === "Tab") {
|
|
131
|
+
if (event.shiftKey && document.activeElement === firstElement) {
|
|
132
|
+
event.preventDefault();
|
|
133
|
+
lastElement.focus();
|
|
134
|
+
} else if (!event.shiftKey && document.activeElement && document.activeElement.className.indexOf(
|
|
135
|
+
"mobius-date-picker__day-button"
|
|
136
|
+
) > -1) {
|
|
137
|
+
event.preventDefault();
|
|
138
|
+
firstElement.focus();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
element.addEventListener("keydown", handleTabKeyPress);
|
|
143
|
+
return () => {
|
|
144
|
+
element.removeEventListener("keydown", handleTabKeyPress);
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
return () => {
|
|
148
|
+
};
|
|
149
|
+
}, []);
|
|
150
|
+
return containerRef;
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// src/components/DatePicker/utils/getStartWeekday.ts
|
|
156
|
+
var getStartWeekday;
|
|
157
|
+
var init_getStartWeekday = __esm({
|
|
158
|
+
"src/components/DatePicker/utils/getStartWeekday.ts"() {
|
|
159
|
+
"use strict";
|
|
160
|
+
init_constants();
|
|
161
|
+
getStartWeekday = (locale) => {
|
|
162
|
+
switch (locale || DEFAULT_LOCALE) {
|
|
163
|
+
case "en-US":
|
|
164
|
+
return SUNDAY_AS_NUMBER;
|
|
165
|
+
default:
|
|
166
|
+
return MONDAY_AS_NUMBER;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// src/components/DatePicker/utils/timezoneOffset.ts
|
|
173
|
+
function toLocal(utcDateString) {
|
|
174
|
+
const utcDate = new Date(utcDateString);
|
|
175
|
+
if (Number.isNaN(utcDate.getTime())) {
|
|
176
|
+
throw new Error("Invalid date string");
|
|
177
|
+
}
|
|
178
|
+
return new Date(utcDate.getTime() + utcDate.getTimezoneOffset() * 6e4);
|
|
179
|
+
}
|
|
180
|
+
var init_timezoneOffset = __esm({
|
|
181
|
+
"src/components/DatePicker/utils/timezoneOffset.ts"() {
|
|
182
|
+
"use strict";
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// src/components/DatePicker/CustomComponents/CaptionLabel.tsx
|
|
187
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
188
|
+
var CaptionLabel;
|
|
189
|
+
var init_CaptionLabel = __esm({
|
|
190
|
+
"src/components/DatePicker/CustomComponents/CaptionLabel.tsx"() {
|
|
191
|
+
"use strict";
|
|
192
|
+
CaptionLabel = (props) => {
|
|
193
|
+
return /* @__PURE__ */ jsx2("h2", { ...props });
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// src/components/DatePicker/CustomComponents/ChevronComponent.tsx
|
|
199
|
+
import { chevronLeft, chevronRight } from "@simplybusiness/icons";
|
|
200
|
+
import { Icon } from "@simplybusiness/mobius";
|
|
201
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
202
|
+
var ChevronComponent;
|
|
203
|
+
var init_ChevronComponent = __esm({
|
|
204
|
+
"src/components/DatePicker/CustomComponents/ChevronComponent.tsx"() {
|
|
205
|
+
"use strict";
|
|
206
|
+
ChevronComponent = ({ orientation }) => {
|
|
207
|
+
if (orientation === "left") {
|
|
208
|
+
return /* @__PURE__ */ jsx3(Icon, { icon: chevronLeft });
|
|
209
|
+
}
|
|
210
|
+
return /* @__PURE__ */ jsx3(Icon, { icon: chevronRight });
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
// src/components/DatePicker/CustomComponents/index.tsx
|
|
216
|
+
var init_CustomComponents = __esm({
|
|
217
|
+
"src/components/DatePicker/CustomComponents/index.tsx"() {
|
|
218
|
+
"use strict";
|
|
219
|
+
init_CaptionLabel();
|
|
220
|
+
init_ChevronComponent();
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// src/components/DatePicker/DatePickerModal.tsx
|
|
225
|
+
var DatePickerModal_exports = {};
|
|
226
|
+
__export(DatePickerModal_exports, {
|
|
227
|
+
default: () => DatePickerModal_default
|
|
228
|
+
});
|
|
229
|
+
import { VisuallyHidden, useOnClickOutside } from "@simplybusiness/mobius";
|
|
230
|
+
import classNames from "classnames/dedupe";
|
|
231
|
+
import { parseISO } from "date-fns";
|
|
232
|
+
import { useId, useRef as useRef2 } from "react";
|
|
233
|
+
import { DayPicker } from "react-day-picker";
|
|
234
|
+
import { jsx as jsx4, jsxs } from "react/jsx-runtime";
|
|
235
|
+
var startWeekday, DatePickerModal, DatePickerModal_default;
|
|
236
|
+
var init_DatePickerModal = __esm({
|
|
237
|
+
"src/components/DatePicker/DatePickerModal.tsx"() {
|
|
238
|
+
"use strict";
|
|
239
|
+
"use client";
|
|
240
|
+
init_useFocusTrap();
|
|
241
|
+
init_utils();
|
|
242
|
+
init_getStartWeekday();
|
|
243
|
+
init_timezoneOffset();
|
|
244
|
+
init_CustomComponents();
|
|
245
|
+
startWeekday = getStartWeekday(
|
|
246
|
+
// eslint-disable-next-line ssr-friendly/no-dom-globals-in-module-scope
|
|
247
|
+
typeof navigator !== "undefined" ? navigator?.language : void 0
|
|
248
|
+
);
|
|
249
|
+
DatePickerModal = ({
|
|
250
|
+
date,
|
|
251
|
+
isOpen,
|
|
252
|
+
onSelected,
|
|
253
|
+
top,
|
|
254
|
+
min,
|
|
255
|
+
max
|
|
256
|
+
}) => {
|
|
257
|
+
const modalRef = useRef2(null);
|
|
258
|
+
const initialDate = date ? toLocal(date) : void 0;
|
|
259
|
+
const minDate = min ? toLocal(min) : void 0;
|
|
260
|
+
const maxDate = max ? toLocal(max) : void 0;
|
|
261
|
+
const hiddenId = `screen-reader-title-${useId()}`;
|
|
262
|
+
const handleSelected = (selectedDate) => {
|
|
263
|
+
onSelected(selectedDate);
|
|
264
|
+
};
|
|
265
|
+
const handleDayPickerSelect = (selectedDate) => {
|
|
266
|
+
if (!selectedDate) return;
|
|
267
|
+
handleSelected(dateObjToString(selectedDate));
|
|
268
|
+
};
|
|
269
|
+
useOnClickOutside(modalRef, () => {
|
|
270
|
+
if (modalRef.current && isOpen) {
|
|
271
|
+
handleSelected();
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
const modalClasses = classNames("mobius-date-picker__modal", {
|
|
275
|
+
"--is-open": isOpen
|
|
276
|
+
});
|
|
277
|
+
return /* @__PURE__ */ jsx4(FocusTrap, { children: /* @__PURE__ */ jsxs(
|
|
278
|
+
"div",
|
|
279
|
+
{
|
|
280
|
+
ref: modalRef,
|
|
281
|
+
className: modalClasses,
|
|
282
|
+
style: { top },
|
|
283
|
+
"aria-describedby": hiddenId,
|
|
284
|
+
"data-testid": "modal-container",
|
|
285
|
+
children: [
|
|
286
|
+
/* @__PURE__ */ jsx4(VisuallyHidden, { children: /* @__PURE__ */ jsx4("div", { id: hiddenId, children: "Please select a date from the calendar" }) }),
|
|
287
|
+
/* @__PURE__ */ jsx4(
|
|
288
|
+
DayPicker,
|
|
289
|
+
{
|
|
290
|
+
autoFocus: true,
|
|
291
|
+
mode: "single",
|
|
292
|
+
...minDate && { startMonth: minDate },
|
|
293
|
+
...maxDate && { endMonth: maxDate },
|
|
294
|
+
disabled: {
|
|
295
|
+
...min && { before: parseISO(min) },
|
|
296
|
+
...max && { after: parseISO(max) }
|
|
297
|
+
},
|
|
298
|
+
selected: initialDate,
|
|
299
|
+
defaultMonth: initialDate,
|
|
300
|
+
onSelect: handleDayPickerSelect,
|
|
301
|
+
pagedNavigation: true,
|
|
302
|
+
showOutsideDays: true,
|
|
303
|
+
weekStartsOn: startWeekday,
|
|
304
|
+
formatters: { formatWeekdayName: weekdayAsOneLetter },
|
|
305
|
+
components: {
|
|
306
|
+
Chevron: ChevronComponent,
|
|
307
|
+
CaptionLabel
|
|
308
|
+
},
|
|
309
|
+
classNames: {
|
|
310
|
+
root: "mobius-date-picker__root",
|
|
311
|
+
months: "mobius-date-picker__months",
|
|
312
|
+
month: "mobius-date-picker__month",
|
|
313
|
+
nav: "mobius-date-picker__nav",
|
|
314
|
+
button_previous: "mobius-date-picker__nav-button --previous",
|
|
315
|
+
button_next: "mobius-date-picker__nav-button --next",
|
|
316
|
+
month_caption: "mobius-date-picker__caption",
|
|
317
|
+
caption_label: "mobius-date-picker__caption-label",
|
|
318
|
+
month_grid: "mobius-date-picker__month-grid",
|
|
319
|
+
weekdays: "mobius-date-picker__weekdays",
|
|
320
|
+
weekday: "mobius-date-picker__weekday",
|
|
321
|
+
weeks: "mobius-date-picker__weeks",
|
|
322
|
+
week: "mobius-date-picker__week",
|
|
323
|
+
day: "mobius-date-picker__day",
|
|
324
|
+
day_button: "mobius-date-picker__day-button",
|
|
325
|
+
selected: "--is-selected",
|
|
326
|
+
disabled: "--is-disabled",
|
|
327
|
+
outside: "--is-outside",
|
|
328
|
+
hidden: "--is-hidden",
|
|
329
|
+
today: "--is-today",
|
|
330
|
+
focused: "--is-focused"
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
)
|
|
334
|
+
]
|
|
335
|
+
}
|
|
336
|
+
) });
|
|
337
|
+
};
|
|
338
|
+
DatePickerModal_default = DatePickerModal;
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
|
|
1
342
|
// src/components/DatePicker/DatePicker.tsx
|
|
2
343
|
import { calendarDay } from "@simplybusiness/icons";
|
|
3
344
|
import {
|
|
4
345
|
Button,
|
|
5
|
-
Icon,
|
|
346
|
+
Icon as Icon2,
|
|
6
347
|
TextField,
|
|
7
|
-
VisuallyHidden,
|
|
348
|
+
VisuallyHidden as VisuallyHidden2,
|
|
8
349
|
useValidationClasses
|
|
9
350
|
} from "@simplybusiness/mobius";
|
|
10
|
-
import
|
|
351
|
+
import classNames2 from "classnames/dedupe";
|
|
11
352
|
import {
|
|
12
353
|
Suspense,
|
|
13
354
|
lazy,
|
|
14
355
|
useCallback,
|
|
15
|
-
useEffect,
|
|
16
|
-
useRef,
|
|
356
|
+
useEffect as useEffect2,
|
|
357
|
+
useRef as useRef3,
|
|
17
358
|
useState
|
|
18
359
|
} from "react";
|
|
19
360
|
|
|
@@ -25,42 +366,10 @@ var isTouchDevice = () => {
|
|
|
25
366
|
return void 0;
|
|
26
367
|
};
|
|
27
368
|
|
|
28
|
-
// src/components/DatePicker/utils/formatErrorMessageText.ts
|
|
29
|
-
import { isAfter, isBefore } from "date-fns";
|
|
30
|
-
var DEFAULT_INVALID_DATE_MESSAGE = "Please enter a valid date";
|
|
31
|
-
var DEFAULT_BEFORE_MIN = "The date you selected is before the earliest allowed date";
|
|
32
|
-
var DEFAULT_AFTER_MAX = "The date you selected is after the latest allowed date";
|
|
33
|
-
var formatErrorMessageText = (actual, min, max) => {
|
|
34
|
-
const actualDate = new Date(actual);
|
|
35
|
-
const minDate = min && new Date(min);
|
|
36
|
-
const maxDate = max && new Date(max);
|
|
37
|
-
if (minDate && isBefore(actualDate, minDate)) {
|
|
38
|
-
return DEFAULT_BEFORE_MIN;
|
|
39
|
-
}
|
|
40
|
-
if (maxDate && isAfter(actualDate, maxDate)) {
|
|
41
|
-
return DEFAULT_AFTER_MAX;
|
|
42
|
-
}
|
|
43
|
-
return DEFAULT_INVALID_DATE_MESSAGE;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
// src/components/DatePicker/utils/validateDateFormat.ts
|
|
47
|
-
import { isMatch } from "date-fns";
|
|
48
|
-
var DATE_FORMAT = "yyyy-MM-dd";
|
|
49
|
-
var validateDateFormat = (date) => {
|
|
50
|
-
if (date === "") {
|
|
51
|
-
return "";
|
|
52
|
-
}
|
|
53
|
-
if (isMatch(date, DATE_FORMAT)) {
|
|
54
|
-
return date;
|
|
55
|
-
}
|
|
56
|
-
throw Error(
|
|
57
|
-
`DatePicker defaultValue '${date}' is invalid. The expected format is '${DATE_FORMAT}' `
|
|
58
|
-
);
|
|
59
|
-
};
|
|
60
|
-
|
|
61
369
|
// src/components/DatePicker/DatePicker.tsx
|
|
62
|
-
|
|
63
|
-
|
|
370
|
+
init_utils();
|
|
371
|
+
import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
372
|
+
var DatePickerModal2 = lazy(() => Promise.resolve().then(() => (init_DatePickerModal(), DatePickerModal_exports)));
|
|
64
373
|
var getValidationState = (isInvalid) => {
|
|
65
374
|
if (isInvalid) {
|
|
66
375
|
return true;
|
|
@@ -79,9 +388,9 @@ var DatePicker = (props) => {
|
|
|
79
388
|
errorMessage = "",
|
|
80
389
|
...otherProps
|
|
81
390
|
} = props;
|
|
82
|
-
const containerRef =
|
|
391
|
+
const containerRef = useRef3(null);
|
|
83
392
|
const [top, setTop] = useState(0);
|
|
84
|
-
const inputRef =
|
|
393
|
+
const inputRef = useRef3(null);
|
|
85
394
|
const [isOpen, setIsOpen] = useState(false);
|
|
86
395
|
const [textFieldVal, setTextFieldVal] = useState(
|
|
87
396
|
validateDateFormat(defaultValue)
|
|
@@ -91,7 +400,7 @@ var DatePicker = (props) => {
|
|
|
91
400
|
const errorMessageText = isInvalidProp ? formatErrorMessageText(textFieldVal, props.min, props.max) : errorMessage;
|
|
92
401
|
const touchDevice = isTouchDevice();
|
|
93
402
|
const validationClasses = useValidationClasses({ isInvalid: isInvalidProp });
|
|
94
|
-
const containerClasses =
|
|
403
|
+
const containerClasses = classNames2(
|
|
95
404
|
"mobius-date-picker__container",
|
|
96
405
|
{
|
|
97
406
|
"--is-disabled": isDisabled,
|
|
@@ -99,7 +408,7 @@ var DatePicker = (props) => {
|
|
|
99
408
|
},
|
|
100
409
|
validationClasses
|
|
101
410
|
);
|
|
102
|
-
const popoverToggleClasses =
|
|
411
|
+
const popoverToggleClasses = classNames2(
|
|
103
412
|
"mobius-date-picker__field-button",
|
|
104
413
|
validationClasses
|
|
105
414
|
);
|
|
@@ -110,7 +419,7 @@ var DatePicker = (props) => {
|
|
|
110
419
|
setIsValid(false);
|
|
111
420
|
}
|
|
112
421
|
}, [isOpen]);
|
|
113
|
-
|
|
422
|
+
useEffect2(() => {
|
|
114
423
|
if (!inputRef.current) return;
|
|
115
424
|
const validatedValue = validateDateFormat(defaultValue);
|
|
116
425
|
setTextFieldVal(validatedValue);
|
|
@@ -150,7 +459,7 @@ var DatePicker = (props) => {
|
|
|
150
459
|
event.preventDefault();
|
|
151
460
|
togglePopoverVisibility();
|
|
152
461
|
};
|
|
153
|
-
|
|
462
|
+
useEffect2(() => {
|
|
154
463
|
if (isOpen) {
|
|
155
464
|
setTop(containerRef.current?.getBoundingClientRect().height || 0);
|
|
156
465
|
setIsValid(true);
|
|
@@ -159,7 +468,7 @@ var DatePicker = (props) => {
|
|
|
159
468
|
validate();
|
|
160
469
|
}, [isOpen, validate]);
|
|
161
470
|
if (touchDevice) {
|
|
162
|
-
return /* @__PURE__ */
|
|
471
|
+
return /* @__PURE__ */ jsx5("div", { className: containerClasses, children: /* @__PURE__ */ jsx5(
|
|
163
472
|
TextField,
|
|
164
473
|
{
|
|
165
474
|
ref: inputRef,
|
|
@@ -175,8 +484,8 @@ var DatePicker = (props) => {
|
|
|
175
484
|
}
|
|
176
485
|
) });
|
|
177
486
|
}
|
|
178
|
-
return /* @__PURE__ */
|
|
179
|
-
/* @__PURE__ */
|
|
487
|
+
return /* @__PURE__ */ jsxs2("div", { className: containerClasses, ref: containerRef, children: [
|
|
488
|
+
/* @__PURE__ */ jsx5(
|
|
180
489
|
TextField,
|
|
181
490
|
{
|
|
182
491
|
ref: inputRef,
|
|
@@ -190,7 +499,7 @@ var DatePicker = (props) => {
|
|
|
190
499
|
isInvalid: isInvalidProp,
|
|
191
500
|
...otherProps,
|
|
192
501
|
errorMessage: errorMessage || errorMessageText,
|
|
193
|
-
suffixOutside: /* @__PURE__ */
|
|
502
|
+
suffixOutside: /* @__PURE__ */ jsxs2(
|
|
194
503
|
Button,
|
|
195
504
|
{
|
|
196
505
|
className: popoverToggleClasses,
|
|
@@ -198,15 +507,15 @@ var DatePicker = (props) => {
|
|
|
198
507
|
isDisabled,
|
|
199
508
|
size: "sm",
|
|
200
509
|
children: [
|
|
201
|
-
/* @__PURE__ */
|
|
202
|
-
/* @__PURE__ */
|
|
510
|
+
/* @__PURE__ */ jsx5(Icon2, { size: "sm", icon: calendarDay }),
|
|
511
|
+
/* @__PURE__ */ jsx5(VisuallyHidden2, { children: "Pick date" })
|
|
203
512
|
]
|
|
204
513
|
}
|
|
205
514
|
)
|
|
206
515
|
}
|
|
207
516
|
),
|
|
208
|
-
isOpen && /* @__PURE__ */
|
|
209
|
-
|
|
517
|
+
isOpen && /* @__PURE__ */ jsx5(Suspense, { children: /* @__PURE__ */ jsx5(
|
|
518
|
+
DatePickerModal2,
|
|
210
519
|
{
|
|
211
520
|
date: textFieldVal,
|
|
212
521
|
isOpen,
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../src/components/DatePicker/DatePicker.tsx", "../../src/utils/
|
|
4
|
-
"sourcesContent": ["\"use client\";\n\nimport { calendarDay } from \"@simplybusiness/icons\";\nimport type {\n TextFieldElementType,\n TextFieldProps,\n Validation,\n} from \"@simplybusiness/mobius\";\nimport {\n Button,\n Icon,\n TextField,\n VisuallyHidden,\n useValidationClasses,\n} from \"@simplybusiness/mobius\";\nimport classNames from \"classnames/dedupe\";\nimport type { ChangeEvent, FocusEvent } from \"react\";\nimport {\n Suspense,\n lazy,\n useCallback,\n useEffect,\n useRef,\n useState,\n type MouseEvent,\n} from \"react\";\nimport { isTouchDevice } from \"../../utils/isTouchDevice\";\nimport { formatErrorMessageText, validateDateFormat } from \"./utils\";\n\nconst DatePickerModal = lazy(() => import(\"./DatePickerModal\"));\n\nconst getValidationState = (isInvalid: boolean | undefined) => {\n if (isInvalid) {\n return true;\n }\n\n if (isInvalid === false) {\n return false;\n }\n\n return undefined;\n};\n\nexport interface DatePickerProps\n extends\n Validation,\n Omit<TextFieldProps, \"defaultValue\" | \"onChange\" | \"onBlur\" | \"onFocus\"> {\n onChange?: (date: string | undefined) => void;\n defaultValue?: string;\n min?: string;\n max?: string;\n id?: string;\n}\n\nexport const DatePicker = (props: DatePickerProps) => {\n const {\n onChange,\n defaultValue = \"\",\n isDisabled,\n isInvalid,\n errorMessage = \"\",\n ...otherProps\n } = props;\n const containerRef = useRef<HTMLDivElement | null>(null);\n const [top, setTop] = useState<number>(0);\n const inputRef = useRef<TextFieldElementType | null>(null);\n const [isOpen, setIsOpen] = useState<boolean>(false);\n const [textFieldVal, setTextFieldVal] = useState<string>(\n validateDateFormat(defaultValue),\n );\n const [isValid, setIsValid] = useState<boolean | undefined>(undefined);\n const isInvalidProp = getValidationState(isValid === false || isInvalid);\n const errorMessageText = isInvalidProp\n ? formatErrorMessageText(textFieldVal, props.min, props.max)\n : errorMessage;\n const touchDevice = isTouchDevice();\n\n const validationClasses = useValidationClasses({ isInvalid: isInvalidProp });\n\n const containerClasses = classNames(\n \"mobius-date-picker__container\",\n {\n \"--is-disabled\": isDisabled,\n \"--is-touch-device\": touchDevice,\n },\n validationClasses,\n );\n\n const popoverToggleClasses = classNames(\n \"mobius-date-picker__field-button\",\n validationClasses,\n );\n\n const validate = useCallback(() => {\n if (isOpen) return;\n\n // If 'min' or 'max' values are provided, checkValidity() will\n // validate the date and return a boolean\n const isValidInput = inputRef.current?.checkValidity();\n\n if (!isValidInput) {\n setIsValid(false);\n }\n }, [isOpen]);\n\n useEffect(() => {\n if (!inputRef.current) return;\n const validatedValue = validateDateFormat(defaultValue);\n setTextFieldVal(validatedValue);\n inputRef.current.value = validatedValue;\n setIsValid(true);\n validate();\n }, [defaultValue, validate]);\n\n const togglePopoverVisibility = () => {\n setIsValid(true);\n setIsOpen(!isOpen);\n };\n\n const handleTextFieldChange = (event: ChangeEvent<TextFieldElementType>) => {\n setTextFieldVal(event.target.value);\n // onChange only triggers on a valid date\n // so this clears the error\n setIsValid(true);\n };\n\n const onDateSelected = (selectedDate: string | undefined) => {\n // Handle null callback from useOnClickOutside\n if (selectedDate) {\n setTextFieldVal(selectedDate);\n setIsValid(true);\n // Add other callback events here\n onChange?.(selectedDate);\n }\n // Focus the input\n inputRef.current?.focus();\n setIsOpen(false);\n };\n\n // User has interacted with the component and navigated away\n const handleBlur = (event: FocusEvent) => {\n const target = event.target as TextFieldElementType;\n // If the blur is caused by focusing on the DayPicker modal, do nothing\n // The modal is rendered after the input in the DOM,\n // so check if the relatedTarget is inside the modal\n if (\n isOpen &&\n event.relatedTarget &&\n containerRef.current?.contains(event.relatedTarget as HTMLElement)\n ) {\n return;\n }\n validate();\n\n // User hasn't entered a date, or entered an invalid date\n if (!textFieldVal) {\n setIsValid(false);\n }\n\n onChange?.(target.value);\n };\n\n const handleClick = (event: MouseEvent<TextFieldElementType>) => {\n event.preventDefault();\n togglePopoverVisibility();\n };\n\n useEffect(() => {\n if (isOpen) {\n setTop(containerRef.current?.getBoundingClientRect().height || 0);\n // Disable validation when day picker is open\n setIsValid(true);\n return;\n }\n\n validate();\n }, [isOpen, validate]);\n\n if (touchDevice) {\n return (\n <div className={containerClasses}>\n <TextField\n ref={inputRef}\n type=\"date\"\n className=\"mobius-date-picker\"\n onBlur={handleBlur}\n onChange={handleTextFieldChange}\n value={textFieldVal}\n isDisabled={isDisabled}\n isInvalid={isInvalidProp}\n {...otherProps}\n errorMessage={errorMessage || errorMessageText}\n />\n </div>\n );\n }\n\n return (\n <div className={containerClasses} ref={containerRef}>\n <TextField\n ref={inputRef}\n type=\"date\"\n className=\"mobius-date-picker\"\n onBlur={handleBlur}\n onChange={handleTextFieldChange}\n // @ts-expect-error onClick is not in TextField's props but is passed through via otherProps spread\n onClick={handleClick}\n value={textFieldVal}\n isDisabled={isDisabled}\n isInvalid={isInvalidProp}\n {...otherProps}\n errorMessage={errorMessage || errorMessageText}\n suffixOutside={\n <Button\n className={popoverToggleClasses}\n onClick={togglePopoverVisibility}\n isDisabled={isDisabled}\n size=\"sm\"\n >\n <Icon size=\"sm\" icon={calendarDay} />\n <VisuallyHidden>Pick date</VisuallyHidden>\n </Button>\n }\n />\n {isOpen && (\n <Suspense>\n <DatePickerModal\n date={textFieldVal}\n isOpen={isOpen}\n top={top}\n onSelected={onDateSelected}\n min={props.min}\n max={props.max}\n />\n </Suspense>\n )}\n </div>\n );\n};\n", "export const isTouchDevice = (): boolean | undefined => {\n if (typeof window !== \"undefined\") {\n return window.matchMedia(\"(hover: none), (pointer: coarse)\").matches;\n }\n\n return undefined;\n};\n", "import { isAfter, isBefore } from \"date-fns\";\n\nexport const DEFAULT_INVALID_DATE_MESSAGE = \"Please enter a valid date\";\nexport const DEFAULT_BEFORE_MIN =\n \"The date you selected is before the earliest allowed date\";\nexport const DEFAULT_AFTER_MAX =\n \"The date you selected is after the latest allowed date\";\n\nexport const formatErrorMessageText = (\n actual: string,\n min?: string,\n max?: string,\n) => {\n const actualDate = new Date(actual);\n const minDate = min && new Date(min);\n const maxDate = max && new Date(max);\n\n if (minDate && isBefore(actualDate, minDate)) {\n return DEFAULT_BEFORE_MIN;\n }\n\n if (maxDate && isAfter(actualDate, maxDate)) {\n return DEFAULT_AFTER_MAX;\n }\n\n return DEFAULT_INVALID_DATE_MESSAGE;\n};\n", "import { isMatch } from \"date-fns\";\n\n// eg 2023-12-31\nexport const DATE_FORMAT = \"yyyy-MM-dd\";\n\nexport const validateDateFormat = (date: string) => {\n if (date === \"\") {\n return \"\";\n }\n\n if (isMatch(date, DATE_FORMAT)) {\n return date;\n }\n\n throw Error(\n `DatePicker defaultValue '${date}' is invalid. The expected format is '${DATE_FORMAT}' `,\n );\n};\n"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": []
|
|
3
|
+
"sources": ["../../src/components/DatePicker/utils/dateObjToString.ts", "../../src/components/DatePicker/utils/formatErrorMessageText.ts", "../../src/components/DatePicker/utils/validateDateFormat.ts", "../../src/components/DatePicker/constants.ts", "../../src/components/DatePicker/utils/weekdayAsOneLetter.ts", "../../src/components/DatePicker/utils/index.ts", "../../src/hooks/useFocusTrap/useFocusTrap.tsx", "../../src/components/DatePicker/utils/getStartWeekday.ts", "../../src/components/DatePicker/utils/timezoneOffset.ts", "../../src/components/DatePicker/CustomComponents/CaptionLabel.tsx", "../../src/components/DatePicker/CustomComponents/ChevronComponent.tsx", "../../src/components/DatePicker/CustomComponents/index.tsx", "../../src/components/DatePicker/DatePickerModal.tsx", "../../src/components/DatePicker/DatePicker.tsx", "../../src/utils/isTouchDevice.ts"],
|
|
4
|
+
"sourcesContent": ["export const dateObjToString = (date: Date) => {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n const day = String(date.getDate()).padStart(2, \"0\");\n\n // Extract the date part from the Date object\n return `${year}-${month}-${day}`;\n};\n", "import { isAfter, isBefore } from \"date-fns\";\n\nexport const DEFAULT_INVALID_DATE_MESSAGE = \"Please enter a valid date\";\nexport const DEFAULT_BEFORE_MIN =\n \"The date you selected is before the earliest allowed date\";\nexport const DEFAULT_AFTER_MAX =\n \"The date you selected is after the latest allowed date\";\n\nexport const formatErrorMessageText = (\n actual: string,\n min?: string,\n max?: string,\n) => {\n const actualDate = new Date(actual);\n const minDate = min && new Date(min);\n const maxDate = max && new Date(max);\n\n if (minDate && isBefore(actualDate, minDate)) {\n return DEFAULT_BEFORE_MIN;\n }\n\n if (maxDate && isAfter(actualDate, maxDate)) {\n return DEFAULT_AFTER_MAX;\n }\n\n return DEFAULT_INVALID_DATE_MESSAGE;\n};\n", "import { isMatch } from \"date-fns\";\n\n// eg 2023-12-31\nexport const DATE_FORMAT = \"yyyy-MM-dd\";\n\nexport const validateDateFormat = (date: string) => {\n if (date === \"\") {\n return \"\";\n }\n\n if (isMatch(date, DATE_FORMAT)) {\n return date;\n }\n\n throw Error(\n `DatePicker defaultValue '${date}' is invalid. The expected format is '${DATE_FORMAT}' `,\n );\n};\n", "export const SUNDAY_AS_NUMBER = 0;\nexport const MONDAY_AS_NUMBER = 1;\nexport const DEFAULT_LOCALE = \"en-GB\";\n", "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", "export * from \"./dateObjToString\";\nexport * from \"./formatErrorMessageText\";\nexport * from \"./validateDateFormat\";\nexport * from \"./weekdayAsOneLetter\";\n", "import type { ReactNode } from \"react\";\nimport { useEffect, useRef } from \"react\";\n\nconst useFocusTrap = () => {\n const containerRef = useRef<HTMLDivElement | null>(null);\n\n useEffect(() => {\n if (containerRef.current) {\n const element = containerRef.current;\n const focusableElements =\n containerRef.current.querySelectorAll<HTMLElement>(\n '[tabindex=\"0\"], .mobius-date-picker__nav-button',\n );\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n\n const handleTabKeyPress = (event: KeyboardEvent) => {\n if (event.key === \"Tab\") {\n if (event.shiftKey && document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n } else if (\n !event.shiftKey &&\n document.activeElement &&\n document.activeElement.className.indexOf(\n \"mobius-date-picker__day-button\",\n ) > -1\n ) {\n event.preventDefault();\n firstElement.focus();\n }\n }\n };\n\n element.addEventListener(\"keydown\", handleTabKeyPress);\n return () => {\n element.removeEventListener(\"keydown\", handleTabKeyPress);\n };\n }\n return () => {};\n }, []);\n\n return containerRef;\n};\n\nexport type FocusTrapProps = {\n children: ReactNode;\n};\n\nexport default function FocusTrap({ children }: FocusTrapProps) {\n const focusRef = useFocusTrap();\n\n return (\n <div className=\"trap\" ref={focusRef}>\n {children}\n </div>\n );\n}\n", "import {\n DEFAULT_LOCALE,\n MONDAY_AS_NUMBER,\n SUNDAY_AS_NUMBER,\n} from \"../constants\";\n\ntype WeekStart = 0 | 1 | 2 | 3 | 4 | 5 | 6 | undefined;\n\n// Calculates start of week for calendar in UK and US locales\n// Add more to the switch statement as needed\nexport const getStartWeekday = (locale?: string): WeekStart => {\n switch (locale || DEFAULT_LOCALE) {\n case \"en-US\":\n return SUNDAY_AS_NUMBER;\n\n default:\n return MONDAY_AS_NUMBER;\n }\n};\n", "/**\n * Converts a local date-time to UTC\n * @param localDate - Date object in local timezone\n * @returns Date object in UTC\n */\nexport function toUTC(localDate: Date): Date {\n return new Date(localDate.getTime() - localDate.getTimezoneOffset() * 60000);\n}\n\nexport function toLocal(utcDateString: string): Date {\n const utcDate = new Date(utcDateString);\n if (Number.isNaN(utcDate.getTime())) {\n throw new Error(\"Invalid date string\");\n }\n // Convert UTC date to local date\n // by adding the timezone offset in milliseconds\n return new Date(utcDate.getTime() + utcDate.getTimezoneOffset() * 60000);\n}\n", "import { type HTMLAttributes } from \"react\";\n\n/**\n *\n * This component is used to render the caption label for the date picker.\n * We are overriding the standard span with an h2 for accessibility reasons.\n */\nexport const CaptionLabel = (props: HTMLAttributes<HTMLSpanElement>) => {\n return <h2 {...props} />;\n};\n", "import { chevronLeft, chevronRight } from \"@simplybusiness/icons\";\nimport { Icon } from \"@simplybusiness/mobius\";\n\ntype ChevronComponentProps = {\n orientation?: \"up\" | \"down\" | \"left\" | \"right\";\n};\n\nexport const ChevronComponent = ({ orientation }: ChevronComponentProps) => {\n if (orientation === \"left\") {\n return <Icon icon={chevronLeft} />;\n }\n return <Icon icon={chevronRight} />;\n};\n", "export * from \"./CaptionLabel\";\nexport * from \"./ChevronComponent\";\n", "\"use client\";\n\nimport { VisuallyHidden, useOnClickOutside } from \"@simplybusiness/mobius\";\nimport classNames from \"classnames/dedupe\";\nimport { parseISO } from \"date-fns\";\nimport { useId, useRef } from \"react\";\nimport type { Matcher } from \"react-day-picker\";\nimport { DayPicker } from \"react-day-picker\";\nimport FocusTrap from \"../../hooks/useFocusTrap/useFocusTrap\";\nimport { dateObjToString, weekdayAsOneLetter } from \"./utils\";\nimport { getStartWeekday } from \"./utils/getStartWeekday\";\nimport { toLocal } from \"./utils/timezoneOffset\";\nimport { ChevronComponent, CaptionLabel } from \"./CustomComponents\";\n\nexport type DatePickerModalProps = {\n date?: string; // yyyy-mm-dd\n isOpen: boolean;\n top: number;\n onSelected: (date?: string) => void;\n min?: string;\n max?: string;\n};\n\nconst startWeekday = getStartWeekday(\n // eslint-disable-next-line ssr-friendly/no-dom-globals-in-module-scope\n typeof navigator !== \"undefined\" ? navigator?.language : undefined,\n);\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 ? toLocal(date) : undefined;\n const minDate = min ? toLocal(min) : undefined;\n const maxDate = max ? toLocal(max) : undefined;\n const hiddenId = `screen-reader-title-${useId()}`;\n\n const handleSelected = (selectedDate?: string) => {\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-date-picker__modal\", {\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 autoFocus\n mode=\"single\"\n {...(minDate && { startMonth: minDate })}\n {...(maxDate && { endMonth: maxDate })}\n disabled={\n {\n ...(min && { before: parseISO(min) }),\n ...(max && { after: parseISO(max) }),\n } as Matcher\n }\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 CaptionLabel,\n }}\n classNames={{\n root: \"mobius-date-picker__root\",\n months: \"mobius-date-picker__months\",\n month: \"mobius-date-picker__month\",\n nav: \"mobius-date-picker__nav\",\n button_previous: \"mobius-date-picker__nav-button --previous\",\n button_next: \"mobius-date-picker__nav-button --next\",\n month_caption: \"mobius-date-picker__caption\",\n caption_label: \"mobius-date-picker__caption-label\",\n month_grid: \"mobius-date-picker__month-grid\",\n weekdays: \"mobius-date-picker__weekdays\",\n weekday: \"mobius-date-picker__weekday\",\n weeks: \"mobius-date-picker__weeks\",\n week: \"mobius-date-picker__week\",\n day: \"mobius-date-picker__day\",\n day_button: \"mobius-date-picker__day-button\",\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", "\"use client\";\n\nimport { calendarDay } from \"@simplybusiness/icons\";\nimport type {\n TextFieldElementType,\n TextFieldProps,\n Validation,\n} from \"@simplybusiness/mobius\";\nimport {\n Button,\n Icon,\n TextField,\n VisuallyHidden,\n useValidationClasses,\n} from \"@simplybusiness/mobius\";\nimport classNames from \"classnames/dedupe\";\nimport type { ChangeEvent, FocusEvent } from \"react\";\nimport {\n Suspense,\n lazy,\n useCallback,\n useEffect,\n useRef,\n useState,\n type MouseEvent,\n} from \"react\";\nimport { isTouchDevice } from \"../../utils/isTouchDevice\";\nimport { formatErrorMessageText, validateDateFormat } from \"./utils\";\n\nconst DatePickerModal = lazy(() => import(\"./DatePickerModal\"));\n\nconst getValidationState = (isInvalid: boolean | undefined) => {\n if (isInvalid) {\n return true;\n }\n\n if (isInvalid === false) {\n return false;\n }\n\n return undefined;\n};\n\nexport interface DatePickerProps\n extends\n Validation,\n Omit<TextFieldProps, \"defaultValue\" | \"onChange\" | \"onBlur\" | \"onFocus\"> {\n onChange?: (date: string | undefined) => void;\n defaultValue?: string;\n min?: string;\n max?: string;\n id?: string;\n}\n\nexport const DatePicker = (props: DatePickerProps) => {\n const {\n onChange,\n defaultValue = \"\",\n isDisabled,\n isInvalid,\n errorMessage = \"\",\n ...otherProps\n } = props;\n const containerRef = useRef<HTMLDivElement | null>(null);\n const [top, setTop] = useState<number>(0);\n const inputRef = useRef<TextFieldElementType | null>(null);\n const [isOpen, setIsOpen] = useState<boolean>(false);\n const [textFieldVal, setTextFieldVal] = useState<string>(\n validateDateFormat(defaultValue),\n );\n const [isValid, setIsValid] = useState<boolean | undefined>(undefined);\n const isInvalidProp = getValidationState(isValid === false || isInvalid);\n const errorMessageText = isInvalidProp\n ? formatErrorMessageText(textFieldVal, props.min, props.max)\n : errorMessage;\n const touchDevice = isTouchDevice();\n\n const validationClasses = useValidationClasses({ isInvalid: isInvalidProp });\n\n const containerClasses = classNames(\n \"mobius-date-picker__container\",\n {\n \"--is-disabled\": isDisabled,\n \"--is-touch-device\": touchDevice,\n },\n validationClasses,\n );\n\n const popoverToggleClasses = classNames(\n \"mobius-date-picker__field-button\",\n validationClasses,\n );\n\n const validate = useCallback(() => {\n if (isOpen) return;\n\n // If 'min' or 'max' values are provided, checkValidity() will\n // validate the date and return a boolean\n const isValidInput = inputRef.current?.checkValidity();\n\n if (!isValidInput) {\n setIsValid(false);\n }\n }, [isOpen]);\n\n useEffect(() => {\n if (!inputRef.current) return;\n const validatedValue = validateDateFormat(defaultValue);\n setTextFieldVal(validatedValue);\n inputRef.current.value = validatedValue;\n setIsValid(true);\n validate();\n }, [defaultValue, validate]);\n\n const togglePopoverVisibility = () => {\n setIsValid(true);\n setIsOpen(!isOpen);\n };\n\n const handleTextFieldChange = (event: ChangeEvent<TextFieldElementType>) => {\n setTextFieldVal(event.target.value);\n // onChange only triggers on a valid date\n // so this clears the error\n setIsValid(true);\n };\n\n const onDateSelected = (selectedDate: string | undefined) => {\n // Handle null callback from useOnClickOutside\n if (selectedDate) {\n setTextFieldVal(selectedDate);\n setIsValid(true);\n // Add other callback events here\n onChange?.(selectedDate);\n }\n // Focus the input\n inputRef.current?.focus();\n setIsOpen(false);\n };\n\n // User has interacted with the component and navigated away\n const handleBlur = (event: FocusEvent) => {\n const target = event.target as TextFieldElementType;\n // If the blur is caused by focusing on the DayPicker modal, do nothing\n // The modal is rendered after the input in the DOM,\n // so check if the relatedTarget is inside the modal\n if (\n isOpen &&\n event.relatedTarget &&\n containerRef.current?.contains(event.relatedTarget as HTMLElement)\n ) {\n return;\n }\n validate();\n\n // User hasn't entered a date, or entered an invalid date\n if (!textFieldVal) {\n setIsValid(false);\n }\n\n onChange?.(target.value);\n };\n\n const handleClick = (event: MouseEvent<TextFieldElementType>) => {\n event.preventDefault();\n togglePopoverVisibility();\n };\n\n useEffect(() => {\n if (isOpen) {\n setTop(containerRef.current?.getBoundingClientRect().height || 0);\n // Disable validation when day picker is open\n setIsValid(true);\n return;\n }\n\n validate();\n }, [isOpen, validate]);\n\n if (touchDevice) {\n return (\n <div className={containerClasses}>\n <TextField\n ref={inputRef}\n type=\"date\"\n className=\"mobius-date-picker\"\n onBlur={handleBlur}\n onChange={handleTextFieldChange}\n value={textFieldVal}\n isDisabled={isDisabled}\n isInvalid={isInvalidProp}\n {...otherProps}\n errorMessage={errorMessage || errorMessageText}\n />\n </div>\n );\n }\n\n return (\n <div className={containerClasses} ref={containerRef}>\n <TextField\n ref={inputRef}\n type=\"date\"\n className=\"mobius-date-picker\"\n onBlur={handleBlur}\n onChange={handleTextFieldChange}\n // @ts-expect-error onClick is not in TextField's props but is passed through via otherProps spread\n onClick={handleClick}\n value={textFieldVal}\n isDisabled={isDisabled}\n isInvalid={isInvalidProp}\n {...otherProps}\n errorMessage={errorMessage || errorMessageText}\n suffixOutside={\n <Button\n className={popoverToggleClasses}\n onClick={togglePopoverVisibility}\n isDisabled={isDisabled}\n size=\"sm\"\n >\n <Icon size=\"sm\" icon={calendarDay} />\n <VisuallyHidden>Pick date</VisuallyHidden>\n </Button>\n }\n />\n {isOpen && (\n <Suspense>\n <DatePickerModal\n date={textFieldVal}\n isOpen={isOpen}\n top={top}\n onSelected={onDateSelected}\n min={props.min}\n max={props.max}\n />\n </Suspense>\n )}\n </div>\n );\n};\n", "export const isTouchDevice = (): boolean | undefined => {\n if (typeof window !== \"undefined\") {\n return window.matchMedia(\"(hover: none), (pointer: coarse)\").matches;\n }\n\n return undefined;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["jsx", "jsx", "useRef", "jsx", "Icon", "VisuallyHidden", "classNames", "useEffect", "useRef", "jsx", "jsxs", "DatePickerModal", "useRef", "classNames", "useEffect", "Icon", "VisuallyHidden"]
|
|
7
7
|
}
|
package/dist/esm/meta.json
CHANGED
|
@@ -305,81 +305,50 @@
|
|
|
305
305
|
"imports": [],
|
|
306
306
|
"exports": [],
|
|
307
307
|
"inputs": {},
|
|
308
|
-
"bytes":
|
|
308
|
+
"bytes": 25914
|
|
309
309
|
},
|
|
310
310
|
"dist/esm/index.js": {
|
|
311
311
|
"imports": [
|
|
312
312
|
{
|
|
313
|
-
"path": "
|
|
313
|
+
"path": "date-fns",
|
|
314
314
|
"kind": "import-statement",
|
|
315
315
|
"external": true
|
|
316
316
|
},
|
|
317
317
|
{
|
|
318
|
-
"path": "
|
|
318
|
+
"path": "date-fns",
|
|
319
319
|
"kind": "import-statement",
|
|
320
320
|
"external": true
|
|
321
321
|
},
|
|
322
322
|
{
|
|
323
|
-
"path": "
|
|
323
|
+
"path": "react",
|
|
324
324
|
"kind": "import-statement",
|
|
325
325
|
"external": true
|
|
326
326
|
},
|
|
327
327
|
{
|
|
328
|
-
"path": "react",
|
|
328
|
+
"path": "react/jsx-runtime",
|
|
329
329
|
"kind": "import-statement",
|
|
330
330
|
"external": true
|
|
331
331
|
},
|
|
332
332
|
{
|
|
333
|
-
"path": "
|
|
333
|
+
"path": "react/jsx-runtime",
|
|
334
334
|
"kind": "import-statement",
|
|
335
335
|
"external": true
|
|
336
336
|
},
|
|
337
337
|
{
|
|
338
|
-
"path": "
|
|
338
|
+
"path": "@simplybusiness/icons",
|
|
339
339
|
"kind": "import-statement",
|
|
340
340
|
"external": true
|
|
341
341
|
},
|
|
342
342
|
{
|
|
343
|
-
"path": "
|
|
343
|
+
"path": "@simplybusiness/mobius",
|
|
344
344
|
"kind": "import-statement",
|
|
345
345
|
"external": true
|
|
346
346
|
},
|
|
347
347
|
{
|
|
348
|
-
"path": "
|
|
349
|
-
"kind": "
|
|
350
|
-
|
|
351
|
-
],
|
|
352
|
-
"exports": [
|
|
353
|
-
"DatePicker"
|
|
354
|
-
],
|
|
355
|
-
"entryPoint": "index.tsx",
|
|
356
|
-
"inputs": {
|
|
357
|
-
"src/components/DatePicker/DatePicker.tsx": {
|
|
358
|
-
"bytesInOutput": 4832
|
|
359
|
-
},
|
|
360
|
-
"src/utils/isTouchDevice.ts": {
|
|
361
|
-
"bytesInOutput": 165
|
|
362
|
-
},
|
|
363
|
-
"src/components/DatePicker/utils/formatErrorMessageText.ts": {
|
|
364
|
-
"bytesInOutput": 660
|
|
365
|
-
},
|
|
366
|
-
"src/components/DatePicker/utils/validateDateFormat.ts": {
|
|
367
|
-
"bytesInOutput": 318
|
|
348
|
+
"path": "react/jsx-runtime",
|
|
349
|
+
"kind": "import-statement",
|
|
350
|
+
"external": true
|
|
368
351
|
},
|
|
369
|
-
"index.tsx": {
|
|
370
|
-
"bytesInOutput": 0
|
|
371
|
-
}
|
|
372
|
-
},
|
|
373
|
-
"bytes": 6274
|
|
374
|
-
},
|
|
375
|
-
"dist/esm/DatePickerModal-WRMRIQDP.js.map": {
|
|
376
|
-
"imports": [],
|
|
377
|
-
"exports": [],
|
|
378
|
-
"inputs": {},
|
|
379
|
-
"bytes": 12712
|
|
380
|
-
},
|
|
381
|
-
"dist/esm/DatePickerModal-WRMRIQDP.js": {
|
|
382
|
-
"imports": [
|
|
383
352
|
{
|
|
384
353
|
"path": "@simplybusiness/mobius",
|
|
385
354
|
"kind": "import-statement",
|
|
@@ -405,33 +374,28 @@
|
|
|
405
374
|
"kind": "import-statement",
|
|
406
375
|
"external": true
|
|
407
376
|
},
|
|
408
|
-
{
|
|
409
|
-
"path": "react",
|
|
410
|
-
"kind": "import-statement",
|
|
411
|
-
"external": true
|
|
412
|
-
},
|
|
413
377
|
{
|
|
414
378
|
"path": "react/jsx-runtime",
|
|
415
379
|
"kind": "import-statement",
|
|
416
380
|
"external": true
|
|
417
381
|
},
|
|
418
382
|
{
|
|
419
|
-
"path": "
|
|
383
|
+
"path": "@simplybusiness/icons",
|
|
420
384
|
"kind": "import-statement",
|
|
421
385
|
"external": true
|
|
422
386
|
},
|
|
423
387
|
{
|
|
424
|
-
"path": "@simplybusiness/
|
|
388
|
+
"path": "@simplybusiness/mobius",
|
|
425
389
|
"kind": "import-statement",
|
|
426
390
|
"external": true
|
|
427
391
|
},
|
|
428
392
|
{
|
|
429
|
-
"path": "
|
|
393
|
+
"path": "classnames/dedupe",
|
|
430
394
|
"kind": "import-statement",
|
|
431
395
|
"external": true
|
|
432
396
|
},
|
|
433
397
|
{
|
|
434
|
-
"path": "react
|
|
398
|
+
"path": "react",
|
|
435
399
|
"kind": "import-statement",
|
|
436
400
|
"external": true
|
|
437
401
|
},
|
|
@@ -442,39 +406,60 @@
|
|
|
442
406
|
}
|
|
443
407
|
],
|
|
444
408
|
"exports": [
|
|
445
|
-
"
|
|
409
|
+
"DatePicker"
|
|
446
410
|
],
|
|
447
|
-
"entryPoint": "
|
|
411
|
+
"entryPoint": "index.tsx",
|
|
448
412
|
"inputs": {
|
|
449
|
-
"src/components/DatePicker/
|
|
450
|
-
"bytesInOutput":
|
|
413
|
+
"src/components/DatePicker/utils/dateObjToString.ts": {
|
|
414
|
+
"bytesInOutput": 386
|
|
451
415
|
},
|
|
452
|
-
"src/
|
|
453
|
-
"bytesInOutput":
|
|
416
|
+
"src/components/DatePicker/utils/formatErrorMessageText.ts": {
|
|
417
|
+
"bytesInOutput": 935
|
|
454
418
|
},
|
|
455
|
-
"src/components/DatePicker/utils/
|
|
456
|
-
"bytesInOutput":
|
|
419
|
+
"src/components/DatePicker/utils/validateDateFormat.ts": {
|
|
420
|
+
"bytesInOutput": 521
|
|
457
421
|
},
|
|
458
422
|
"src/components/DatePicker/constants.ts": {
|
|
459
|
-
"bytesInOutput":
|
|
423
|
+
"bytesInOutput": 240
|
|
460
424
|
},
|
|
461
425
|
"src/components/DatePicker/utils/weekdayAsOneLetter.ts": {
|
|
462
|
-
"bytesInOutput":
|
|
426
|
+
"bytesInOutput": 389
|
|
427
|
+
},
|
|
428
|
+
"src/components/DatePicker/utils/index.ts": {
|
|
429
|
+
"bytesInOutput": 225
|
|
430
|
+
},
|
|
431
|
+
"src/hooks/useFocusTrap/useFocusTrap.tsx": {
|
|
432
|
+
"bytesInOutput": 1640
|
|
463
433
|
},
|
|
464
434
|
"src/components/DatePicker/utils/getStartWeekday.ts": {
|
|
465
|
-
"bytesInOutput":
|
|
435
|
+
"bytesInOutput": 365
|
|
466
436
|
},
|
|
467
437
|
"src/components/DatePicker/utils/timezoneOffset.ts": {
|
|
468
|
-
"bytesInOutput":
|
|
438
|
+
"bytesInOutput": 360
|
|
469
439
|
},
|
|
470
440
|
"src/components/DatePicker/CustomComponents/CaptionLabel.tsx": {
|
|
471
|
-
"bytesInOutput":
|
|
441
|
+
"bytesInOutput": 287
|
|
472
442
|
},
|
|
473
443
|
"src/components/DatePicker/CustomComponents/ChevronComponent.tsx": {
|
|
474
|
-
"bytesInOutput":
|
|
444
|
+
"bytesInOutput": 547
|
|
445
|
+
},
|
|
446
|
+
"src/components/DatePicker/CustomComponents/index.tsx": {
|
|
447
|
+
"bytesInOutput": 177
|
|
448
|
+
},
|
|
449
|
+
"src/components/DatePicker/DatePickerModal.tsx": {
|
|
450
|
+
"bytesInOutput": 4419
|
|
451
|
+
},
|
|
452
|
+
"src/components/DatePicker/DatePicker.tsx": {
|
|
453
|
+
"bytesInOutput": 4976
|
|
454
|
+
},
|
|
455
|
+
"src/utils/isTouchDevice.ts": {
|
|
456
|
+
"bytesInOutput": 165
|
|
457
|
+
},
|
|
458
|
+
"index.tsx": {
|
|
459
|
+
"bytesInOutput": 0
|
|
475
460
|
}
|
|
476
461
|
},
|
|
477
|
-
"bytes":
|
|
462
|
+
"bytes": 16863
|
|
478
463
|
}
|
|
479
464
|
}
|
|
480
465
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplybusiness/mobius-datepicker",
|
|
3
3
|
"license": "UNLICENSED",
|
|
4
|
-
"version": "9.0.
|
|
4
|
+
"version": "9.0.1",
|
|
5
5
|
"description": "Mobius date picker component",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"simplyBusiness": {
|
|
11
11
|
"publishToPublicNpm": true
|
|
12
12
|
},
|
|
13
|
+
"type": "module",
|
|
13
14
|
"main": "dist/esm/index.js",
|
|
14
15
|
"types": "./dist/types/index.d.ts",
|
|
15
16
|
"files": [
|
|
@@ -25,7 +26,6 @@
|
|
|
25
26
|
"./src/*.css": "./src/*.css"
|
|
26
27
|
},
|
|
27
28
|
"publishConfig": {
|
|
28
|
-
"type": "module",
|
|
29
29
|
"main": "dist/esm/index.js",
|
|
30
30
|
"module": "dist/esm/index.js",
|
|
31
31
|
"types": "./dist/types/index.d.ts",
|
|
@@ -58,8 +58,8 @@
|
|
|
58
58
|
"@eslint/compat": "^2.0.2",
|
|
59
59
|
"@eslint/eslintrc": "^3.3.3",
|
|
60
60
|
"@eslint/js": "^9.39.2",
|
|
61
|
-
"@simplybusiness/build-scripts": "^2.0.
|
|
62
|
-
"@simplybusiness/eslint-config": "^2.0.
|
|
61
|
+
"@simplybusiness/build-scripts": "^2.0.1",
|
|
62
|
+
"@simplybusiness/eslint-config": "^2.0.1",
|
|
63
63
|
"@swc/core": "^1.12.5",
|
|
64
64
|
"@swc/jest": "^0.2.39",
|
|
65
65
|
"@testing-library/dom": "^10.4.1",
|
|
@@ -96,8 +96,8 @@
|
|
|
96
96
|
"react-dom": "^19.2.0"
|
|
97
97
|
},
|
|
98
98
|
"dependencies": {
|
|
99
|
-
"@simplybusiness/icons": "^5.0.
|
|
100
|
-
"@simplybusiness/mobius": "^8.0.
|
|
99
|
+
"@simplybusiness/icons": "^5.0.1",
|
|
100
|
+
"@simplybusiness/mobius": "^8.0.1",
|
|
101
101
|
"classnames": "^2.5.1",
|
|
102
102
|
"date-fns": "^4.1.0",
|
|
103
103
|
"react-day-picker": "^9.13.0"
|
|
@@ -105,6 +105,5 @@
|
|
|
105
105
|
"lint-staged": {
|
|
106
106
|
"*.{js,ts,jsx,tsx}": "eslint --fix"
|
|
107
107
|
},
|
|
108
|
-
"type": "module",
|
|
109
108
|
"module": "dist/esm/index.js"
|
|
110
109
|
}
|
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
// src/components/DatePicker/DatePickerModal.tsx
|
|
4
|
-
import { VisuallyHidden, useOnClickOutside } from "@simplybusiness/mobius";
|
|
5
|
-
import classNames from "classnames/dedupe";
|
|
6
|
-
import { parseISO } from "date-fns";
|
|
7
|
-
import { useId, useRef as useRef2 } from "react";
|
|
8
|
-
import { DayPicker } from "react-day-picker";
|
|
9
|
-
|
|
10
|
-
// src/hooks/useFocusTrap/useFocusTrap.tsx
|
|
11
|
-
import { useEffect, useRef } from "react";
|
|
12
|
-
import { jsx } from "react/jsx-runtime";
|
|
13
|
-
var useFocusTrap = () => {
|
|
14
|
-
const containerRef = useRef(null);
|
|
15
|
-
useEffect(() => {
|
|
16
|
-
if (containerRef.current) {
|
|
17
|
-
const element = containerRef.current;
|
|
18
|
-
const focusableElements = containerRef.current.querySelectorAll(
|
|
19
|
-
'[tabindex="0"], .mobius-date-picker__nav-button'
|
|
20
|
-
);
|
|
21
|
-
const firstElement = focusableElements[0];
|
|
22
|
-
const lastElement = focusableElements[focusableElements.length - 1];
|
|
23
|
-
const handleTabKeyPress = (event) => {
|
|
24
|
-
if (event.key === "Tab") {
|
|
25
|
-
if (event.shiftKey && document.activeElement === firstElement) {
|
|
26
|
-
event.preventDefault();
|
|
27
|
-
lastElement.focus();
|
|
28
|
-
} else if (!event.shiftKey && document.activeElement && document.activeElement.className.indexOf(
|
|
29
|
-
"mobius-date-picker__day-button"
|
|
30
|
-
) > -1) {
|
|
31
|
-
event.preventDefault();
|
|
32
|
-
firstElement.focus();
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
element.addEventListener("keydown", handleTabKeyPress);
|
|
37
|
-
return () => {
|
|
38
|
-
element.removeEventListener("keydown", handleTabKeyPress);
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
return () => {
|
|
42
|
-
};
|
|
43
|
-
}, []);
|
|
44
|
-
return containerRef;
|
|
45
|
-
};
|
|
46
|
-
function FocusTrap({ children }) {
|
|
47
|
-
const focusRef = useFocusTrap();
|
|
48
|
-
return /* @__PURE__ */ jsx("div", { className: "trap", ref: focusRef, children });
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// src/components/DatePicker/utils/dateObjToString.ts
|
|
52
|
-
var dateObjToString = (date) => {
|
|
53
|
-
const year = date.getFullYear();
|
|
54
|
-
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
55
|
-
const day = String(date.getDate()).padStart(2, "0");
|
|
56
|
-
return `${year}-${month}-${day}`;
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
// src/components/DatePicker/constants.ts
|
|
60
|
-
var SUNDAY_AS_NUMBER = 0;
|
|
61
|
-
var MONDAY_AS_NUMBER = 1;
|
|
62
|
-
var DEFAULT_LOCALE = "en-GB";
|
|
63
|
-
|
|
64
|
-
// src/components/DatePicker/utils/weekdayAsOneLetter.ts
|
|
65
|
-
var weekdayAsOneLetter = (date) => {
|
|
66
|
-
const locale = navigator.language || DEFAULT_LOCALE;
|
|
67
|
-
const oneLetter = date.toLocaleString(locale, {
|
|
68
|
-
weekday: "narrow"
|
|
69
|
-
});
|
|
70
|
-
return oneLetter;
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
// src/components/DatePicker/utils/getStartWeekday.ts
|
|
74
|
-
var getStartWeekday = (locale) => {
|
|
75
|
-
switch (locale || DEFAULT_LOCALE) {
|
|
76
|
-
case "en-US":
|
|
77
|
-
return SUNDAY_AS_NUMBER;
|
|
78
|
-
default:
|
|
79
|
-
return MONDAY_AS_NUMBER;
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
// src/components/DatePicker/utils/timezoneOffset.ts
|
|
84
|
-
function toLocal(utcDateString) {
|
|
85
|
-
const utcDate = new Date(utcDateString);
|
|
86
|
-
if (Number.isNaN(utcDate.getTime())) {
|
|
87
|
-
throw new Error("Invalid date string");
|
|
88
|
-
}
|
|
89
|
-
return new Date(utcDate.getTime() + utcDate.getTimezoneOffset() * 6e4);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// src/components/DatePicker/CustomComponents/CaptionLabel.tsx
|
|
93
|
-
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
94
|
-
var CaptionLabel = (props) => {
|
|
95
|
-
return /* @__PURE__ */ jsx2("h2", { ...props });
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
// src/components/DatePicker/CustomComponents/ChevronComponent.tsx
|
|
99
|
-
import { chevronLeft, chevronRight } from "@simplybusiness/icons";
|
|
100
|
-
import { Icon } from "@simplybusiness/mobius";
|
|
101
|
-
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
102
|
-
var ChevronComponent = ({ orientation }) => {
|
|
103
|
-
if (orientation === "left") {
|
|
104
|
-
return /* @__PURE__ */ jsx3(Icon, { icon: chevronLeft });
|
|
105
|
-
}
|
|
106
|
-
return /* @__PURE__ */ jsx3(Icon, { icon: chevronRight });
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
// src/components/DatePicker/DatePickerModal.tsx
|
|
110
|
-
import { jsx as jsx4, jsxs } from "react/jsx-runtime";
|
|
111
|
-
var startWeekday = getStartWeekday(
|
|
112
|
-
// eslint-disable-next-line ssr-friendly/no-dom-globals-in-module-scope
|
|
113
|
-
typeof navigator !== "undefined" ? navigator?.language : void 0
|
|
114
|
-
);
|
|
115
|
-
var DatePickerModal = ({
|
|
116
|
-
date,
|
|
117
|
-
isOpen,
|
|
118
|
-
onSelected,
|
|
119
|
-
top,
|
|
120
|
-
min,
|
|
121
|
-
max
|
|
122
|
-
}) => {
|
|
123
|
-
const modalRef = useRef2(null);
|
|
124
|
-
const initialDate = date ? toLocal(date) : void 0;
|
|
125
|
-
const minDate = min ? toLocal(min) : void 0;
|
|
126
|
-
const maxDate = max ? toLocal(max) : void 0;
|
|
127
|
-
const hiddenId = `screen-reader-title-${useId()}`;
|
|
128
|
-
const handleSelected = (selectedDate) => {
|
|
129
|
-
onSelected(selectedDate);
|
|
130
|
-
};
|
|
131
|
-
const handleDayPickerSelect = (selectedDate) => {
|
|
132
|
-
if (!selectedDate) return;
|
|
133
|
-
handleSelected(dateObjToString(selectedDate));
|
|
134
|
-
};
|
|
135
|
-
useOnClickOutside(modalRef, () => {
|
|
136
|
-
if (modalRef.current && isOpen) {
|
|
137
|
-
handleSelected();
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
const modalClasses = classNames("mobius-date-picker__modal", {
|
|
141
|
-
"--is-open": isOpen
|
|
142
|
-
});
|
|
143
|
-
return /* @__PURE__ */ jsx4(FocusTrap, { children: /* @__PURE__ */ jsxs(
|
|
144
|
-
"div",
|
|
145
|
-
{
|
|
146
|
-
ref: modalRef,
|
|
147
|
-
className: modalClasses,
|
|
148
|
-
style: { top },
|
|
149
|
-
"aria-describedby": hiddenId,
|
|
150
|
-
"data-testid": "modal-container",
|
|
151
|
-
children: [
|
|
152
|
-
/* @__PURE__ */ jsx4(VisuallyHidden, { children: /* @__PURE__ */ jsx4("div", { id: hiddenId, children: "Please select a date from the calendar" }) }),
|
|
153
|
-
/* @__PURE__ */ jsx4(
|
|
154
|
-
DayPicker,
|
|
155
|
-
{
|
|
156
|
-
autoFocus: true,
|
|
157
|
-
mode: "single",
|
|
158
|
-
...minDate && { startMonth: minDate },
|
|
159
|
-
...maxDate && { endMonth: maxDate },
|
|
160
|
-
disabled: {
|
|
161
|
-
...min && { before: parseISO(min) },
|
|
162
|
-
...max && { after: parseISO(max) }
|
|
163
|
-
},
|
|
164
|
-
selected: initialDate,
|
|
165
|
-
defaultMonth: initialDate,
|
|
166
|
-
onSelect: handleDayPickerSelect,
|
|
167
|
-
pagedNavigation: true,
|
|
168
|
-
showOutsideDays: true,
|
|
169
|
-
weekStartsOn: startWeekday,
|
|
170
|
-
formatters: { formatWeekdayName: weekdayAsOneLetter },
|
|
171
|
-
components: {
|
|
172
|
-
Chevron: ChevronComponent,
|
|
173
|
-
CaptionLabel
|
|
174
|
-
},
|
|
175
|
-
classNames: {
|
|
176
|
-
root: "mobius-date-picker__root",
|
|
177
|
-
months: "mobius-date-picker__months",
|
|
178
|
-
month: "mobius-date-picker__month",
|
|
179
|
-
nav: "mobius-date-picker__nav",
|
|
180
|
-
button_previous: "mobius-date-picker__nav-button --previous",
|
|
181
|
-
button_next: "mobius-date-picker__nav-button --next",
|
|
182
|
-
month_caption: "mobius-date-picker__caption",
|
|
183
|
-
caption_label: "mobius-date-picker__caption-label",
|
|
184
|
-
month_grid: "mobius-date-picker__month-grid",
|
|
185
|
-
weekdays: "mobius-date-picker__weekdays",
|
|
186
|
-
weekday: "mobius-date-picker__weekday",
|
|
187
|
-
weeks: "mobius-date-picker__weeks",
|
|
188
|
-
week: "mobius-date-picker__week",
|
|
189
|
-
day: "mobius-date-picker__day",
|
|
190
|
-
day_button: "mobius-date-picker__day-button",
|
|
191
|
-
selected: "--is-selected",
|
|
192
|
-
disabled: "--is-disabled",
|
|
193
|
-
outside: "--is-outside",
|
|
194
|
-
hidden: "--is-hidden",
|
|
195
|
-
today: "--is-today",
|
|
196
|
-
focused: "--is-focused"
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
)
|
|
200
|
-
]
|
|
201
|
-
}
|
|
202
|
-
) });
|
|
203
|
-
};
|
|
204
|
-
var DatePickerModal_default = DatePickerModal;
|
|
205
|
-
export {
|
|
206
|
-
DatePickerModal_default as default
|
|
207
|
-
};
|
|
208
|
-
//# sourceMappingURL=DatePickerModal-WRMRIQDP.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/components/DatePicker/DatePickerModal.tsx", "../../src/hooks/useFocusTrap/useFocusTrap.tsx", "../../src/components/DatePicker/utils/dateObjToString.ts", "../../src/components/DatePicker/constants.ts", "../../src/components/DatePicker/utils/weekdayAsOneLetter.ts", "../../src/components/DatePicker/utils/getStartWeekday.ts", "../../src/components/DatePicker/utils/timezoneOffset.ts", "../../src/components/DatePicker/CustomComponents/CaptionLabel.tsx", "../../src/components/DatePicker/CustomComponents/ChevronComponent.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\";\n\nimport { VisuallyHidden, useOnClickOutside } from \"@simplybusiness/mobius\";\nimport classNames from \"classnames/dedupe\";\nimport { parseISO } from \"date-fns\";\nimport { useId, useRef } from \"react\";\nimport type { Matcher } from \"react-day-picker\";\nimport { DayPicker } from \"react-day-picker\";\nimport FocusTrap from \"../../hooks/useFocusTrap/useFocusTrap\";\nimport { dateObjToString, weekdayAsOneLetter } from \"./utils\";\nimport { getStartWeekday } from \"./utils/getStartWeekday\";\nimport { toLocal } from \"./utils/timezoneOffset\";\nimport { ChevronComponent, CaptionLabel } from \"./CustomComponents\";\n\nexport type DatePickerModalProps = {\n date?: string; // yyyy-mm-dd\n isOpen: boolean;\n top: number;\n onSelected: (date?: string) => void;\n min?: string;\n max?: string;\n};\n\nconst startWeekday = getStartWeekday(\n // eslint-disable-next-line ssr-friendly/no-dom-globals-in-module-scope\n typeof navigator !== \"undefined\" ? navigator?.language : undefined,\n);\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 ? toLocal(date) : undefined;\n const minDate = min ? toLocal(min) : undefined;\n const maxDate = max ? toLocal(max) : undefined;\n const hiddenId = `screen-reader-title-${useId()}`;\n\n const handleSelected = (selectedDate?: string) => {\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-date-picker__modal\", {\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 autoFocus\n mode=\"single\"\n {...(minDate && { startMonth: minDate })}\n {...(maxDate && { endMonth: maxDate })}\n disabled={\n {\n ...(min && { before: parseISO(min) }),\n ...(max && { after: parseISO(max) }),\n } as Matcher\n }\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 CaptionLabel,\n }}\n classNames={{\n root: \"mobius-date-picker__root\",\n months: \"mobius-date-picker__months\",\n month: \"mobius-date-picker__month\",\n nav: \"mobius-date-picker__nav\",\n button_previous: \"mobius-date-picker__nav-button --previous\",\n button_next: \"mobius-date-picker__nav-button --next\",\n month_caption: \"mobius-date-picker__caption\",\n caption_label: \"mobius-date-picker__caption-label\",\n month_grid: \"mobius-date-picker__month-grid\",\n weekdays: \"mobius-date-picker__weekdays\",\n weekday: \"mobius-date-picker__weekday\",\n weeks: \"mobius-date-picker__weeks\",\n week: \"mobius-date-picker__week\",\n day: \"mobius-date-picker__day\",\n day_button: \"mobius-date-picker__day-button\",\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", "import type { ReactNode } from \"react\";\nimport { useEffect, useRef } from \"react\";\n\nconst useFocusTrap = () => {\n const containerRef = useRef<HTMLDivElement | null>(null);\n\n useEffect(() => {\n if (containerRef.current) {\n const element = containerRef.current;\n const focusableElements =\n containerRef.current.querySelectorAll<HTMLElement>(\n '[tabindex=\"0\"], .mobius-date-picker__nav-button',\n );\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n\n const handleTabKeyPress = (event: KeyboardEvent) => {\n if (event.key === \"Tab\") {\n if (event.shiftKey && document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n } else if (\n !event.shiftKey &&\n document.activeElement &&\n document.activeElement.className.indexOf(\n \"mobius-date-picker__day-button\",\n ) > -1\n ) {\n event.preventDefault();\n firstElement.focus();\n }\n }\n };\n\n element.addEventListener(\"keydown\", handleTabKeyPress);\n return () => {\n element.removeEventListener(\"keydown\", handleTabKeyPress);\n };\n }\n return () => {};\n }, []);\n\n return containerRef;\n};\n\nexport type FocusTrapProps = {\n children: ReactNode;\n};\n\nexport default function FocusTrap({ children }: FocusTrapProps) {\n const focusRef = useFocusTrap();\n\n return (\n <div className=\"trap\" ref={focusRef}>\n {children}\n </div>\n );\n}\n", "export const dateObjToString = (date: Date) => {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n const day = String(date.getDate()).padStart(2, \"0\");\n\n // Extract the date part from the Date object\n return `${year}-${month}-${day}`;\n};\n", "export const SUNDAY_AS_NUMBER = 0;\nexport const MONDAY_AS_NUMBER = 1;\nexport const DEFAULT_LOCALE = \"en-GB\";\n", "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", "import {\n DEFAULT_LOCALE,\n MONDAY_AS_NUMBER,\n SUNDAY_AS_NUMBER,\n} from \"../constants\";\n\ntype WeekStart = 0 | 1 | 2 | 3 | 4 | 5 | 6 | undefined;\n\n// Calculates start of week for calendar in UK and US locales\n// Add more to the switch statement as needed\nexport const getStartWeekday = (locale?: string): WeekStart => {\n switch (locale || DEFAULT_LOCALE) {\n case \"en-US\":\n return SUNDAY_AS_NUMBER;\n\n default:\n return MONDAY_AS_NUMBER;\n }\n};\n", "/**\n * Converts a local date-time to UTC\n * @param localDate - Date object in local timezone\n * @returns Date object in UTC\n */\nexport function toUTC(localDate: Date): Date {\n return new Date(localDate.getTime() - localDate.getTimezoneOffset() * 60000);\n}\n\nexport function toLocal(utcDateString: string): Date {\n const utcDate = new Date(utcDateString);\n if (Number.isNaN(utcDate.getTime())) {\n throw new Error(\"Invalid date string\");\n }\n // Convert UTC date to local date\n // by adding the timezone offset in milliseconds\n return new Date(utcDate.getTime() + utcDate.getTimezoneOffset() * 60000);\n}\n", "import { type HTMLAttributes } from \"react\";\n\n/**\n *\n * This component is used to render the caption label for the date picker.\n * We are overriding the standard span with an h2 for accessibility reasons.\n */\nexport const CaptionLabel = (props: HTMLAttributes<HTMLSpanElement>) => {\n return <h2 {...props} />;\n};\n", "import { chevronLeft, chevronRight } from \"@simplybusiness/icons\";\nimport { Icon } from \"@simplybusiness/mobius\";\n\ntype ChevronComponentProps = {\n orientation?: \"up\" | \"down\" | \"left\" | \"right\";\n};\n\nexport const ChevronComponent = ({ orientation }: ChevronComponentProps) => {\n if (orientation === \"left\") {\n return <Icon icon={chevronLeft} />;\n }\n return <Icon icon={chevronRight} />;\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["useRef", "jsx", "jsx", "jsx", "useRef"]
|
|
7
|
-
}
|