sanity-plugin-recurring-dates 1.4.0 → 2.0.0

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/dist/index.esm.js DELETED
@@ -1,4945 +0,0 @@
1
- import { set, unset, ObjectInputMember, defineField, definePlugin } from 'sanity';
2
- import { ChevronLeftIcon, ChevronRightIcon, CalendarIcon, WarningOutlineIcon, TrashIcon } from '@sanity/icons';
3
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
- import { Card, Text, Box, Grid, TextInput, useForwardedRef, Flex, Select, Button, useClickOutside, LayerProvider, Popover, Stack, Dialog, Radio } from '@sanity/ui';
5
- import { range, upperFirst } from 'lodash';
6
- import * as React from 'react';
7
- import React__default, { useState, useEffect, PureComponent, useCallback, forwardRef, useRef, useMemo } from 'react';
8
- import { rrulestr, Weekday, RRule, datetime } from 'rrule';
9
- import { Feedback } from 'sanity-plugin-utils';
10
- import { toDate as toDate$1, format as format$1 } from 'date-fns-tz';
11
- import { format, parse, DEFAULT_DATE_FORMAT as DEFAULT_DATE_FORMAT$1, DEFAULT_TIME_FORMAT } from '@sanity/util/legacyDateFormat';
12
- const DEFAULT_RECURRENCES = ["RRULE:FREQ=DAILY;INTERVAL=1", "RRULE:FREQ=WEEKLY;INTERVAL=1", "RRULE:FREQ=MONTHLY;INTERVAL=1", "RRULE:FREQ=YEARLY;INTERVAL=1"];
13
- const DEFAULT_CONFIG = {
14
- defaultRecurrences: DEFAULT_RECURRENCES
15
- };
16
- const DAYS = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];
17
- const DEFAULT_COUNTS = [5,
18
- // yearly
19
- 12,
20
- // monthly
21
- 12,
22
- // weekly
23
- 30
24
- // daily
25
- ];
26
- const validateRRuleString = recurrence => {
27
- try {
28
- rrulestr(recurrence);
29
- return false;
30
- } catch (e) {
31
- return true;
32
- }
33
- };
34
- const validateRRuleStrings = recurrences => {
35
- return recurrences.some(recurrence => {
36
- return validateRRuleString(recurrence);
37
- });
38
- };
39
- function _objectWithoutPropertiesLoose(r, e) {
40
- if (null == r) return {};
41
- var t = {};
42
- for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
43
- if (e.includes(n)) continue;
44
- t[n] = r[n];
45
- }
46
- return t;
47
- }
48
- function _extends() {
49
- return _extends = Object.assign ? Object.assign.bind() : function (n) {
50
- for (var e = 1; e < arguments.length; e++) {
51
- var t = arguments[e];
52
- for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
53
- }
54
- return n;
55
- }, _extends.apply(null, arguments);
56
- }
57
- function getDefaultExportFromCjs(x) {
58
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
59
- }
60
- var propTypes$1 = {
61
- exports: {}
62
- };
63
- var reactIs = {
64
- exports: {}
65
- };
66
- var reactIs_production_min = {};
67
-
68
- /** @license React v16.13.1
69
- * react-is.production.min.js
70
- *
71
- * Copyright (c) Facebook, Inc. and its affiliates.
72
- *
73
- * This source code is licensed under the MIT license found in the
74
- * LICENSE file in the root directory of this source tree.
75
- */
76
-
77
- var hasRequiredReactIs_production_min;
78
- function requireReactIs_production_min() {
79
- if (hasRequiredReactIs_production_min) return reactIs_production_min;
80
- hasRequiredReactIs_production_min = 1;
81
- var b = "function" === typeof Symbol && Symbol.for,
82
- c = b ? Symbol.for("react.element") : 60103,
83
- d = b ? Symbol.for("react.portal") : 60106,
84
- e = b ? Symbol.for("react.fragment") : 60107,
85
- f = b ? Symbol.for("react.strict_mode") : 60108,
86
- g = b ? Symbol.for("react.profiler") : 60114,
87
- h = b ? Symbol.for("react.provider") : 60109,
88
- k = b ? Symbol.for("react.context") : 60110,
89
- l = b ? Symbol.for("react.async_mode") : 60111,
90
- m = b ? Symbol.for("react.concurrent_mode") : 60111,
91
- n = b ? Symbol.for("react.forward_ref") : 60112,
92
- p = b ? Symbol.for("react.suspense") : 60113,
93
- q = b ? Symbol.for("react.suspense_list") : 60120,
94
- r = b ? Symbol.for("react.memo") : 60115,
95
- t = b ? Symbol.for("react.lazy") : 60116,
96
- v = b ? Symbol.for("react.block") : 60121,
97
- w = b ? Symbol.for("react.fundamental") : 60117,
98
- x = b ? Symbol.for("react.responder") : 60118,
99
- y = b ? Symbol.for("react.scope") : 60119;
100
- function z(a) {
101
- if ("object" === typeof a && null !== a) {
102
- var u = a.$$typeof;
103
- switch (u) {
104
- case c:
105
- switch (a = a.type, a) {
106
- case l:
107
- case m:
108
- case e:
109
- case g:
110
- case f:
111
- case p:
112
- return a;
113
- default:
114
- switch (a = a && a.$$typeof, a) {
115
- case k:
116
- case n:
117
- case t:
118
- case r:
119
- case h:
120
- return a;
121
- default:
122
- return u;
123
- }
124
- }
125
- case d:
126
- return u;
127
- }
128
- }
129
- }
130
- function A(a) {
131
- return z(a) === m;
132
- }
133
- reactIs_production_min.AsyncMode = l;
134
- reactIs_production_min.ConcurrentMode = m;
135
- reactIs_production_min.ContextConsumer = k;
136
- reactIs_production_min.ContextProvider = h;
137
- reactIs_production_min.Element = c;
138
- reactIs_production_min.ForwardRef = n;
139
- reactIs_production_min.Fragment = e;
140
- reactIs_production_min.Lazy = t;
141
- reactIs_production_min.Memo = r;
142
- reactIs_production_min.Portal = d;
143
- reactIs_production_min.Profiler = g;
144
- reactIs_production_min.StrictMode = f;
145
- reactIs_production_min.Suspense = p;
146
- reactIs_production_min.isAsyncMode = function (a) {
147
- return A(a) || z(a) === l;
148
- };
149
- reactIs_production_min.isConcurrentMode = A;
150
- reactIs_production_min.isContextConsumer = function (a) {
151
- return z(a) === k;
152
- };
153
- reactIs_production_min.isContextProvider = function (a) {
154
- return z(a) === h;
155
- };
156
- reactIs_production_min.isElement = function (a) {
157
- return "object" === typeof a && null !== a && a.$$typeof === c;
158
- };
159
- reactIs_production_min.isForwardRef = function (a) {
160
- return z(a) === n;
161
- };
162
- reactIs_production_min.isFragment = function (a) {
163
- return z(a) === e;
164
- };
165
- reactIs_production_min.isLazy = function (a) {
166
- return z(a) === t;
167
- };
168
- reactIs_production_min.isMemo = function (a) {
169
- return z(a) === r;
170
- };
171
- reactIs_production_min.isPortal = function (a) {
172
- return z(a) === d;
173
- };
174
- reactIs_production_min.isProfiler = function (a) {
175
- return z(a) === g;
176
- };
177
- reactIs_production_min.isStrictMode = function (a) {
178
- return z(a) === f;
179
- };
180
- reactIs_production_min.isSuspense = function (a) {
181
- return z(a) === p;
182
- };
183
- reactIs_production_min.isValidElementType = function (a) {
184
- return "string" === typeof a || "function" === typeof a || a === e || a === m || a === g || a === f || a === p || a === q || "object" === typeof a && null !== a && (a.$$typeof === t || a.$$typeof === r || a.$$typeof === h || a.$$typeof === k || a.$$typeof === n || a.$$typeof === w || a.$$typeof === x || a.$$typeof === y || a.$$typeof === v);
185
- };
186
- reactIs_production_min.typeOf = z;
187
- return reactIs_production_min;
188
- }
189
- var reactIs_development = {};
190
-
191
- /** @license React v16.13.1
192
- * react-is.development.js
193
- *
194
- * Copyright (c) Facebook, Inc. and its affiliates.
195
- *
196
- * This source code is licensed under the MIT license found in the
197
- * LICENSE file in the root directory of this source tree.
198
- */
199
-
200
- var hasRequiredReactIs_development;
201
- function requireReactIs_development() {
202
- if (hasRequiredReactIs_development) return reactIs_development;
203
- hasRequiredReactIs_development = 1;
204
- if (process.env.NODE_ENV !== "production") {
205
- (function () {
206
- // The Symbol used to tag the ReactElement-like types. If there is no native Symbol
207
- // nor polyfill, then a plain number is used for performance.
208
- var hasSymbol = typeof Symbol === 'function' && Symbol.for;
209
- var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
210
- var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
211
- var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
212
- var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
213
- var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
214
- var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
215
- var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
216
- // (unstable) APIs that have been removed. Can we remove the symbols?
217
-
218
- var REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol.for('react.async_mode') : 0xeacf;
219
- var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
220
- var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
221
- var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
222
- var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;
223
- var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
224
- var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
225
- var REACT_BLOCK_TYPE = hasSymbol ? Symbol.for('react.block') : 0xead9;
226
- var REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for('react.fundamental') : 0xead5;
227
- var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for('react.responder') : 0xead6;
228
- var REACT_SCOPE_TYPE = hasSymbol ? Symbol.for('react.scope') : 0xead7;
229
- function isValidElementType(type) {
230
- return typeof type === 'string' || typeof type === 'function' ||
231
- // Note: its typeof might be other than 'symbol' or 'number' if it's a polyfill.
232
- type === REACT_FRAGMENT_TYPE || type === REACT_CONCURRENT_MODE_TYPE || type === REACT_PROFILER_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || typeof type === 'object' && type !== null && (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_FUNDAMENTAL_TYPE || type.$$typeof === REACT_RESPONDER_TYPE || type.$$typeof === REACT_SCOPE_TYPE || type.$$typeof === REACT_BLOCK_TYPE);
233
- }
234
- function typeOf(object) {
235
- if (typeof object === 'object' && object !== null) {
236
- var $$typeof = object.$$typeof;
237
- switch ($$typeof) {
238
- case REACT_ELEMENT_TYPE:
239
- var type = object.type;
240
- switch (type) {
241
- case REACT_ASYNC_MODE_TYPE:
242
- case REACT_CONCURRENT_MODE_TYPE:
243
- case REACT_FRAGMENT_TYPE:
244
- case REACT_PROFILER_TYPE:
245
- case REACT_STRICT_MODE_TYPE:
246
- case REACT_SUSPENSE_TYPE:
247
- return type;
248
- default:
249
- var $$typeofType = type && type.$$typeof;
250
- switch ($$typeofType) {
251
- case REACT_CONTEXT_TYPE:
252
- case REACT_FORWARD_REF_TYPE:
253
- case REACT_LAZY_TYPE:
254
- case REACT_MEMO_TYPE:
255
- case REACT_PROVIDER_TYPE:
256
- return $$typeofType;
257
- default:
258
- return $$typeof;
259
- }
260
- }
261
- case REACT_PORTAL_TYPE:
262
- return $$typeof;
263
- }
264
- }
265
- return undefined;
266
- } // AsyncMode is deprecated along with isAsyncMode
267
-
268
- var AsyncMode = REACT_ASYNC_MODE_TYPE;
269
- var ConcurrentMode = REACT_CONCURRENT_MODE_TYPE;
270
- var ContextConsumer = REACT_CONTEXT_TYPE;
271
- var ContextProvider = REACT_PROVIDER_TYPE;
272
- var Element = REACT_ELEMENT_TYPE;
273
- var ForwardRef = REACT_FORWARD_REF_TYPE;
274
- var Fragment = REACT_FRAGMENT_TYPE;
275
- var Lazy = REACT_LAZY_TYPE;
276
- var Memo = REACT_MEMO_TYPE;
277
- var Portal = REACT_PORTAL_TYPE;
278
- var Profiler = REACT_PROFILER_TYPE;
279
- var StrictMode = REACT_STRICT_MODE_TYPE;
280
- var Suspense = REACT_SUSPENSE_TYPE;
281
- var hasWarnedAboutDeprecatedIsAsyncMode = false; // AsyncMode should be deprecated
282
-
283
- function isAsyncMode(object) {
284
- {
285
- if (!hasWarnedAboutDeprecatedIsAsyncMode) {
286
- hasWarnedAboutDeprecatedIsAsyncMode = true; // Using console['warn'] to evade Babel and ESLint
287
-
288
- console['warn']('The ReactIs.isAsyncMode() alias has been deprecated, ' + 'and will be removed in React 17+. Update your code to use ' + 'ReactIs.isConcurrentMode() instead. It has the exact same API.');
289
- }
290
- }
291
- return isConcurrentMode(object) || typeOf(object) === REACT_ASYNC_MODE_TYPE;
292
- }
293
- function isConcurrentMode(object) {
294
- return typeOf(object) === REACT_CONCURRENT_MODE_TYPE;
295
- }
296
- function isContextConsumer(object) {
297
- return typeOf(object) === REACT_CONTEXT_TYPE;
298
- }
299
- function isContextProvider(object) {
300
- return typeOf(object) === REACT_PROVIDER_TYPE;
301
- }
302
- function isElement(object) {
303
- return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
304
- }
305
- function isForwardRef(object) {
306
- return typeOf(object) === REACT_FORWARD_REF_TYPE;
307
- }
308
- function isFragment(object) {
309
- return typeOf(object) === REACT_FRAGMENT_TYPE;
310
- }
311
- function isLazy(object) {
312
- return typeOf(object) === REACT_LAZY_TYPE;
313
- }
314
- function isMemo(object) {
315
- return typeOf(object) === REACT_MEMO_TYPE;
316
- }
317
- function isPortal(object) {
318
- return typeOf(object) === REACT_PORTAL_TYPE;
319
- }
320
- function isProfiler(object) {
321
- return typeOf(object) === REACT_PROFILER_TYPE;
322
- }
323
- function isStrictMode(object) {
324
- return typeOf(object) === REACT_STRICT_MODE_TYPE;
325
- }
326
- function isSuspense(object) {
327
- return typeOf(object) === REACT_SUSPENSE_TYPE;
328
- }
329
- reactIs_development.AsyncMode = AsyncMode;
330
- reactIs_development.ConcurrentMode = ConcurrentMode;
331
- reactIs_development.ContextConsumer = ContextConsumer;
332
- reactIs_development.ContextProvider = ContextProvider;
333
- reactIs_development.Element = Element;
334
- reactIs_development.ForwardRef = ForwardRef;
335
- reactIs_development.Fragment = Fragment;
336
- reactIs_development.Lazy = Lazy;
337
- reactIs_development.Memo = Memo;
338
- reactIs_development.Portal = Portal;
339
- reactIs_development.Profiler = Profiler;
340
- reactIs_development.StrictMode = StrictMode;
341
- reactIs_development.Suspense = Suspense;
342
- reactIs_development.isAsyncMode = isAsyncMode;
343
- reactIs_development.isConcurrentMode = isConcurrentMode;
344
- reactIs_development.isContextConsumer = isContextConsumer;
345
- reactIs_development.isContextProvider = isContextProvider;
346
- reactIs_development.isElement = isElement;
347
- reactIs_development.isForwardRef = isForwardRef;
348
- reactIs_development.isFragment = isFragment;
349
- reactIs_development.isLazy = isLazy;
350
- reactIs_development.isMemo = isMemo;
351
- reactIs_development.isPortal = isPortal;
352
- reactIs_development.isProfiler = isProfiler;
353
- reactIs_development.isStrictMode = isStrictMode;
354
- reactIs_development.isSuspense = isSuspense;
355
- reactIs_development.isValidElementType = isValidElementType;
356
- reactIs_development.typeOf = typeOf;
357
- })();
358
- }
359
- return reactIs_development;
360
- }
361
- var hasRequiredReactIs;
362
- function requireReactIs() {
363
- if (hasRequiredReactIs) return reactIs.exports;
364
- hasRequiredReactIs = 1;
365
- if (process.env.NODE_ENV === 'production') {
366
- reactIs.exports = requireReactIs_production_min();
367
- } else {
368
- reactIs.exports = requireReactIs_development();
369
- }
370
- return reactIs.exports;
371
- }
372
-
373
- /*
374
- object-assign
375
- (c) Sindre Sorhus
376
- @license MIT
377
- */
378
-
379
- var objectAssign;
380
- var hasRequiredObjectAssign;
381
- function requireObjectAssign() {
382
- if (hasRequiredObjectAssign) return objectAssign;
383
- hasRequiredObjectAssign = 1;
384
- /* eslint-disable no-unused-vars */
385
- var getOwnPropertySymbols = Object.getOwnPropertySymbols;
386
- var hasOwnProperty = Object.prototype.hasOwnProperty;
387
- var propIsEnumerable = Object.prototype.propertyIsEnumerable;
388
- function toObject(val) {
389
- if (val === null || val === undefined) {
390
- throw new TypeError('Object.assign cannot be called with null or undefined');
391
- }
392
- return Object(val);
393
- }
394
- function shouldUseNative() {
395
- try {
396
- if (!Object.assign) {
397
- return false;
398
- }
399
-
400
- // Detect buggy property enumeration order in older V8 versions.
401
-
402
- // https://bugs.chromium.org/p/v8/issues/detail?id=4118
403
- var test1 = new String('abc'); // eslint-disable-line no-new-wrappers
404
- test1[5] = 'de';
405
- if (Object.getOwnPropertyNames(test1)[0] === '5') {
406
- return false;
407
- }
408
-
409
- // https://bugs.chromium.org/p/v8/issues/detail?id=3056
410
- var test2 = {};
411
- for (var i = 0; i < 10; i++) {
412
- test2['_' + String.fromCharCode(i)] = i;
413
- }
414
- var order2 = Object.getOwnPropertyNames(test2).map(function (n) {
415
- return test2[n];
416
- });
417
- if (order2.join('') !== '0123456789') {
418
- return false;
419
- }
420
-
421
- // https://bugs.chromium.org/p/v8/issues/detail?id=3056
422
- var test3 = {};
423
- 'abcdefghijklmnopqrst'.split('').forEach(function (letter) {
424
- test3[letter] = letter;
425
- });
426
- if (Object.keys(Object.assign({}, test3)).join('') !== 'abcdefghijklmnopqrst') {
427
- return false;
428
- }
429
- return true;
430
- } catch (err) {
431
- // We don't expect any of the above to throw, but better to be safe.
432
- return false;
433
- }
434
- }
435
- objectAssign = shouldUseNative() ? Object.assign : function (target, source) {
436
- var from;
437
- var to = toObject(target);
438
- var symbols;
439
- for (var s = 1; s < arguments.length; s++) {
440
- from = Object(arguments[s]);
441
- for (var key in from) {
442
- if (hasOwnProperty.call(from, key)) {
443
- to[key] = from[key];
444
- }
445
- }
446
- if (getOwnPropertySymbols) {
447
- symbols = getOwnPropertySymbols(from);
448
- for (var i = 0; i < symbols.length; i++) {
449
- if (propIsEnumerable.call(from, symbols[i])) {
450
- to[symbols[i]] = from[symbols[i]];
451
- }
452
- }
453
- }
454
- }
455
- return to;
456
- };
457
- return objectAssign;
458
- }
459
-
460
- /**
461
- * Copyright (c) 2013-present, Facebook, Inc.
462
- *
463
- * This source code is licensed under the MIT license found in the
464
- * LICENSE file in the root directory of this source tree.
465
- */
466
-
467
- var ReactPropTypesSecret_1;
468
- var hasRequiredReactPropTypesSecret;
469
- function requireReactPropTypesSecret() {
470
- if (hasRequiredReactPropTypesSecret) return ReactPropTypesSecret_1;
471
- hasRequiredReactPropTypesSecret = 1;
472
- var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
473
- ReactPropTypesSecret_1 = ReactPropTypesSecret;
474
- return ReactPropTypesSecret_1;
475
- }
476
- var has;
477
- var hasRequiredHas;
478
- function requireHas() {
479
- if (hasRequiredHas) return has;
480
- hasRequiredHas = 1;
481
- has = Function.call.bind(Object.prototype.hasOwnProperty);
482
- return has;
483
- }
484
-
485
- /**
486
- * Copyright (c) 2013-present, Facebook, Inc.
487
- *
488
- * This source code is licensed under the MIT license found in the
489
- * LICENSE file in the root directory of this source tree.
490
- */
491
-
492
- var checkPropTypes_1;
493
- var hasRequiredCheckPropTypes;
494
- function requireCheckPropTypes() {
495
- if (hasRequiredCheckPropTypes) return checkPropTypes_1;
496
- hasRequiredCheckPropTypes = 1;
497
- var printWarning = function () {};
498
- if (process.env.NODE_ENV !== 'production') {
499
- var ReactPropTypesSecret = requireReactPropTypesSecret();
500
- var loggedTypeFailures = {};
501
- var has = requireHas();
502
- printWarning = function (text) {
503
- var message = 'Warning: ' + text;
504
- if (typeof console !== 'undefined') {
505
- console.error(message);
506
- }
507
- try {
508
- // --- Welcome to debugging React ---
509
- // This error was thrown as a convenience so that you can use this stack
510
- // to find the callsite that caused this warning to fire.
511
- throw new Error(message);
512
- } catch (x) {/**/}
513
- };
514
- }
515
-
516
- /**
517
- * Assert that the values match with the type specs.
518
- * Error messages are memorized and will only be shown once.
519
- *
520
- * @param {object} typeSpecs Map of name to a ReactPropType
521
- * @param {object} values Runtime values that need to be type-checked
522
- * @param {string} location e.g. "prop", "context", "child context"
523
- * @param {string} componentName Name of the component for error messages.
524
- * @param {?Function} getStack Returns the component stack.
525
- * @private
526
- */
527
- function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
528
- if (process.env.NODE_ENV !== 'production') {
529
- for (var typeSpecName in typeSpecs) {
530
- if (has(typeSpecs, typeSpecName)) {
531
- var error;
532
- // Prop type validation may throw. In case they do, we don't want to
533
- // fail the render phase where it didn't fail before. So we log it.
534
- // After these have been cleaned up, we'll let them throw.
535
- try {
536
- // This is intentionally an invariant that gets caught. It's the same
537
- // behavior as without this statement except with a better message.
538
- if (typeof typeSpecs[typeSpecName] !== 'function') {
539
- var err = Error((componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' + 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.' + 'This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.');
540
- err.name = 'Invariant Violation';
541
- throw err;
542
- }
543
- error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
544
- } catch (ex) {
545
- error = ex;
546
- }
547
- if (error && !(error instanceof Error)) {
548
- printWarning((componentName || 'React class') + ': type specification of ' + location + ' `' + typeSpecName + '` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).');
549
- }
550
- if (error instanceof Error && !(error.message in loggedTypeFailures)) {
551
- // Only monitor this failure once because there tends to be a lot of the
552
- // same error.
553
- loggedTypeFailures[error.message] = true;
554
- var stack = getStack ? getStack() : '';
555
- printWarning('Failed ' + location + ' type: ' + error.message + (stack != null ? stack : ''));
556
- }
557
- }
558
- }
559
- }
560
- }
561
-
562
- /**
563
- * Resets warning cache when testing.
564
- *
565
- * @private
566
- */
567
- checkPropTypes.resetWarningCache = function () {
568
- if (process.env.NODE_ENV !== 'production') {
569
- loggedTypeFailures = {};
570
- }
571
- };
572
- checkPropTypes_1 = checkPropTypes;
573
- return checkPropTypes_1;
574
- }
575
-
576
- /**
577
- * Copyright (c) 2013-present, Facebook, Inc.
578
- *
579
- * This source code is licensed under the MIT license found in the
580
- * LICENSE file in the root directory of this source tree.
581
- */
582
-
583
- var factoryWithTypeCheckers;
584
- var hasRequiredFactoryWithTypeCheckers;
585
- function requireFactoryWithTypeCheckers() {
586
- if (hasRequiredFactoryWithTypeCheckers) return factoryWithTypeCheckers;
587
- hasRequiredFactoryWithTypeCheckers = 1;
588
- var ReactIs = requireReactIs();
589
- var assign = requireObjectAssign();
590
- var ReactPropTypesSecret = requireReactPropTypesSecret();
591
- var has = requireHas();
592
- var checkPropTypes = requireCheckPropTypes();
593
- var printWarning = function () {};
594
- if (process.env.NODE_ENV !== 'production') {
595
- printWarning = function (text) {
596
- var message = 'Warning: ' + text;
597
- if (typeof console !== 'undefined') {
598
- console.error(message);
599
- }
600
- try {
601
- // --- Welcome to debugging React ---
602
- // This error was thrown as a convenience so that you can use this stack
603
- // to find the callsite that caused this warning to fire.
604
- throw new Error(message);
605
- } catch (x) {}
606
- };
607
- }
608
- function emptyFunctionThatReturnsNull() {
609
- return null;
610
- }
611
- factoryWithTypeCheckers = function (isValidElement, throwOnDirectAccess) {
612
- /* global Symbol */
613
- var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
614
- var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec.
615
-
616
- /**
617
- * Returns the iterator method function contained on the iterable object.
618
- *
619
- * Be sure to invoke the function with the iterable as context:
620
- *
621
- * var iteratorFn = getIteratorFn(myIterable);
622
- * if (iteratorFn) {
623
- * var iterator = iteratorFn.call(myIterable);
624
- * ...
625
- * }
626
- *
627
- * @param {?object} maybeIterable
628
- * @return {?function}
629
- */
630
- function getIteratorFn(maybeIterable) {
631
- var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]);
632
- if (typeof iteratorFn === 'function') {
633
- return iteratorFn;
634
- }
635
- }
636
-
637
- /**
638
- * Collection of methods that allow declaration and validation of props that are
639
- * supplied to React components. Example usage:
640
- *
641
- * var Props = require('ReactPropTypes');
642
- * var MyArticle = React.createClass({
643
- * propTypes: {
644
- * // An optional string prop named "description".
645
- * description: Props.string,
646
- *
647
- * // A required enum prop named "category".
648
- * category: Props.oneOf(['News','Photos']).isRequired,
649
- *
650
- * // A prop named "dialog" that requires an instance of Dialog.
651
- * dialog: Props.instanceOf(Dialog).isRequired
652
- * },
653
- * render: function() { ... }
654
- * });
655
- *
656
- * A more formal specification of how these methods are used:
657
- *
658
- * type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...)
659
- * decl := ReactPropTypes.{type}(.isRequired)?
660
- *
661
- * Each and every declaration produces a function with the same signature. This
662
- * allows the creation of custom validation functions. For example:
663
- *
664
- * var MyLink = React.createClass({
665
- * propTypes: {
666
- * // An optional string or URI prop named "href".
667
- * href: function(props, propName, componentName) {
668
- * var propValue = props[propName];
669
- * if (propValue != null && typeof propValue !== 'string' &&
670
- * !(propValue instanceof URI)) {
671
- * return new Error(
672
- * 'Expected a string or an URI for ' + propName + ' in ' +
673
- * componentName
674
- * );
675
- * }
676
- * }
677
- * },
678
- * render: function() {...}
679
- * });
680
- *
681
- * @internal
682
- */
683
-
684
- var ANONYMOUS = '<<anonymous>>';
685
-
686
- // Important!
687
- // Keep this list in sync with production version in `./factoryWithThrowingShims.js`.
688
- var ReactPropTypes = {
689
- array: createPrimitiveTypeChecker('array'),
690
- bigint: createPrimitiveTypeChecker('bigint'),
691
- bool: createPrimitiveTypeChecker('boolean'),
692
- func: createPrimitiveTypeChecker('function'),
693
- number: createPrimitiveTypeChecker('number'),
694
- object: createPrimitiveTypeChecker('object'),
695
- string: createPrimitiveTypeChecker('string'),
696
- symbol: createPrimitiveTypeChecker('symbol'),
697
- any: createAnyTypeChecker(),
698
- arrayOf: createArrayOfTypeChecker,
699
- element: createElementTypeChecker(),
700
- elementType: createElementTypeTypeChecker(),
701
- instanceOf: createInstanceTypeChecker,
702
- node: createNodeChecker(),
703
- objectOf: createObjectOfTypeChecker,
704
- oneOf: createEnumTypeChecker,
705
- oneOfType: createUnionTypeChecker,
706
- shape: createShapeTypeChecker,
707
- exact: createStrictShapeTypeChecker
708
- };
709
-
710
- /**
711
- * inlined Object.is polyfill to avoid requiring consumers ship their own
712
- * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
713
- */
714
- /*eslint-disable no-self-compare*/
715
- function is(x, y) {
716
- // SameValue algorithm
717
- if (x === y) {
718
- // Steps 1-5, 7-10
719
- // Steps 6.b-6.e: +0 != -0
720
- return x !== 0 || 1 / x === 1 / y;
721
- } else {
722
- // Step 6.a: NaN == NaN
723
- return x !== x && y !== y;
724
- }
725
- }
726
- /*eslint-enable no-self-compare*/
727
-
728
- /**
729
- * We use an Error-like object for backward compatibility as people may call
730
- * PropTypes directly and inspect their output. However, we don't use real
731
- * Errors anymore. We don't inspect their stack anyway, and creating them
732
- * is prohibitively expensive if they are created too often, such as what
733
- * happens in oneOfType() for any type before the one that matched.
734
- */
735
- function PropTypeError(message, data) {
736
- this.message = message;
737
- this.data = data && typeof data === 'object' ? data : {};
738
- this.stack = '';
739
- }
740
- // Make `instanceof Error` still work for returned errors.
741
- PropTypeError.prototype = Error.prototype;
742
- function createChainableTypeChecker(validate) {
743
- if (process.env.NODE_ENV !== 'production') {
744
- var manualPropTypeCallCache = {};
745
- var manualPropTypeWarningCount = 0;
746
- }
747
- function checkType(isRequired, props, propName, componentName, location, propFullName, secret) {
748
- componentName = componentName || ANONYMOUS;
749
- propFullName = propFullName || propName;
750
- if (secret !== ReactPropTypesSecret) {
751
- if (throwOnDirectAccess) {
752
- // New behavior only for users of `prop-types` package
753
- var err = new Error('Calling PropTypes validators directly is not supported by the `prop-types` package. ' + 'Use `PropTypes.checkPropTypes()` to call them. ' + 'Read more at http://fb.me/use-check-prop-types');
754
- err.name = 'Invariant Violation';
755
- throw err;
756
- } else if (process.env.NODE_ENV !== 'production' && typeof console !== 'undefined') {
757
- // Old behavior for people using React.PropTypes
758
- var cacheKey = componentName + ':' + propName;
759
- if (!manualPropTypeCallCache[cacheKey] &&
760
- // Avoid spamming the console because they are often not actionable except for lib authors
761
- manualPropTypeWarningCount < 3) {
762
- printWarning('You are manually calling a React.PropTypes validation ' + 'function for the `' + propFullName + '` prop on `' + componentName + '`. This is deprecated ' + 'and will throw in the standalone `prop-types` package. ' + 'You may be seeing this warning due to a third-party PropTypes ' + 'library. See https://fb.me/react-warning-dont-call-proptypes ' + 'for details.');
763
- manualPropTypeCallCache[cacheKey] = true;
764
- manualPropTypeWarningCount++;
765
- }
766
- }
767
- }
768
- if (props[propName] == null) {
769
- if (isRequired) {
770
- if (props[propName] === null) {
771
- return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.'));
772
- }
773
- return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required in ' + ('`' + componentName + '`, but its value is `undefined`.'));
774
- }
775
- return null;
776
- } else {
777
- return validate(props, propName, componentName, location, propFullName);
778
- }
779
- }
780
- var chainedCheckType = checkType.bind(null, false);
781
- chainedCheckType.isRequired = checkType.bind(null, true);
782
- return chainedCheckType;
783
- }
784
- function createPrimitiveTypeChecker(expectedType) {
785
- function validate(props, propName, componentName, location, propFullName, secret) {
786
- var propValue = props[propName];
787
- var propType = getPropType(propValue);
788
- if (propType !== expectedType) {
789
- // `propValue` being instance of, say, date/regexp, pass the 'object'
790
- // check, but we can offer a more precise error message here rather than
791
- // 'of type `object`'.
792
- var preciseType = getPreciseType(propValue);
793
- return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.'), {
794
- expectedType: expectedType
795
- });
796
- }
797
- return null;
798
- }
799
- return createChainableTypeChecker(validate);
800
- }
801
- function createAnyTypeChecker() {
802
- return createChainableTypeChecker(emptyFunctionThatReturnsNull);
803
- }
804
- function createArrayOfTypeChecker(typeChecker) {
805
- function validate(props, propName, componentName, location, propFullName) {
806
- if (typeof typeChecker !== 'function') {
807
- return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside arrayOf.');
808
- }
809
- var propValue = props[propName];
810
- if (!Array.isArray(propValue)) {
811
- var propType = getPropType(propValue);
812
- return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.'));
813
- }
814
- for (var i = 0; i < propValue.length; i++) {
815
- var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']', ReactPropTypesSecret);
816
- if (error instanceof Error) {
817
- return error;
818
- }
819
- }
820
- return null;
821
- }
822
- return createChainableTypeChecker(validate);
823
- }
824
- function createElementTypeChecker() {
825
- function validate(props, propName, componentName, location, propFullName) {
826
- var propValue = props[propName];
827
- if (!isValidElement(propValue)) {
828
- var propType = getPropType(propValue);
829
- return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement.'));
830
- }
831
- return null;
832
- }
833
- return createChainableTypeChecker(validate);
834
- }
835
- function createElementTypeTypeChecker() {
836
- function validate(props, propName, componentName, location, propFullName) {
837
- var propValue = props[propName];
838
- if (!ReactIs.isValidElementType(propValue)) {
839
- var propType = getPropType(propValue);
840
- return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement type.'));
841
- }
842
- return null;
843
- }
844
- return createChainableTypeChecker(validate);
845
- }
846
- function createInstanceTypeChecker(expectedClass) {
847
- function validate(props, propName, componentName, location, propFullName) {
848
- if (!(props[propName] instanceof expectedClass)) {
849
- var expectedClassName = expectedClass.name || ANONYMOUS;
850
- var actualClassName = getClassName(props[propName]);
851
- return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.'));
852
- }
853
- return null;
854
- }
855
- return createChainableTypeChecker(validate);
856
- }
857
- function createEnumTypeChecker(expectedValues) {
858
- if (!Array.isArray(expectedValues)) {
859
- if (process.env.NODE_ENV !== 'production') {
860
- if (arguments.length > 1) {
861
- printWarning('Invalid arguments supplied to oneOf, expected an array, got ' + arguments.length + ' arguments. ' + 'A common mistake is to write oneOf(x, y, z) instead of oneOf([x, y, z]).');
862
- } else {
863
- printWarning('Invalid argument supplied to oneOf, expected an array.');
864
- }
865
- }
866
- return emptyFunctionThatReturnsNull;
867
- }
868
- function validate(props, propName, componentName, location, propFullName) {
869
- var propValue = props[propName];
870
- for (var i = 0; i < expectedValues.length; i++) {
871
- if (is(propValue, expectedValues[i])) {
872
- return null;
873
- }
874
- }
875
- var valuesString = JSON.stringify(expectedValues, function replacer(key, value) {
876
- var type = getPreciseType(value);
877
- if (type === 'symbol') {
878
- return String(value);
879
- }
880
- return value;
881
- });
882
- return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of value `' + String(propValue) + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.'));
883
- }
884
- return createChainableTypeChecker(validate);
885
- }
886
- function createObjectOfTypeChecker(typeChecker) {
887
- function validate(props, propName, componentName, location, propFullName) {
888
- if (typeof typeChecker !== 'function') {
889
- return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside objectOf.');
890
- }
891
- var propValue = props[propName];
892
- var propType = getPropType(propValue);
893
- if (propType !== 'object') {
894
- return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an object.'));
895
- }
896
- for (var key in propValue) {
897
- if (has(propValue, key)) {
898
- var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret);
899
- if (error instanceof Error) {
900
- return error;
901
- }
902
- }
903
- }
904
- return null;
905
- }
906
- return createChainableTypeChecker(validate);
907
- }
908
- function createUnionTypeChecker(arrayOfTypeCheckers) {
909
- if (!Array.isArray(arrayOfTypeCheckers)) {
910
- process.env.NODE_ENV !== 'production' ? printWarning('Invalid argument supplied to oneOfType, expected an instance of array.') : void 0;
911
- return emptyFunctionThatReturnsNull;
912
- }
913
- for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
914
- var checker = arrayOfTypeCheckers[i];
915
- if (typeof checker !== 'function') {
916
- printWarning('Invalid argument supplied to oneOfType. Expected an array of check functions, but ' + 'received ' + getPostfixForTypeWarning(checker) + ' at index ' + i + '.');
917
- return emptyFunctionThatReturnsNull;
918
- }
919
- }
920
- function validate(props, propName, componentName, location, propFullName) {
921
- var expectedTypes = [];
922
- for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
923
- var checker = arrayOfTypeCheckers[i];
924
- var checkerResult = checker(props, propName, componentName, location, propFullName, ReactPropTypesSecret);
925
- if (checkerResult == null) {
926
- return null;
927
- }
928
- if (checkerResult.data && has(checkerResult.data, 'expectedType')) {
929
- expectedTypes.push(checkerResult.data.expectedType);
930
- }
931
- }
932
- var expectedTypesMessage = expectedTypes.length > 0 ? ', expected one of type [' + expectedTypes.join(', ') + ']' : '';
933
- return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`' + expectedTypesMessage + '.'));
934
- }
935
- return createChainableTypeChecker(validate);
936
- }
937
- function createNodeChecker() {
938
- function validate(props, propName, componentName, location, propFullName) {
939
- if (!isNode(props[propName])) {
940
- return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.'));
941
- }
942
- return null;
943
- }
944
- return createChainableTypeChecker(validate);
945
- }
946
- function invalidValidatorError(componentName, location, propFullName, key, type) {
947
- return new PropTypeError((componentName || 'React class') + ': ' + location + ' type `' + propFullName + '.' + key + '` is invalid; ' + 'it must be a function, usually from the `prop-types` package, but received `' + type + '`.');
948
- }
949
- function createShapeTypeChecker(shapeTypes) {
950
- function validate(props, propName, componentName, location, propFullName) {
951
- var propValue = props[propName];
952
- var propType = getPropType(propValue);
953
- if (propType !== 'object') {
954
- return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.'));
955
- }
956
- for (var key in shapeTypes) {
957
- var checker = shapeTypes[key];
958
- if (typeof checker !== 'function') {
959
- return invalidValidatorError(componentName, location, propFullName, key, getPreciseType(checker));
960
- }
961
- var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret);
962
- if (error) {
963
- return error;
964
- }
965
- }
966
- return null;
967
- }
968
- return createChainableTypeChecker(validate);
969
- }
970
- function createStrictShapeTypeChecker(shapeTypes) {
971
- function validate(props, propName, componentName, location, propFullName) {
972
- var propValue = props[propName];
973
- var propType = getPropType(propValue);
974
- if (propType !== 'object') {
975
- return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.'));
976
- }
977
- // We need to check all keys in case some are required but missing from props.
978
- var allKeys = assign({}, props[propName], shapeTypes);
979
- for (var key in allKeys) {
980
- var checker = shapeTypes[key];
981
- if (has(shapeTypes, key) && typeof checker !== 'function') {
982
- return invalidValidatorError(componentName, location, propFullName, key, getPreciseType(checker));
983
- }
984
- if (!checker) {
985
- return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` key `' + key + '` supplied to `' + componentName + '`.' + '\nBad object: ' + JSON.stringify(props[propName], null, ' ') + '\nValid keys: ' + JSON.stringify(Object.keys(shapeTypes), null, ' '));
986
- }
987
- var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret);
988
- if (error) {
989
- return error;
990
- }
991
- }
992
- return null;
993
- }
994
- return createChainableTypeChecker(validate);
995
- }
996
- function isNode(propValue) {
997
- switch (typeof propValue) {
998
- case 'number':
999
- case 'string':
1000
- case 'undefined':
1001
- return true;
1002
- case 'boolean':
1003
- return !propValue;
1004
- case 'object':
1005
- if (Array.isArray(propValue)) {
1006
- return propValue.every(isNode);
1007
- }
1008
- if (propValue === null || isValidElement(propValue)) {
1009
- return true;
1010
- }
1011
- var iteratorFn = getIteratorFn(propValue);
1012
- if (iteratorFn) {
1013
- var iterator = iteratorFn.call(propValue);
1014
- var step;
1015
- if (iteratorFn !== propValue.entries) {
1016
- while (!(step = iterator.next()).done) {
1017
- if (!isNode(step.value)) {
1018
- return false;
1019
- }
1020
- }
1021
- } else {
1022
- // Iterator will provide entry [k,v] tuples rather than values.
1023
- while (!(step = iterator.next()).done) {
1024
- var entry = step.value;
1025
- if (entry) {
1026
- if (!isNode(entry[1])) {
1027
- return false;
1028
- }
1029
- }
1030
- }
1031
- }
1032
- } else {
1033
- return false;
1034
- }
1035
- return true;
1036
- default:
1037
- return false;
1038
- }
1039
- }
1040
- function isSymbol(propType, propValue) {
1041
- // Native Symbol.
1042
- if (propType === 'symbol') {
1043
- return true;
1044
- }
1045
-
1046
- // falsy value can't be a Symbol
1047
- if (!propValue) {
1048
- return false;
1049
- }
1050
-
1051
- // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol'
1052
- if (propValue['@@toStringTag'] === 'Symbol') {
1053
- return true;
1054
- }
1055
-
1056
- // Fallback for non-spec compliant Symbols which are polyfilled.
1057
- if (typeof Symbol === 'function' && propValue instanceof Symbol) {
1058
- return true;
1059
- }
1060
- return false;
1061
- }
1062
-
1063
- // Equivalent of `typeof` but with special handling for array and regexp.
1064
- function getPropType(propValue) {
1065
- var propType = typeof propValue;
1066
- if (Array.isArray(propValue)) {
1067
- return 'array';
1068
- }
1069
- if (propValue instanceof RegExp) {
1070
- // Old webkits (at least until Android 4.0) return 'function' rather than
1071
- // 'object' for typeof a RegExp. We'll normalize this here so that /bla/
1072
- // passes PropTypes.object.
1073
- return 'object';
1074
- }
1075
- if (isSymbol(propType, propValue)) {
1076
- return 'symbol';
1077
- }
1078
- return propType;
1079
- }
1080
-
1081
- // This handles more types than `getPropType`. Only used for error messages.
1082
- // See `createPrimitiveTypeChecker`.
1083
- function getPreciseType(propValue) {
1084
- if (typeof propValue === 'undefined' || propValue === null) {
1085
- return '' + propValue;
1086
- }
1087
- var propType = getPropType(propValue);
1088
- if (propType === 'object') {
1089
- if (propValue instanceof Date) {
1090
- return 'date';
1091
- } else if (propValue instanceof RegExp) {
1092
- return 'regexp';
1093
- }
1094
- }
1095
- return propType;
1096
- }
1097
-
1098
- // Returns a string that is postfixed to a warning about an invalid type.
1099
- // For example, "undefined" or "of type array"
1100
- function getPostfixForTypeWarning(value) {
1101
- var type = getPreciseType(value);
1102
- switch (type) {
1103
- case 'array':
1104
- case 'object':
1105
- return 'an ' + type;
1106
- case 'boolean':
1107
- case 'date':
1108
- case 'regexp':
1109
- return 'a ' + type;
1110
- default:
1111
- return type;
1112
- }
1113
- }
1114
-
1115
- // Returns class name of the object, if any.
1116
- function getClassName(propValue) {
1117
- if (!propValue.constructor || !propValue.constructor.name) {
1118
- return ANONYMOUS;
1119
- }
1120
- return propValue.constructor.name;
1121
- }
1122
- ReactPropTypes.checkPropTypes = checkPropTypes;
1123
- ReactPropTypes.resetWarningCache = checkPropTypes.resetWarningCache;
1124
- ReactPropTypes.PropTypes = ReactPropTypes;
1125
- return ReactPropTypes;
1126
- };
1127
- return factoryWithTypeCheckers;
1128
- }
1129
-
1130
- /**
1131
- * Copyright (c) 2013-present, Facebook, Inc.
1132
- *
1133
- * This source code is licensed under the MIT license found in the
1134
- * LICENSE file in the root directory of this source tree.
1135
- */
1136
-
1137
- var factoryWithThrowingShims;
1138
- var hasRequiredFactoryWithThrowingShims;
1139
- function requireFactoryWithThrowingShims() {
1140
- if (hasRequiredFactoryWithThrowingShims) return factoryWithThrowingShims;
1141
- hasRequiredFactoryWithThrowingShims = 1;
1142
- var ReactPropTypesSecret = requireReactPropTypesSecret();
1143
- function emptyFunction() {}
1144
- function emptyFunctionWithReset() {}
1145
- emptyFunctionWithReset.resetWarningCache = emptyFunction;
1146
- factoryWithThrowingShims = function () {
1147
- function shim(props, propName, componentName, location, propFullName, secret) {
1148
- if (secret === ReactPropTypesSecret) {
1149
- // It is still safe when called from React.
1150
- return;
1151
- }
1152
- var err = new Error('Calling PropTypes validators directly is not supported by the `prop-types` package. ' + 'Use PropTypes.checkPropTypes() to call them. ' + 'Read more at http://fb.me/use-check-prop-types');
1153
- err.name = 'Invariant Violation';
1154
- throw err;
1155
- }
1156
- shim.isRequired = shim;
1157
- function getShim() {
1158
- return shim;
1159
- } // Important!
1160
- // Keep this list in sync with production version in `./factoryWithTypeCheckers.js`.
1161
- var ReactPropTypes = {
1162
- array: shim,
1163
- bigint: shim,
1164
- bool: shim,
1165
- func: shim,
1166
- number: shim,
1167
- object: shim,
1168
- string: shim,
1169
- symbol: shim,
1170
- any: shim,
1171
- arrayOf: getShim,
1172
- element: shim,
1173
- elementType: shim,
1174
- instanceOf: getShim,
1175
- node: shim,
1176
- objectOf: getShim,
1177
- oneOf: getShim,
1178
- oneOfType: getShim,
1179
- shape: getShim,
1180
- exact: getShim,
1181
- checkPropTypes: emptyFunctionWithReset,
1182
- resetWarningCache: emptyFunction
1183
- };
1184
- ReactPropTypes.PropTypes = ReactPropTypes;
1185
- return ReactPropTypes;
1186
- };
1187
- return factoryWithThrowingShims;
1188
- }
1189
-
1190
- /**
1191
- * Copyright (c) 2013-present, Facebook, Inc.
1192
- *
1193
- * This source code is licensed under the MIT license found in the
1194
- * LICENSE file in the root directory of this source tree.
1195
- */
1196
-
1197
- if (process.env.NODE_ENV !== 'production') {
1198
- var ReactIs = requireReactIs();
1199
-
1200
- // By explicitly using `prop-types` you are opting into new development behavior.
1201
- // http://fb.me/prop-types-in-prod
1202
- var throwOnDirectAccess = true;
1203
- propTypes$1.exports = requireFactoryWithTypeCheckers()(ReactIs.isElement, throwOnDirectAccess);
1204
- } else {
1205
- // By explicitly using `prop-types` you are opting into new production behavior.
1206
- // http://fb.me/prop-types-in-prod
1207
- propTypes$1.exports = requireFactoryWithThrowingShims()();
1208
- }
1209
- var propTypesExports = propTypes$1.exports;
1210
- var PropTypes = /*@__PURE__*/getDefaultExportFromCjs(propTypesExports);
1211
-
1212
- /**
1213
- * defines a focus group
1214
- */
1215
- var FOCUS_GROUP = 'data-focus-lock';
1216
- /**
1217
- * disables element discovery inside a group marked by key
1218
- */
1219
- var FOCUS_DISABLED = 'data-focus-lock-disabled';
1220
- /**
1221
- * allows uncontrolled focus within the marked area, effectively disabling focus lock for it's content
1222
- */
1223
- var FOCUS_ALLOW = 'data-no-focus-lock';
1224
- /**
1225
- * instructs autofocus engine to pick default autofocus inside a given node
1226
- * can be set on the element or container
1227
- */
1228
- var FOCUS_AUTO = 'data-autofocus-inside';
1229
- /**
1230
- * instructs autofocus to ignore elements within a given node
1231
- * can be set on the element or container
1232
- */
1233
- var FOCUS_NO_AUTOFOCUS = 'data-no-autofocus';
1234
-
1235
- /**
1236
- * Assigns a value for a given ref, no matter of the ref format
1237
- * @param {RefObject} ref - a callback function or ref object
1238
- * @param value - a new value
1239
- *
1240
- * @see https://github.com/theKashey/use-callback-ref#assignref
1241
- * @example
1242
- * const refObject = useRef();
1243
- * const refFn = (ref) => {....}
1244
- *
1245
- * assignRef(refObject, "refValue");
1246
- * assignRef(refFn, "refValue");
1247
- */
1248
- function assignRef(ref, value) {
1249
- if (typeof ref === 'function') {
1250
- ref(value);
1251
- } else if (ref) {
1252
- ref.current = value;
1253
- }
1254
- return ref;
1255
- }
1256
-
1257
- /**
1258
- * creates a MutableRef with ref change callback
1259
- * @param initialValue - initial ref value
1260
- * @param {Function} callback - a callback to run when value changes
1261
- *
1262
- * @example
1263
- * const ref = useCallbackRef(0, (newValue, oldValue) => console.log(oldValue, '->', newValue);
1264
- * ref.current = 1;
1265
- * // prints 0 -> 1
1266
- *
1267
- * @see https://reactjs.org/docs/hooks-reference.html#useref
1268
- * @see https://github.com/theKashey/use-callback-ref#usecallbackref---to-replace-reactuseref
1269
- * @returns {MutableRefObject}
1270
- */
1271
- function useCallbackRef(initialValue, callback) {
1272
- var ref = useState(function () {
1273
- return {
1274
- // value
1275
- value: initialValue,
1276
- // last callback
1277
- callback: callback,
1278
- // "memoized" public interface
1279
- facade: {
1280
- get current() {
1281
- return ref.value;
1282
- },
1283
- set current(value) {
1284
- var last = ref.value;
1285
- if (last !== value) {
1286
- ref.value = value;
1287
- ref.callback(value, last);
1288
- }
1289
- }
1290
- }
1291
- };
1292
- })[0];
1293
- // update callback
1294
- ref.callback = callback;
1295
- return ref.facade;
1296
- }
1297
-
1298
- /**
1299
- * Merges two or more refs together providing a single interface to set their value
1300
- * @param {RefObject|Ref} refs
1301
- * @returns {MutableRefObject} - a new ref, which translates all changes to {refs}
1302
- *
1303
- * @see {@link mergeRefs} a version without buit-in memoization
1304
- * @see https://github.com/theKashey/use-callback-ref#usemergerefs
1305
- * @example
1306
- * const Component = React.forwardRef((props, ref) => {
1307
- * const ownRef = useRef();
1308
- * const domRef = useMergeRefs([ref, ownRef]); // 👈 merge together
1309
- * return <div ref={domRef}>...</div>
1310
- * }
1311
- */
1312
- function useMergeRefs(refs, defaultValue) {
1313
- return useCallbackRef(null, function (newValue) {
1314
- return refs.forEach(function (ref) {
1315
- return assignRef(ref, newValue);
1316
- });
1317
- });
1318
- }
1319
- var hiddenGuard = {
1320
- width: '1px',
1321
- height: '0px',
1322
- padding: 0,
1323
- overflow: 'hidden',
1324
- position: 'fixed',
1325
- top: '1px',
1326
- left: '1px'
1327
- };
1328
- process.env.NODE_ENV !== "production" ? {
1329
- children: PropTypes.node
1330
- } : {};
1331
-
1332
- /******************************************************************************
1333
- Copyright (c) Microsoft Corporation.
1334
-
1335
- Permission to use, copy, modify, and/or distribute this software for any
1336
- purpose with or without fee is hereby granted.
1337
-
1338
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
1339
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1340
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
1341
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1342
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
1343
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1344
- PERFORMANCE OF THIS SOFTWARE.
1345
- ***************************************************************************** */
1346
- /* global Reflect, Promise, SuppressedError, Symbol */
1347
-
1348
- var __assign = function () {
1349
- __assign = Object.assign || function __assign(t) {
1350
- for (var s, i = 1, n = arguments.length; i < n; i++) {
1351
- s = arguments[i];
1352
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
1353
- }
1354
- return t;
1355
- };
1356
- return __assign.apply(this, arguments);
1357
- };
1358
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
1359
- var e = new Error(message);
1360
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
1361
- };
1362
- function ItoI(a) {
1363
- return a;
1364
- }
1365
- function innerCreateMedium(defaults, middleware) {
1366
- if (middleware === void 0) {
1367
- middleware = ItoI;
1368
- }
1369
- var buffer = [];
1370
- var assigned = false;
1371
- var medium = {
1372
- read: function () {
1373
- if (assigned) {
1374
- throw new Error('Sidecar: could not `read` from an `assigned` medium. `read` could be used only with `useMedium`.');
1375
- }
1376
- if (buffer.length) {
1377
- return buffer[buffer.length - 1];
1378
- }
1379
- return defaults;
1380
- },
1381
- useMedium: function (data) {
1382
- var item = middleware(data, assigned);
1383
- buffer.push(item);
1384
- return function () {
1385
- buffer = buffer.filter(function (x) {
1386
- return x !== item;
1387
- });
1388
- };
1389
- },
1390
- assignSyncMedium: function (cb) {
1391
- assigned = true;
1392
- while (buffer.length) {
1393
- var cbs = buffer;
1394
- buffer = [];
1395
- cbs.forEach(cb);
1396
- }
1397
- buffer = {
1398
- push: function (x) {
1399
- return cb(x);
1400
- },
1401
- filter: function () {
1402
- return buffer;
1403
- }
1404
- };
1405
- },
1406
- assignMedium: function (cb) {
1407
- assigned = true;
1408
- var pendingQueue = [];
1409
- if (buffer.length) {
1410
- var cbs = buffer;
1411
- buffer = [];
1412
- cbs.forEach(cb);
1413
- pendingQueue = buffer;
1414
- }
1415
- var executeQueue = function () {
1416
- var cbs = pendingQueue;
1417
- pendingQueue = [];
1418
- cbs.forEach(cb);
1419
- };
1420
- var cycle = function () {
1421
- return Promise.resolve().then(executeQueue);
1422
- };
1423
- cycle();
1424
- buffer = {
1425
- push: function (x) {
1426
- pendingQueue.push(x);
1427
- cycle();
1428
- },
1429
- filter: function (filter) {
1430
- pendingQueue = pendingQueue.filter(filter);
1431
- return buffer;
1432
- }
1433
- };
1434
- }
1435
- };
1436
- return medium;
1437
- }
1438
- function createMedium(defaults, middleware) {
1439
- if (middleware === void 0) {
1440
- middleware = ItoI;
1441
- }
1442
- return innerCreateMedium(defaults, middleware);
1443
- }
1444
- // eslint-disable-next-line @typescript-eslint/ban-types
1445
- function createSidecarMedium(options) {
1446
- if (options === void 0) {
1447
- options = {};
1448
- }
1449
- var medium = innerCreateMedium(null);
1450
- medium.options = __assign({
1451
- async: true,
1452
- ssr: false
1453
- }, options);
1454
- return medium;
1455
- }
1456
- var mediumFocus = createMedium({}, function (_ref) {
1457
- var target = _ref.target,
1458
- currentTarget = _ref.currentTarget;
1459
- return {
1460
- target: target,
1461
- currentTarget: currentTarget
1462
- };
1463
- });
1464
- var mediumBlur = createMedium();
1465
- var mediumEffect = createMedium();
1466
- var mediumSidecar = createSidecarMedium({
1467
- async: true // focus-lock sidecar is not required on the server
1468
- // however, it might be required for JSDOM tests
1469
- // ssr: true,
1470
- });
1471
- var emptyArray = [];
1472
- var FocusLock = /*#__PURE__*/React.forwardRef(function FocusLockUI(props, parentRef) {
1473
- var _extends2;
1474
- var _React$useState = React.useState(),
1475
- realObserved = _React$useState[0],
1476
- setObserved = _React$useState[1];
1477
- var observed = React.useRef();
1478
- var isActive = React.useRef(false);
1479
- var originalFocusedElement = React.useRef(null);
1480
- var children = props.children,
1481
- disabled = props.disabled,
1482
- noFocusGuards = props.noFocusGuards,
1483
- persistentFocus = props.persistentFocus,
1484
- crossFrame = props.crossFrame,
1485
- autoFocus = props.autoFocus,
1486
- allowTextSelection = props.allowTextSelection,
1487
- group = props.group,
1488
- className = props.className,
1489
- whiteList = props.whiteList,
1490
- hasPositiveIndices = props.hasPositiveIndices,
1491
- _props$shards = props.shards,
1492
- shards = _props$shards === void 0 ? emptyArray : _props$shards,
1493
- _props$as = props.as,
1494
- Container = _props$as === void 0 ? 'div' : _props$as,
1495
- _props$lockProps = props.lockProps,
1496
- containerProps = _props$lockProps === void 0 ? {} : _props$lockProps,
1497
- SideCar = props.sideCar,
1498
- shouldReturnFocus = props.returnFocus,
1499
- focusOptions = props.focusOptions,
1500
- onActivationCallback = props.onActivation,
1501
- onDeactivationCallback = props.onDeactivation;
1502
- var _React$useState2 = React.useState({}),
1503
- id = _React$useState2[0]; // SIDE EFFECT CALLBACKS
1504
-
1505
- var onActivation = React.useCallback(function () {
1506
- originalFocusedElement.current = originalFocusedElement.current || document && document.activeElement;
1507
- if (observed.current && onActivationCallback) {
1508
- onActivationCallback(observed.current);
1509
- }
1510
- isActive.current = true;
1511
- }, [onActivationCallback]);
1512
- var onDeactivation = React.useCallback(function () {
1513
- isActive.current = false;
1514
- if (onDeactivationCallback) {
1515
- onDeactivationCallback(observed.current);
1516
- }
1517
- }, [onDeactivationCallback]);
1518
- useEffect(function () {
1519
- if (!disabled) {
1520
- // cleanup return focus on trap deactivation
1521
- // sideEffect/returnFocus should happen by this time
1522
- originalFocusedElement.current = null;
1523
- }
1524
- }, []);
1525
- var returnFocus = React.useCallback(function (allowDefer) {
1526
- var returnFocusTo = originalFocusedElement.current;
1527
- if (returnFocusTo && returnFocusTo.focus) {
1528
- var howToReturnFocus = typeof shouldReturnFocus === 'function' ? shouldReturnFocus(returnFocusTo) : shouldReturnFocus;
1529
- if (howToReturnFocus) {
1530
- var returnFocusOptions = typeof howToReturnFocus === 'object' ? howToReturnFocus : undefined;
1531
- originalFocusedElement.current = null;
1532
- if (allowDefer) {
1533
- // React might return focus after update
1534
- // it's safer to defer the action
1535
- Promise.resolve().then(function () {
1536
- return returnFocusTo.focus(returnFocusOptions);
1537
- });
1538
- } else {
1539
- returnFocusTo.focus(returnFocusOptions);
1540
- }
1541
- }
1542
- }
1543
- }, [shouldReturnFocus]); // MEDIUM CALLBACKS
1544
-
1545
- var onFocus = React.useCallback(function (event) {
1546
- if (isActive.current) {
1547
- mediumFocus.useMedium(event);
1548
- }
1549
- }, []);
1550
- var onBlur = mediumBlur.useMedium; // REF PROPAGATION
1551
- // not using real refs due to race conditions
1552
-
1553
- var setObserveNode = React.useCallback(function (newObserved) {
1554
- if (observed.current !== newObserved) {
1555
- observed.current = newObserved;
1556
- setObserved(newObserved);
1557
- }
1558
- }, []);
1559
- if (process.env.NODE_ENV !== 'production') {
1560
- if (typeof allowTextSelection !== 'undefined') {
1561
- // eslint-disable-next-line no-console
1562
- console.warn('React-Focus-Lock: allowTextSelection is deprecated and enabled by default');
1563
- }
1564
- React.useEffect(function () {
1565
- // report incorrect integration - https://github.com/theKashey/react-focus-lock/issues/123
1566
- if (!observed.current && typeof Container !== 'string') {
1567
- // eslint-disable-next-line no-console
1568
- console.error('FocusLock: could not obtain ref to internal node');
1569
- }
1570
- }, []);
1571
- }
1572
- var lockProps = _extends((_extends2 = {}, _extends2[FOCUS_DISABLED] = disabled && 'disabled', _extends2[FOCUS_GROUP] = group, _extends2), containerProps);
1573
- var hasLeadingGuards = noFocusGuards !== true;
1574
- var hasTailingGuards = hasLeadingGuards && noFocusGuards !== 'tail';
1575
- var mergedRef = useMergeRefs([parentRef, setObserveNode]);
1576
- return /*#__PURE__*/React.createElement(React.Fragment, null, hasLeadingGuards && [/*#__PURE__*/
1577
- // nearest focus guard
1578
- React.createElement("div", {
1579
- key: "guard-first",
1580
- "data-focus-guard": true,
1581
- tabIndex: disabled ? -1 : 0,
1582
- style: hiddenGuard
1583
- }),
1584
- // first tabbed element guard
1585
- hasPositiveIndices ? /*#__PURE__*/React.createElement("div", {
1586
- key: "guard-nearest",
1587
- "data-focus-guard": true,
1588
- tabIndex: disabled ? -1 : 1,
1589
- style: hiddenGuard
1590
- }) : null], !disabled && /*#__PURE__*/React.createElement(SideCar, {
1591
- id: id,
1592
- sideCar: mediumSidecar,
1593
- observed: realObserved,
1594
- disabled: disabled,
1595
- persistentFocus: persistentFocus,
1596
- crossFrame: crossFrame,
1597
- autoFocus: autoFocus,
1598
- whiteList: whiteList,
1599
- shards: shards,
1600
- onActivation: onActivation,
1601
- onDeactivation: onDeactivation,
1602
- returnFocus: returnFocus,
1603
- focusOptions: focusOptions
1604
- }), /*#__PURE__*/React.createElement(Container, _extends({
1605
- ref: mergedRef
1606
- }, lockProps, {
1607
- className: className,
1608
- onBlur: onBlur,
1609
- onFocus: onFocus
1610
- }), children), hasTailingGuards && /*#__PURE__*/React.createElement("div", {
1611
- "data-focus-guard": true,
1612
- tabIndex: disabled ? -1 : 0,
1613
- style: hiddenGuard
1614
- }));
1615
- });
1616
- FocusLock.propTypes = process.env.NODE_ENV !== "production" ? {
1617
- children: propTypesExports.node,
1618
- disabled: propTypesExports.bool,
1619
- returnFocus: propTypesExports.oneOfType([propTypesExports.bool, propTypesExports.object, propTypesExports.func]),
1620
- focusOptions: propTypesExports.object,
1621
- noFocusGuards: propTypesExports.bool,
1622
- hasPositiveIndices: propTypesExports.bool,
1623
- allowTextSelection: propTypesExports.bool,
1624
- autoFocus: propTypesExports.bool,
1625
- persistentFocus: propTypesExports.bool,
1626
- crossFrame: propTypesExports.bool,
1627
- group: propTypesExports.string,
1628
- className: propTypesExports.string,
1629
- whiteList: propTypesExports.func,
1630
- shards: propTypesExports.arrayOf(propTypesExports.any),
1631
- as: propTypesExports.oneOfType([propTypesExports.string, propTypesExports.func, propTypesExports.object]),
1632
- lockProps: propTypesExports.object,
1633
- onActivation: propTypesExports.func,
1634
- onDeactivation: propTypesExports.func,
1635
- sideCar: propTypesExports.any.isRequired
1636
- } : {};
1637
- FocusLock.defaultProps = {
1638
- children: undefined,
1639
- disabled: false,
1640
- returnFocus: false,
1641
- focusOptions: undefined,
1642
- noFocusGuards: false,
1643
- autoFocus: true,
1644
- persistentFocus: false,
1645
- crossFrame: true,
1646
- hasPositiveIndices: undefined,
1647
- allowTextSelection: undefined,
1648
- group: undefined,
1649
- className: undefined,
1650
- whiteList: undefined,
1651
- shards: undefined,
1652
- as: 'div',
1653
- lockProps: {},
1654
- onActivation: undefined,
1655
- onDeactivation: undefined
1656
- };
1657
- function _setPrototypeOf(t, e) {
1658
- return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {
1659
- return t.__proto__ = e, t;
1660
- }, _setPrototypeOf(t, e);
1661
- }
1662
- function _inheritsLoose(t, o) {
1663
- t.prototype = Object.create(o.prototype), t.prototype.constructor = t, _setPrototypeOf(t, o);
1664
- }
1665
- function _typeof(o) {
1666
- "@babel/helpers - typeof";
1667
-
1668
- return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
1669
- return typeof o;
1670
- } : function (o) {
1671
- return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
1672
- }, _typeof(o);
1673
- }
1674
- function toPrimitive(t, r) {
1675
- if ("object" != _typeof(t) || !t) return t;
1676
- var e = t[Symbol.toPrimitive];
1677
- if (void 0 !== e) {
1678
- var i = e.call(t, r || "default");
1679
- if ("object" != _typeof(i)) return i;
1680
- throw new TypeError("@@toPrimitive must return a primitive value.");
1681
- }
1682
- return ("string" === r ? String : Number)(t);
1683
- }
1684
- function toPropertyKey(t) {
1685
- var i = toPrimitive(t, "string");
1686
- return "symbol" == _typeof(i) ? i : i + "";
1687
- }
1688
- function _defineProperty(e, r, t) {
1689
- return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
1690
- value: t,
1691
- enumerable: !0,
1692
- configurable: !0,
1693
- writable: !0
1694
- }) : e[r] = t, e;
1695
- }
1696
- function withSideEffect(reducePropsToState, handleStateChangeOnClient) {
1697
- if (process.env.NODE_ENV !== "production") {
1698
- if (typeof reducePropsToState !== 'function') {
1699
- throw new Error('Expected reducePropsToState to be a function.');
1700
- }
1701
- if (typeof handleStateChangeOnClient !== 'function') {
1702
- throw new Error('Expected handleStateChangeOnClient to be a function.');
1703
- }
1704
- }
1705
- function getDisplayName(WrappedComponent) {
1706
- return WrappedComponent.displayName || WrappedComponent.name || 'Component';
1707
- }
1708
- return function wrap(WrappedComponent) {
1709
- if (process.env.NODE_ENV !== "production") {
1710
- if (typeof WrappedComponent !== 'function') {
1711
- throw new Error('Expected WrappedComponent to be a React component.');
1712
- }
1713
- }
1714
- var mountedInstances = [];
1715
- var state;
1716
- function emitChange() {
1717
- state = reducePropsToState(mountedInstances.map(function (instance) {
1718
- return instance.props;
1719
- }));
1720
- handleStateChangeOnClient(state);
1721
- }
1722
- var SideEffect = /*#__PURE__*/function (_PureComponent) {
1723
- _inheritsLoose(SideEffect, _PureComponent);
1724
- function SideEffect() {
1725
- return _PureComponent.apply(this, arguments) || this;
1726
- }
1727
-
1728
- // Try to use displayName of wrapped component
1729
- SideEffect.peek = function peek() {
1730
- return state;
1731
- };
1732
- var _proto = SideEffect.prototype;
1733
- _proto.componentDidMount = function componentDidMount() {
1734
- mountedInstances.push(this);
1735
- emitChange();
1736
- };
1737
- _proto.componentDidUpdate = function componentDidUpdate() {
1738
- emitChange();
1739
- };
1740
- _proto.componentWillUnmount = function componentWillUnmount() {
1741
- var index = mountedInstances.indexOf(this);
1742
- mountedInstances.splice(index, 1);
1743
- emitChange();
1744
- };
1745
- _proto.render = function render() {
1746
- return /*#__PURE__*/React__default.createElement(WrappedComponent, this.props);
1747
- };
1748
- return SideEffect;
1749
- }(PureComponent);
1750
- _defineProperty(SideEffect, "displayName", "SideEffect(" + getDisplayName(WrappedComponent) + ")");
1751
- return SideEffect;
1752
- };
1753
- }
1754
-
1755
- /*
1756
- IE11 support
1757
- */
1758
- var toArray = function (a) {
1759
- var ret = Array(a.length);
1760
- for (var i = 0; i < a.length; ++i) {
1761
- ret[i] = a[i];
1762
- }
1763
- return ret;
1764
- };
1765
- var asArray = function (a) {
1766
- return Array.isArray(a) ? a : [a];
1767
- };
1768
- var getFirst = function (a) {
1769
- return Array.isArray(a) ? a[0] : a;
1770
- };
1771
- var isElementHidden = function (node) {
1772
- // we can measure only "elements"
1773
- // consider others as "visible"
1774
- if (node.nodeType !== Node.ELEMENT_NODE) {
1775
- return false;
1776
- }
1777
- var computedStyle = window.getComputedStyle(node, null);
1778
- if (!computedStyle || !computedStyle.getPropertyValue) {
1779
- return false;
1780
- }
1781
- return computedStyle.getPropertyValue('display') === 'none' || computedStyle.getPropertyValue('visibility') === 'hidden';
1782
- };
1783
- var getParentNode = function (node) {
1784
- // DOCUMENT_FRAGMENT_NODE can also point on ShadowRoot. In this case .host will point on the next node
1785
- return node.parentNode && node.parentNode.nodeType === Node.DOCUMENT_FRAGMENT_NODE ?
1786
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1787
- node.parentNode.host : node.parentNode;
1788
- };
1789
- var isTopNode = function (node) {
1790
- // @ts-ignore
1791
- return node === document || node && node.nodeType === Node.DOCUMENT_NODE;
1792
- };
1793
- var isVisibleUncached = function (node, checkParent) {
1794
- return !node || isTopNode(node) || !isElementHidden(node) && checkParent(getParentNode(node));
1795
- };
1796
- var isVisibleCached = function (visibilityCache, node) {
1797
- var cached = visibilityCache.get(node);
1798
- if (cached !== undefined) {
1799
- return cached;
1800
- }
1801
- var result = isVisibleUncached(node, isVisibleCached.bind(undefined, visibilityCache));
1802
- visibilityCache.set(node, result);
1803
- return result;
1804
- };
1805
- var isAutoFocusAllowedUncached = function (node, checkParent) {
1806
- return node && !isTopNode(node) ? isAutoFocusAllowed(node) ? checkParent(getParentNode(node)) : false : true;
1807
- };
1808
- var isAutoFocusAllowedCached = function (cache, node) {
1809
- var cached = cache.get(node);
1810
- if (cached !== undefined) {
1811
- return cached;
1812
- }
1813
- var result = isAutoFocusAllowedUncached(node, isAutoFocusAllowedCached.bind(undefined, cache));
1814
- cache.set(node, result);
1815
- return result;
1816
- };
1817
- var getDataset = function (node) {
1818
- // @ts-ignore
1819
- return node.dataset;
1820
- };
1821
- var isHTMLButtonElement = function (node) {
1822
- return node.tagName === 'BUTTON';
1823
- };
1824
- var isHTMLInputElement = function (node) {
1825
- return node.tagName === 'INPUT';
1826
- };
1827
- var isRadioElement = function (node) {
1828
- return isHTMLInputElement(node) && node.type === 'radio';
1829
- };
1830
- var notHiddenInput = function (node) {
1831
- return !((isHTMLInputElement(node) || isHTMLButtonElement(node)) && (node.type === 'hidden' || node.disabled));
1832
- };
1833
- var isAutoFocusAllowed = function (node) {
1834
- var attribute = node.getAttribute(FOCUS_NO_AUTOFOCUS);
1835
- return ![true, 'true', ''].includes(attribute);
1836
- };
1837
- var isGuard = function (node) {
1838
- var _a;
1839
- return Boolean(node && ((_a = getDataset(node)) === null || _a === void 0 ? void 0 : _a.focusGuard));
1840
- };
1841
- var isNotAGuard = function (node) {
1842
- return !isGuard(node);
1843
- };
1844
- var isDefined = function (x) {
1845
- return Boolean(x);
1846
- };
1847
- var tabSort = function (a, b) {
1848
- var tabDiff = a.tabIndex - b.tabIndex;
1849
- var indexDiff = a.index - b.index;
1850
- if (tabDiff) {
1851
- if (!a.tabIndex) {
1852
- return 1;
1853
- }
1854
- if (!b.tabIndex) {
1855
- return -1;
1856
- }
1857
- }
1858
- return tabDiff || indexDiff;
1859
- };
1860
- var orderByTabIndex = function (nodes, filterNegative, keepGuards) {
1861
- return toArray(nodes).map(function (node, index) {
1862
- return {
1863
- node: node,
1864
- index: index,
1865
- tabIndex: keepGuards && node.tabIndex === -1 ? (node.dataset || {}).focusGuard ? 0 : -1 : node.tabIndex
1866
- };
1867
- }).filter(function (data) {
1868
- return !filterNegative || data.tabIndex >= 0;
1869
- }).sort(tabSort);
1870
- };
1871
-
1872
- /**
1873
- * list of the object to be considered as focusable
1874
- */
1875
- var tabbables = ['button:enabled', 'select:enabled', 'textarea:enabled', 'input:enabled',
1876
- // elements with explicit roles will also use explicit tabindex
1877
- // '[role="button"]',
1878
- 'a[href]', 'area[href]', 'summary', 'iframe', 'object', 'embed', 'audio[controls]', 'video[controls]', '[tabindex]', '[contenteditable]', '[autofocus]'];
1879
- var queryTabbables = tabbables.join(',');
1880
- var queryGuardTabbables = "".concat(queryTabbables, ", [data-focus-guard]");
1881
- var getFocusablesWithShadowDom = function (parent, withGuards) {
1882
- return toArray((parent.shadowRoot || parent).children).reduce(function (acc, child) {
1883
- return acc.concat(child.matches(withGuards ? queryGuardTabbables : queryTabbables) ? [child] : [], getFocusablesWithShadowDom(child));
1884
- }, []);
1885
- };
1886
- var getFocusablesWithIFrame = function (parent, withGuards) {
1887
- var _a;
1888
- // contentDocument of iframe will be null if current origin cannot access it
1889
- if (parent instanceof HTMLIFrameElement && ((_a = parent.contentDocument) === null || _a === void 0 ? void 0 : _a.body)) {
1890
- return getFocusables([parent.contentDocument.body], withGuards);
1891
- }
1892
- return [parent];
1893
- };
1894
- var getFocusables = function (parents, withGuards) {
1895
- return parents.reduce(function (acc, parent) {
1896
- var _a;
1897
- var focusableWithShadowDom = getFocusablesWithShadowDom(parent, withGuards);
1898
- var focusableWithIframes = (_a = []).concat.apply(_a, focusableWithShadowDom.map(function (node) {
1899
- return getFocusablesWithIFrame(node, withGuards);
1900
- }));
1901
- return acc.concat(
1902
- // add all tabbables inside and within shadow DOMs in DOM order
1903
- focusableWithIframes,
1904
- // add if node is tabbable itself
1905
- parent.parentNode ? toArray(parent.parentNode.querySelectorAll(queryTabbables)).filter(function (node) {
1906
- return node === parent;
1907
- }) : []);
1908
- }, []);
1909
- };
1910
- /**
1911
- * return a list of focusable nodes within an area marked as "auto-focusable"
1912
- * @param parent
1913
- */
1914
- var getParentAutofocusables = function (parent) {
1915
- var parentFocus = parent.querySelectorAll("[".concat(FOCUS_AUTO, "]"));
1916
- return toArray(parentFocus).map(function (node) {
1917
- return getFocusables([node]);
1918
- }).reduce(function (acc, nodes) {
1919
- return acc.concat(nodes);
1920
- }, []);
1921
- };
1922
-
1923
- /**
1924
- * given list of focusable elements keeps the ones user can interact with
1925
- * @param nodes
1926
- * @param visibilityCache
1927
- */
1928
- var filterFocusable = function (nodes, visibilityCache) {
1929
- return toArray(nodes).filter(function (node) {
1930
- return isVisibleCached(visibilityCache, node);
1931
- }).filter(function (node) {
1932
- return notHiddenInput(node);
1933
- });
1934
- };
1935
- var filterAutoFocusable = function (nodes, cache) {
1936
- if (cache === void 0) {
1937
- cache = new Map();
1938
- }
1939
- return toArray(nodes).filter(function (node) {
1940
- return isAutoFocusAllowedCached(cache, node);
1941
- });
1942
- };
1943
- /**
1944
- * !__WARNING__! Low level API.
1945
- * @returns all tabbable nodes
1946
- *
1947
- * @see {@link getFocusableNodes} to get any focusable element
1948
- *
1949
- * @param topNodes - array of top level HTMLElements to search inside
1950
- * @param visibilityCache - an cache to store intermediate measurements. Expected to be a fresh `new Map` on every call
1951
- */
1952
- var getTabbableNodes = function (topNodes, visibilityCache, withGuards) {
1953
- return orderByTabIndex(filterFocusable(getFocusables(topNodes, withGuards), visibilityCache), true, withGuards);
1954
- };
1955
- /**
1956
- * !__WARNING__! Low level API.
1957
- *
1958
- * @returns anything "focusable", not only tabbable. The difference is in `tabIndex=-1`
1959
- * (without guards, as long as they are not expected to be ever focused)
1960
- *
1961
- * @see {@link getTabbableNodes} to get only tabble nodes element
1962
- *
1963
- * @param topNodes - array of top level HTMLElements to search inside
1964
- * @param visibilityCache - an cache to store intermediate measurements. Expected to be a fresh `new Map` on every call
1965
- */
1966
- var getFocusableNodes = function (topNodes, visibilityCache) {
1967
- return orderByTabIndex(filterFocusable(getFocusables(topNodes), visibilityCache), false);
1968
- };
1969
- /**
1970
- * return list of nodes which are expected to be auto-focused
1971
- * @param topNode
1972
- * @param visibilityCache
1973
- */
1974
- var parentAutofocusables = function (topNode, visibilityCache) {
1975
- return filterFocusable(getParentAutofocusables(topNode), visibilityCache);
1976
- };
1977
- /*
1978
- * Determines if element is contained in scope, including nested shadow DOMs
1979
- */
1980
- var contains = function (scope, element) {
1981
- if (scope.shadowRoot) {
1982
- return contains(scope.shadowRoot, element);
1983
- } else {
1984
- if (Object.getPrototypeOf(scope).contains !== undefined && Object.getPrototypeOf(scope).contains.call(scope, element)) {
1985
- return true;
1986
- }
1987
- return toArray(scope.children).some(function (child) {
1988
- var _a;
1989
- if (child instanceof HTMLIFrameElement) {
1990
- var iframeBody = (_a = child.contentDocument) === null || _a === void 0 ? void 0 : _a.body;
1991
- if (iframeBody) {
1992
- return contains(iframeBody, element);
1993
- }
1994
- return false;
1995
- }
1996
- return contains(child, element);
1997
- });
1998
- }
1999
- };
2000
-
2001
- /**
2002
- * in case of multiple nodes nested inside each other
2003
- * keeps only top ones
2004
- * this is O(nlogn)
2005
- * @param nodes
2006
- * @returns {*}
2007
- */
2008
- var filterNested = function (nodes) {
2009
- var contained = new Set();
2010
- var l = nodes.length;
2011
- for (var i = 0; i < l; i += 1) {
2012
- for (var j = i + 1; j < l; j += 1) {
2013
- var position = nodes[i].compareDocumentPosition(nodes[j]);
2014
- /* eslint-disable no-bitwise */
2015
- if ((position & Node.DOCUMENT_POSITION_CONTAINED_BY) > 0) {
2016
- contained.add(j);
2017
- }
2018
- if ((position & Node.DOCUMENT_POSITION_CONTAINS) > 0) {
2019
- contained.add(i);
2020
- }
2021
- /* eslint-enable */
2022
- }
2023
- }
2024
- return nodes.filter(function (_, index) {
2025
- return !contained.has(index);
2026
- });
2027
- };
2028
- /**
2029
- * finds top most parent for a node
2030
- * @param node
2031
- * @returns {*}
2032
- */
2033
- var getTopParent = function (node) {
2034
- return node.parentNode ? getTopParent(node.parentNode) : node;
2035
- };
2036
- /**
2037
- * returns all "focus containers" inside a given node
2038
- * @param node - node or nodes to look inside
2039
- * @returns Element[]
2040
- */
2041
- var getAllAffectedNodes = function (node) {
2042
- var nodes = asArray(node);
2043
- return nodes.filter(Boolean).reduce(function (acc, currentNode) {
2044
- var group = currentNode.getAttribute(FOCUS_GROUP);
2045
- acc.push.apply(acc, group ? filterNested(toArray(getTopParent(currentNode).querySelectorAll("[".concat(FOCUS_GROUP, "=\"").concat(group, "\"]:not([").concat(FOCUS_DISABLED, "=\"disabled\"])")))) : [currentNode]);
2046
- return acc;
2047
- }, []);
2048
- };
2049
- var safeProbe = function (cb) {
2050
- try {
2051
- return cb();
2052
- } catch (e) {
2053
- return undefined;
2054
- }
2055
- };
2056
-
2057
- /**
2058
- * returns active element from document or from nested shadowdoms
2059
- */
2060
- /**
2061
- * returns current active element. If the active element is a "container" itself(shadowRoot or iframe) returns active element inside it
2062
- * @param [inDocument]
2063
- */
2064
- var getActiveElement = function (inDocument) {
2065
- if (inDocument === void 0) {
2066
- inDocument = document;
2067
- }
2068
- if (!inDocument || !inDocument.activeElement) {
2069
- return undefined;
2070
- }
2071
- var activeElement = inDocument.activeElement;
2072
- return activeElement.shadowRoot ? getActiveElement(activeElement.shadowRoot) : activeElement instanceof HTMLIFrameElement && safeProbe(function () {
2073
- return activeElement.contentWindow.document;
2074
- }) ? getActiveElement(activeElement.contentWindow.document) : activeElement;
2075
- };
2076
- var focusInFrame = function (frame, activeElement) {
2077
- return frame === activeElement;
2078
- };
2079
- var focusInsideIframe = function (topNode, activeElement) {
2080
- return Boolean(toArray(topNode.querySelectorAll('iframe')).some(function (node) {
2081
- return focusInFrame(node, activeElement);
2082
- }));
2083
- };
2084
- /**
2085
- * @returns {Boolean} true, if the current focus is inside given node or nodes.
2086
- * Supports nodes hidden inside shadowDom
2087
- */
2088
- var focusInside = function (topNode, activeElement) {
2089
- // const activeElement = document && getActiveElement();
2090
- if (activeElement === void 0) {
2091
- activeElement = getActiveElement(getFirst(topNode).ownerDocument);
2092
- }
2093
- if (!activeElement || activeElement.dataset && activeElement.dataset.focusGuard) {
2094
- return false;
2095
- }
2096
- return getAllAffectedNodes(topNode).some(function (node) {
2097
- return contains(node, activeElement) || focusInsideIframe(node, activeElement);
2098
- });
2099
- };
2100
-
2101
- /**
2102
- * checks if focus is hidden FROM the focus-lock
2103
- * ie contained inside a node focus-lock shall ignore
2104
- *
2105
- * This is a utility function coupled with {@link FOCUS_ALLOW} constant
2106
- *
2107
- * @returns {boolean} focus is currently is in "allow" area
2108
- */
2109
- var focusIsHidden = function (inDocument) {
2110
- if (inDocument === void 0) {
2111
- inDocument = document;
2112
- }
2113
- var activeElement = getActiveElement(inDocument);
2114
- if (!activeElement) {
2115
- return false;
2116
- }
2117
- // this does not support setting FOCUS_ALLOW within shadow dom
2118
- return toArray(inDocument.querySelectorAll("[".concat(FOCUS_ALLOW, "]"))).some(function (node) {
2119
- return contains(node, activeElement);
2120
- });
2121
- };
2122
- var findSelectedRadio = function (node, nodes) {
2123
- return nodes.filter(isRadioElement).filter(function (el) {
2124
- return el.name === node.name;
2125
- }).filter(function (el) {
2126
- return el.checked;
2127
- })[0] || node;
2128
- };
2129
- var correctNode = function (node, nodes) {
2130
- if (isRadioElement(node) && node.name) {
2131
- return findSelectedRadio(node, nodes);
2132
- }
2133
- return node;
2134
- };
2135
- /**
2136
- * giving a set of radio inputs keeps only selected (tabbable) ones
2137
- * @param nodes
2138
- */
2139
- var correctNodes = function (nodes) {
2140
- // IE11 has no Set(array) constructor
2141
- var resultSet = new Set();
2142
- nodes.forEach(function (node) {
2143
- return resultSet.add(correctNode(node, nodes));
2144
- });
2145
- // using filter to support IE11
2146
- return nodes.filter(function (node) {
2147
- return resultSet.has(node);
2148
- });
2149
- };
2150
- var pickFirstFocus = function (nodes) {
2151
- if (nodes[0] && nodes.length > 1) {
2152
- return correctNode(nodes[0], nodes);
2153
- }
2154
- return nodes[0];
2155
- };
2156
- var pickFocusable = function (nodes, index) {
2157
- if (nodes.length > 1) {
2158
- return nodes.indexOf(correctNode(nodes[index], nodes));
2159
- }
2160
- return index;
2161
- };
2162
- var NEW_FOCUS = 'NEW_FOCUS';
2163
- /**
2164
- * Main solver for the "find next focus" question
2165
- * @param innerNodes
2166
- * @param outerNodes
2167
- * @param activeElement
2168
- * @param lastNode
2169
- * @returns {number|string|undefined|*}
2170
- */
2171
- var newFocus = function (innerNodes, outerNodes, activeElement, lastNode) {
2172
- var cnt = innerNodes.length;
2173
- var firstFocus = innerNodes[0];
2174
- var lastFocus = innerNodes[cnt - 1];
2175
- var isOnGuard = isGuard(activeElement);
2176
- // focus is inside
2177
- if (activeElement && innerNodes.indexOf(activeElement) >= 0) {
2178
- return undefined;
2179
- }
2180
- var activeIndex = activeElement !== undefined ? outerNodes.indexOf(activeElement) : -1;
2181
- var lastIndex = lastNode ? outerNodes.indexOf(lastNode) : activeIndex;
2182
- var lastNodeInside = lastNode ? innerNodes.indexOf(lastNode) : -1;
2183
- var indexDiff = activeIndex - lastIndex;
2184
- var firstNodeIndex = outerNodes.indexOf(firstFocus);
2185
- var lastNodeIndex = outerNodes.indexOf(lastFocus);
2186
- var correctedNodes = correctNodes(outerNodes);
2187
- var correctedIndex = activeElement !== undefined ? correctedNodes.indexOf(activeElement) : -1;
2188
- var correctedIndexDiff = correctedIndex - (lastNode ? correctedNodes.indexOf(lastNode) : activeIndex);
2189
- var returnFirstNode = pickFocusable(innerNodes, 0);
2190
- var returnLastNode = pickFocusable(innerNodes, cnt - 1);
2191
- // new focus
2192
- if (activeIndex === -1 || lastNodeInside === -1) {
2193
- return NEW_FOCUS;
2194
- }
2195
- // old focus
2196
- if (!indexDiff && lastNodeInside >= 0) {
2197
- return lastNodeInside;
2198
- }
2199
- // first element
2200
- if (activeIndex <= firstNodeIndex && isOnGuard && Math.abs(indexDiff) > 1) {
2201
- return returnLastNode;
2202
- }
2203
- // last element
2204
- if (activeIndex >= lastNodeIndex && isOnGuard && Math.abs(indexDiff) > 1) {
2205
- return returnFirstNode;
2206
- }
2207
- // jump out, but not on the guard
2208
- if (indexDiff && Math.abs(correctedIndexDiff) > 1) {
2209
- return lastNodeInside;
2210
- }
2211
- // focus above lock
2212
- if (activeIndex <= firstNodeIndex) {
2213
- return returnLastNode;
2214
- }
2215
- // focus below lock
2216
- if (activeIndex > lastNodeIndex) {
2217
- return returnFirstNode;
2218
- }
2219
- // index is inside tab order, but outside Lock
2220
- if (indexDiff) {
2221
- if (Math.abs(indexDiff) > 1) {
2222
- return lastNodeInside;
2223
- }
2224
- return (cnt + lastNodeInside + indexDiff) % cnt;
2225
- }
2226
- // do nothing
2227
- return undefined;
2228
- };
2229
- var findAutoFocused = function (autoFocusables) {
2230
- return function (node) {
2231
- var _a;
2232
- var autofocus = (_a = getDataset(node)) === null || _a === void 0 ? void 0 : _a.autofocus;
2233
- return (
2234
- // @ts-expect-error
2235
- node.autofocus ||
2236
- //
2237
- autofocus !== undefined && autofocus !== 'false' ||
2238
- //
2239
- autoFocusables.indexOf(node) >= 0
2240
- );
2241
- };
2242
- };
2243
- var pickAutofocus = function (nodesIndexes, orderedNodes, groups) {
2244
- var nodes = nodesIndexes.map(function (_a) {
2245
- var node = _a.node;
2246
- return node;
2247
- });
2248
- var autoFocusable = filterAutoFocusable(nodes.filter(findAutoFocused(groups)));
2249
- if (autoFocusable && autoFocusable.length) {
2250
- return pickFirstFocus(autoFocusable);
2251
- }
2252
- return pickFirstFocus(filterAutoFocusable(orderedNodes));
2253
- };
2254
- var getParents = function (node, parents) {
2255
- if (parents === void 0) {
2256
- parents = [];
2257
- }
2258
- parents.push(node);
2259
- if (node.parentNode) {
2260
- getParents(node.parentNode.host || node.parentNode, parents);
2261
- }
2262
- return parents;
2263
- };
2264
- /**
2265
- * finds a parent for both nodeA and nodeB
2266
- * @param nodeA
2267
- * @param nodeB
2268
- * @returns {boolean|*}
2269
- */
2270
- var getCommonParent = function (nodeA, nodeB) {
2271
- var parentsA = getParents(nodeA);
2272
- var parentsB = getParents(nodeB);
2273
- // tslint:disable-next-line:prefer-for-of
2274
- for (var i = 0; i < parentsA.length; i += 1) {
2275
- var currentParent = parentsA[i];
2276
- if (parentsB.indexOf(currentParent) >= 0) {
2277
- return currentParent;
2278
- }
2279
- }
2280
- return false;
2281
- };
2282
- var getTopCommonParent = function (baseActiveElement, leftEntry, rightEntries) {
2283
- var activeElements = asArray(baseActiveElement);
2284
- var leftEntries = asArray(leftEntry);
2285
- var activeElement = activeElements[0];
2286
- var topCommon = false;
2287
- leftEntries.filter(Boolean).forEach(function (entry) {
2288
- topCommon = getCommonParent(topCommon || entry, entry) || topCommon;
2289
- rightEntries.filter(Boolean).forEach(function (subEntry) {
2290
- var common = getCommonParent(activeElement, subEntry);
2291
- if (common) {
2292
- if (!topCommon || contains(common, topCommon)) {
2293
- topCommon = common;
2294
- } else {
2295
- topCommon = getCommonParent(common, topCommon);
2296
- }
2297
- }
2298
- });
2299
- });
2300
- // TODO: add assert here?
2301
- return topCommon;
2302
- };
2303
- /**
2304
- * return list of nodes which are expected to be autofocused inside a given top nodes
2305
- * @param entries
2306
- * @param visibilityCache
2307
- */
2308
- var allParentAutofocusables = function (entries, visibilityCache) {
2309
- return entries.reduce(function (acc, node) {
2310
- return acc.concat(parentAutofocusables(node, visibilityCache));
2311
- }, []);
2312
- };
2313
- var reorderNodes = function (srcNodes, dstNodes) {
2314
- var remap = new Map();
2315
- // no Set(dstNodes) for IE11 :(
2316
- dstNodes.forEach(function (entity) {
2317
- return remap.set(entity.node, entity);
2318
- });
2319
- // remap to dstNodes
2320
- return srcNodes.map(function (node) {
2321
- return remap.get(node);
2322
- }).filter(isDefined);
2323
- };
2324
- /**
2325
- * contains the main logic of the `focus-lock` package.
2326
- *
2327
- * ! you probably dont need this function !
2328
- *
2329
- * given top node(s) and the last active element returns the element to be focused next
2330
- * @returns element which should be focused to move focus inside
2331
- * @param topNode
2332
- * @param lastNode
2333
- */
2334
- var focusSolver = function (topNode, lastNode) {
2335
- var activeElement = getActiveElement(asArray(topNode).length > 0 ? document : getFirst(topNode).ownerDocument);
2336
- var entries = getAllAffectedNodes(topNode).filter(isNotAGuard);
2337
- var commonParent = getTopCommonParent(activeElement || topNode, topNode, entries);
2338
- var visibilityCache = new Map();
2339
- var anyFocusable = getFocusableNodes(entries, visibilityCache);
2340
- var innerElements = getTabbableNodes(entries, visibilityCache).filter(function (_a) {
2341
- var node = _a.node;
2342
- return isNotAGuard(node);
2343
- });
2344
- if (!innerElements[0]) {
2345
- innerElements = anyFocusable;
2346
- if (!innerElements[0]) {
2347
- return undefined;
2348
- }
2349
- }
2350
- var outerNodes = getFocusableNodes([commonParent], visibilityCache).map(function (_a) {
2351
- var node = _a.node;
2352
- return node;
2353
- });
2354
- var orderedInnerElements = reorderNodes(outerNodes, innerElements);
2355
- var innerNodes = orderedInnerElements.map(function (_a) {
2356
- var node = _a.node;
2357
- return node;
2358
- });
2359
- var newId = newFocus(innerNodes, outerNodes, activeElement, lastNode);
2360
- if (newId === NEW_FOCUS) {
2361
- var focusNode = pickAutofocus(anyFocusable, innerNodes, allParentAutofocusables(entries, visibilityCache));
2362
- if (focusNode) {
2363
- return {
2364
- node: focusNode
2365
- };
2366
- } else {
2367
- console.warn('focus-lock: cannot find any node to move focus into');
2368
- return undefined;
2369
- }
2370
- }
2371
- if (newId === undefined) {
2372
- return newId;
2373
- }
2374
- return orderedInnerElements[newId];
2375
- };
2376
-
2377
- /**
2378
- * @returns list of focusable elements inside a given top node
2379
- * @see {@link getFocusableNodes} for lower level access
2380
- */
2381
- var expandFocusableNodes = function (topNode) {
2382
- var entries = getAllAffectedNodes(topNode).filter(isNotAGuard);
2383
- var commonParent = getTopCommonParent(topNode, topNode, entries);
2384
- var visibilityCache = new Map();
2385
- var outerNodes = getTabbableNodes([commonParent], visibilityCache, true);
2386
- var innerElements = getTabbableNodes(entries, visibilityCache).filter(function (_a) {
2387
- var node = _a.node;
2388
- return isNotAGuard(node);
2389
- }).map(function (_a) {
2390
- var node = _a.node;
2391
- return node;
2392
- });
2393
- return outerNodes.map(function (_a) {
2394
- var node = _a.node,
2395
- index = _a.index;
2396
- return {
2397
- node: node,
2398
- index: index,
2399
- lockItem: innerElements.indexOf(node) >= 0,
2400
- guard: isGuard(node)
2401
- };
2402
- });
2403
- };
2404
- var focusOn = function (target, focusOptions) {
2405
- if ('focus' in target) {
2406
- target.focus(focusOptions);
2407
- }
2408
- if ('contentWindow' in target && target.contentWindow) {
2409
- target.contentWindow.focus();
2410
- }
2411
- };
2412
- var guardCount = 0;
2413
- var lockDisabled = false;
2414
- /**
2415
- * The main functionality of the focus-lock package
2416
- *
2417
- * Contains focus at a given node.
2418
- * The last focused element will help to determine which element(first or last) should be focused.
2419
- * The found element will be focused.
2420
- *
2421
- * This is one time action (move), not a persistent focus-lock
2422
- *
2423
- * HTML markers (see {@link import('./constants').FOCUS_AUTO} constants) can control autofocus
2424
- * @see {@link focusSolver} for the same functionality without autofocus
2425
- */
2426
- var moveFocusInside = function (topNode, lastNode, options) {
2427
- if (options === void 0) {
2428
- options = {};
2429
- }
2430
- var focusable = focusSolver(topNode, lastNode);
2431
- // global local side effect to countain recursive lock activation and resolve focus-fighting
2432
- if (lockDisabled) {
2433
- return;
2434
- }
2435
- if (focusable) {
2436
- /** +FOCUS-FIGHTING prevention **/
2437
- if (guardCount > 2) {
2438
- // we have recursive entered back the lock activation
2439
- console.error('FocusLock: focus-fighting detected. Only one focus management system could be active. ' + 'See https://github.com/theKashey/focus-lock/#focus-fighting');
2440
- lockDisabled = true;
2441
- setTimeout(function () {
2442
- lockDisabled = false;
2443
- }, 1);
2444
- return;
2445
- }
2446
- guardCount++;
2447
- focusOn(focusable.node, options.focusOptions);
2448
- guardCount--;
2449
- }
2450
- };
2451
- function deferAction(action) {
2452
- setTimeout(action, 1);
2453
- }
2454
-
2455
- /* eslint-disable no-mixed-operators */
2456
-
2457
- var focusOnBody = function focusOnBody() {
2458
- return document && document.activeElement === document.body;
2459
- };
2460
- var isFreeFocus = function isFreeFocus() {
2461
- return focusOnBody() || focusIsHidden();
2462
- };
2463
- var lastActiveTrap = null;
2464
- var lastActiveFocus = null;
2465
- var lastPortaledElement = null;
2466
- var focusWasOutsideWindow = false;
2467
- var defaultWhitelist = function defaultWhitelist() {
2468
- return true;
2469
- };
2470
- var focusWhitelisted = function focusWhitelisted(activeElement) {
2471
- return (lastActiveTrap.whiteList || defaultWhitelist)(activeElement);
2472
- };
2473
- var recordPortal = function recordPortal(observerNode, portaledElement) {
2474
- lastPortaledElement = {
2475
- observerNode: observerNode,
2476
- portaledElement: portaledElement
2477
- };
2478
- };
2479
- var focusIsPortaledPair = function focusIsPortaledPair(element) {
2480
- return lastPortaledElement && lastPortaledElement.portaledElement === element;
2481
- };
2482
- function autoGuard(startIndex, end, step, allNodes) {
2483
- var lastGuard = null;
2484
- var i = startIndex;
2485
- do {
2486
- var item = allNodes[i];
2487
- if (item.guard) {
2488
- if (item.node.dataset.focusAutoGuard) {
2489
- lastGuard = item;
2490
- }
2491
- } else if (item.lockItem) {
2492
- if (i !== startIndex) {
2493
- // we will tab to the next element
2494
- return;
2495
- }
2496
- lastGuard = null;
2497
- } else {
2498
- break;
2499
- }
2500
- } while ((i += step) !== end);
2501
- if (lastGuard) {
2502
- lastGuard.node.tabIndex = 0;
2503
- }
2504
- }
2505
- var extractRef = function extractRef(ref) {
2506
- return ref && 'current' in ref ? ref.current : ref;
2507
- };
2508
- var focusWasOutside = function focusWasOutside(crossFrameOption) {
2509
- if (crossFrameOption) {
2510
- // with cross frame return true for any value
2511
- return Boolean(focusWasOutsideWindow);
2512
- } // in other case return only of focus went a while aho
2513
-
2514
- return focusWasOutsideWindow === 'meanwhile';
2515
- };
2516
- var checkInHost = function checkInHost(check, el, boundary) {
2517
- return el && (
2518
- // find host equal to active element and check nested active element
2519
- el.host === check && (!el.activeElement || boundary.contains(el.activeElement)) // dive up
2520
- || el.parentNode && checkInHost(check, el.parentNode, boundary));
2521
- };
2522
- var withinHost = function withinHost(activeElement, workingArea) {
2523
- return workingArea.some(function (area) {
2524
- return checkInHost(activeElement, area, area);
2525
- });
2526
- };
2527
- var activateTrap = function activateTrap() {
2528
- var result = false;
2529
- if (lastActiveTrap) {
2530
- var _lastActiveTrap = lastActiveTrap,
2531
- observed = _lastActiveTrap.observed,
2532
- persistentFocus = _lastActiveTrap.persistentFocus,
2533
- autoFocus = _lastActiveTrap.autoFocus,
2534
- shards = _lastActiveTrap.shards,
2535
- crossFrame = _lastActiveTrap.crossFrame,
2536
- focusOptions = _lastActiveTrap.focusOptions;
2537
- var workingNode = observed || lastPortaledElement && lastPortaledElement.portaledElement;
2538
- var activeElement = document && document.activeElement;
2539
- if (workingNode) {
2540
- var workingArea = [workingNode].concat(shards.map(extractRef).filter(Boolean));
2541
- if (!activeElement || focusWhitelisted(activeElement)) {
2542
- if (persistentFocus || focusWasOutside(crossFrame) || !isFreeFocus() || !lastActiveFocus && autoFocus) {
2543
- if (workingNode && !(
2544
- // active element is "inside" working area
2545
- focusInside(workingArea) ||
2546
- // check for shadow-dom contained elements
2547
- activeElement && withinHost(activeElement, workingArea) || focusIsPortaledPair(activeElement))) {
2548
- if (document && !lastActiveFocus && activeElement && !autoFocus) {
2549
- // Check if blur() exists, which is missing on certain elements on IE
2550
- if (activeElement.blur) {
2551
- activeElement.blur();
2552
- }
2553
- document.body.focus();
2554
- } else {
2555
- result = moveFocusInside(workingArea, lastActiveFocus, {
2556
- focusOptions: focusOptions
2557
- });
2558
- lastPortaledElement = {};
2559
- }
2560
- }
2561
- focusWasOutsideWindow = false;
2562
- lastActiveFocus = document && document.activeElement;
2563
- }
2564
- }
2565
- if (document) {
2566
- var newActiveElement = document && document.activeElement;
2567
- var allNodes = expandFocusableNodes(workingArea);
2568
- var focusedIndex = allNodes.map(function (_ref) {
2569
- var node = _ref.node;
2570
- return node;
2571
- }).indexOf(newActiveElement);
2572
- if (focusedIndex > -1) {
2573
- // remove old focus
2574
- allNodes.filter(function (_ref2) {
2575
- var guard = _ref2.guard,
2576
- node = _ref2.node;
2577
- return guard && node.dataset.focusAutoGuard;
2578
- }).forEach(function (_ref3) {
2579
- var node = _ref3.node;
2580
- return node.removeAttribute('tabIndex');
2581
- });
2582
- autoGuard(focusedIndex, allNodes.length, +1, allNodes);
2583
- autoGuard(focusedIndex, -1, -1, allNodes);
2584
- }
2585
- }
2586
- }
2587
- }
2588
- return result;
2589
- };
2590
- var onTrap = function onTrap(event) {
2591
- if (activateTrap() && event) {
2592
- // prevent scroll jump
2593
- event.stopPropagation();
2594
- event.preventDefault();
2595
- }
2596
- };
2597
- var onBlur = function onBlur() {
2598
- return deferAction(activateTrap);
2599
- };
2600
- var onFocus = function onFocus(event) {
2601
- // detect portal
2602
- var source = event.target;
2603
- var currentNode = event.currentTarget;
2604
- if (!currentNode.contains(source)) {
2605
- recordPortal(currentNode, source);
2606
- }
2607
- };
2608
- var FocusWatcher = function FocusWatcher() {
2609
- return null;
2610
- };
2611
- process.env.NODE_ENV !== "production" ? {
2612
- children: PropTypes.node.isRequired
2613
- } : {};
2614
- var onWindowBlur = function onWindowBlur() {
2615
- focusWasOutsideWindow = 'just'; // using setTimeout to set this variable after React/sidecar reaction
2616
-
2617
- deferAction(function () {
2618
- focusWasOutsideWindow = 'meanwhile';
2619
- });
2620
- };
2621
- var attachHandler = function attachHandler() {
2622
- document.addEventListener('focusin', onTrap);
2623
- document.addEventListener('focusout', onBlur);
2624
- window.addEventListener('blur', onWindowBlur);
2625
- };
2626
- var detachHandler = function detachHandler() {
2627
- document.removeEventListener('focusin', onTrap);
2628
- document.removeEventListener('focusout', onBlur);
2629
- window.removeEventListener('blur', onWindowBlur);
2630
- };
2631
- function reducePropsToState(propsList) {
2632
- return propsList.filter(function (_ref5) {
2633
- var disabled = _ref5.disabled;
2634
- return !disabled;
2635
- });
2636
- }
2637
- function handleStateChangeOnClient(traps) {
2638
- var trap = traps.slice(-1)[0];
2639
- if (trap && !lastActiveTrap) {
2640
- attachHandler();
2641
- }
2642
- var lastTrap = lastActiveTrap;
2643
- var sameTrap = lastTrap && trap && trap.id === lastTrap.id;
2644
- lastActiveTrap = trap;
2645
- if (lastTrap && !sameTrap) {
2646
- lastTrap.onDeactivation(); // return focus only of last trap was removed
2647
-
2648
- if (!traps.filter(function (_ref6) {
2649
- var id = _ref6.id;
2650
- return id === lastTrap.id;
2651
- }).length) {
2652
- // allow defer is no other trap is awaiting restore
2653
- lastTrap.returnFocus(!trap);
2654
- }
2655
- }
2656
- if (trap) {
2657
- lastActiveFocus = null;
2658
- if (!sameTrap || lastTrap.observed !== trap.observed) {
2659
- trap.onActivation();
2660
- }
2661
- activateTrap();
2662
- deferAction(activateTrap);
2663
- } else {
2664
- detachHandler();
2665
- lastActiveFocus = null;
2666
- }
2667
- } // bind medium
2668
-
2669
- mediumFocus.assignSyncMedium(onFocus);
2670
- mediumBlur.assignMedium(onBlur);
2671
- mediumEffect.assignMedium(function (cb) {
2672
- return cb({
2673
- moveFocusInside: moveFocusInside,
2674
- focusInside: focusInside
2675
- });
2676
- });
2677
- var FocusTrap = withSideEffect(reducePropsToState, handleStateChangeOnClient)(FocusWatcher);
2678
-
2679
- /* that would be a BREAKING CHANGE!
2680
- // delaying sidecar execution till the first usage
2681
- const RequireSideCar = (props) => {
2682
- // eslint-disable-next-line global-require
2683
- const SideCar = require('./Trap').default;
2684
- return <SideCar {...props} />;
2685
- };
2686
- */
2687
-
2688
- var FocusLockCombination = /*#__PURE__*/React.forwardRef(function FocusLockUICombination(props, ref) {
2689
- return /*#__PURE__*/React.createElement(FocusLock, _extends({
2690
- sideCar: FocusTrap,
2691
- ref: ref
2692
- }, props));
2693
- });
2694
- var _ref = FocusLock.propTypes || {},
2695
- propTypes = _objectWithoutPropertiesLoose(_ref, ["sideCar"]);
2696
- FocusLockCombination.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {};
2697
- process.env.NODE_ENV !== "production" ? {
2698
- children: PropTypes.node.isRequired,
2699
- disabled: PropTypes.bool,
2700
- className: PropTypes.string
2701
- } : {};
2702
- process.env.NODE_ENV !== "production" ? {
2703
- children: PropTypes.node.isRequired,
2704
- disabled: PropTypes.bool,
2705
- className: PropTypes.string
2706
- } : {};
2707
- process.env.NODE_ENV !== "production" ? {
2708
- children: PropTypes.node.isRequired,
2709
- className: PropTypes.string
2710
- } : {};
2711
-
2712
- /**
2713
- * @module constants
2714
- * @summary Useful constants
2715
- * @description
2716
- * Collection of useful date constants.
2717
- *
2718
- * The constants could be imported from `date-fns/constants`:
2719
- *
2720
- * ```ts
2721
- * import { maxTime, minTime } from "./constants/date-fns/constants";
2722
- *
2723
- * function isAllowedTime(time) {
2724
- * return time <= maxTime && time >= minTime;
2725
- * }
2726
- * ```
2727
- */
2728
-
2729
- /**
2730
- * @constant
2731
- * @name millisecondsInWeek
2732
- * @summary Milliseconds in 1 week.
2733
- */
2734
- const millisecondsInWeek = 604800000;
2735
-
2736
- /**
2737
- * @constant
2738
- * @name constructFromSymbol
2739
- * @summary Symbol enabling Date extensions to inherit properties from the reference date.
2740
- *
2741
- * The symbol is used to enable the `constructFrom` function to construct a date
2742
- * using a reference date and a value. It allows to transfer extra properties
2743
- * from the reference date to the new date. It's useful for extensions like
2744
- * [`TZDate`](https://github.com/date-fns/tz) that accept a time zone as
2745
- * a constructor argument.
2746
- */
2747
- const constructFromSymbol = Symbol.for("constructDateFrom");
2748
-
2749
- /**
2750
- * @name constructFrom
2751
- * @category Generic Helpers
2752
- * @summary Constructs a date using the reference date and the value
2753
- *
2754
- * @description
2755
- * The function constructs a new date using the constructor from the reference
2756
- * date and the given value. It helps to build generic functions that accept
2757
- * date extensions.
2758
- *
2759
- * It defaults to `Date` if the passed reference date is a number or a string.
2760
- *
2761
- * Starting from v3.7.0, it allows to construct a date using `[Symbol.for("constructDateFrom")]`
2762
- * enabling to transfer extra properties from the reference date to the new date.
2763
- * It's useful for extensions like [`TZDate`](https://github.com/date-fns/tz)
2764
- * that accept a time zone as a constructor argument.
2765
- *
2766
- * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
2767
- *
2768
- * @param date - The reference date to take constructor from
2769
- * @param value - The value to create the date
2770
- *
2771
- * @returns Date initialized using the given date and value
2772
- *
2773
- * @example
2774
- * import { constructFrom } from "./constructFrom/date-fns";
2775
- *
2776
- * // A function that clones a date preserving the original type
2777
- * function cloneDate<DateType extends Date>(date: DateType): DateType {
2778
- * return constructFrom(
2779
- * date, // Use constructor from the given date
2780
- * date.getTime() // Use the date value to create a new date
2781
- * );
2782
- * }
2783
- */
2784
- function constructFrom(date, value) {
2785
- if (typeof date === "function") return date(value);
2786
- if (date && typeof date === "object" && constructFromSymbol in date) return date[constructFromSymbol](value);
2787
- if (date instanceof Date) return new date.constructor(value);
2788
- return new Date(value);
2789
- }
2790
-
2791
- /**
2792
- * @name toDate
2793
- * @category Common Helpers
2794
- * @summary Convert the given argument to an instance of Date.
2795
- *
2796
- * @description
2797
- * Convert the given argument to an instance of Date.
2798
- *
2799
- * If the argument is an instance of Date, the function returns its clone.
2800
- *
2801
- * If the argument is a number, it is treated as a timestamp.
2802
- *
2803
- * If the argument is none of the above, the function returns Invalid Date.
2804
- *
2805
- * Starting from v3.7.0, it clones a date using `[Symbol.for("constructDateFrom")]`
2806
- * enabling to transfer extra properties from the reference date to the new date.
2807
- * It's useful for extensions like [`TZDate`](https://github.com/date-fns/tz)
2808
- * that accept a time zone as a constructor argument.
2809
- *
2810
- * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`.
2811
- *
2812
- * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
2813
- * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
2814
- *
2815
- * @param argument - The value to convert
2816
- *
2817
- * @returns The parsed date in the local time zone
2818
- *
2819
- * @example
2820
- * // Clone the date:
2821
- * const result = toDate(new Date(2014, 1, 11, 11, 30, 30))
2822
- * //=> Tue Feb 11 2014 11:30:30
2823
- *
2824
- * @example
2825
- * // Convert the timestamp to date:
2826
- * const result = toDate(1392098430000)
2827
- * //=> Tue Feb 11 2014 11:30:30
2828
- */
2829
- function toDate(argument, context) {
2830
- // [TODO] Get rid of `toDate` or `constructFrom`?
2831
- return constructFrom(argument, argument);
2832
- }
2833
-
2834
- /**
2835
- * The {@link addDays} function options.
2836
- */
2837
-
2838
- /**
2839
- * @name addDays
2840
- * @category Day Helpers
2841
- * @summary Add the specified number of days to the given date.
2842
- *
2843
- * @description
2844
- * Add the specified number of days to the given date.
2845
- *
2846
- * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
2847
- * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
2848
- *
2849
- * @param date - The date to be changed
2850
- * @param amount - The amount of days to be added.
2851
- * @param options - An object with options
2852
- *
2853
- * @returns The new date with the days added
2854
- *
2855
- * @example
2856
- * // Add 10 days to 1 September 2014:
2857
- * const result = addDays(new Date(2014, 8, 1), 10)
2858
- * //=> Thu Sep 11 2014 00:00:00
2859
- */
2860
- function addDays(date, amount, options) {
2861
- const _date = toDate(date);
2862
- if (isNaN(amount)) return constructFrom(date, NaN);
2863
-
2864
- // If 0 days, no-op to avoid changing times in the hour before end of DST
2865
- if (!amount) return _date;
2866
- _date.setDate(_date.getDate() + amount);
2867
- return _date;
2868
- }
2869
-
2870
- /**
2871
- * The {@link addMonths} function options.
2872
- */
2873
-
2874
- /**
2875
- * @name addMonths
2876
- * @category Month Helpers
2877
- * @summary Add the specified number of months to the given date.
2878
- *
2879
- * @description
2880
- * Add the specified number of months to the given date.
2881
- *
2882
- * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
2883
- * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
2884
- *
2885
- * @param date - The date to be changed
2886
- * @param amount - The amount of months to be added.
2887
- * @param options - The options object
2888
- *
2889
- * @returns The new date with the months added
2890
- *
2891
- * @example
2892
- * // Add 5 months to 1 September 2014:
2893
- * const result = addMonths(new Date(2014, 8, 1), 5)
2894
- * //=> Sun Feb 01 2015 00:00:00
2895
- *
2896
- * // Add one month to 30 January 2023:
2897
- * const result = addMonths(new Date(2023, 0, 30), 1)
2898
- * //=> Tue Feb 28 2023 00:00:00
2899
- */
2900
- function addMonths(date, amount, options) {
2901
- const _date = toDate(date);
2902
- if (isNaN(amount)) return constructFrom(date, NaN);
2903
- if (!amount) {
2904
- // If 0 months, no-op to avoid changing times in the hour before end of DST
2905
- return _date;
2906
- }
2907
- const dayOfMonth = _date.getDate();
2908
-
2909
- // The JS Date object supports date math by accepting out-of-bounds values for
2910
- // month, day, etc. For example, new Date(2020, 0, 0) returns 31 Dec 2019 and
2911
- // new Date(2020, 13, 1) returns 1 Feb 2021. This is *almost* the behavior we
2912
- // want except that dates will wrap around the end of a month, meaning that
2913
- // new Date(2020, 13, 31) will return 3 Mar 2021 not 28 Feb 2021 as desired. So
2914
- // we'll default to the end of the desired month by adding 1 to the desired
2915
- // month and using a date of 0 to back up one day to the end of the desired
2916
- // month.
2917
- const endOfDesiredMonth = constructFrom(date, _date.getTime());
2918
- endOfDesiredMonth.setMonth(_date.getMonth() + amount + 1, 0);
2919
- const daysInMonth = endOfDesiredMonth.getDate();
2920
- if (dayOfMonth >= daysInMonth) {
2921
- // If we're already at the end of the month, then this is the correct date
2922
- // and we're done.
2923
- return endOfDesiredMonth;
2924
- } else {
2925
- // Otherwise, we now know that setting the original day-of-month value won't
2926
- // cause an overflow, so set the desired day-of-month. Note that we can't
2927
- // just set the date of `endOfDesiredMonth` because that object may have had
2928
- // its time changed in the unusual case where where a DST transition was on
2929
- // the last day of the month and its local time was in the hour skipped or
2930
- // repeated next to a DST transition. So we use `date` instead which is
2931
- // guaranteed to still have the original time.
2932
- _date.setFullYear(endOfDesiredMonth.getFullYear(), endOfDesiredMonth.getMonth(), dayOfMonth);
2933
- return _date;
2934
- }
2935
- }
2936
- let defaultOptions = {};
2937
- function getDefaultOptions() {
2938
- return defaultOptions;
2939
- }
2940
-
2941
- /**
2942
- * The {@link startOfWeek} function options.
2943
- */
2944
-
2945
- /**
2946
- * @name startOfWeek
2947
- * @category Week Helpers
2948
- * @summary Return the start of a week for the given date.
2949
- *
2950
- * @description
2951
- * Return the start of a week for the given date.
2952
- * The result will be in the local timezone.
2953
- *
2954
- * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
2955
- * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
2956
- *
2957
- * @param date - The original date
2958
- * @param options - An object with options
2959
- *
2960
- * @returns The start of a week
2961
- *
2962
- * @example
2963
- * // The start of a week for 2 September 2014 11:55:00:
2964
- * const result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0))
2965
- * //=> Sun Aug 31 2014 00:00:00
2966
- *
2967
- * @example
2968
- * // If the week starts on Monday, the start of the week for 2 September 2014 11:55:00:
2969
- * const result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0), { weekStartsOn: 1 })
2970
- * //=> Mon Sep 01 2014 00:00:00
2971
- */
2972
- function startOfWeek(date, options) {
2973
- const defaultOptions = getDefaultOptions();
2974
- const weekStartsOn = defaultOptions.weekStartsOn ?? defaultOptions.locale?.options?.weekStartsOn ?? 0;
2975
- const _date = toDate(date);
2976
- const day = _date.getDay();
2977
- const diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;
2978
- _date.setDate(_date.getDate() - diff);
2979
- _date.setHours(0, 0, 0, 0);
2980
- return _date;
2981
- }
2982
- function normalizeDates(context) {
2983
- for (var _len = arguments.length, dates = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
2984
- dates[_key - 1] = arguments[_key];
2985
- }
2986
- const normalize = constructFrom.bind(null, dates.find(date => typeof date === "object"));
2987
- return dates.map(normalize);
2988
- }
2989
-
2990
- /**
2991
- * The {@link startOfDay} function options.
2992
- */
2993
-
2994
- /**
2995
- * @name startOfDay
2996
- * @category Day Helpers
2997
- * @summary Return the start of a day for the given date.
2998
- *
2999
- * @description
3000
- * Return the start of a day for the given date.
3001
- * The result will be in the local timezone.
3002
- *
3003
- * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
3004
- * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
3005
- *
3006
- * @param date - The original date
3007
- * @param options - The options
3008
- *
3009
- * @returns The start of a day
3010
- *
3011
- * @example
3012
- * // The start of a day for 2 September 2014 11:55:00:
3013
- * const result = startOfDay(new Date(2014, 8, 2, 11, 55, 0))
3014
- * //=> Tue Sep 02 2014 00:00:00
3015
- */
3016
- function startOfDay(date, options) {
3017
- const _date = toDate(date);
3018
- _date.setHours(0, 0, 0, 0);
3019
- return _date;
3020
- }
3021
-
3022
- /**
3023
- * The {@link addWeeks} function options.
3024
- */
3025
-
3026
- /**
3027
- * @name addWeeks
3028
- * @category Week Helpers
3029
- * @summary Add the specified number of weeks to the given date.
3030
- *
3031
- * @description
3032
- * Add the specified number of weeks to the given date.
3033
- *
3034
- * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
3035
- * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
3036
- *
3037
- * @param date - The date to be changed
3038
- * @param amount - The amount of weeks to be added.
3039
- * @param options - An object with options
3040
- *
3041
- * @returns The new date with the weeks added
3042
- *
3043
- * @example
3044
- * // Add 4 weeks to 1 September 2014:
3045
- * const result = addWeeks(new Date(2014, 8, 1), 4)
3046
- * //=> Mon Sep 29 2014 00:00:00
3047
- */
3048
- function addWeeks(date, amount, options) {
3049
- return addDays(date, amount * 7);
3050
- }
3051
-
3052
- /**
3053
- * The {@link isSameDay} function options.
3054
- */
3055
-
3056
- /**
3057
- * @name isSameDay
3058
- * @category Day Helpers
3059
- * @summary Are the given dates in the same day (and year and month)?
3060
- *
3061
- * @description
3062
- * Are the given dates in the same day (and year and month)?
3063
- *
3064
- * @param laterDate - The first date to check
3065
- * @param earlierDate - The second date to check
3066
- * @param options - An object with options
3067
- *
3068
- * @returns The dates are in the same day (and year and month)
3069
- *
3070
- * @example
3071
- * // Are 4 September 06:00:00 and 4 September 18:00:00 in the same day?
3072
- * const result = isSameDay(new Date(2014, 8, 4, 6, 0), new Date(2014, 8, 4, 18, 0))
3073
- * //=> true
3074
- *
3075
- * @example
3076
- * // Are 4 September and 4 October in the same day?
3077
- * const result = isSameDay(new Date(2014, 8, 4), new Date(2014, 9, 4))
3078
- * //=> false
3079
- *
3080
- * @example
3081
- * // Are 4 September, 2014 and 4 September, 2015 in the same day?
3082
- * const result = isSameDay(new Date(2014, 8, 4), new Date(2015, 8, 4))
3083
- * //=> false
3084
- */
3085
- function isSameDay(laterDate, earlierDate, options) {
3086
- const [dateLeft_, dateRight_] = normalizeDates(options?.in, laterDate, earlierDate);
3087
- return +startOfDay(dateLeft_) === +startOfDay(dateRight_);
3088
- }
3089
- function normalizeInterval(context, interval) {
3090
- const [start, end] = normalizeDates(context, interval.start, interval.end);
3091
- return {
3092
- start,
3093
- end
3094
- };
3095
- }
3096
-
3097
- /**
3098
- * The {@link eachWeekOfInterval} function options.
3099
- */
3100
-
3101
- /**
3102
- * The {@link eachWeekOfInterval} function result type. It resolves the proper data type.
3103
- * It uses the first argument date object type, starting from the interval start date,
3104
- * then the end interval date. If a context function is passed, it uses the context function return type.
3105
- */
3106
-
3107
- /**
3108
- * @name eachWeekOfInterval
3109
- * @category Interval Helpers
3110
- * @summary Return the array of weeks within the specified time interval.
3111
- *
3112
- * @description
3113
- * Return the array of weeks within the specified time interval.
3114
- *
3115
- * @param interval - The interval.
3116
- * @param options - An object with options.
3117
- *
3118
- * @returns The array with starts of weeks from the week of the interval start to the week of the interval end
3119
- *
3120
- * @example
3121
- * // Each week within interval 6 October 2014 - 23 November 2014:
3122
- * const result = eachWeekOfInterval({
3123
- * start: new Date(2014, 9, 6),
3124
- * end: new Date(2014, 10, 23)
3125
- * })
3126
- * //=> [
3127
- * // Sun Oct 05 2014 00:00:00,
3128
- * // Sun Oct 12 2014 00:00:00,
3129
- * // Sun Oct 19 2014 00:00:00,
3130
- * // Sun Oct 26 2014 00:00:00,
3131
- * // Sun Nov 02 2014 00:00:00,
3132
- * // Sun Nov 09 2014 00:00:00,
3133
- * // Sun Nov 16 2014 00:00:00,
3134
- * // Sun Nov 23 2014 00:00:00
3135
- * // ]
3136
- */
3137
- function eachWeekOfInterval(interval, options) {
3138
- const {
3139
- start,
3140
- end
3141
- } = normalizeInterval(options?.in, interval);
3142
- let reversed = +start > +end;
3143
- const startDateWeek = reversed ? startOfWeek(end) : startOfWeek(start);
3144
- const endDateWeek = reversed ? startOfWeek(start) : startOfWeek(end);
3145
- startDateWeek.setHours(15);
3146
- endDateWeek.setHours(15);
3147
- const endTime = +endDateWeek.getTime();
3148
- let currentDate = startDateWeek;
3149
- let step = 1;
3150
- const dates = [];
3151
- while (+currentDate <= endTime) {
3152
- currentDate.setHours(0);
3153
- dates.push(constructFrom(start, currentDate));
3154
- currentDate = addWeeks(currentDate, step);
3155
- currentDate.setHours(15);
3156
- }
3157
- return reversed ? dates.reverse() : dates;
3158
- }
3159
-
3160
- /**
3161
- * The {@link startOfMonth} function options.
3162
- */
3163
-
3164
- /**
3165
- * @name startOfMonth
3166
- * @category Month Helpers
3167
- * @summary Return the start of a month for the given date.
3168
- *
3169
- * @description
3170
- * Return the start of a month for the given date. The result will be in the local timezone.
3171
- *
3172
- * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments.
3173
- * Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
3174
- * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed,
3175
- * or inferred from the arguments.
3176
- *
3177
- * @param date - The original date
3178
- * @param options - An object with options
3179
- *
3180
- * @returns The start of a month
3181
- *
3182
- * @example
3183
- * // The start of a month for 2 September 2014 11:55:00:
3184
- * const result = startOfMonth(new Date(2014, 8, 2, 11, 55, 0))
3185
- * //=> Mon Sep 01 2014 00:00:00
3186
- */
3187
- function startOfMonth(date, options) {
3188
- const _date = toDate(date);
3189
- _date.setDate(1);
3190
- _date.setHours(0, 0, 0, 0);
3191
- return _date;
3192
- }
3193
-
3194
- /**
3195
- * The {@link getWeekYear} function options.
3196
- */
3197
-
3198
- /**
3199
- * @name getWeekYear
3200
- * @category Week-Numbering Year Helpers
3201
- * @summary Get the local week-numbering year of the given date.
3202
- *
3203
- * @description
3204
- * Get the local week-numbering year of the given date.
3205
- * The exact calculation depends on the values of
3206
- * `options.weekStartsOn` (which is the index of the first day of the week)
3207
- * and `options.firstWeekContainsDate` (which is the day of January, which is always in
3208
- * the first week of the week-numbering year)
3209
- *
3210
- * Week numbering: https://en.wikipedia.org/wiki/Week#The_ISO_week_date_system
3211
- *
3212
- * @param date - The given date
3213
- * @param options - An object with options.
3214
- *
3215
- * @returns The local week-numbering year
3216
- *
3217
- * @example
3218
- * // Which week numbering year is 26 December 2004 with the default settings?
3219
- * const result = getWeekYear(new Date(2004, 11, 26))
3220
- * //=> 2005
3221
- *
3222
- * @example
3223
- * // Which week numbering year is 26 December 2004 if week starts on Saturday?
3224
- * const result = getWeekYear(new Date(2004, 11, 26), { weekStartsOn: 6 })
3225
- * //=> 2004
3226
- *
3227
- * @example
3228
- * // Which week numbering year is 26 December 2004 if the first week contains 4 January?
3229
- * const result = getWeekYear(new Date(2004, 11, 26), { firstWeekContainsDate: 4 })
3230
- * //=> 2004
3231
- */
3232
- function getWeekYear(date, options) {
3233
- const _date = toDate(date);
3234
- const year = _date.getFullYear();
3235
- const defaultOptions = getDefaultOptions();
3236
- const firstWeekContainsDate = defaultOptions.firstWeekContainsDate ?? defaultOptions.locale?.options?.firstWeekContainsDate ?? 1;
3237
- const firstWeekOfNextYear = constructFrom(date, 0);
3238
- firstWeekOfNextYear.setFullYear(year + 1, 0, firstWeekContainsDate);
3239
- firstWeekOfNextYear.setHours(0, 0, 0, 0);
3240
- const startOfNextYear = startOfWeek(firstWeekOfNextYear);
3241
- const firstWeekOfThisYear = constructFrom(date, 0);
3242
- firstWeekOfThisYear.setFullYear(year, 0, firstWeekContainsDate);
3243
- firstWeekOfThisYear.setHours(0, 0, 0, 0);
3244
- const startOfThisYear = startOfWeek(firstWeekOfThisYear);
3245
- if (+_date >= +startOfNextYear) {
3246
- return year + 1;
3247
- } else if (+_date >= +startOfThisYear) {
3248
- return year;
3249
- } else {
3250
- return year - 1;
3251
- }
3252
- }
3253
-
3254
- /**
3255
- * The {@link startOfWeekYear} function options.
3256
- */
3257
-
3258
- /**
3259
- * @name startOfWeekYear
3260
- * @category Week-Numbering Year Helpers
3261
- * @summary Return the start of a local week-numbering year for the given date.
3262
- *
3263
- * @description
3264
- * Return the start of a local week-numbering year.
3265
- * The exact calculation depends on the values of
3266
- * `options.weekStartsOn` (which is the index of the first day of the week)
3267
- * and `options.firstWeekContainsDate` (which is the day of January, which is always in
3268
- * the first week of the week-numbering year)
3269
- *
3270
- * Week numbering: https://en.wikipedia.org/wiki/Week#The_ISO_week_date_system
3271
- *
3272
- * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
3273
- * @typeParam ResultDate - The result `Date` type.
3274
- *
3275
- * @param date - The original date
3276
- * @param options - An object with options
3277
- *
3278
- * @returns The start of a week-numbering year
3279
- *
3280
- * @example
3281
- * // The start of an a week-numbering year for 2 July 2005 with default settings:
3282
- * const result = startOfWeekYear(new Date(2005, 6, 2))
3283
- * //=> Sun Dec 26 2004 00:00:00
3284
- *
3285
- * @example
3286
- * // The start of a week-numbering year for 2 July 2005
3287
- * // if Monday is the first day of week
3288
- * // and 4 January is always in the first week of the year:
3289
- * const result = startOfWeekYear(new Date(2005, 6, 2), {
3290
- * weekStartsOn: 1,
3291
- * firstWeekContainsDate: 4
3292
- * })
3293
- * //=> Mon Jan 03 2005 00:00:00
3294
- */
3295
- function startOfWeekYear(date, options) {
3296
- const defaultOptions = getDefaultOptions();
3297
- const firstWeekContainsDate = defaultOptions.firstWeekContainsDate ?? defaultOptions.locale?.options?.firstWeekContainsDate ?? 1;
3298
- const year = getWeekYear(date);
3299
- const firstWeek = constructFrom(date, 0);
3300
- firstWeek.setFullYear(year, 0, firstWeekContainsDate);
3301
- firstWeek.setHours(0, 0, 0, 0);
3302
- const _date = startOfWeek(firstWeek);
3303
- return _date;
3304
- }
3305
-
3306
- /**
3307
- * The {@link getWeek} function options.
3308
- */
3309
-
3310
- /**
3311
- * @name getWeek
3312
- * @category Week Helpers
3313
- * @summary Get the local week index of the given date.
3314
- *
3315
- * @description
3316
- * Get the local week index of the given date.
3317
- * The exact calculation depends on the values of
3318
- * `options.weekStartsOn` (which is the index of the first day of the week)
3319
- * and `options.firstWeekContainsDate` (which is the day of January, which is always in
3320
- * the first week of the week-numbering year)
3321
- *
3322
- * Week numbering: https://en.wikipedia.org/wiki/Week#The_ISO_week_date_system
3323
- *
3324
- * @param date - The given date
3325
- * @param options - An object with options
3326
- *
3327
- * @returns The week
3328
- *
3329
- * @example
3330
- * // Which week of the local week numbering year is 2 January 2005 with default options?
3331
- * const result = getWeek(new Date(2005, 0, 2))
3332
- * //=> 2
3333
- *
3334
- * @example
3335
- * // Which week of the local week numbering year is 2 January 2005,
3336
- * // if Monday is the first day of the week,
3337
- * // and the first week of the year always contains 4 January?
3338
- * const result = getWeek(new Date(2005, 0, 2), {
3339
- * weekStartsOn: 1,
3340
- * firstWeekContainsDate: 4
3341
- * })
3342
- * //=> 53
3343
- */
3344
- function getWeek(date, options) {
3345
- const _date = toDate(date);
3346
- const diff = +startOfWeek(_date) - +startOfWeekYear(_date);
3347
-
3348
- // Round the number of weeks to the nearest integer because the number of
3349
- // milliseconds in a week is not constant (e.g. it's different in the week of
3350
- // the daylight saving time clock shift).
3351
- return Math.round(diff / millisecondsInWeek) + 1;
3352
- }
3353
-
3354
- /**
3355
- * The {@link getDaysInMonth} function options.
3356
- */
3357
-
3358
- /**
3359
- * @name getDaysInMonth
3360
- * @category Month Helpers
3361
- * @summary Get the number of days in a month of the given date.
3362
- *
3363
- * @description
3364
- * Get the number of days in a month of the given date, considering the context if provided.
3365
- *
3366
- * @param date - The given date
3367
- * @param options - An object with options
3368
- *
3369
- * @returns The number of days in a month
3370
- *
3371
- * @example
3372
- * // How many days are in February 2000?
3373
- * const result = getDaysInMonth(new Date(2000, 1))
3374
- * //=> 29
3375
- */
3376
- function getDaysInMonth(date, options) {
3377
- const _date = toDate(date);
3378
- const year = _date.getFullYear();
3379
- const monthIndex = _date.getMonth();
3380
- const lastDayOfMonth = constructFrom(_date, 0);
3381
- lastDayOfMonth.setFullYear(year, monthIndex + 1, 0);
3382
- lastDayOfMonth.setHours(0, 0, 0, 0);
3383
- return lastDayOfMonth.getDate();
3384
- }
3385
-
3386
- /**
3387
- * The {@link lastDayOfMonth} function options.
3388
- */
3389
-
3390
- /**
3391
- * @name lastDayOfMonth
3392
- * @category Month Helpers
3393
- * @summary Return the last day of a month for the given date.
3394
- *
3395
- * @description
3396
- * Return the last day of a month for the given date.
3397
- * The result will be in the local timezone.
3398
- *
3399
- * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
3400
- * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
3401
- *
3402
- * @param date - The original date
3403
- * @param options - An object with options
3404
- *
3405
- * @returns The last day of a month
3406
- *
3407
- * @example
3408
- * // The last day of a month for 2 September 2014 11:55:00:
3409
- * const result = lastDayOfMonth(new Date(2014, 8, 2, 11, 55, 0))
3410
- * //=> Tue Sep 30 2014 00:00:00
3411
- */
3412
- function lastDayOfMonth(date, options) {
3413
- const _date = toDate(date);
3414
- const month = _date.getMonth();
3415
- _date.setFullYear(_date.getFullYear(), month + 1, 0);
3416
- _date.setHours(0, 0, 0, 0);
3417
- return toDate(_date);
3418
- }
3419
-
3420
- /**
3421
- * The {@link isSameMonth} function options.
3422
- */
3423
-
3424
- /**
3425
- * @name isSameMonth
3426
- * @category Month Helpers
3427
- * @summary Are the given dates in the same month (and year)?
3428
- *
3429
- * @description
3430
- * Are the given dates in the same month (and year)?
3431
- *
3432
- * @param laterDate - The first date to check
3433
- * @param earlierDate - The second date to check
3434
- * @param options - An object with options
3435
- *
3436
- * @returns The dates are in the same month (and year)
3437
- *
3438
- * @example
3439
- * // Are 2 September 2014 and 25 September 2014 in the same month?
3440
- * const result = isSameMonth(new Date(2014, 8, 2), new Date(2014, 8, 25))
3441
- * //=> true
3442
- *
3443
- * @example
3444
- * // Are 2 September 2014 and 25 September 2015 in the same month?
3445
- * const result = isSameMonth(new Date(2014, 8, 2), new Date(2015, 8, 25))
3446
- * //=> false
3447
- */
3448
- function isSameMonth(laterDate, earlierDate, options) {
3449
- const [laterDate_, earlierDate_] = normalizeDates(options?.in, laterDate, earlierDate);
3450
- return laterDate_.getFullYear() === earlierDate_.getFullYear() && laterDate_.getMonth() === earlierDate_.getMonth();
3451
- }
3452
-
3453
- /**
3454
- * The {@link setMonth} function options.
3455
- */
3456
-
3457
- /**
3458
- * @name setMonth
3459
- * @category Month Helpers
3460
- * @summary Set the month to the given date.
3461
- *
3462
- * @description
3463
- * Set the month to the given date.
3464
- *
3465
- * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
3466
- * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
3467
- *
3468
- * @param date - The date to be changed
3469
- * @param month - The month index to set (0-11)
3470
- * @param options - The options
3471
- *
3472
- * @returns The new date with the month set
3473
- *
3474
- * @example
3475
- * // Set February to 1 September 2014:
3476
- * const result = setMonth(new Date(2014, 8, 1), 1)
3477
- * //=> Sat Feb 01 2014 00:00:00
3478
- */
3479
- function setMonth(date, month, options) {
3480
- const _date = toDate(date);
3481
- const year = _date.getFullYear();
3482
- const day = _date.getDate();
3483
- const midMonth = constructFrom(date, 0);
3484
- midMonth.setFullYear(year, month, 15);
3485
- midMonth.setHours(0, 0, 0, 0);
3486
- const daysInMonth = getDaysInMonth(midMonth);
3487
-
3488
- // Set the earlier date, allows to wrap Jan 31 to Feb 28
3489
- _date.setMonth(month, Math.min(day, daysInMonth));
3490
- return _date;
3491
- }
3492
-
3493
- /**
3494
- * The {@link setDate} function options.
3495
- */
3496
-
3497
- /**
3498
- * @name setDate
3499
- * @category Day Helpers
3500
- * @summary Set the day of the month to the given date.
3501
- *
3502
- * @description
3503
- * Set the day of the month to the given date.
3504
- *
3505
- * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows using extensions like [`UTCDate`](https://github.com/date-fns/utc).
3506
- * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
3507
- *
3508
- * @param date - The date to be changed
3509
- * @param dayOfMonth - The day of the month of the new date
3510
- * @param options - The options
3511
- *
3512
- * @returns The new date with the day of the month set
3513
- *
3514
- * @example
3515
- * // Set the 30th day of the month to 1 September 2014:
3516
- * const result = setDate(new Date(2014, 8, 1), 30)
3517
- * //=> Tue Sep 30 2014 00:00:00
3518
- */
3519
- function setDate(date, dayOfMonth, options) {
3520
- const _date = toDate(date);
3521
- _date.setDate(dayOfMonth);
3522
- return _date;
3523
- }
3524
-
3525
- /**
3526
- * The {@link setHours} function options.
3527
- */
3528
-
3529
- /**
3530
- * @name setHours
3531
- * @category Hour Helpers
3532
- * @summary Set the hours to the given date.
3533
- *
3534
- * @description
3535
- * Set the hours to the given date.
3536
- *
3537
- * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
3538
- * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
3539
- *
3540
- * @param date - The date to be changed
3541
- * @param hours - The hours of the new date
3542
- * @param options - An object with options
3543
- *
3544
- * @returns The new date with the hours set
3545
- *
3546
- * @example
3547
- * // Set 4 hours to 1 September 2014 11:30:00:
3548
- * const result = setHours(new Date(2014, 8, 1, 11, 30), 4)
3549
- * //=> Mon Sep 01 2014 04:30:00
3550
- */
3551
- function setHours(date, hours, options) {
3552
- const _date = toDate(date);
3553
- _date.setHours(hours);
3554
- return _date;
3555
- }
3556
-
3557
- /**
3558
- * The {@link setMinutes} function options.
3559
- */
3560
-
3561
- /**
3562
- * @name setMinutes
3563
- * @category Minute Helpers
3564
- * @summary Set the minutes to the given date.
3565
- *
3566
- * @description
3567
- * Set the minutes to the given date.
3568
- *
3569
- * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows using extensions like [`UTCDate`](https://github.com/date-fns/utc).
3570
- * @typeParam ResultDate - The result `Date` type, returned from the context function, or inferred from the arguments.
3571
- *
3572
- * @param date - The date to be changed
3573
- * @param minutes - The minutes of the new date
3574
- * @param options - An object with options
3575
- *
3576
- * @returns The new date with the minutes set
3577
- *
3578
- * @example
3579
- * // Set 45 minutes to 1 September 2014 11:30:40:
3580
- * const result = setMinutes(new Date(2014, 8, 1, 11, 30, 40), 45)
3581
- * //=> Mon Sep 01 2014 11:45:40
3582
- */
3583
- function setMinutes(date, minutes, options) {
3584
- const date_ = toDate(date);
3585
- date_.setMinutes(minutes);
3586
- return date_;
3587
- }
3588
-
3589
- /**
3590
- * The {@link setYear} function options.
3591
- */
3592
-
3593
- /**
3594
- * @name setYear
3595
- * @category Year Helpers
3596
- * @summary Set the year to the given date.
3597
- *
3598
- * @description
3599
- * Set the year to the given date.
3600
- *
3601
- * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
3602
- * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.
3603
- *
3604
- * @param date - The date to be changed
3605
- * @param year - The year of the new date
3606
- * @param options - An object with options.
3607
- *
3608
- * @returns The new date with the year set
3609
- *
3610
- * @example
3611
- * // Set year 2013 to 1 September 2014:
3612
- * const result = setYear(new Date(2014, 8, 1), 2013)
3613
- * //=> Sun Sep 01 2013 00:00:00
3614
- */
3615
- function setYear(date, year, options) {
3616
- const date_ = toDate(date);
3617
-
3618
- // Check if date is Invalid Date because Date.prototype.setFullYear ignores the value of Invalid Date
3619
- if (isNaN(+date_)) return constructFrom(date, NaN);
3620
- date_.setFullYear(year);
3621
- return date_;
3622
- }
3623
- function CalendarDay(props) {
3624
- const {
3625
- date,
3626
- focused,
3627
- isCurrentMonth,
3628
- isToday,
3629
- onSelect,
3630
- selected
3631
- } = props;
3632
- const handleClick = useCallback(() => {
3633
- onSelect(date);
3634
- }, [date, onSelect]);
3635
- return /* @__PURE__ */jsx("div", {
3636
- "aria-selected": selected,
3637
- "data-ui": "CalendarDay",
3638
- children: /* @__PURE__ */jsx(Card, {
3639
- "aria-label": date.toDateString(),
3640
- "aria-pressed": selected,
3641
- as: "button",
3642
- __unstable_focusRing: true,
3643
- "data-weekday": true,
3644
- "data-focused": focused ? "true" : "",
3645
- role: "button",
3646
- tabIndex: -1,
3647
- onClick: handleClick,
3648
- padding: 3,
3649
- radius: 2,
3650
- selected,
3651
- tone: isToday || selected ? "primary" : "default",
3652
- children: /* @__PURE__ */jsx(Text, {
3653
- muted: !selected && !isCurrentMonth,
3654
- style: {
3655
- textAlign: "center"
3656
- },
3657
- weight: isCurrentMonth ? "medium" : "regular",
3658
- children: date.getDate()
3659
- })
3660
- })
3661
- });
3662
- }
3663
- const MONTH_NAMES = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
3664
- const WEEK_DAY_NAMES = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
3665
- const HOURS_24 = range(0, 24);
3666
- const ARROW_KEYS = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"];
3667
- const TAIL_WEEKDAYS = [1, 2, 3, 4, 5, 6];
3668
- const getWeekStartsOfMonth = date => {
3669
- const firstDay = startOfMonth(date);
3670
- return eachWeekOfInterval({
3671
- start: firstDay,
3672
- end: lastDayOfMonth(firstDay)
3673
- });
3674
- };
3675
- const getWeekDaysFromWeekStarts = weekStarts => {
3676
- return weekStarts.map(weekStart => [weekStart, ...TAIL_WEEKDAYS.map(d => addDays(weekStart, d))]);
3677
- };
3678
- const getWeeksOfMonth = date => getWeekDaysFromWeekStarts(getWeekStartsOfMonth(date)).map(days => ({
3679
- number: getWeek(days[0]),
3680
- days
3681
- }));
3682
- function CalendarMonth(props) {
3683
- return /* @__PURE__ */jsx(Box, {
3684
- "aria-hidden": props.hidden || false,
3685
- "data-ui": "CalendarMonth",
3686
- children: /* @__PURE__ */jsxs(Grid, {
3687
- gap: 1,
3688
- style: {
3689
- gridTemplateColumns: "repeat(7, minmax(44px, 46px))"
3690
- },
3691
- children: [WEEK_DAY_NAMES.map(weekday => /* @__PURE__ */jsx(Box, {
3692
- paddingY: 2,
3693
- children: /* @__PURE__ */jsx(Text, {
3694
- size: 1,
3695
- weight: "medium",
3696
- style: {
3697
- textAlign: "center"
3698
- },
3699
- children: weekday
3700
- })
3701
- }, weekday)), getWeeksOfMonth(props.date).map((week, weekIdx) => week.days.map((date, dayIdx) => {
3702
- const focused = props.focused && isSameDay(date, props.focused);
3703
- const selected = props.selected && isSameDay(date, props.selected);
3704
- const isToday = isSameDay(date, /* @__PURE__ */new Date());
3705
- const isCurrentMonth = props.focused && isSameMonth(date, props.focused);
3706
- return /* @__PURE__ */jsx(CalendarDay, {
3707
- date,
3708
- focused,
3709
- isCurrentMonth,
3710
- isToday,
3711
- onSelect: props.onSelect,
3712
- selected
3713
- }, `${weekIdx}-${dayIdx}`);
3714
- }))]
3715
- })
3716
- });
3717
- }
3718
- const features = {
3719
- dayPresets: false,
3720
- timePresets: false
3721
- };
3722
- const LazyTextInput = React__default.forwardRef(function LazyTextInput2(_ref4, forwardedRef) {
3723
- let {
3724
- onChange,
3725
- onBlur,
3726
- onKeyPress,
3727
- value,
3728
- ...rest
3729
- } = _ref4;
3730
- const [inputValue, setInputValue] = React__default.useState();
3731
- const handleChange = React__default.useCallback(event => {
3732
- setInputValue(event.currentTarget.value);
3733
- }, []);
3734
- const checkEvent = React__default.useCallback(
3735
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
3736
- event => {
3737
- const currentValue = event.currentTarget.value;
3738
- if (currentValue !== `${value}`) {
3739
- if (onChange) {
3740
- onChange(event);
3741
- }
3742
- }
3743
- setInputValue(void 0);
3744
- }, [onChange, value]);
3745
- const handleBlur = React__default.useCallback(
3746
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
3747
- e => {
3748
- checkEvent(e);
3749
- if (onBlur) {
3750
- onBlur(e);
3751
- }
3752
- }, [checkEvent, onBlur]);
3753
- const handleKeyPress = React__default.useCallback(e => {
3754
- if (e.key === "Enter") {
3755
- checkEvent(e);
3756
- }
3757
- if (onKeyPress) {
3758
- onKeyPress(e);
3759
- }
3760
- }, [checkEvent, onKeyPress]);
3761
- return /* @__PURE__ */jsx(TextInput, {
3762
- ...rest,
3763
- "data-testid": "date-input",
3764
- ref: forwardedRef,
3765
- value: inputValue === void 0 ? value : inputValue,
3766
- onChange: handleChange,
3767
- onBlur: handleBlur,
3768
- onKeyPress: handleKeyPress
3769
- });
3770
- });
3771
- const YearInput = _ref7 => {
3772
- let {
3773
- onChange,
3774
- ...props
3775
- } = _ref7;
3776
- const handleChange = React__default.useCallback(event => {
3777
- const numericValue = parseInt(event.currentTarget.value, 10);
3778
- if (!isNaN(numericValue)) {
3779
- onChange(numericValue);
3780
- }
3781
- }, [onChange]);
3782
- return /* @__PURE__ */jsx(LazyTextInput, {
3783
- ...props,
3784
- onChange: handleChange,
3785
- inputMode: "numeric"
3786
- });
3787
- };
3788
- const PRESERVE_FOCUS_ELEMENT = /* @__PURE__ */jsx("span", {
3789
- "data-preserve-focus": true,
3790
- style: {
3791
- overflow: "hidden",
3792
- position: "absolute",
3793
- outline: "none"
3794
- },
3795
- tabIndex: -1
3796
- });
3797
- const Calendar = forwardRef(function Calendar2(props, forwardedRef) {
3798
- const {
3799
- selectTime,
3800
- onFocusedDateChange,
3801
- selectedDate = /* @__PURE__ */new Date(),
3802
- focusedDate = selectedDate,
3803
- timeStep = 1,
3804
- onSelect,
3805
- ...restProps
3806
- } = props;
3807
- const setFocusedDate = useCallback(date => onFocusedDateChange(date), [onFocusedDateChange]);
3808
- const setFocusedDateMonth = useCallback(month => setFocusedDate(setDate(setMonth(focusedDate, month), 1)), [focusedDate, setFocusedDate]);
3809
- const handleFocusedMonthChange = useCallback(e => setFocusedDateMonth(Number(e.currentTarget.value)), [setFocusedDateMonth]);
3810
- const moveFocusedDate = useCallback(by => setFocusedDate(addMonths(focusedDate, by)), [focusedDate, setFocusedDate]);
3811
- const setFocusedDateYear = useCallback(year => setFocusedDate(setYear(focusedDate, year)), [focusedDate, setFocusedDate]);
3812
- const handleDateChange = useCallback(date => {
3813
- onSelect(setMinutes(setHours(date, selectedDate.getHours()), selectedDate.getMinutes()));
3814
- }, [onSelect, selectedDate]);
3815
- const handleMinutesChange = useCallback(event => {
3816
- const m = Number(event.currentTarget.value);
3817
- onSelect(setMinutes(selectedDate, m));
3818
- }, [onSelect, selectedDate]);
3819
- const handleHoursChange = useCallback(event => {
3820
- const m = Number(event.currentTarget.value);
3821
- onSelect(setHours(selectedDate, m));
3822
- }, [onSelect, selectedDate]);
3823
- useCallback((hours, mins) => {
3824
- onSelect(setHours(setMinutes(selectedDate, mins), hours));
3825
- }, [onSelect, selectedDate]);
3826
- const ref = useForwardedRef(forwardedRef);
3827
- const focusCurrentWeekDay = useCallback(() => {
3828
- ref.current?.querySelector(`[data-focused="true"]`)?.focus();
3829
- }, [ref]);
3830
- const handleKeyDown = useCallback(
3831
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
3832
- event => {
3833
- if (!ARROW_KEYS.includes(event.key)) {
3834
- return;
3835
- }
3836
- event.preventDefault();
3837
- if (event.target.hasAttribute("data-calendar-grid")) {
3838
- focusCurrentWeekDay();
3839
- return;
3840
- }
3841
- if (event.key === "ArrowUp") {
3842
- onFocusedDateChange(addDays(focusedDate, -7));
3843
- }
3844
- if (event.key === "ArrowDown") {
3845
- onFocusedDateChange(addDays(focusedDate, 7));
3846
- }
3847
- if (event.key === "ArrowLeft") {
3848
- onFocusedDateChange(addDays(focusedDate, -1));
3849
- }
3850
- if (event.key === "ArrowRight") {
3851
- onFocusedDateChange(addDays(focusedDate, 1));
3852
- }
3853
- ref.current?.querySelector("[data-preserve-focus]")?.focus();
3854
- }, [ref, focusCurrentWeekDay, onFocusedDateChange, focusedDate]);
3855
- useEffect(() => {
3856
- focusCurrentWeekDay();
3857
- }, [focusCurrentWeekDay]);
3858
- useEffect(() => {
3859
- const currentFocusInCalendarGrid = document.activeElement?.matches("[data-calendar-grid], [data-calendar-grid] [data-preserve-focus]");
3860
- if (
3861
- // Only move focus if it's currently in the calendar grid
3862
- currentFocusInCalendarGrid) {
3863
- focusCurrentWeekDay();
3864
- }
3865
- }, [ref, focusCurrentWeekDay, focusedDate]);
3866
- useCallback(() => handleDateChange(addDays(/* @__PURE__ */new Date(), -1)), [handleDateChange]);
3867
- useCallback(() => handleDateChange(/* @__PURE__ */new Date()), [handleDateChange]);
3868
- useCallback(() => handleDateChange(addDays(/* @__PURE__ */new Date(), 1)), [handleDateChange]);
3869
- const handleNowClick = useCallback(() => onSelect(/* @__PURE__ */new Date()), [onSelect]);
3870
- return /* @__PURE__ */jsxs(Box, {
3871
- "data-ui": "Calendar",
3872
- ...restProps,
3873
- ref,
3874
- children: [/* @__PURE__ */jsxs(Box, {
3875
- padding: 2,
3876
- children: [features.dayPresets, /* @__PURE__ */jsxs(Flex, {
3877
- children: [/* @__PURE__ */jsx(Box, {
3878
- flex: 1,
3879
- children: /* @__PURE__ */jsx(CalendarMonthSelect, {
3880
- moveFocusedDate,
3881
- onChange: handleFocusedMonthChange,
3882
- value: focusedDate?.getMonth()
3883
- })
3884
- }), /* @__PURE__ */jsx(Box, {
3885
- marginLeft: 2,
3886
- children: /* @__PURE__ */jsx(CalendarYearSelect, {
3887
- moveFocusedDate,
3888
- onChange: setFocusedDateYear,
3889
- value: focusedDate.getFullYear()
3890
- })
3891
- })]
3892
- }), /* @__PURE__ */jsxs(Box, {
3893
- "data-calendar-grid": true,
3894
- onKeyDown: handleKeyDown,
3895
- marginTop: 2,
3896
- overflow: "hidden",
3897
- tabIndex: 0,
3898
- children: [/* @__PURE__ */jsx(CalendarMonth, {
3899
- date: focusedDate,
3900
- focused: focusedDate,
3901
- onSelect: handleDateChange,
3902
- selected: selectedDate
3903
- }), PRESERVE_FOCUS_ELEMENT]
3904
- })]
3905
- }), selectTime && /* @__PURE__ */jsxs(Box, {
3906
- padding: 2,
3907
- style: {
3908
- borderTop: "1px solid var(--card-border-color)"
3909
- },
3910
- children: [/* @__PURE__ */jsxs(Flex, {
3911
- align: "center",
3912
- children: [/* @__PURE__ */jsxs(Flex, {
3913
- align: "center",
3914
- flex: 1,
3915
- children: [/* @__PURE__ */jsx(Box, {
3916
- children: /* @__PURE__ */jsx(Select, {
3917
- "aria-label": "Select hour",
3918
- value: selectedDate?.getHours(),
3919
- onChange: handleHoursChange,
3920
- children: HOURS_24.map(h => /* @__PURE__ */jsx("option", {
3921
- value: h,
3922
- children: `${h}`.padStart(2, "0")
3923
- }, h))
3924
- })
3925
- }), /* @__PURE__ */jsx(Box, {
3926
- paddingX: 1,
3927
- children: /* @__PURE__ */jsx(Text, {
3928
- children: ":"
3929
- })
3930
- }), /* @__PURE__ */jsx(Box, {
3931
- children: /* @__PURE__ */jsx(Select, {
3932
- "aria-label": "Select minutes",
3933
- value: selectedDate?.getMinutes(),
3934
- onChange: handleMinutesChange,
3935
- children: range(0, 60, timeStep).map(m => /* @__PURE__ */jsx("option", {
3936
- value: m,
3937
- children: `${m}`.padStart(2, "0")
3938
- }, m))
3939
- })
3940
- })]
3941
- }), /* @__PURE__ */jsx(Box, {
3942
- marginLeft: 2,
3943
- children: /* @__PURE__ */jsx(Button, {
3944
- text: "Set to current time",
3945
- mode: "bleed",
3946
- onClick: handleNowClick
3947
- })
3948
- })]
3949
- }), features.timePresets]
3950
- })]
3951
- });
3952
- });
3953
- function CalendarMonthSelect(props) {
3954
- const {
3955
- moveFocusedDate,
3956
- onChange,
3957
- value
3958
- } = props;
3959
- const handlePrevMonthClick = useCallback(() => moveFocusedDate(-1), [moveFocusedDate]);
3960
- const handleNextMonthClick = useCallback(() => moveFocusedDate(1), [moveFocusedDate]);
3961
- return /* @__PURE__ */jsxs(Flex, {
3962
- flex: 1,
3963
- children: [/* @__PURE__ */jsx(Button, {
3964
- "aria-label": "Go to previous month",
3965
- onClick: handlePrevMonthClick,
3966
- mode: "bleed",
3967
- icon: ChevronLeftIcon,
3968
- paddingX: 2,
3969
- radius: 0
3970
- }), /* @__PURE__ */jsx(Box, {
3971
- flex: 1,
3972
- children: /* @__PURE__ */jsx(Select, {
3973
- radius: 0,
3974
- value,
3975
- onChange,
3976
- children: MONTH_NAMES.map((m, i) =>
3977
- // eslint-disable-next-line react/no-array-index-key
3978
- /* @__PURE__ */
3979
- jsx("option", {
3980
- value: i,
3981
- children: m
3982
- }, i))
3983
- })
3984
- }), /* @__PURE__ */jsx(Button, {
3985
- "aria-label": "Go to next month",
3986
- mode: "bleed",
3987
- icon: ChevronRightIcon,
3988
- onClick: handleNextMonthClick,
3989
- paddingX: 2,
3990
- radius: 0
3991
- })]
3992
- });
3993
- }
3994
- function CalendarYearSelect(props) {
3995
- const {
3996
- moveFocusedDate,
3997
- onChange,
3998
- value
3999
- } = props;
4000
- const handlePrevYearClick = useCallback(() => moveFocusedDate(-12), [moveFocusedDate]);
4001
- const handleNextYearClick = useCallback(() => moveFocusedDate(12), [moveFocusedDate]);
4002
- return /* @__PURE__ */jsxs(Flex, {
4003
- children: [/* @__PURE__ */jsx(Button, {
4004
- "aria-label": "Previous year",
4005
- onClick: handlePrevYearClick,
4006
- mode: "bleed",
4007
- icon: ChevronLeftIcon,
4008
- paddingX: 2,
4009
- radius: 0
4010
- }), /* @__PURE__ */jsx(YearInput, {
4011
- value,
4012
- onChange,
4013
- radius: 0,
4014
- style: {
4015
- width: 65
4016
- }
4017
- }), /* @__PURE__ */jsx(Button, {
4018
- "aria-label": "Next year",
4019
- onClick: handleNextYearClick,
4020
- mode: "bleed",
4021
- icon: ChevronRightIcon,
4022
- paddingX: 2,
4023
- radius: 0
4024
- })]
4025
- });
4026
- }
4027
- const DatePicker = React__default.forwardRef(function DatePicker2(props, ref) {
4028
- const {
4029
- value = /* @__PURE__ */new Date(),
4030
- onChange,
4031
- ...rest
4032
- } = props;
4033
- const [focusedDate, setFocusedDay] = React__default.useState();
4034
- const handleSelect = React__default.useCallback(
4035
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
4036
- nextDate => {
4037
- onChange(nextDate);
4038
- setFocusedDay(void 0);
4039
- }, [onChange]);
4040
- return /* @__PURE__ */jsx(Calendar, {
4041
- ...rest,
4042
- ref,
4043
- selectedDate: value,
4044
- onSelect: handleSelect,
4045
- focusedDate: focusedDate || value,
4046
- onFocusedDateChange: setFocusedDay
4047
- });
4048
- });
4049
- const DateTimeInput = forwardRef(function DateTimeInput2(props, ref) {
4050
- const {
4051
- value,
4052
- inputValue,
4053
- onInputChange,
4054
- onChange,
4055
- selectTime,
4056
- timeStep,
4057
- ...rest
4058
- } = props;
4059
- const [popoverRef, setPopoverRef] = useState(null);
4060
- const forwardedRef = useForwardedRef(ref);
4061
- const buttonRef = useRef(null);
4062
- const [isPickerOpen, setPickerOpen] = useState(false);
4063
- useClickOutside(() => setPickerOpen(false), [popoverRef]);
4064
- const handleDeactivation = useCallback(() => {
4065
- forwardedRef.current?.focus();
4066
- forwardedRef.current?.select();
4067
- }, [forwardedRef]);
4068
- const handleKeyUp = useCallback(e => {
4069
- if (e.key === "Escape") {
4070
- setPickerOpen(false);
4071
- }
4072
- }, []);
4073
- const handleClick = useCallback(() => setPickerOpen(true), []);
4074
- const suffix = /* @__PURE__ */jsx(Box, {
4075
- padding: 1,
4076
- children: /* @__PURE__ */jsx(Button, {
4077
- ref: buttonRef,
4078
- icon: CalendarIcon,
4079
- mode: "bleed",
4080
- padding: 2,
4081
- onClick: handleClick,
4082
- style: {
4083
- display: "block"
4084
- },
4085
- "data-testid": "select-date-button"
4086
- })
4087
- });
4088
- return /* @__PURE__ */jsx(LazyTextInput, {
4089
- ref: forwardedRef,
4090
- ...rest,
4091
- value: inputValue,
4092
- onChange: onInputChange,
4093
- suffix: isPickerOpen ?
4094
- // Note: we're conditionally inserting the popover here due to an
4095
- // issue with popovers rendering incorrectly on subsequent renders
4096
- // see https://github.com/sanity-io/design/issues/519
4097
- /* @__PURE__ */
4098
- jsx(LayerProvider, {
4099
- zOffset: 1e3,
4100
- children: /* @__PURE__ */jsx(Popover, {
4101
- constrainSize: true,
4102
- "data-testid": "date-input-dialog",
4103
- portal: true,
4104
- content: /* @__PURE__ */jsx(Box, {
4105
- overflow: "auto",
4106
- children: /* @__PURE__ */jsx(FocusLockCombination, {
4107
- onDeactivation: handleDeactivation,
4108
- children: /* @__PURE__ */jsx(DatePicker, {
4109
- selectTime,
4110
- timeStep,
4111
- onKeyUp: handleKeyUp,
4112
- value,
4113
- onChange
4114
- })
4115
- })
4116
- }),
4117
- open: true,
4118
- placement: "bottom",
4119
- ref: setPopoverRef,
4120
- radius: 2,
4121
- children: suffix
4122
- })
4123
- }) : suffix
4124
- });
4125
- });
4126
- const DEFAULT_PLACEHOLDER_TIME = /* @__PURE__ */new Date();
4127
- const CommonDateTimeInput = React__default.forwardRef(function CommonDateTimeInput2(props, ref) {
4128
- const {
4129
- id,
4130
- deserialize,
4131
- formatInputValue,
4132
- onChange,
4133
- parseInputValue,
4134
- placeholder,
4135
- readOnly,
4136
- selectTime,
4137
- serialize,
4138
- timeStep,
4139
- value,
4140
- ...restProps
4141
- } = props;
4142
- const [localValue, setLocalValue] = React__default.useState(null);
4143
- useEffect(() => {
4144
- setLocalValue(null);
4145
- }, [value]);
4146
- const handleDatePickerInputChange = React__default.useCallback(
4147
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
4148
- event => {
4149
- const nextInputValue = event.currentTarget.value;
4150
- const result = nextInputValue === "" ? null : parseInputValue(nextInputValue);
4151
- if (result === null) {
4152
- onChange(null);
4153
- if (typeof value === "undefined" && localValue) {
4154
- setLocalValue(null);
4155
- }
4156
- } else if (result.isValid) {
4157
- onChange(serialize(result.date));
4158
- } else {
4159
- setLocalValue(nextInputValue);
4160
- }
4161
- }, [parseInputValue, onChange, value, localValue, serialize]);
4162
- const handleDatePickerChange = React__default.useCallback(nextDate => {
4163
- onChange(nextDate ? serialize(nextDate) : null);
4164
- }, [serialize, onChange]);
4165
- const forwardedRef = useForwardedRef(ref);
4166
- const parseResult = localValue ? parseInputValue(localValue) : value ? deserialize(value) : null;
4167
- const inputValue = localValue ? localValue : parseResult?.isValid ? formatInputValue(parseResult.date) : value;
4168
- return readOnly ? /* @__PURE__ */jsx(TextInput, {
4169
- value: inputValue,
4170
- readOnly: true,
4171
- disabled: readOnly
4172
- }) : /* @__PURE__ */jsx(DateTimeInput, {
4173
- ...restProps,
4174
- id,
4175
- selectTime,
4176
- timeStep,
4177
- placeholder: placeholder || `e.g. ${formatInputValue(DEFAULT_PLACEHOLDER_TIME)}`,
4178
- ref: forwardedRef,
4179
- value: parseResult?.date,
4180
- inputValue: inputValue || "",
4181
- readOnly: Boolean(readOnly),
4182
- onInputChange: handleDatePickerInputChange,
4183
- onChange: handleDatePickerChange,
4184
- customValidity: parseResult?.error
4185
- });
4186
- });
4187
- const VALUE_FORMAT = "YYYY-MM-DD";
4188
- const DEFAULT_DATE_FORMAT = VALUE_FORMAT;
4189
- function parseOptions() {
4190
- let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
4191
- return {
4192
- dateFormat: options.dateFormat || DEFAULT_DATE_FORMAT,
4193
- calendarTodayLabel: options.calendarTodayLabel || "Today"
4194
- };
4195
- }
4196
- const deserialize = value => parse(value, VALUE_FORMAT);
4197
- const serialize = date => format(date, VALUE_FORMAT);
4198
- function DateInput(props) {
4199
- const {
4200
- id,
4201
- onChange,
4202
- type,
4203
- value,
4204
- readOnly,
4205
- ...rest
4206
- } = props;
4207
- const {
4208
- dateFormat
4209
- } = parseOptions(type.options);
4210
- const handleChange = useCallback(nextDate => {
4211
- onChange(nextDate || null);
4212
- }, [onChange]);
4213
- const formatInputValue = useCallback(date => format(date, dateFormat), [dateFormat]);
4214
- const parseInputValue = useCallback(inputValue => parse(inputValue, dateFormat), [dateFormat]);
4215
- return /* @__PURE__ */jsx(CommonDateTimeInput, {
4216
- id,
4217
- ...rest,
4218
- deserialize,
4219
- formatInputValue,
4220
- onChange: handleChange,
4221
- parseInputValue,
4222
- readOnly,
4223
- selectTime: false,
4224
- serialize,
4225
- value
4226
- });
4227
- }
4228
- function Monthly(props) {
4229
- const {
4230
- byweekday,
4231
- setByweekday
4232
- } = props;
4233
- const {
4234
- weekday: dayNo,
4235
- n: weekNo
4236
- } = byweekday && Array.isArray(byweekday) ? byweekday[0] : {
4237
- weekday: null,
4238
- n: null
4239
- };
4240
- const handleChange = useCallback(event => {
4241
- const {
4242
- value,
4243
- name
4244
- } = event.currentTarget;
4245
- if (name == "week") {
4246
- if (value == "") {
4247
- setByweekday(null);
4248
- } else {
4249
- const newWeekday = new Weekday(dayNo ? dayNo : 0, Number(value));
4250
- setByweekday([newWeekday]);
4251
- }
4252
- } else if (name == "day") {
4253
- const newWeekday = new Weekday(Number(value), weekNo ? weekNo : 1);
4254
- setByweekday([newWeekday]);
4255
- }
4256
- }, [dayNo, setByweekday, weekNo]);
4257
- return /* @__PURE__ */jsxs(Flex, {
4258
- gap: 2,
4259
- align: "center",
4260
- children: [/* @__PURE__ */jsx(Text, {
4261
- style: {
4262
- whiteSpace: "nowrap"
4263
- },
4264
- children: "On the"
4265
- }), /* @__PURE__ */jsx(Box, {
4266
- children: /* @__PURE__ */jsxs(Select, {
4267
- name: "week",
4268
- value: weekNo?.toString(),
4269
- onChange: handleChange,
4270
- children: [/* @__PURE__ */jsx("option", {
4271
- value: "",
4272
- children: "same day"
4273
- }), /* @__PURE__ */jsx("option", {
4274
- value: "1",
4275
- children: "first"
4276
- }), /* @__PURE__ */jsx("option", {
4277
- value: "2",
4278
- children: "second"
4279
- }), /* @__PURE__ */jsx("option", {
4280
- value: "3",
4281
- children: "third"
4282
- }), /* @__PURE__ */jsx("option", {
4283
- value: "4",
4284
- children: "fourth"
4285
- }), /* @__PURE__ */jsx("option", {
4286
- value: "5",
4287
- children: "fifth"
4288
- }), /* @__PURE__ */jsx("option", {
4289
- value: "-1",
4290
- children: "last"
4291
- })]
4292
- })
4293
- }), weekNo && /* @__PURE__ */jsx(Box, {
4294
- children: /* @__PURE__ */jsx(Select, {
4295
- name: "day",
4296
- value: dayNo ? dayNo : 0,
4297
- onChange: handleChange,
4298
- children: DAYS.map((day, i) => {
4299
- const weekday = new Weekday(i);
4300
- return /* @__PURE__ */jsx("option", {
4301
- value: weekday.weekday,
4302
- children: day
4303
- }, weekday.weekday);
4304
- })
4305
- })
4306
- })]
4307
- });
4308
- }
4309
- function Weekly(props) {
4310
- const {
4311
- byweekday,
4312
- setByweekday
4313
- } = props;
4314
- const currentWeekdays = useMemo(() => {
4315
- return Array.isArray(byweekday) ? byweekday.map(weekday => weekday.weekday) : [];
4316
- }, [byweekday]);
4317
- const handleChange = useCallback(event => {
4318
- const value = Number(event.currentTarget.value);
4319
- const index = currentWeekdays.indexOf(value);
4320
- if (index === -1) {
4321
- currentWeekdays.push(value);
4322
- } else {
4323
- currentWeekdays.splice(index, 1);
4324
- }
4325
- setByweekday(currentWeekdays.length ? currentWeekdays.map(currentWeekday => new Weekday(Number(currentWeekday))) : null);
4326
- }, [currentWeekdays, setByweekday]);
4327
- return /* @__PURE__ */jsxs(Stack, {
4328
- space: 3,
4329
- children: [/* @__PURE__ */jsx(Text, {
4330
- style: {
4331
- whiteSpace: "nowrap"
4332
- },
4333
- children: "Repeats on"
4334
- }), /* @__PURE__ */jsx(Grid, {
4335
- columns: DAYS.length,
4336
- gap: 1,
4337
- children: DAYS.map((day, i) => {
4338
- const weekday = new Weekday(i);
4339
- return /* @__PURE__ */jsx(Button, {
4340
- mode: currentWeekdays && currentWeekdays.includes(i) ? "default" : "ghost",
4341
- tone: currentWeekdays && currentWeekdays.includes(i) ? "primary" : "default",
4342
- text: weekday.toString(),
4343
- value: i,
4344
- style: {
4345
- cursor: "pointer"
4346
- },
4347
- onClick: handleChange
4348
- }, day);
4349
- })
4350
- })]
4351
- });
4352
- }
4353
- function CustomRule(_ref8) {
4354
- let {
4355
- open,
4356
- onClose,
4357
- onChange,
4358
- initialValue,
4359
- startDate,
4360
- endDate,
4361
- dateTimeOptions
4362
- } = _ref8;
4363
- const initialRule = useMemo(() => {
4364
- return initialValue ? rrulestr(initialValue) : new RRule();
4365
- }, [initialValue]);
4366
- const [frequency, setFrequency] = useState(initialRule.origOptions.freq || 1);
4367
- const [interval, setInterval] = useState(initialRule.origOptions.interval && initialRule.origOptions.interval > 0 ? initialRule.origOptions.interval : 1);
4368
- const [count, setCount] = useState(initialRule.origOptions.count || null);
4369
- const [until, setUntil] = useState(initialRule.origOptions.until || null);
4370
- const [byweekday, setByweekday] = useState(initialRule.origOptions.byweekday || null);
4371
- const [untilValid, setUntilValid] = useState(true);
4372
- const handleChange = useCallback(event => {
4373
- const {
4374
- name,
4375
- value
4376
- } = event.currentTarget;
4377
- if (name === "freq") {
4378
- setFrequency(Number(value));
4379
- } else if (name === "interval") {
4380
- setInterval(Number(value) > 1 ? Number(value) : 1);
4381
- } else if (name === "count") {
4382
- setCount(Number(value));
4383
- }
4384
- }, []);
4385
- const getUntilDate = useCallback(() => {
4386
- const fromDate = new Date(startDate ? startDate : Date.now());
4387
- if (frequency === RRule.YEARLY) {
4388
- fromDate.setFullYear(fromDate.getFullYear() + DEFAULT_COUNTS[frequency]);
4389
- } else if (frequency === RRule.MONTHLY) {
4390
- fromDate.setMonth(fromDate.getMonth() + DEFAULT_COUNTS[frequency]);
4391
- } else if (frequency === RRule.WEEKLY) {
4392
- fromDate.setDate(fromDate.getDate() + DEFAULT_COUNTS[frequency] * 7);
4393
- } else if (frequency === RRule.DAILY) {
4394
- fromDate.setDate(fromDate.getDate() + DEFAULT_COUNTS[frequency]);
4395
- }
4396
- fromDate.setHours(23, 59, 59, 999);
4397
- return fromDate;
4398
- }, [frequency, startDate]);
4399
- const handleUntilChange = useCallback(date => {
4400
- if (date) {
4401
- const untilDate = toDate$1(`${date}T23:59:59`);
4402
- if (endDate && untilDate < toDate$1(endDate) || startDate && untilDate < toDate$1(startDate)) {
4403
- setUntilValid(false);
4404
- } else {
4405
- setUntilValid(true);
4406
- }
4407
- setUntil(untilDate);
4408
- }
4409
- }, [endDate, startDate]);
4410
- const handleEndChange = useCallback(event => {
4411
- const {
4412
- value
4413
- } = event.currentTarget;
4414
- if (!value) {
4415
- setUntil(null);
4416
- setCount(null);
4417
- } else if (value == "count") {
4418
- setCount(DEFAULT_COUNTS[frequency]);
4419
- setUntil(null);
4420
- } else if (value == "until") {
4421
- const untilDate = getUntilDate();
4422
- setUntil(untilDate);
4423
- setCount(null);
4424
- }
4425
- }, [frequency, getUntilDate]);
4426
- const handleConfirm = useCallback(() => {
4427
- const newOptions = {
4428
- freq: frequency,
4429
- interval,
4430
- count: count || null,
4431
- until: until ? until : null,
4432
- byweekday
4433
- };
4434
- const newRule = new RRule(newOptions);
4435
- onClose();
4436
- onChange(set(newRule.toString(), ["rrule"]));
4437
- }, [byweekday, count, frequency, interval, onChange, onClose, until]);
4438
- const formatUntilValue = useCallback(date => format$1(date, "yyyy-MM-dd"), []);
4439
- return open ? /* @__PURE__ */jsx(Dialog, {
4440
- header: "Custom recurrence",
4441
- id: "dialog-example",
4442
- onClose,
4443
- zOffset: 1e3,
4444
- width: 1,
4445
- children: /* @__PURE__ */jsxs(Flex, {
4446
- direction: "column",
4447
- children: [/* @__PURE__ */jsx(Box, {
4448
- flex: 1,
4449
- overflow: "auto",
4450
- padding: 4,
4451
- children: /* @__PURE__ */jsxs(Stack, {
4452
- space: 4,
4453
- children: [/* @__PURE__ */jsxs(Flex, {
4454
- gap: 2,
4455
- align: "center",
4456
- children: [/* @__PURE__ */jsx(Text, {
4457
- style: {
4458
- whiteSpace: "nowrap"
4459
- },
4460
- children: "Repeat every"
4461
- }), /* @__PURE__ */jsx(Box, {
4462
- style: {
4463
- width: "75px"
4464
- },
4465
- children: /* @__PURE__ */jsx(TextInput, {
4466
- name: "interval",
4467
- type: "number",
4468
- min: 1,
4469
- value: interval,
4470
- onChange: handleChange
4471
- })
4472
- }), /* @__PURE__ */jsx(Box, {
4473
- children: /* @__PURE__ */jsxs(Select, {
4474
- name: "freq",
4475
- value: frequency,
4476
- onChange: handleChange,
4477
- children: [/* @__PURE__ */jsx("option", {
4478
- value: RRule.YEARLY,
4479
- children: "year(s)"
4480
- }), /* @__PURE__ */jsx("option", {
4481
- value: RRule.MONTHLY,
4482
- children: "month(s)"
4483
- }), /* @__PURE__ */jsx("option", {
4484
- value: RRule.WEEKLY,
4485
- children: "week(s)"
4486
- }), /* @__PURE__ */jsx("option", {
4487
- value: RRule.DAILY,
4488
- children: "day(s)"
4489
- })]
4490
- })
4491
- })]
4492
- }), frequency === RRule.MONTHLY && /* @__PURE__ */jsx(Monthly, {
4493
- byweekday,
4494
- setByweekday
4495
- }), frequency === RRule.WEEKLY && /* @__PURE__ */jsx(Weekly, {
4496
- byweekday,
4497
- setByweekday
4498
- }), /* @__PURE__ */jsxs(Stack, {
4499
- space: 2,
4500
- children: [/* @__PURE__ */jsx(Text, {
4501
- children: "Ends"
4502
- }), /* @__PURE__ */jsxs(Flex, {
4503
- gap: 2,
4504
- paddingY: 2,
4505
- align: "center",
4506
- children: [/* @__PURE__ */jsx(Radio, {
4507
- checked: !count && !until,
4508
- name: "ends",
4509
- onChange: handleEndChange,
4510
- value: "",
4511
- id: "ends-never"
4512
- }), /* @__PURE__ */jsx(Text, {
4513
- htmlFor: "ends-never",
4514
- as: "label",
4515
- children: "Never"
4516
- })]
4517
- }), /* @__PURE__ */jsxs(Flex, {
4518
- gap: 2,
4519
- align: "center",
4520
- children: [/* @__PURE__ */jsx(Radio, {
4521
- checked: !!until,
4522
- name: "ends",
4523
- onChange: handleEndChange,
4524
- value: "until",
4525
- id: "ends-until"
4526
- }), /* @__PURE__ */jsx(Text, {
4527
- htmlFor: "ends-until",
4528
- as: "label",
4529
- style: {
4530
- width: "75px"
4531
- },
4532
- children: "On"
4533
- }), /* @__PURE__ */jsx(Box, {
4534
- style: {
4535
- width: "200px"
4536
- },
4537
- children: /* @__PURE__ */jsx(DateInput, {
4538
- id: "until",
4539
- onChange: handleUntilChange,
4540
- type: {
4541
- name: "until",
4542
- title: "Date",
4543
- options: dateTimeOptions
4544
- },
4545
- value: until ? formatUntilValue(new Date(until)) : formatUntilValue(getUntilDate()),
4546
- readOnly: !until
4547
- })
4548
- }), !untilValid && /* @__PURE__ */jsx(Feedback, {
4549
- tone: "critical",
4550
- children: /* @__PURE__ */jsx(Text, {
4551
- size: 1,
4552
- children: "Until date must be after event ends"
4553
- })
4554
- })]
4555
- }), /* @__PURE__ */jsxs(Flex, {
4556
- gap: 2,
4557
- align: "center",
4558
- children: [/* @__PURE__ */jsx(Radio, {
4559
- checked: !!count,
4560
- name: "ends",
4561
- onChange: handleEndChange,
4562
- value: "count",
4563
- id: "ends-count"
4564
- }), /* @__PURE__ */jsx(Text, {
4565
- htmlFor: "ends-count",
4566
- as: "label",
4567
- style: {
4568
- width: "75px"
4569
- },
4570
- children: "After"
4571
- }), /* @__PURE__ */jsx(Box, {
4572
- style: {
4573
- width: "75px"
4574
- },
4575
- children: /* @__PURE__ */jsx(TextInput, {
4576
- name: "count",
4577
- type: "number",
4578
- value: count || DEFAULT_COUNTS[frequency],
4579
- onChange: handleChange,
4580
- disabled: !count
4581
- })
4582
- }), /* @__PURE__ */jsx(Text, {
4583
- style: {
4584
- whiteSpace: "nowrap"
4585
- },
4586
- children: "occurrence(s)"
4587
- })]
4588
- })]
4589
- })]
4590
- })
4591
- }), /* @__PURE__ */jsx(Box, {
4592
- paddingX: 4,
4593
- paddingY: 3,
4594
- style: {
4595
- borderTop: "1px solid var(--card-border-color)"
4596
- },
4597
- children: /* @__PURE__ */jsxs(Flex, {
4598
- gap: 2,
4599
- justify: "flex-end",
4600
- children: [/* @__PURE__ */jsx(Button, {
4601
- text: "Cancel",
4602
- mode: "ghost",
4603
- onClick: onClose
4604
- }), /* @__PURE__ */jsx(Button, {
4605
- text: "Done",
4606
- tone: "positive",
4607
- onClick: handleConfirm,
4608
- disabled: !untilValid
4609
- })]
4610
- })
4611
- })]
4612
- })
4613
- }) : /* @__PURE__ */jsx(Fragment, {});
4614
- }
4615
- function RemoveEndDate(_ref9) {
4616
- let {
4617
- title,
4618
- onChange
4619
- } = _ref9;
4620
- const handleUnsetClick = useCallback(() => {
4621
- onChange(unset(["endDate"]));
4622
- }, [onChange]);
4623
- return /* @__PURE__ */jsx(Card, {
4624
- padding: 4,
4625
- radius: 2,
4626
- tone: "caution",
4627
- "data-ui": "Alert",
4628
- children: /* @__PURE__ */jsxs(Flex, {
4629
- children: [/* @__PURE__ */jsx(Box, {
4630
- children: /* @__PURE__ */jsx(Text, {
4631
- size: 1,
4632
- children: /* @__PURE__ */jsx(WarningOutlineIcon, {})
4633
- })
4634
- }), /* @__PURE__ */jsxs(Stack, {
4635
- space: 3,
4636
- flex: 1,
4637
- marginLeft: 3,
4638
- children: [/* @__PURE__ */jsxs(Text, {
4639
- size: 1,
4640
- weight: "semibold",
4641
- children: ["The ", title ? upperFirst(title) : `current`, " field has an end date"]
4642
- }), /* @__PURE__ */jsx(Box, {
4643
- children: /* @__PURE__ */jsx(Text, {
4644
- as: "p",
4645
- muted: true,
4646
- size: 1,
4647
- children: "This field has an end date value, but the end date is currently disabled for this field."
4648
- })
4649
- }), /* @__PURE__ */jsx(Button, {
4650
- icon: TrashIcon,
4651
- tone: "critical",
4652
- text: /* @__PURE__ */jsx(Fragment, {
4653
- children: "Remove end date"
4654
- }),
4655
- onClick: handleUnsetClick,
4656
- width: "fill"
4657
- })]
4658
- })]
4659
- })
4660
- });
4661
- }
4662
- function RecurringDates(props) {
4663
- const {
4664
- onChange,
4665
- members,
4666
- value: currentValue,
4667
- schemaType,
4668
- pluginConfig
4669
- } = props;
4670
- const {
4671
- options,
4672
- title
4673
- } = schemaType;
4674
- const {
4675
- defaultRecurrences,
4676
- hideEndDate,
4677
- hideCustom,
4678
- dateTimeOptions,
4679
- dateOnly,
4680
- validation
4681
- } = {
4682
- ...pluginConfig,
4683
- ...options
4684
- };
4685
- const [open, setOpen] = useState(false);
4686
- const onClose = useCallback(() => setOpen(false), []);
4687
- const onOpen = useCallback(() => setOpen(true), []);
4688
- const handleChange = useCallback(event => {
4689
- const {
4690
- value
4691
- } = event.currentTarget;
4692
- if (value == "custom") {
4693
- onOpen();
4694
- } else {
4695
- onChange(set(value, ["rrule"]));
4696
- }
4697
- }, [onChange, onOpen]);
4698
- const invalidRecurrences = validateRRuleStrings(defaultRecurrences);
4699
- const startDateMember = members.find(member => member.kind === "field" && member.name === "startDate");
4700
- const endDateMember = members.find(member => member.kind === "field" && member.name === "endDate");
4701
- const rruleMember = members.find(member => member.kind === "field" && member.name === "rrule");
4702
- const availableRecurrences = [...defaultRecurrences];
4703
- if (currentValue && !availableRecurrences.includes(currentValue?.rrule)) {
4704
- availableRecurrences.push(currentValue?.rrule);
4705
- }
4706
- const renderProps = {
4707
- renderField: props.renderField,
4708
- renderInput: props.renderInput,
4709
- renderItem: props.renderItem,
4710
- renderPreview: props.renderPreview
4711
- };
4712
- if (startDateMember?.kind == "field") {
4713
- startDateMember.field.schemaType.options = {
4714
- ...startDateMember?.field?.schemaType.options,
4715
- ...dateTimeOptions
4716
- };
4717
- if (dateOnly === true) {
4718
- startDateMember.field.schemaType.name = "date";
4719
- } else {
4720
- startDateMember.field.schemaType.name = "datetime";
4721
- }
4722
- if (validation?.startDate) {
4723
- startDateMember.field.schemaType.validation = CustomValidation => validation?.startDate?.(CustomValidation);
4724
- } else {
4725
- startDateMember.field.schemaType.validation = DefaultRule => DefaultRule.required();
4726
- }
4727
- if (options?.fieldTitles?.startDate) {
4728
- startDateMember.field.schemaType.title = options.fieldTitles.startDate;
4729
- }
4730
- if (options?.fieldDescriptions?.startDate) {
4731
- startDateMember.field.schemaType.description = options.fieldDescriptions.startDate;
4732
- }
4733
- }
4734
- if (endDateMember?.kind == "field") {
4735
- endDateMember.field.schemaType.options = {
4736
- ...endDateMember?.field?.schemaType.options,
4737
- ...dateTimeOptions
4738
- };
4739
- if (dateOnly === true) {
4740
- endDateMember.field.schemaType.name = "date";
4741
- } else {
4742
- endDateMember.field.schemaType.name = "datetime";
4743
- }
4744
- if (validation?.endDate) {
4745
- endDateMember.field.schemaType.validation = CustomValidation => validation?.endDate?.(CustomValidation);
4746
- } else {
4747
- endDateMember.field.schemaType.validation = DefaultRule => DefaultRule.min(DefaultRule.valueOfField("startDate"));
4748
- }
4749
- if (options?.fieldTitles?.endDate) {
4750
- endDateMember.field.schemaType.title = options.fieldTitles.endDate;
4751
- }
4752
- if (options?.fieldDescriptions?.endDate) {
4753
- endDateMember.field.schemaType.description = options.fieldDescriptions.endDate;
4754
- }
4755
- }
4756
- const hasEndDate = currentValue?.endDate;
4757
- return /* @__PURE__ */jsxs(Stack, {
4758
- space: 3,
4759
- children: [/* @__PURE__ */jsxs(Grid, {
4760
- columns: hideEndDate ? 1 : 2,
4761
- gap: 3,
4762
- children: [hasEndDate && hideEndDate && /* @__PURE__ */jsx(RemoveEndDate, {
4763
- title,
4764
- onChange
4765
- }), /* @__PURE__ */jsx(Flex, {
4766
- align: "flex-end",
4767
- gap: 2,
4768
- children: /* @__PURE__ */jsx(Box, {
4769
- flex: 1,
4770
- children: startDateMember && /* @__PURE__ */jsx(ObjectInputMember, {
4771
- member: startDateMember,
4772
- ...renderProps
4773
- })
4774
- })
4775
- }), !hideEndDate && /* @__PURE__ */jsx(Flex, {
4776
- align: "flex-end",
4777
- gap: 2,
4778
- children: /* @__PURE__ */jsx(Box, {
4779
- flex: 1,
4780
- children: endDateMember && /* @__PURE__ */jsx(ObjectInputMember, {
4781
- member: endDateMember,
4782
- ...renderProps
4783
- })
4784
- })
4785
- })]
4786
- }), invalidRecurrences ? /* @__PURE__ */jsx(Feedback, {
4787
- tone: "critical",
4788
- children: /* @__PURE__ */jsxs(Text, {
4789
- size: 1,
4790
- children: [/* @__PURE__ */jsx("strong", {
4791
- children: "Error:"
4792
- }), " An invalid RRULE string was provided in the", " ", /* @__PURE__ */jsx("code", {
4793
- children: "defaultRecurrences"
4794
- }), " array. Check plugin configuration."]
4795
- })
4796
- }) : /* @__PURE__ */jsxs(Select, {
4797
- onChange: handleChange,
4798
- value: currentValue?.rrule,
4799
- children: [/* @__PURE__ */jsx("option", {
4800
- value: "",
4801
- children: "Doesn't repeat"
4802
- }), availableRecurrences.map(recurrence => {
4803
- if (!recurrence) {
4804
- return null;
4805
- }
4806
- const rule = rrulestr(recurrence);
4807
- rule.options.until = rule?.options?.until && datetime(rule?.options?.until?.getFullYear(), rule?.options?.until?.getMonth() + 1, rule?.options?.until?.getDate(), rule?.options?.until?.getHours(), rule?.options?.until?.getMinutes(), rule?.options?.until?.getSeconds());
4808
- return /* @__PURE__ */jsx("option", {
4809
- value: recurrence,
4810
- children: upperFirst(rule.toText())
4811
- }, recurrence);
4812
- }), !hideCustom && /* @__PURE__ */jsx("option", {
4813
- value: "custom",
4814
- children: "Custom..."
4815
- })]
4816
- }), rruleMember && /* @__PURE__ */jsx(ObjectInputMember, {
4817
- member: rruleMember,
4818
- ...renderProps
4819
- }), /* @__PURE__ */jsx(CustomRule, {
4820
- open,
4821
- onClose,
4822
- onChange,
4823
- initialValue: currentValue?.rrule,
4824
- startDate: startDateMember?.kind == "field" ? startDateMember?.field?.value : void 0,
4825
- endDate: endDateMember?.kind == "field" ? endDateMember?.field?.value : void 0,
4826
- dateTimeOptions
4827
- })]
4828
- });
4829
- }
4830
- function RecurringDatesPreview(props) {
4831
- const {
4832
- startDate,
4833
- endDate,
4834
- rrule,
4835
- schemaType,
4836
- pluginConfig
4837
- } = props;
4838
- const options = schemaType?.options;
4839
- const {
4840
- dateTimeOptions,
4841
- dateOnly
4842
- } = {
4843
- ...pluginConfig,
4844
- ...options
4845
- };
4846
- const rule = rrule && rrulestr(rrule);
4847
- if (rule) {
4848
- rule.options.until = rule?.options?.until && datetime(rule?.options?.until?.getFullYear(), rule?.options?.until?.getMonth() + 1, rule?.options?.until?.getDate(), rule?.options?.until?.getHours(), rule?.options?.until?.getMinutes(), rule?.options?.until?.getSeconds());
4849
- }
4850
- const dateFormat = dateTimeOptions?.dateFormat || DEFAULT_DATE_FORMAT$1;
4851
- const timeFormat = dateTimeOptions?.timeFormat || DEFAULT_TIME_FORMAT;
4852
- const start = startDate ? new Date(startDate) : void 0;
4853
- const end = endDate ? new Date(endDate) : void 0;
4854
- const sameDay = start && end && start.toDateString() === end.toDateString();
4855
- let title = "No start date";
4856
- if (dateOnly) {
4857
- title = start ? format(start, dateFormat) : "No start date";
4858
- if (end && !sameDay) {
4859
- title += ` - ${format(end, dateFormat)}`;
4860
- }
4861
- } else {
4862
- title = start ? format(start, `${dateFormat} ${timeFormat}`) : "No start date";
4863
- if (end) {
4864
- title += ` - ${format(end, sameDay ? timeFormat : `${dateFormat} ${timeFormat}`)}`;
4865
- }
4866
- }
4867
- const previewProps = {
4868
- title,
4869
- subtitle: rule && upperFirst(rule.toText())
4870
- };
4871
- return props.renderDefault({
4872
- ...previewProps,
4873
- ...props
4874
- });
4875
- }
4876
- var recurringDateSchema = config => {
4877
- const {
4878
- dateTimeOptions,
4879
- dateOnly,
4880
- validation,
4881
- fieldTitles,
4882
- fieldDescriptions
4883
- } = config;
4884
- return defineField({
4885
- name: "recurringDates",
4886
- title: "Dates",
4887
- type: "object",
4888
- icon: CalendarIcon,
4889
- fields: [defineField({
4890
- title: fieldTitles?.startDate || "Start Date",
4891
- description: fieldDescriptions?.startDate || "",
4892
- name: "startDate",
4893
- type: dateOnly ? "date" : "datetime",
4894
- options: dateTimeOptions,
4895
- validation: Rule => validation?.startDate ? validation.startDate(Rule) : Rule.required()
4896
- }), defineField({
4897
- title: fieldTitles?.endDate || "End Date",
4898
- description: fieldDescriptions?.endDate || "",
4899
- name: "endDate",
4900
- type: dateOnly ? "date" : "datetime",
4901
- options: dateTimeOptions,
4902
- validation: Rule => validation?.endDate ? validation.endDate(Rule) : Rule.min(Rule.valueOfField("startDate"))
4903
- }), defineField({
4904
- title: "Recurring event",
4905
- name: "recurs",
4906
- type: "boolean"
4907
- }), defineField({
4908
- title: "RRULE",
4909
- name: "rrule",
4910
- type: "string",
4911
- hidden: true
4912
- })],
4913
- components: {
4914
- input: props => RecurringDates({
4915
- ...props,
4916
- pluginConfig: config
4917
- }),
4918
- preview: props => RecurringDatesPreview({
4919
- ...props,
4920
- pluginConfig: config
4921
- })
4922
- },
4923
- preview: {
4924
- select: {
4925
- startDate: "startDate",
4926
- endDate: "endDate",
4927
- rrule: "rrule"
4928
- }
4929
- }
4930
- });
4931
- };
4932
- const recurringDates = definePlugin(config => {
4933
- const pluginConfig = {
4934
- ...DEFAULT_CONFIG,
4935
- ...config
4936
- };
4937
- return {
4938
- name: "sanity-plugin-recurring-dates",
4939
- schema: {
4940
- types: [recurringDateSchema(pluginConfig)]
4941
- }
4942
- };
4943
- });
4944
- export { recurringDates };
4945
- //# sourceMappingURL=index.esm.js.map