@dynamic-framework/ui-react 1.34.0 → 1.35.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/README.md +1 -1
  2. package/dist/css/bootstrap-icons.css +3 -3
  3. package/dist/css/bootstrap-icons.min.css +2 -2
  4. package/dist/css/bootstrap-icons.scss +1 -1
  5. package/dist/css/dynamic-ui-non-root.css +722 -962
  6. package/dist/css/dynamic-ui-non-root.min.css +2 -2
  7. package/dist/css/dynamic-ui-root.css +1 -1
  8. package/dist/css/dynamic-ui-root.min.css +1 -1
  9. package/dist/css/dynamic-ui.css +722 -962
  10. package/dist/css/dynamic-ui.min.css +2 -2
  11. package/dist/css/fonts/bootstrap-icons.woff +0 -0
  12. package/dist/css/fonts/bootstrap-icons.woff2 +0 -0
  13. package/dist/index.esm.js +576 -146
  14. package/dist/index.esm.js.map +1 -1
  15. package/dist/index.js +573 -143
  16. package/dist/index.js.map +1 -1
  17. package/dist/js/bootstrap.bundle.js +19 -18
  18. package/dist/js/bootstrap.bundle.min.js +3 -3
  19. package/dist/js/bootstrap.esm.js +19 -16
  20. package/dist/js/bootstrap.esm.min.js +3 -3
  21. package/dist/js/bootstrap.js +19 -16
  22. package/dist/js/bootstrap.min.js +3 -3
  23. package/dist/types/components/DBoxFile/DBoxFile.d.ts +6 -5
  24. package/dist/types/components/DBoxFile/useDBoxFile.d.ts +37 -0
  25. package/dist/types/components/DBoxFile/utils.d.ts +39 -0
  26. package/dist/types/components/DDatePicker/DDatePicker.d.ts +6 -12
  27. package/dist/types/components/DDatePicker/components/DDatePickerHeaderSelector.d.ts +38 -0
  28. package/dist/types/components/{DDatePickerInput → DDatePicker/components}/DDatePickerInput.d.ts +2 -2
  29. package/dist/types/components/{DDatePickerTime → DDatePicker/components}/DDatePickerTime.d.ts +2 -2
  30. package/dist/types/components/DInput/DInput.d.ts +1 -1
  31. package/dist/types/components/DInputCounter/DInputCounter.d.ts +2 -2
  32. package/dist/types/components/DInputCurrency/DInputCurrency.d.ts +2 -2
  33. package/dist/types/components/DInputCurrencyBase/DInputCurrencyBase.d.ts +2 -2
  34. package/dist/types/components/DInputMask/DInputMask.d.ts +1 -1
  35. package/dist/types/components/DInputRange/DInputRange.d.ts +1 -1
  36. package/dist/types/components/DInputSearch/DInputSearch.d.ts +1 -1
  37. package/dist/types/components/DPopover/DPopover.d.ts +0 -3
  38. package/dist/types/utils/attr-accept.d.ts +11 -0
  39. package/dist/types/utils/getKeyboardFocusableElements.d.ts +1 -0
  40. package/jest/setup.js +14 -0
  41. package/package.json +13 -14
  42. package/src/style/abstracts/variables/_+import.scss +1 -0
  43. package/src/style/abstracts/variables/_box-file.scss +14 -7
  44. package/src/style/abstracts/variables/_cards.scss +1 -1
  45. package/src/style/abstracts/variables/_datepicker.scss +50 -0
  46. package/src/style/abstracts/variables/_forms.scss +6 -3
  47. package/src/style/base/_form-switch.scss +23 -2
  48. package/src/style/base/_input-group.scss +18 -1
  49. package/src/style/base/_nav.scss +0 -1
  50. package/src/style/base/_toast.scss +2 -0
  51. package/src/style/components/_d-box-file.scss +31 -15
  52. package/src/style/components/_d-button-icon.scss +17 -16
  53. package/src/style/components/_d-datepicker.scss +582 -243
  54. package/src/style/components/_d-input-pin.scss +8 -5
  55. package/src/style/components/_d-quick-action-button.scss +1 -1
  56. package/src/style/components/_d-quick-action-check.scss +1 -1
  57. package/src/style/components/_d-select.scss +35 -6
  58. package/src/style/components/_d-stepper-desktop.scss +1 -1
  59. package/src/style/helpers/_text-truncate.scss +2 -2
  60. package/dist/types/components/DDatePickerHeader/DDatePickerHeader.d.ts +0 -24
  61. package/dist/types/components/DDatePickerHeader/index.d.ts +0 -2
  62. package/dist/types/components/DDatePickerInput/index.d.ts +0 -2
  63. package/dist/types/components/DDatePickerTime/index.d.ts +0 -2
package/dist/index.esm.js CHANGED
@@ -1,17 +1,18 @@
1
1
  import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
2
- import React, { useMemo, useEffect, useState, useCallback, createContext, useContext, Fragment, useLayoutEffect, forwardRef, useId, useRef, useSyncExternalStore } from 'react';
2
+ import React, { useMemo, useEffect, useState, useCallback, useContext, createContext, Fragment, useLayoutEffect, forwardRef, useId, useRef, useSyncExternalStore } from 'react';
3
3
  import classNames from 'classnames';
4
4
  import { __rest } from 'tslib';
5
5
  import { createPortal } from 'react-dom';
6
- import { useDropzone } from 'react-dropzone';
6
+ import { fromEvent } from 'file-selector';
7
7
  import { SplideSlide, Splide } from '@splidejs/react-splide';
8
8
  import currency from 'currency.js';
9
9
  import DatePicker from 'react-datepicker';
10
- import { getYear, format, getMonth, parseISO } from 'date-fns';
10
+ import { getYear, format, getMonth } from 'date-fns';
11
+ import { enUS } from 'date-fns/locale';
11
12
  import Select, { components } from 'react-select';
12
13
  import { InputMask } from '@react-input/mask';
13
14
  import ResponsivePagination from 'react-responsive-pagination';
14
- import { useFloating, offset, flip, shift, autoUpdate, useClick, useDismiss, useRole, useInteractions, useId as useId$1, FloatingFocusManager, arrow, useHover, useFocus, FloatingPortal, FloatingArrow } from '@floating-ui/react';
15
+ import { useFloating, autoUpdate, offset, flip, shift, useClick, useDismiss, useRole, useInteractions, useId as useId$1, FloatingFocusManager, arrow, useHover, useFocus, FloatingPortal, FloatingArrow } from '@floating-ui/react';
15
16
  import ContentLoader from 'react-content-loader';
16
17
  import { Toaster, toast } from 'react-hot-toast';
17
18
  import i18n from 'i18next';
@@ -19,7 +20,7 @@ import { initReactI18next } from 'react-i18next';
19
20
 
20
21
  const PREFIX_BS = 'bs-';
21
22
 
22
- function DIconBase({ icon, theme, style, className, size = '1.5rem', loading = false, loadingDuration = 1.8, hasCircle = false, circleSize = `calc(var(--${PREFIX_BS}icon-component-size) * 1)`, color, backgroundColor, materialStyle = false, familyClass = 'bi', familyPrefix = 'bi-', dataAttributes, }) {
23
+ function DIconBase({ icon, theme, style, className, size, loading = false, loadingDuration = 1.8, hasCircle = false, circleSize = `calc(var(--${PREFIX_BS}icon-size) * 1)`, color, backgroundColor, materialStyle = false, familyClass = 'bi', familyPrefix = 'bi-', dataAttributes, }) {
23
24
  const colorStyle = useMemo(() => {
24
25
  if (color) {
25
26
  return { [`--${PREFIX_BS}icon-component-color`]: color };
@@ -47,7 +48,7 @@ function DIconBase({ icon, theme, style, className, size = '1.5rem', loading = f
47
48
  }
48
49
  return { [`--${PREFIX_BS}icon-component-padding`]: '0' };
49
50
  }, [circleSize, hasCircle]);
50
- const generateStyleVariables = useMemo(() => (Object.assign(Object.assign(Object.assign(Object.assign({ [`--${PREFIX_BS}icon-component-size`]: size, [`--${PREFIX_BS}icon-component-loading-duration`]: `${loadingDuration}s` }, colorStyle), backgroundStyle), circleSizeStyle), style)), [size, loadingDuration, colorStyle, backgroundStyle, circleSizeStyle, style]);
51
+ const generateStyleVariables = useMemo(() => (Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ [`--${PREFIX_BS}icon-component-loading-duration`]: `${loadingDuration}s` }, size && { [`--${PREFIX_BS}icon-component-size`]: size }), colorStyle), backgroundStyle), circleSizeStyle), style)), [size, loadingDuration, colorStyle, backgroundStyle, circleSizeStyle, style]);
51
52
  const generateClasses = useMemo(() => (Object.assign(Object.assign({ 'd-icon': true, [familyClass]: true, 'd-icon-loading': loading }, !materialStyle && {
52
53
  [`${familyPrefix}${icon}`]: true,
53
54
  }), className && { [className]: true })), [
@@ -126,12 +127,22 @@ function useStackState(initialList = []) {
126
127
  return [list, controls];
127
128
  }
128
129
 
130
+ function getKeyboardFocusableElements(container) {
131
+ if (!container) {
132
+ return [];
133
+ }
134
+ return [
135
+ ...container.querySelectorAll('a, button, input, textarea, select, details, [tabindex]:not([tabindex="-1"])'),
136
+ ].filter((element) => !element.hasAttribute('disabled'));
137
+ }
138
+
129
139
  const DPortalContext = createContext(undefined);
130
140
  function DPortalContextProvider({ portalName, children, availablePortals, }) {
131
141
  const { created } = usePortal(portalName);
132
142
  const [stack, { push, pop, isEmpty }] = useStackState([]);
133
143
  useDisableBodyScrollEffect(Boolean(stack.length));
134
144
  const openPortal = useCallback((name, payload) => {
145
+ var _a;
135
146
  if (!availablePortals) {
136
147
  throw new Error(`there is no component for portal ${name.toString()}`);
137
148
  }
@@ -144,6 +155,7 @@ function DPortalContextProvider({ portalName, children, availablePortals, }) {
144
155
  Component,
145
156
  payload,
146
157
  });
158
+ (_a = document.activeElement) === null || _a === void 0 ? void 0 : _a.blur();
147
159
  }, [availablePortals, push]);
148
160
  const closePortal = useCallback(() => {
149
161
  if (isEmpty()) {
@@ -173,10 +185,26 @@ function DPortalContextProvider({ portalName, children, availablePortals, }) {
173
185
  }, [closePortal]);
174
186
  useEffect(() => {
175
187
  const keyEvent = (event) => {
188
+ const lastPortal = document.querySelector(`#${portalName} > div > div:last-child`);
176
189
  if (event.key === 'Escape') {
177
- const lastPortal = document.querySelector(`#${portalName} > div > div:last-child`);
178
190
  if (lastPortal) {
179
191
  handleClose(lastPortal);
192
+ return;
193
+ }
194
+ }
195
+ if (event.key === 'Tab') {
196
+ const focusableElements = getKeyboardFocusableElements(lastPortal);
197
+ if (focusableElements.length === 0)
198
+ return;
199
+ const firstElement = focusableElements[0];
200
+ const lastElement = focusableElements[focusableElements.length - 1];
201
+ if (event.shiftKey && document.activeElement === firstElement) {
202
+ event.preventDefault();
203
+ lastElement.focus();
204
+ }
205
+ else if (!event.shiftKey && document.activeElement === lastElement) {
206
+ event.preventDefault();
207
+ firstElement.focus();
180
208
  }
181
209
  }
182
210
  };
@@ -270,7 +298,6 @@ function DContextProvider({ language = DEFAULT_STATE.language, currency = DEFAUL
270
298
  });
271
299
  const setContext = useCallback((newValue) => (setInternalContext((prevInternalContext) => (Object.assign(Object.assign({}, prevInternalContext), newValue)))), []);
272
300
  useLayoutEffect(() => {
273
- console.log('context');
274
301
  setContext({
275
302
  breakpoints: {
276
303
  xs: getCssVariable(`--${PREFIX_BS}breakpoint-xs`),
@@ -340,18 +367,494 @@ function DBadge({ text, soft = false, theme = 'primary', id, rounded, className,
340
367
  return (jsxs("span", Object.assign({ className: classNames(generateClasses, className), style: style }, id && { id }, dataAttributes, { children: [iconStart && (jsx(DIcon, { icon: iconStart, familyClass: iconFamilyClass, familyPrefix: iconFamilyPrefix, materialStyle: iconMaterialStyle })), jsx("span", { children: text }), iconEnd && (jsx(DIcon, { icon: iconEnd, familyClass: iconFamilyClass, familyPrefix: iconFamilyPrefix, materialStyle: iconMaterialStyle }))] })));
341
368
  }
342
369
 
370
+ /* eslint-disable */
371
+ /**
372
+ * This file is originally from `@primer/react`
373
+ * The original source for this lived in the URL below.
374
+ *
375
+ * @see https://github.com/primer/react/blob/216d2a9f57b8acb0701ab4e04a23e057fc325c90/src/hooks/useProvidedRefOrCreate.ts
376
+ */
377
+ /**
378
+ * There are some situations where we only want to create a new ref if one is not provided to a component
379
+ * or hook as a prop. However, due to the `rules-of-hooks`, we cannot conditionally make a call to `React.useRef`
380
+ * only in the situations where the ref is not provided as a prop.
381
+ * This hook aims to encapsulate that logic, so the consumer doesn't need to be concerned with violating `rules-of-hooks`.
382
+ * @param providedRef The ref to use - if undefined, will use the ref from a call to React.useRef
383
+ * @type TRef The type of the RefObject which should be created.
384
+ */
385
+ function useProvidedRefOrCreate(providedRef) {
386
+ const createdRef = React.useRef(null);
387
+ return providedRef !== null && providedRef !== void 0 ? providedRef : createdRef;
388
+ }
389
+
390
+ function DInput(_a, ref) {
391
+ var { id: idProp, style, className, label = '', labelIcon, labelIconFamilyClass, labelIconFamilyPrefix, labelIconMaterialStyle, disabled = false, loading = false, iconFamilyClass, iconFamilyPrefix, iconMaterialStyle, iconStart, iconStartDisabled, iconStartFamilyClass, iconStartFamilyPrefix, iconStartAriaLabel, iconStartTabIndex, iconStartMaterialStyle, iconEnd, iconEndDisabled, iconEndFamilyClass, iconEndFamilyPrefix, iconEndAriaLabel, iconEndTabIndex, iconEndMaterialStyle, hint, size, invalid = false, valid = false, floatingLabel = false, inputStart, inputEnd, value, placeholder = '', dataAttributes, onChange, onIconStartClick, onIconEndClick } = _a, inputProps = __rest(_a, ["id", "style", "className", "label", "labelIcon", "labelIconFamilyClass", "labelIconFamilyPrefix", "labelIconMaterialStyle", "disabled", "loading", "iconFamilyClass", "iconFamilyPrefix", "iconMaterialStyle", "iconStart", "iconStartDisabled", "iconStartFamilyClass", "iconStartFamilyPrefix", "iconStartAriaLabel", "iconStartTabIndex", "iconStartMaterialStyle", "iconEnd", "iconEndDisabled", "iconEndFamilyClass", "iconEndFamilyPrefix", "iconEndAriaLabel", "iconEndTabIndex", "iconEndMaterialStyle", "hint", "size", "invalid", "valid", "floatingLabel", "inputStart", "inputEnd", "value", "placeholder", "dataAttributes", "onChange", "onIconStartClick", "onIconEndClick"]);
392
+ const inputRef = useProvidedRefOrCreate(ref);
393
+ const innerId = useId();
394
+ const id = useMemo(() => idProp || innerId, [idProp, innerId]);
395
+ const handleOnChange = useCallback((event) => {
396
+ onChange === null || onChange === void 0 ? void 0 : onChange(event.currentTarget.value);
397
+ }, [onChange]);
398
+ const handleOnIconStartClick = useCallback(() => {
399
+ onIconStartClick === null || onIconStartClick === void 0 ? void 0 : onIconStartClick(value);
400
+ }, [onIconStartClick, value]);
401
+ const handleOnIconEndClick = useCallback(() => {
402
+ onIconEndClick === null || onIconEndClick === void 0 ? void 0 : onIconEndClick(value);
403
+ }, [onIconEndClick, value]);
404
+ const ariaDescribedby = useMemo(() => ([
405
+ !!inputStart && `${id}InputStart`,
406
+ !!iconStart && `${id}Start`,
407
+ (invalid || valid) && !iconEnd && !loading && `${id}State`,
408
+ (iconEnd && !loading) && `${id}End`,
409
+ loading && `${id}Loading`,
410
+ !!inputEnd && `${id}InputEnd`,
411
+ !!hint && `${id}Hint`,
412
+ ]
413
+ .filter(Boolean)
414
+ .join(' ')), [
415
+ id,
416
+ inputStart,
417
+ iconStart,
418
+ invalid,
419
+ valid,
420
+ iconEnd,
421
+ loading,
422
+ inputEnd,
423
+ hint,
424
+ ]);
425
+ const inputComponent = useMemo(() => (jsx("input", Object.assign({ ref: inputRef, id: id, className: classNames('form-control', {
426
+ 'is-invalid': invalid,
427
+ 'is-valid': valid,
428
+ }), disabled: disabled || loading, value: value, onChange: handleOnChange }, (floatingLabel || placeholder) && { placeholder: floatingLabel ? '' : placeholder }, ariaDescribedby && { 'aria-describedby': ariaDescribedby }, inputProps))), [
429
+ ariaDescribedby,
430
+ disabled,
431
+ handleOnChange,
432
+ id,
433
+ inputProps,
434
+ inputRef,
435
+ invalid,
436
+ loading,
437
+ placeholder,
438
+ floatingLabel,
439
+ valid,
440
+ value,
441
+ ]);
442
+ const labelComponent = useMemo(() => (jsxs("label", { htmlFor: id, children: [label, labelIcon && (jsx(DIcon, { icon: labelIcon, size: `var(--${PREFIX_BS}label-font-size)`, familyClass: labelIconFamilyClass, familyPrefix: labelIconFamilyPrefix, materialStyle: labelIconMaterialStyle }))] })), [
443
+ id,
444
+ label,
445
+ labelIcon,
446
+ labelIconFamilyClass,
447
+ labelIconFamilyPrefix,
448
+ labelIconMaterialStyle,
449
+ ]);
450
+ const dynamicComponent = useMemo(() => {
451
+ if (floatingLabel) {
452
+ return (jsxs("div", { className: "form-floating", children: [inputComponent, labelComponent] }));
453
+ }
454
+ return inputComponent;
455
+ }, [floatingLabel, inputComponent, labelComponent]);
456
+ return (jsxs("div", Object.assign({ className: className, style: style }, dataAttributes, { children: [label && !floatingLabel && labelComponent, jsxs("div", { className: classNames({
457
+ [`input-group-${size}`]: !!size,
458
+ 'input-group': true,
459
+ 'has-validation': invalid || valid,
460
+ }), children: [!!inputStart && (jsx("div", { className: "input-group-text", id: `${id}InputStart`, children: inputStart })), iconStart && (jsx("button", { type: "button", className: "input-group-text", id: `${id}Start`, onClick: handleOnIconStartClick, disabled: disabled || loading || iconStartDisabled, "aria-label": iconStartAriaLabel, tabIndex: onIconStartClick ? iconStartTabIndex : -1, children: jsx(DIcon, { icon: iconStart, familyClass: iconStartFamilyClass, familyPrefix: iconStartFamilyPrefix, materialStyle: iconStartMaterialStyle }) })), dynamicComponent, (iconEnd && !loading) && (jsx("button", { type: "button", className: "input-group-text", id: `${id}End`, onClick: handleOnIconEndClick, disabled: disabled || loading || iconEndDisabled, "aria-label": iconEndAriaLabel, tabIndex: onIconEndClick ? iconEndTabIndex : -1, children: jsx(DIcon, { icon: iconEnd, familyClass: iconEndFamilyClass, familyPrefix: iconEndFamilyPrefix, materialStyle: iconEndMaterialStyle }) })), loading && (jsx("div", { className: "input-group-text", id: `${id}Loading`, children: jsx("span", { className: "spinner-border spinner-border-sm", role: "status", "aria-hidden": "true", children: jsx("span", { className: "visually-hidden", children: "Loading..." }) }) })), !!inputEnd && (jsx("div", { className: "input-group-text", id: `${id}InputEnd`, children: inputEnd }))] }), hint && (jsx("div", { className: "form-text", id: `${id}Hint`, children: hint }))] })));
461
+ }
462
+ const ForwardedDInput = forwardRef(DInput);
463
+ ForwardedDInput.displayName = 'DInput';
464
+
465
+ /**
466
+ * Check if the provided file type should be accepted by the input with accept attribute.
467
+ * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input#attr-accept
468
+ *
469
+ * Inspired by https://github.com/enyo/dropzone
470
+ *
471
+ * @param file {File} https://developer.mozilla.org/en-US/docs/Web/API/File
472
+ * @param acceptedFiles {string|string[]}
473
+ * @returns {boolean}
474
+ */
475
+ function attrAccept(file, acceptedFiles) {
476
+ if (file && acceptedFiles) {
477
+ const acceptedFilesArray = Array.isArray(acceptedFiles)
478
+ ? acceptedFiles
479
+ : acceptedFiles.split(',');
480
+ if (acceptedFilesArray.length === 0) {
481
+ return true;
482
+ }
483
+ const fileName = file.name || '';
484
+ const mimeType = (file.type || '').toLowerCase();
485
+ const baseMimeType = mimeType.replace(/\/.*$/, '');
486
+ return acceptedFilesArray.some((type) => {
487
+ const validType = type.trim().toLowerCase();
488
+ if (validType.charAt(0) === '.') {
489
+ return fileName.toLowerCase().endsWith(validType);
490
+ }
491
+ if (validType.endsWith('/*')) {
492
+ // This is something like a image/* mime type
493
+ return baseMimeType === validType.replace(/\/.*$/, '');
494
+ }
495
+ return mimeType === validType;
496
+ });
497
+ }
498
+ return true;
499
+ }
500
+
501
+ const isIeOrEdge = (userAgent = window.navigator.userAgent) => ((userAgent.indexOf('MSIE') !== -1 || userAgent.indexOf('Trident/') !== -1)
502
+ || userAgent.indexOf('Edge/') !== -1);
503
+ const ErrorCodes = {
504
+ FileInvalidType: 'file-invalid-type',
505
+ FileTooLarge: 'file-too-large',
506
+ FileTooSmall: 'file-too-small',
507
+ TooManyFiles: 'too-many-files',
508
+ FailedFetch: 'failed-fetch-file',
509
+ };
510
+ // Check if v is a MIME type string.
511
+ function isMIMEType(v) {
512
+ return (v === 'audio/*'
513
+ || v === 'video/*'
514
+ || v === 'image/*'
515
+ || v === 'text/*'
516
+ || v === 'application/*'
517
+ || /\w+\/[-+.\w]+/g.test(v));
518
+ }
519
+ // Check if v is a file extension.
520
+ function isExt(v) {
521
+ return /^.*\.[\w]+$/.test(v);
522
+ }
523
+ function isDefined(value) {
524
+ return value !== undefined && value !== null;
525
+ }
526
+ // Convert the `{accept}` dropzone prop to an array of MIME types/extensions.
527
+ function acceptPropAsAcceptAttr(accept) {
528
+ return (Object.entries(accept)
529
+ .reduce((a, [mimeType, ext]) => [...a, mimeType, ...ext], [])
530
+ .filter((v) => isMIMEType(v) || isExt(v))
531
+ .join(','));
532
+ }
533
+ function fileAccepted(file, accept) {
534
+ const isAcceptable = file.type === 'application/x-moz-file' || attrAccept(file, accept);
535
+ if (!isAcceptable) {
536
+ return [
537
+ false,
538
+ {
539
+ code: ErrorCodes.FileInvalidType,
540
+ message: 'File has an unsupported file type',
541
+ },
542
+ ];
543
+ }
544
+ return [true, null];
545
+ }
546
+ function fileMatchSize(file, minSize, maxSize) {
547
+ if (isDefined(file.size)) {
548
+ if (isDefined(minSize) && file.size < minSize) {
549
+ return [
550
+ false,
551
+ {
552
+ code: ErrorCodes.FileTooSmall,
553
+ message: `File "${file.name}" is too small. Minimum size is ${minSize} bytes.`,
554
+ },
555
+ ];
556
+ }
557
+ if (isDefined(maxSize) && file.size > maxSize) {
558
+ return [
559
+ false, {
560
+ code: ErrorCodes.FileTooLarge,
561
+ message: `File "${file.name}" is too large. Maximum size is ${maxSize} bytes.`,
562
+ },
563
+ ];
564
+ }
565
+ }
566
+ return [true, null];
567
+ }
568
+ async function urlToFile(url) {
569
+ var _a;
570
+ try {
571
+ const res = await fetch(url);
572
+ if (!res.ok) {
573
+ return [
574
+ null,
575
+ {
576
+ code: ErrorCodes.FailedFetch,
577
+ message: `Failed to fetch file from ${url}`,
578
+ },
579
+ ];
580
+ }
581
+ const blob = await res.blob();
582
+ const filename = ((_a = url.split('/').pop()) === null || _a === void 0 ? void 0 : _a.split('?')[0]) || 'file';
583
+ const file = new File([blob], filename, { type: blob.type });
584
+ return [file, null];
585
+ }
586
+ catch (error) {
587
+ return [
588
+ null,
589
+ {
590
+ code: ErrorCodes.FailedFetch,
591
+ message: `Failed to fetch file from ${url}}`,
592
+ },
593
+ ];
594
+ }
595
+ }
596
+ async function urlsToFiles(urls) {
597
+ const results = await Promise.all(urls.map(urlToFile));
598
+ let acceptedFiles = [];
599
+ let errors = [];
600
+ results.forEach(([file, error]) => {
601
+ if (file) {
602
+ acceptedFiles = [...acceptedFiles, file];
603
+ }
604
+ if (error) {
605
+ errors = [...errors, error];
606
+ }
607
+ });
608
+ return [acceptedFiles, errors];
609
+ }
610
+ const DEFAULT_PROPS = {
611
+ disabled: false,
612
+ maxSize: Infinity,
613
+ minSize: 0,
614
+ multiple: false,
615
+ maxFiles: Infinity,
616
+ noClick: false,
617
+ noKeyboard: false,
618
+ noDrag: false,
619
+ autoFocus: false,
620
+ };
621
+
622
+ /* eslint-disable no-param-reassign */
623
+ function useDBoxFile(props) {
624
+ const { accept, autoFocus, disabled, maxSize, minSize, multiple, maxFiles, value: preloadUrls, onDragEnter, onDragLeave, onDrop, onError, noClick, noKeyboard, noDrag, } = Object.assign(Object.assign({}, DEFAULT_PROPS), props);
625
+ const inputRef = useRef(null);
626
+ const rootRef = useRef(null);
627
+ const dragTargetsRef = useRef([]);
628
+ const acceptAttr = useMemo(() => acceptPropAsAcceptAttr(accept), [accept]);
629
+ const [files, setFiles] = useState([]);
630
+ const [isDragValid, setIsDragValid] = useState(false);
631
+ const [isDragInvalid, setIsDragInvalid] = useState(false);
632
+ const preventDropOnDocument = useCallback((event) => {
633
+ if (rootRef.current && rootRef.current.contains(event.target)) {
634
+ // If we intercepted an event for our instance
635
+ // let it propagate down to the instance's onDrop handler
636
+ return;
637
+ }
638
+ event.preventDefault();
639
+ dragTargetsRef.current = [];
640
+ }, []);
641
+ useEffect(() => {
642
+ // Prevent drop over anywhere in the document
643
+ document.addEventListener('dragover', preventDropOnDocument, false);
644
+ document.addEventListener('drop', preventDropOnDocument, false);
645
+ return () => {
646
+ document.removeEventListener('dragover', preventDropOnDocument);
647
+ document.removeEventListener('drop', preventDropOnDocument);
648
+ };
649
+ }, [preventDropOnDocument]);
650
+ // Auto focus the root when autoFocus is true
651
+ useEffect(() => {
652
+ if (!disabled && autoFocus && rootRef.current) {
653
+ rootRef.current.focus();
654
+ }
655
+ }, [rootRef, autoFocus, disabled]);
656
+ useEffect(() => {
657
+ if (!preloadUrls || !preloadUrls.length)
658
+ return;
659
+ // eslint-disable-next-line no-void
660
+ void (async () => {
661
+ const [accepted, errors] = await urlsToFiles(preloadUrls);
662
+ if (accepted.length) {
663
+ setFiles(accepted);
664
+ }
665
+ if (errors.length) {
666
+ onError === null || onError === void 0 ? void 0 : onError(new Error(errors.map((e) => e.message).join(', ')));
667
+ }
668
+ })();
669
+ }, [preloadUrls, onError]);
670
+ const processFiles = useCallback((inputFiles, event) => {
671
+ let acceptedFiles = [];
672
+ let rejectedFiles = [];
673
+ // Handle size and type validation
674
+ inputFiles.forEach((file) => {
675
+ const [isTypeValid, acceptError] = fileAccepted(file, acceptAttr);
676
+ const [isSizeValid, sizeError] = fileMatchSize(file, minSize, maxSize);
677
+ const errors = [acceptError, sizeError].filter((e) => Boolean(e));
678
+ if (isTypeValid && isSizeValid) {
679
+ acceptedFiles = [...acceptedFiles, file];
680
+ }
681
+ else {
682
+ rejectedFiles = [...rejectedFiles, { file, errors }];
683
+ }
684
+ });
685
+ // Handle maxFiles overflow by trimming
686
+ const total = files.length + acceptedFiles.length;
687
+ if (total > maxFiles) {
688
+ const allowed = Math.max(0, maxFiles - files.length);
689
+ const accepted = acceptedFiles.slice(0, allowed);
690
+ const rejected = acceptedFiles.slice(allowed).map((file) => ({
691
+ file,
692
+ errors: [
693
+ {
694
+ code: ErrorCodes.TooManyFiles,
695
+ message: `Exceeds maximum number of files (${maxFiles})`,
696
+ },
697
+ ],
698
+ }));
699
+ acceptedFiles = [...accepted];
700
+ rejectedFiles = [...rejectedFiles, ...rejected];
701
+ }
702
+ if (multiple) {
703
+ setFiles((prev) => [...prev, ...acceptedFiles]);
704
+ }
705
+ else {
706
+ setFiles(acceptedFiles.slice(0, 1));
707
+ }
708
+ if (onDrop) {
709
+ onDrop(acceptedFiles, rejectedFiles, event);
710
+ }
711
+ }, [
712
+ acceptAttr,
713
+ files.length,
714
+ maxFiles,
715
+ maxSize,
716
+ minSize,
717
+ multiple,
718
+ onDrop,
719
+ ]);
720
+ const handleDragEnter = useCallback((event) => {
721
+ event.preventDefault();
722
+ event.stopPropagation();
723
+ if (disabled || noDrag)
724
+ return;
725
+ if (event.target instanceof HTMLElement) {
726
+ dragTargetsRef.current = [...dragTargetsRef.current, event.target];
727
+ }
728
+ fromEvent(event).then((eventFiles) => {
729
+ const fileCount = eventFiles.length;
730
+ if (fileCount === 0) {
731
+ setIsDragValid(false);
732
+ setIsDragInvalid(true);
733
+ return;
734
+ }
735
+ const isDragAccepted = eventFiles.every((file) => {
736
+ const [typeValid] = fileAccepted(file, acceptAttr);
737
+ const [sizeValid] = fileMatchSize(file, minSize, maxSize);
738
+ return typeValid && sizeValid;
739
+ });
740
+ setIsDragValid(isDragAccepted);
741
+ setIsDragInvalid(!isDragAccepted);
742
+ onDragEnter === null || onDragEnter === void 0 ? void 0 : onDragEnter(event);
743
+ }).catch((error) => {
744
+ onError === null || onError === void 0 ? void 0 : onError(error);
745
+ });
746
+ }, [
747
+ acceptAttr,
748
+ disabled,
749
+ maxSize,
750
+ minSize,
751
+ noDrag,
752
+ onDragEnter,
753
+ onError,
754
+ ]);
755
+ const handleDrop = useCallback((event) => {
756
+ event.preventDefault();
757
+ event.persist();
758
+ event.stopPropagation();
759
+ dragTargetsRef.current = [];
760
+ setIsDragValid(false);
761
+ setIsDragInvalid(false);
762
+ if (disabled || noDrag)
763
+ return;
764
+ const droppedArray = Array.from(event.dataTransfer.files);
765
+ processFiles(droppedArray, event.nativeEvent);
766
+ }, [
767
+ disabled,
768
+ noDrag,
769
+ processFiles,
770
+ ]);
771
+ const handleDragLeave = useCallback((event) => {
772
+ event.preventDefault();
773
+ event.stopPropagation();
774
+ if (disabled || noDrag)
775
+ return;
776
+ // Only deactivate once the dropzone and all children have been left
777
+ const targets = dragTargetsRef.current.filter((target) => rootRef.current && rootRef.current.contains(target));
778
+ // Make sure to remove a target present multiple times only once
779
+ // (Firefox may fire dragenter/dragleave multiple times on the same element)
780
+ if (event.target instanceof HTMLElement) {
781
+ const targetIdx = targets.indexOf(event.target);
782
+ if (targetIdx !== -1) {
783
+ targets.splice(targetIdx, 1);
784
+ }
785
+ dragTargetsRef.current = targets;
786
+ }
787
+ if (targets.length === 0) {
788
+ setIsDragValid(false);
789
+ setIsDragInvalid(false);
790
+ onDragLeave === null || onDragLeave === void 0 ? void 0 : onDragLeave(event);
791
+ }
792
+ }, [disabled, noDrag, onDragLeave]);
793
+ const handleFileSelect = useCallback((event) => {
794
+ const targetFiles = event.target.files;
795
+ if (!targetFiles)
796
+ return;
797
+ const selectedFiles = Array.from(targetFiles);
798
+ processFiles(selectedFiles, event.nativeEvent);
799
+ event.target.value = '';
800
+ }, [processFiles]);
801
+ const handleRemoveFile = useCallback((index) => {
802
+ setFiles((prevFiles) => prevFiles.filter((_, i) => i !== index));
803
+ }, []);
804
+ const openFileDialog = useCallback(() => {
805
+ var _a;
806
+ if (disabled)
807
+ return;
808
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.click();
809
+ }, [disabled]);
810
+ const handleClick = useCallback(() => {
811
+ if (noClick) {
812
+ return;
813
+ }
814
+ if (isIeOrEdge()) {
815
+ setTimeout(openFileDialog, 0);
816
+ }
817
+ else {
818
+ openFileDialog();
819
+ }
820
+ }, [noClick, openFileDialog]);
821
+ const handleKeyDown = useCallback((event) => {
822
+ if (!noKeyboard && (event.key === ' ' || event.key === 'Enter')) {
823
+ event.preventDefault();
824
+ openFileDialog();
825
+ }
826
+ }, [noKeyboard, openFileDialog]);
827
+ return {
828
+ inputRef,
829
+ rootRef,
830
+ files,
831
+ isDragValid,
832
+ isDragInvalid,
833
+ acceptAttr,
834
+ openFileDialog,
835
+ handleFileSelect,
836
+ handleDrop,
837
+ handleDragEnter,
838
+ handleDragLeave,
839
+ handleRemoveFile,
840
+ handleClick,
841
+ handleKeyDown,
842
+ };
843
+ }
844
+
343
845
  function DBoxFile(_a) {
344
- var { icon: iconProp, iconFamilyClass, iconFamilyPrefix, iconMaterialStyle, disabled = false, children, className, style, dataAttributes } = _a, dropzoneOptions = __rest(_a, ["icon", "iconFamilyClass", "iconFamilyPrefix", "iconMaterialStyle", "disabled", "children", "className", "style", "dataAttributes"]);
345
- const { acceptedFiles, getRootProps, getInputProps, } = useDropzone(Object.assign({ disabled }, dropzoneOptions));
346
- const { iconMap: { upload, }, } = useDContext();
846
+ var { icon: iconProp, iconFamilyClass, iconFamilyPrefix, iconMaterialStyle, children, className, style, dataAttributes } = _a, props = __rest(_a, ["icon", "iconFamilyClass", "iconFamilyPrefix", "iconMaterialStyle", "children", "className", "style", "dataAttributes"]);
847
+ const { iconMap: { upload } } = useDContext();
347
848
  const icon = useMemo(() => iconProp || upload, [iconProp, upload]);
348
- return (jsxs("section", Object.assign({ className: classNames('d-box-file', {
349
- 'd-box-file-selected': !!acceptedFiles.length,
350
- }, className), style: style }, dataAttributes, { children: [jsxs("div", Object.assign({}, getRootProps({
351
- className: classNames('d-box-file-dropzone', {
352
- disabled,
353
- }),
354
- }), { children: [jsx("input", Object.assign({}, getInputProps())), jsx(DIcon, { icon: icon, familyClass: iconFamilyClass, familyPrefix: iconFamilyPrefix, materialStyle: iconMaterialStyle }), jsx("div", { className: "d-box-content", children: children })] })), !!acceptedFiles.length && (jsx("aside", { className: "d-box-files", children: acceptedFiles.map((file) => (jsx("div", { className: "d-box-files-text", children: `${file.name} - ${file.size} bytes` }, file.name))) }))] })));
849
+ const { inputRef, rootRef, isDragValid, isDragInvalid, acceptAttr, files, handleFileSelect, handleDrop, handleDragEnter, handleDragLeave, handleClick, handleKeyDown, handleRemoveFile, openFileDialog, } = useDBoxFile(props);
850
+ return (jsxs(Fragment$1, { children: [jsx("section", Object.assign({ className: classNames('d-box-file', {
851
+ 'd-box-file-selected': files.length > 0,
852
+ 'd-box-file-disabled': props.disabled,
853
+ 'd-box-file-valid': isDragValid,
854
+ 'd-box-file-invalid': isDragInvalid,
855
+ }, className), style: style }, dataAttributes, { children: jsxs("div", Object.assign({ className: "d-box-file-dropzone", ref: rootRef, onDragEnter: handleDragEnter, onDragOver: (e) => e.preventDefault(), onDragLeave: handleDragLeave, onDrop: handleDrop, onClick: handleClick, onKeyDown: handleKeyDown }, (!props.disabled && !props.noKeyboard ? { tabIndex: 0 } : {}), { role: "presentation", children: [jsx("input", { type: "file", multiple: props.multiple, style: { display: 'none' }, ref: inputRef, disabled: props.disabled, onChange: handleFileSelect, onClick: (e) => e.stopPropagation(), tabIndex: -1, accept: acceptAttr }), jsx(DIcon, { icon: icon, familyClass: iconFamilyClass, familyPrefix: iconFamilyPrefix, materialStyle: iconMaterialStyle }), jsx("div", { className: "d-box-content", children: typeof children === 'function'
856
+ ? children(openFileDialog)
857
+ : children })] })) })), !!files.length && (jsx("ul", { className: "d-box-files", children: files.map((file, index) => (jsx(ForwardedDInput, { value: file.name, iconStart: "paperclip", iconEnd: "trash", readOnly: true, onIconEndClick: () => handleRemoveFile(index) }, file.name))) }))] }));
355
858
  }
356
859
 
357
860
  function DButton({ theme = 'primary', size, variant, state, text = '', ariaLabel, iconStart, iconStartFamilyClass, iconStartFamilyPrefix, iconStartMaterialStyle, iconEnd, iconEndFamilyClass, iconEndFamilyPrefix, iconEndMaterialStyle, value, type = 'button', loading = false, loadingAriaLabel, disabled = false, stopPropagationEnabled = true, className, style, form, dataAttributes, onClick, }) {
@@ -492,102 +995,6 @@ function DCurrencyText({ value, className, style, dataAttributes, }) {
492
995
  return (jsx("span", Object.assign({ className: className, style: style }, dataAttributes, { children: valueFormatted })));
493
996
  }
494
997
 
495
- /* eslint-disable */
496
- /**
497
- * This file is originally from `@primer/react`
498
- * The original source for this lived in the URL below.
499
- *
500
- * @see https://github.com/primer/react/blob/216d2a9f57b8acb0701ab4e04a23e057fc325c90/src/hooks/useProvidedRefOrCreate.ts
501
- */
502
- /**
503
- * There are some situations where we only want to create a new ref if one is not provided to a component
504
- * or hook as a prop. However, due to the `rules-of-hooks`, we cannot conditionally make a call to `React.useRef`
505
- * only in the situations where the ref is not provided as a prop.
506
- * This hook aims to encapsulate that logic, so the consumer doesn't need to be concerned with violating `rules-of-hooks`.
507
- * @param providedRef The ref to use - if undefined, will use the ref from a call to React.useRef
508
- * @type TRef The type of the RefObject which should be created.
509
- */
510
- function useProvidedRefOrCreate(providedRef) {
511
- const createdRef = React.useRef(null);
512
- return providedRef !== null && providedRef !== void 0 ? providedRef : createdRef;
513
- }
514
-
515
- function DInput(_a, ref) {
516
- var { id: idProp, style, className, label = '', labelIcon, labelIconFamilyClass, labelIconFamilyPrefix, labelIconMaterialStyle, disabled = false, loading = false, iconFamilyClass, iconFamilyPrefix, iconMaterialStyle, iconStart, iconStartDisabled, iconStartFamilyClass, iconStartFamilyPrefix, iconStartAriaLabel, iconStartTabIndex, iconStartMaterialStyle, iconEnd, iconEndDisabled, iconEndFamilyClass, iconEndFamilyPrefix, iconEndAriaLabel, iconEndTabIndex, iconEndMaterialStyle, hint, size, invalid = false, valid = false, floatingLabel = false, inputStart, inputEnd, value, placeholder = '', dataAttributes, onChange, onIconStartClick, onIconEndClick } = _a, inputProps = __rest(_a, ["id", "style", "className", "label", "labelIcon", "labelIconFamilyClass", "labelIconFamilyPrefix", "labelIconMaterialStyle", "disabled", "loading", "iconFamilyClass", "iconFamilyPrefix", "iconMaterialStyle", "iconStart", "iconStartDisabled", "iconStartFamilyClass", "iconStartFamilyPrefix", "iconStartAriaLabel", "iconStartTabIndex", "iconStartMaterialStyle", "iconEnd", "iconEndDisabled", "iconEndFamilyClass", "iconEndFamilyPrefix", "iconEndAriaLabel", "iconEndTabIndex", "iconEndMaterialStyle", "hint", "size", "invalid", "valid", "floatingLabel", "inputStart", "inputEnd", "value", "placeholder", "dataAttributes", "onChange", "onIconStartClick", "onIconEndClick"]);
517
- const inputRef = useProvidedRefOrCreate(ref);
518
- const innerId = useId();
519
- const id = useMemo(() => idProp || innerId, [idProp, innerId]);
520
- const handleOnChange = useCallback((event) => {
521
- onChange === null || onChange === void 0 ? void 0 : onChange(event.currentTarget.value);
522
- }, [onChange]);
523
- const handleOnIconStartClick = useCallback(() => {
524
- onIconStartClick === null || onIconStartClick === void 0 ? void 0 : onIconStartClick(value);
525
- }, [onIconStartClick, value]);
526
- const handleOnIconEndClick = useCallback(() => {
527
- onIconEndClick === null || onIconEndClick === void 0 ? void 0 : onIconEndClick(value);
528
- }, [onIconEndClick, value]);
529
- const ariaDescribedby = useMemo(() => ([
530
- !!inputStart && `${id}InputStart`,
531
- !!iconStart && `${id}Start`,
532
- (invalid || valid) && !iconEnd && !loading && `${id}State`,
533
- (iconEnd && !loading) && `${id}End`,
534
- loading && `${id}Loading`,
535
- !!inputEnd && `${id}InputEnd`,
536
- !!hint && `${id}Hint`,
537
- ]
538
- .filter(Boolean)
539
- .join(' ')), [
540
- id,
541
- inputStart,
542
- iconStart,
543
- invalid,
544
- valid,
545
- iconEnd,
546
- loading,
547
- inputEnd,
548
- hint,
549
- ]);
550
- const inputComponent = useMemo(() => (jsx("input", Object.assign({ ref: inputRef, id: id, className: classNames('form-control', {
551
- [`form-control-${size}`]: !!size,
552
- 'is-invalid': invalid,
553
- 'is-valid': valid,
554
- }), disabled: disabled || loading, value: value, onChange: handleOnChange }, (floatingLabel || placeholder) && { placeholder: floatingLabel ? '' : placeholder }, ariaDescribedby && { 'aria-describedby': ariaDescribedby }, inputProps))), [
555
- ariaDescribedby,
556
- disabled,
557
- handleOnChange,
558
- id,
559
- inputProps,
560
- inputRef,
561
- invalid,
562
- loading,
563
- placeholder,
564
- floatingLabel,
565
- valid,
566
- value,
567
- size,
568
- ]);
569
- const labelComponent = useMemo(() => (jsxs("label", { htmlFor: id, children: [label, labelIcon && (jsx(DIcon, { icon: labelIcon, size: `var(--${PREFIX_BS}label-font-size)`, familyClass: labelIconFamilyClass, familyPrefix: labelIconFamilyPrefix, materialStyle: labelIconMaterialStyle }))] })), [
570
- id,
571
- label,
572
- labelIcon,
573
- labelIconFamilyClass,
574
- labelIconFamilyPrefix,
575
- labelIconMaterialStyle,
576
- ]);
577
- const dynamicComponent = useMemo(() => {
578
- if (floatingLabel) {
579
- return (jsxs("div", { className: "form-floating", children: [inputComponent, labelComponent] }));
580
- }
581
- return inputComponent;
582
- }, [floatingLabel, inputComponent, labelComponent]);
583
- return (jsxs("div", Object.assign({ className: className, style: style }, dataAttributes, { children: [label && !floatingLabel && labelComponent, jsxs("div", { className: classNames({
584
- 'input-group': true,
585
- 'has-validation': invalid || valid,
586
- }), children: [!!inputStart && (jsx("div", { className: "input-group-text", id: `${id}InputStart`, children: inputStart })), iconStart && (jsx("button", { type: "button", className: "input-group-text", id: `${id}Start`, onClick: handleOnIconStartClick, disabled: disabled || loading || iconStartDisabled, "aria-label": iconStartAriaLabel, tabIndex: onIconStartClick ? iconStartTabIndex : -1, children: jsx(DIcon, { icon: iconStart, familyClass: iconStartFamilyClass, familyPrefix: iconStartFamilyPrefix, materialStyle: iconStartMaterialStyle }) })), dynamicComponent, (iconEnd && !loading) && (jsx("button", { type: "button", className: "input-group-text", id: `${id}End`, onClick: handleOnIconEndClick, disabled: disabled || loading || iconEndDisabled, "aria-label": iconEndAriaLabel, tabIndex: onIconEndClick ? iconEndTabIndex : -1, children: jsx(DIcon, { icon: iconEnd, familyClass: iconEndFamilyClass, familyPrefix: iconEndFamilyPrefix, materialStyle: iconEndMaterialStyle }) })), loading && (jsx("div", { className: "input-group-text", id: `${id}Loading`, children: jsx("span", { className: "spinner-border spinner-border-sm", role: "status", "aria-hidden": "true", children: jsx("span", { className: "visually-hidden", children: "Loading..." }) }) })), !!inputEnd && (jsx("div", { className: "input-group-text", id: `${id}InputEnd`, children: inputEnd }))] }), hint && (jsx("div", { className: "form-text", id: `${id}Hint`, children: hint }))] })));
587
- }
588
- const ForwardedDInput = forwardRef(DInput);
589
- ForwardedDInput.displayName = 'DInput';
590
-
591
998
  function DDatePickerTime(_a) {
592
999
  var { value, onChange, id, label, className, style } = _a, props = __rest(_a, ["value", "onChange", "id", "label", "className", "style"]);
593
1000
  return (jsxs("div", { className: classNames('d-flex align-items-center gap-2 flex-column d-datepicker-time', className), style: style, children: [label && (jsx("label", { htmlFor: id, className: "d-datepicker-time-label", children: label })), jsx(ForwardedDInput, Object.assign({ className: "w-100" }, onChange && {
@@ -597,7 +1004,8 @@ function DDatePickerTime(_a) {
597
1004
 
598
1005
  function DDatePickerInput(_a, ref) {
599
1006
  var { value, onClick, id, iconEnd, className, style, inputLabel, readOnly: ignored } = _a, props = __rest(_a, ["value", "onClick", "id", "iconEnd", "className", "style", "inputLabel", "readOnly"]);
600
- return (jsx(ForwardedDInput, Object.assign({ ref: ref, onClick: onClick, readOnly: true, type: "text", id: id, value: value, onIconEndClick: onClick, iconEnd: iconEnd, className: className, style: style, label: inputLabel }, props)));
1007
+ const { iconMap: { calendar } } = useDContext();
1008
+ return (jsx(ForwardedDInput, Object.assign({ ref: ref, onClick: onClick, readOnly: true, type: "text", id: id, value: value, onIconEndClick: onClick, iconEnd: iconEnd || calendar, className: className, style: style, label: inputLabel }, props)));
601
1009
  }
602
1010
  const ForwardedDDatePickerInput = forwardRef(DDatePickerInput);
603
1011
  ForwardedDDatePickerInput.displayName = 'DDatePickerInput';
@@ -681,8 +1089,8 @@ function DSelectDropdownIndicator(props) {
681
1089
  }
682
1090
 
683
1091
  function DSelectClearIndicator(props) {
684
- const { iconMap: { xLg, }, } = useDContext();
685
- return (jsx(components.ClearIndicator, Object.assign({}, props, { children: jsx(DIcon, { icon: xLg }) })));
1092
+ const { iconMap: { x, }, } = useDContext();
1093
+ return (jsx(components.ClearIndicator, Object.assign({}, props, { children: jsx(DIcon, { icon: x }) })));
686
1094
  }
687
1095
 
688
1096
  function DSelectMultiValueRemove(props) {
@@ -766,43 +1174,65 @@ var DSelect$1 = Object.assign(DSelect, {
766
1174
  Placeholder: DSelectPlaceholder,
767
1175
  });
768
1176
 
769
- function DDatePickerHeader({ date, changeYear, changeMonth, decreaseMonth, increaseMonth, prevMonthButtonDisabled, nextMonthButtonDisabled, iconPrevMonth, iconNextMonth, iconFamilyClass, iconFamilyPrefix, iconMaterialStyle, prevMonthAriaLabel = 'decrease month', nextMonthAriaLabel = 'increase month', iconSize, buttonVariant, buttonTheme, locale, style, className, minYearSelect, maxYearSelect, }) {
1177
+ var PickerType;
1178
+ (function (PickerType) {
1179
+ PickerType["Default"] = "default";
1180
+ PickerType["Quarter"] = "quarter";
1181
+ PickerType["Month"] = "month";
1182
+ PickerType["Year"] = "year";
1183
+ })(PickerType || (PickerType = {}));
1184
+ function DDatePickerHeaderSelector({ date, changeYear, changeMonth, decreaseMonth, increaseMonth, decreaseYear, increaseYear, monthDate, pickerType, prevMonthButtonDisabled, nextMonthButtonDisabled, monthsShown = 1, iconPrev, iconNext, prevYearButtonDisabled, nextYearButtonDisabled, iconFamilyClass, iconFamilyPrefix, iconMaterialStyle = false, prevMonthAriaLabel = 'decrease month', nextMonthAriaLabel = 'increase month', prevYearAriaLabel = 'decrease year', nextYearAriaLabel = 'increase year', iconSize = 'sm', buttonVariant = 'link', buttonTheme = 'dark', style, className, minYearSelect = 1900, maxYearSelect = 2100, showHeaderSelectors = false, customHeaderCount, }) {
1185
+ const { iconMap: { chevronLeft, chevronRight, }, } = useDContext();
770
1186
  const arrayYears = useMemo(() => Array.from({ length: maxYearSelect - minYearSelect + 1 }, (_, index) => minYearSelect + index), [maxYearSelect, minYearSelect]);
771
1187
  const years = useMemo(() => arrayYears.map((year) => ({
772
1188
  label: year.toString(),
773
1189
  value: year,
774
1190
  })), [arrayYears]);
775
- const defaultYear = useMemo(() => years.find((year) => year.value === getYear(date)), [date, years]);
776
- const arrayMonths = useMemo(() => Array.from({ length: 12 }, (_, i) => format(new Date(2000, i), 'LLLL', { locale })), [locale]);
1191
+ const defaultYear = useMemo(() => years.find((year) => year.value === getYear(monthDate)), [monthDate, years]);
1192
+ const arrayMonths = useMemo(() => Array.from({ length: 12 }, (_, i) => format(new Date(2000, i), 'LLLL', { locale: enUS })), []);
777
1193
  const months = useMemo(() => arrayMonths.map((month, i) => ({
778
1194
  label: month,
779
1195
  value: i,
780
1196
  })), [arrayMonths]);
781
1197
  const defaultMonth = useMemo(() => ({
782
- label: arrayMonths[getMonth(date)],
783
- value: getMonth(date),
784
- }), [arrayMonths, date]);
785
- return (jsxs("div", { className: classNames('d-flex align-items-center d-datepicker-header', className), style: style, children: [jsx(DButton, { iconStart: iconPrevMonth, iconStartFamilyClass: iconFamilyClass, iconStartFamilyPrefix: iconFamilyPrefix, iconStartMaterialStyle: iconMaterialStyle, size: iconSize, variant: buttonVariant, theme: buttonTheme, onClick: decreaseMonth, disabled: prevMonthButtonDisabled, ariaLabel: prevMonthAriaLabel, className: "header-button" }), jsxs("div", { className: "d-flex justify-content-center flex-grow-1", children: [jsx(DSelect$1, { options: months, value: defaultMonth, defaultValue: defaultMonth, onChange: (month) => changeMonth((month === null || month === void 0 ? void 0 : month.value) || 0), searchable: false }), jsx(DSelect$1, { options: years, value: defaultYear, defaultValue: defaultYear, onChange: (year) => changeYear(Number(year === null || year === void 0 ? void 0 : year.value)), searchable: false })] }), jsx(DButton, { iconStart: iconNextMonth, iconStartFamilyClass: iconFamilyClass, iconStartFamilyPrefix: iconFamilyPrefix, iconStartMaterialStyle: iconMaterialStyle, size: iconSize, variant: buttonVariant, theme: buttonTheme, onClick: increaseMonth, disabled: nextMonthButtonDisabled, ariaLabel: nextMonthAriaLabel, className: "header-button" })] }));
1198
+ label: arrayMonths[getMonth(monthDate)],
1199
+ value: getMonth(monthDate),
1200
+ }), [arrayMonths, monthDate]);
1201
+ const getYearRange = useCallback(() => {
1202
+ const blockIndex = Math.floor((date.getFullYear() - 1) / 12);
1203
+ const startYear = blockIndex * 12 + 1;
1204
+ const endYear = startYear + 11;
1205
+ return [startYear, endYear];
1206
+ }, [date]);
1207
+ const [startYear, endYear] = getYearRange();
1208
+ if (pickerType === PickerType.Year) {
1209
+ return (jsxs("div", { className: classNames('react-datepicker__header-selector react-datepicker__header-year-selector', className), style: style, children: [jsx(DButton, { iconStart: iconPrev || chevronLeft, iconStartFamilyClass: iconFamilyClass, iconStartFamilyPrefix: iconFamilyPrefix, iconStartMaterialStyle: iconMaterialStyle, size: iconSize, variant: buttonVariant, theme: buttonTheme, onClick: decreaseYear, disabled: prevYearButtonDisabled, ariaLabel: prevYearAriaLabel, className: "header-button" }), jsx("p", { children: `${startYear} - ${endYear}` }), jsx(DButton, { iconStart: iconNext || chevronRight, iconStartFamilyClass: iconFamilyClass, iconStartFamilyPrefix: iconFamilyPrefix, iconStartMaterialStyle: iconMaterialStyle, size: iconSize, variant: buttonVariant, theme: buttonTheme, onClick: increaseYear, disabled: nextYearButtonDisabled, ariaLabel: nextYearAriaLabel, className: "header-button" })] }));
1210
+ }
1211
+ if (pickerType === PickerType.Quarter || pickerType === PickerType.Month) {
1212
+ return (jsxs("div", { className: classNames(`react-datepicker__header-selector react-datepicker__header-${pickerType}-selector`, className), style: style, children: [jsx(DButton, { iconStart: iconPrev || chevronLeft, iconStartFamilyClass: iconFamilyClass, iconStartFamilyPrefix: iconFamilyPrefix, iconStartMaterialStyle: iconMaterialStyle, size: iconSize, variant: buttonVariant, theme: buttonTheme, onClick: decreaseYear, disabled: prevMonthButtonDisabled, ariaLabel: prevMonthAriaLabel, className: "header-button", style: { visibility: customHeaderCount === 0 ? 'visible' : 'hidden' } }), jsx("div", { className: "d-flex justify-content-center flex-grow-1", children: showHeaderSelectors ? (jsx(DSelect$1, { options: years, value: defaultYear, defaultValue: defaultYear, onChange: (year) => changeYear(Number(year === null || year === void 0 ? void 0 : year.value)), searchable: false })) : (jsx("p", { children: defaultYear === null || defaultYear === void 0 ? void 0 : defaultYear.label })) }), jsx(DButton, { iconStart: iconNext || chevronRight, iconStartFamilyClass: iconFamilyClass, iconStartFamilyPrefix: iconFamilyPrefix, iconStartMaterialStyle: iconMaterialStyle, size: iconSize, variant: buttonVariant, theme: buttonTheme, onClick: increaseYear, disabled: nextMonthButtonDisabled, ariaLabel: nextMonthAriaLabel, className: "header-button", style: { visibility: customHeaderCount === monthsShown - 1 ? 'visible' : 'hidden' } })] }));
1213
+ }
1214
+ return (jsxs("div", { className: classNames('react-datepicker__header-selector react-datepicker__header-day-selector', className), style: style, children: [jsx(DButton, { iconStart: iconPrev || chevronLeft, iconStartFamilyClass: iconFamilyClass, iconStartFamilyPrefix: iconFamilyPrefix, iconStartMaterialStyle: iconMaterialStyle, size: iconSize, variant: buttonVariant, theme: buttonTheme, onClick: decreaseMonth, disabled: prevMonthButtonDisabled, ariaLabel: prevMonthAriaLabel, className: "header-button", style: { visibility: customHeaderCount === 0 ? 'visible' : 'hidden' } }), showHeaderSelectors ? (jsxs(Fragment$1, { children: [jsx(DSelect$1, { options: months, value: defaultMonth, defaultValue: defaultMonth, onChange: (month) => changeMonth((month === null || month === void 0 ? void 0 : month.value) || 0), searchable: false, className: "custom-month-selector" }), jsx(DSelect$1, { options: years, value: defaultYear, defaultValue: defaultYear, onChange: (year) => changeYear(Number(year === null || year === void 0 ? void 0 : year.value)), searchable: false, className: "custom-year-selector" })] })) : (jsx("p", { children: `${defaultMonth.label} ${defaultYear === null || defaultYear === void 0 ? void 0 : defaultYear.label}` })), jsx(DButton, { iconStart: iconNext || chevronRight, iconStartFamilyClass: iconFamilyClass, iconStartFamilyPrefix: iconFamilyPrefix, iconStartMaterialStyle: iconMaterialStyle, size: iconSize, variant: buttonVariant, theme: buttonTheme, onClick: increaseMonth, disabled: nextMonthButtonDisabled, ariaLabel: nextMonthAriaLabel, className: "header-button", style: { visibility: customHeaderCount === monthsShown - 1 ? 'visible' : 'hidden' } })] }));
786
1215
  }
787
1216
 
788
- /**
789
- * @deprecated
790
- */
791
1217
  function DDatePicker(_a) {
792
- var { date, selectsRange = false, inputLabel, inputHint, inputAriaLabel, inputActionAriaLabel = 'open calendar', inputId = 'input-calendar', timeId = 'input-time', timeLabel, iconInput: iconInputProp, iconHeaderPrevMonth: iconHeaderPrevMonthProp, iconHeaderNextMonth: iconHeaderNextMonthProp, iconMaterialStyle: iconMaterialStyleProp, iconFamilyClass, iconFamilyPrefix, minYearSelect = 1900, maxYearSelect = 2100, iconHeaderSize = 'sm', headerPrevMonthAriaLabel = 'decrease month', headerNextMonthAriaLabel = 'increase month', headerButtonVariant = 'link', headerButtonTheme = 'dark', invalid = false, valid = false, renderCustomHeader: renderCustomHeaderProp, locale, className, formatWeekDay: formatWeekDayProp, style, dataAttributes, placeholder } = _a, props = __rest(_a, ["date", "selectsRange", "inputLabel", "inputHint", "inputAriaLabel", "inputActionAriaLabel", "inputId", "timeId", "timeLabel", "iconInput", "iconHeaderPrevMonth", "iconHeaderNextMonth", "iconMaterialStyle", "iconFamilyClass", "iconFamilyPrefix", "minYearSelect", "maxYearSelect", "iconHeaderSize", "headerPrevMonthAriaLabel", "headerNextMonthAriaLabel", "headerButtonVariant", "headerButtonTheme", "invalid", "valid", "renderCustomHeader", "locale", "className", "formatWeekDay", "style", "dataAttributes", "placeholder"]);
793
- const { iconMap: { calendar, chevronLeft, chevronRight, }, } = useDContext();
794
- const selected = useMemo(() => (date ? parseISO(date) : null), [date]);
795
- const iconInput = useMemo(() => iconInputProp || calendar, [calendar, iconInputProp]);
796
- const handleFormatWeekDay = useMemo(() => (formatWeekDayProp
797
- ? (day) => formatWeekDayProp(day)
798
- : (day) => day.substring(0, 1)), [formatWeekDayProp]);
799
- const iconPrevMonth = useMemo(() => iconHeaderPrevMonthProp || chevronLeft, [chevronLeft, iconHeaderPrevMonthProp]);
800
- const iconNextMonth = useMemo(() => iconHeaderNextMonthProp || chevronRight, [chevronRight, iconHeaderNextMonthProp]);
801
- const DatePickerHeader = useCallback((headerProps) => (jsx(DDatePickerHeader, Object.assign({}, headerProps, locale && { locale }, { iconPrevMonth: iconPrevMonth, iconNextMonth: iconNextMonth, iconMaterialStyle: iconMaterialStyleProp, prevMonthAriaLabel: headerPrevMonthAriaLabel, nextMonthAriaLabel: headerNextMonthAriaLabel, iconSize: iconHeaderSize, buttonVariant: headerButtonVariant, buttonTheme: headerButtonTheme, minYearSelect: minYearSelect, maxYearSelect: maxYearSelect }))), [
802
- locale,
803
- iconPrevMonth,
804
- iconNextMonth,
805
- iconMaterialStyleProp,
1218
+ var { inputLabel, inputHint, inputAriaLabel, inputActionAriaLabel = 'open calendar', inputId = 'input-calendar', timeId = 'input-time', timeLabel, iconInput, iconHeaderPrev, iconHeaderNext, iconMaterialStyle, iconFamilyClass, iconFamilyPrefix, minYearSelect, maxYearSelect, iconHeaderSize, headerPrevMonthAriaLabel, headerNextMonthAriaLabel, headerButtonVariant, headerButtonTheme, invalid = false, valid = false, renderCustomHeader: renderCustomHeaderProp, className, dateFormatCalendar: dateFormatCalendarProp, style, dataAttributes, placeholder, showHeaderSelectors } = _a, props = __rest(_a, ["inputLabel", "inputHint", "inputAriaLabel", "inputActionAriaLabel", "inputId", "timeId", "timeLabel", "iconInput", "iconHeaderPrev", "iconHeaderNext", "iconMaterialStyle", "iconFamilyClass", "iconFamilyPrefix", "minYearSelect", "maxYearSelect", "iconHeaderSize", "headerPrevMonthAriaLabel", "headerNextMonthAriaLabel", "headerButtonVariant", "headerButtonTheme", "invalid", "valid", "renderCustomHeader", "className", "dateFormatCalendar", "style", "dataAttributes", "placeholder", "showHeaderSelectors"]);
1219
+ const pickerType = useMemo(() => {
1220
+ if (props.showQuarterYearPicker)
1221
+ return PickerType.Quarter;
1222
+ if (props.showMonthYearPicker)
1223
+ return PickerType.Month;
1224
+ if (props.showYearPicker)
1225
+ return PickerType.Year;
1226
+ return PickerType.Default;
1227
+ }, [
1228
+ props.showQuarterYearPicker,
1229
+ props.showMonthYearPicker,
1230
+ props.showYearPicker,
1231
+ ]);
1232
+ const DatePickerHeader = useCallback((headerProps) => (jsx(DDatePickerHeaderSelector, Object.assign({}, headerProps, { monthsShown: props.monthsShown, iconPrev: iconHeaderPrev, iconNext: iconHeaderNext, iconMaterialStyle: iconMaterialStyle, prevMonthAriaLabel: headerPrevMonthAriaLabel, nextMonthAriaLabel: headerNextMonthAriaLabel, iconSize: iconHeaderSize, buttonVariant: headerButtonVariant, buttonTheme: headerButtonTheme, minYearSelect: minYearSelect, maxYearSelect: maxYearSelect, pickerType: pickerType, showHeaderSelectors: showHeaderSelectors }))), [
1233
+ iconHeaderNext,
1234
+ iconHeaderPrev,
1235
+ iconMaterialStyle,
806
1236
  headerPrevMonthAriaLabel,
807
1237
  headerNextMonthAriaLabel,
808
1238
  iconHeaderSize,
@@ -810,10 +1240,13 @@ function DDatePicker(_a) {
810
1240
  headerButtonTheme,
811
1241
  minYearSelect,
812
1242
  maxYearSelect,
1243
+ pickerType,
1244
+ showHeaderSelectors,
1245
+ props.monthsShown,
813
1246
  ]);
814
1247
  const defaultRenderCustomHeader = useCallback((headerProps) => (jsx(DatePickerHeader, Object.assign({}, headerProps))), [DatePickerHeader]);
815
1248
  const renderCustomHeader = useMemo(() => (renderCustomHeaderProp || defaultRenderCustomHeader), [defaultRenderCustomHeader, renderCustomHeaderProp]);
816
- return (jsx(DatePicker, Object.assign({ selected: selected, calendarClassName: "d-date-picker", renderCustomHeader: renderCustomHeader, selectsRange: selectsRange, formatWeekDay: handleFormatWeekDay, customInput: (jsx(ForwardedDDatePickerInput, { id: inputId, "aria-label": inputAriaLabel, iconEndAriaLabel: inputActionAriaLabel, iconMaterialStyle: iconMaterialStyleProp, iconEnd: iconInput, inputLabel: inputLabel, className: className, style: style, invalid: invalid, valid: valid, hint: inputHint })), customTimeInput: (jsx(DDatePickerTime, { id: timeId, label: timeLabel })), placeholderText: placeholder }, locale && { locale }, dataAttributes, props)));
1249
+ return (jsx(DatePicker, Object.assign({ calendarClassName: "d-date-picker", renderCustomHeader: renderCustomHeader, customInput: (jsx(ForwardedDDatePickerInput, { id: inputId, "aria-label": inputAriaLabel, iconEndAriaLabel: inputActionAriaLabel, iconMaterialStyle: iconMaterialStyle, iconEnd: iconInput, inputLabel: inputLabel, className: className, style: style, invalid: invalid, valid: valid, hint: inputHint })), customTimeInput: (jsx(DDatePickerTime, { id: timeId, label: timeLabel })), placeholderText: placeholder }, dataAttributes, props)));
817
1250
  }
818
1251
 
819
1252
  function DInputMask(props, ref) {
@@ -1322,7 +1755,7 @@ function DListGroupItem({ as = 'li', action: actionProp, active, disabled, href,
1322
1755
  }
1323
1756
  return Object.assign(Object.assign({}, active && { 'aria-current': true }), disabled && { 'aria-disabled': true });
1324
1757
  }, [Tag, active, disabled]);
1325
- return (jsx(Tag, Object.assign({ className: classNames(generateClasses, className), style: style }, Tag === 'a' && href && { href }, onClick && { onClick }, ariaAttributes, dataAttributes, { children: children })));
1758
+ return (jsx(Tag, Object.assign({ className: classNames(generateClasses, className), style: style }, Tag === 'a' && href && { href }, onClick && { onClick }, ariaAttributes, dataAttributes, Tag === 'button' && { type: 'button' }, { children: children })));
1326
1759
  }
1327
1760
 
1328
1761
  function DListGroup({ as = 'ul', numbered, flush, horizontal, children, className, style, dataAttributes, }) {
@@ -1432,9 +1865,6 @@ function DPaginator(_a) {
1432
1865
  return (jsx(ResponsivePagination, Object.assign({ navClassName: classNames('page-item-arrow', navClassName) }, backwardCompatibilityProps)));
1433
1866
  }
1434
1867
 
1435
- /**
1436
- * @deprecated
1437
- */
1438
1868
  function DPopover({ children, renderComponent, open, setOpen, adjustContentToRender = false, className, style, dataAttributes, }) {
1439
1869
  const [isOpen, setIsOpen] = useState(false);
1440
1870
  useEffect(() => {