@dynamic-framework/ui-react 2.0.0-dev.2 → 2.0.0-dev.21

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 (64) hide show
  1. package/README.md +52 -3
  2. package/dist/css/dynamic-ui-non-root.css +6344 -627
  3. package/dist/css/dynamic-ui-non-root.min.css +3 -3
  4. package/dist/css/dynamic-ui-root.css +63 -557
  5. package/dist/css/dynamic-ui-root.min.css +3 -3
  6. package/dist/css/dynamic-ui.css +6405 -1182
  7. package/dist/css/dynamic-ui.min.css +3 -3
  8. package/dist/index.esm.js +520 -159
  9. package/dist/index.esm.js.map +1 -1
  10. package/dist/index.js +542 -179
  11. package/dist/index.js.map +1 -1
  12. package/dist/types/components/DBoxFile/DBoxFile.d.ts +1 -1
  13. package/dist/types/components/DButton/DButton.d.ts +7 -17
  14. package/dist/types/components/DCollapse/DCollapse.d.ts +6 -0
  15. package/dist/types/components/DDatePicker/DDatePicker.d.ts +2 -1
  16. package/dist/types/components/DDatePicker/components/DDatePickerHeaderSelector.d.ts +2 -1
  17. package/dist/types/components/DIconBase/DIconBase.d.ts +10 -2
  18. package/dist/types/components/DInput/DInput.d.ts +2 -1
  19. package/dist/types/components/DInputCheck/DInputCheck.d.ts +2 -1
  20. package/dist/types/components/DInputCounter/DInputCounter.d.ts +3 -2
  21. package/dist/types/components/DInputCurrency/DInputCurrency.d.ts +3 -2
  22. package/dist/types/components/DInputMask/DInputMask.d.ts +7 -17
  23. package/dist/types/components/DInputPhone/DInputPhone.d.ts +1 -1
  24. package/dist/types/components/DInputSwitch/DInputSwitch.d.ts +2 -1
  25. package/dist/types/components/DLayout/DLayout.d.ts +13 -2
  26. package/dist/types/components/DModal/DModal.d.ts +3 -1
  27. package/dist/types/components/DOffcanvas/DOffcanvas.d.ts +3 -1
  28. package/dist/types/components/DPasswordStrengthMeter/DPasswordStrengthMeter.d.ts +23 -0
  29. package/dist/types/components/DPasswordStrengthMeter/PasswordCheckItem.d.ts +7 -0
  30. package/dist/types/components/DPasswordStrengthMeter/PasswordCheckList.d.ts +14 -0
  31. package/dist/types/components/DPasswordStrengthMeter/PasswordStrength.d.ts +6 -0
  32. package/dist/types/components/DPasswordStrengthMeter/index.d.ts +3 -0
  33. package/dist/types/components/DVoucher/DVoucher.d.ts +14 -0
  34. package/dist/types/components/DVoucher/hooks/useScreenshot.d.ts +5 -0
  35. package/dist/types/components/DVoucher/hooks/useScreenshotDownload.d.ts +5 -0
  36. package/dist/types/components/DVoucher/hooks/useScreenshotWebShare.d.ts +5 -0
  37. package/dist/types/components/DVoucher/index.d.ts +2 -0
  38. package/dist/types/components/config.d.ts +0 -2
  39. package/dist/types/components/index.d.ts +4 -1
  40. package/dist/types/hooks/useResponsiveProp.d.ts +35 -0
  41. package/jest/setup.js +0 -2
  42. package/package.json +38 -40
  43. package/src/style/abstracts/_mixins.scss +34 -20
  44. package/src/style/abstracts/_utilities-hover.scss +55 -0
  45. package/src/style/abstracts/_utilities.scss +19 -0
  46. package/src/style/abstracts/variables/_buttons.scss +2 -0
  47. package/src/style/abstracts/variables/_colors.scss +8 -2
  48. package/src/style/base/_buttons.scss +25 -142
  49. package/src/style/base/_label.scss +0 -4
  50. package/src/style/components/_+import.scss +1 -0
  51. package/src/style/components/_d-box-file.scss +1 -1
  52. package/src/style/components/_d-carousel.scss +4 -3
  53. package/src/style/components/_d-datepicker.scss +23 -4
  54. package/src/style/components/_d-voucher.scss +29 -0
  55. package/src/style/dynamic-ui-non-root.scss +2 -0
  56. package/src/style/dynamic-ui.scss +2 -0
  57. package/src/style/root/_root.scss +94 -88
  58. package/dist/types/components/DBarChart/DBarChart.d.ts +0 -9
  59. package/dist/types/components/DMinimalLineChart/DMinimalLineChart.d.ts +0 -9
  60. package/dist/types/components/DMultiLineChart/DMultiLineChart.d.ts +0 -9
  61. package/dist/types/components/DPieChart/DPieChart.d.ts +0 -9
  62. package/dist/types/components/DRadialBarChart/DRadialBarChart.d.ts +0 -6
  63. package/dist/types/components/DTableHead/DTableHead.d.ts +0 -9
  64. package/dist/types/components/DTableHead/index.d.ts +0 -2
package/dist/index.esm.js CHANGED
@@ -1,9 +1,10 @@
1
- import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
1
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
2
  import classNames from 'classnames';
3
- import React, { useMemo, useEffect, useState, useCallback, useContext, createContext, Fragment, useLayoutEffect, forwardRef, useId, useRef, useSyncExternalStore } from 'react';
3
+ import React, { useEffect, useState, useCallback, useMemo, useContext, createContext, useLayoutEffect, useSyncExternalStore, forwardRef, useId, useRef } from 'react';
4
4
  import { __rest } from 'tslib';
5
5
  import * as LucideIcons from 'lucide-react';
6
6
  import { createPortal } from 'react-dom';
7
+ import { AnimatePresence, motion } from 'framer-motion';
7
8
  import { fromEvent } from 'file-selector';
8
9
  import { SplideSlide, Splide } from '@splidejs/react-splide';
9
10
  import currency from 'currency.js';
@@ -16,65 +17,12 @@ import { useFloating, autoUpdate, offset, flip, shift, useClick, useDismiss, use
16
17
  import { Toaster, toast } from 'react-hot-toast';
17
18
  import { defaultCountries, parseCountry, usePhoneInput, CountrySelector } from 'react-international-phone';
18
19
  import { PhoneNumberUtil } from 'google-libphonenumber';
20
+ import html2canvas from 'html2canvas';
19
21
  import i18n from 'i18next';
20
22
  import { initReactI18next } from 'react-i18next';
21
23
 
22
24
  const PREFIX_BS = 'bs-';
23
25
 
24
- function DIconBase({ icon, color, style, className, size, hasCircle = false, materialStyle = false, familyClass = 'material-symbols-outlined', strokeWidth = 2, dataAttributes, }) {
25
- // If materialStyle is true, use Material Design icons (legacy)
26
- const useMaterialIcons = materialStyle;
27
- // Get Lucide icon component
28
- const LucideIcon = useMemo(() => {
29
- if (useMaterialIcons)
30
- return null;
31
- // Try to find the icon in Lucide (expects PascalCase)
32
- const icons = LucideIcons;
33
- return icons[icon] || null;
34
- }, [icon, useMaterialIcons]);
35
- const colorStyle = useMemo(() => {
36
- if (color) {
37
- return { [`--${PREFIX_BS}icon-component-color`]: `var(--${PREFIX_BS}${color})` };
38
- }
39
- return {};
40
- }, [color]);
41
- const backgroundStyle = useMemo(() => {
42
- if (hasCircle) {
43
- if (color) {
44
- return { [`--${PREFIX_BS}icon-component-bg-color`]: `rgba(var(--${PREFIX_BS}${color}-rgb), 0.1)` };
45
- }
46
- return { [`--${PREFIX_BS}icon-component-bg-color`]: `rgba(var(--${PREFIX_BS}body-color-rgb), 0.1)` };
47
- }
48
- return {};
49
- }, [hasCircle, color]);
50
- const generateStyleVariables = useMemo(() => (Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, size && { [`--${PREFIX_BS}icon-component-size`]: size }), colorStyle), backgroundStyle), hasCircle && { [`--${PREFIX_BS}icon-component-padding`]: `calc(var(--${PREFIX_BS}icon-component-size, 24px) * 0.4)` }), style)), [size, colorStyle, backgroundStyle, hasCircle, style]);
51
- const generateClasses = useMemo(() => (Object.assign(Object.assign({ 'd-icon': true }, useMaterialIcons && {
52
- [familyClass]: true,
53
- }), className && { [className]: true })), [
54
- className,
55
- useMaterialIcons,
56
- familyClass,
57
- ]);
58
- const iconSize = useMemo(() => {
59
- if (size) {
60
- const numSize = parseInt(size, 10);
61
- return !Number.isNaN(numSize) ? numSize : size;
62
- }
63
- return undefined;
64
- }, [size]);
65
- // Render Material Design icon (legacy support)
66
- if (useMaterialIcons) {
67
- return (jsx("i", Object.assign({ className: classNames(generateClasses), style: generateStyleVariables }, dataAttributes, { children: icon })));
68
- }
69
- // Render Lucide icon
70
- if (!LucideIcon) {
71
- // eslint-disable-next-line no-console
72
- console.warn(`Icon "${icon}" not found in Lucide. Make sure to use PascalCase names (e.g., "Home", "User", "Settings")`);
73
- return (jsx("span", Object.assign({ className: classNames(generateClasses), style: generateStyleVariables }, dataAttributes, { children: "?" })));
74
- }
75
- return (jsx("span", Object.assign({ className: classNames(generateClasses), style: generateStyleVariables }, dataAttributes, { children: jsx(LucideIcon, { size: iconSize || 24, strokeWidth: strokeWidth }) })));
76
- }
77
-
78
26
  function useDisableBodyScrollEffect(disable) {
79
27
  useEffect(() => {
80
28
  if (disable) {
@@ -231,7 +179,10 @@ function DPortalContextProvider({ portalName, children, availablePortals, }) {
231
179
  return (jsxs(DPortalContext.Provider, { value: value, children: [children, created && createPortal(
232
180
  // eslint-disable-next-line max-len
233
181
  // eslint-disable-next-line jsx-a11y/no-static-element-interactions
234
- jsx("div", { onClick: ({ target }) => handleClose(target), onKeyDown: () => { }, children: stack.map(({ Component, name, payload, }) => (jsxs(Fragment, { children: [jsx("div", { className: "backdrop fade show" }), jsx(Component, { name: name, payload: payload })] }, name))) }), document.getElementById(portalName))] }));
182
+ jsx("div", { onClick: ({ target }) => handleClose(target), onKeyDown: () => { }, children: jsx(AnimatePresence, { children: stack.flatMap(({ Component, name, payload, }) => [
183
+ jsx(motion.div, { className: "backdrop", initial: { opacity: 0 }, animate: { opacity: 0.5 }, exit: { opacity: 0, transition: { delay: 0.3 } }, transition: { duration: 0.15, ease: 'linear' } }, `${name}-backdrop`),
184
+ jsx(Component, { name: name, payload: payload }, name),
185
+ ]) }) }), document.getElementById(portalName))] }));
235
186
  }
236
187
  function useDPortalContext() {
237
188
  const context = useContext(DPortalContext);
@@ -327,6 +278,151 @@ function useDContext() {
327
278
  return context;
328
279
  }
329
280
 
281
+ function subscribeToMediaQuery(query, callback) {
282
+ const mediaQueryList = window.matchMedia(query);
283
+ mediaQueryList.addEventListener('change', callback);
284
+ return () => {
285
+ mediaQueryList.removeEventListener('change', callback);
286
+ };
287
+ }
288
+ function checkMediaQuery(query) {
289
+ return window.matchMedia(query).matches;
290
+ }
291
+
292
+ function useMediaQuery(mediaQuery, useListener = false) {
293
+ /* eslint-disable-next-line @typescript-eslint/no-unused-vars */
294
+ const noop = (_) => () => { };
295
+ return useSyncExternalStore(useListener ? (cb) => subscribeToMediaQuery(mediaQuery, cb) : noop, () => (mediaQuery ? checkMediaQuery(mediaQuery) : true), () => false);
296
+ }
297
+
298
+ function useMediaBreakpointUp(breakpoint, useListener = false) {
299
+ const { breakpoints } = useDContext();
300
+ const mediaQuery = useMemo(() => (`(min-width: ${breakpoints[breakpoint]})`), [breakpoint, breakpoints]);
301
+ return useMediaQuery(mediaQuery, useListener);
302
+ }
303
+ function useMediaBreakpointUpXs(useListener = false) {
304
+ return useMediaBreakpointUp('xs', useListener);
305
+ }
306
+ function useMediaBreakpointUpSm(useListener = false) {
307
+ return useMediaBreakpointUp('sm', useListener);
308
+ }
309
+ function useMediaBreakpointUpMd(useListener = false) {
310
+ return useMediaBreakpointUp('md', useListener);
311
+ }
312
+ function useMediaBreakpointUpLg(useListener = false) {
313
+ return useMediaBreakpointUp('lg', useListener);
314
+ }
315
+ function useMediaBreakpointUpXl(useListener = false) {
316
+ return useMediaBreakpointUp('xl', useListener);
317
+ }
318
+ function useMediaBreakpointUpXxl(useListener = false) {
319
+ return useMediaBreakpointUp('xxl', useListener);
320
+ }
321
+
322
+ /**
323
+ * React hook to resolve a responsive property value based on the current viewport breakpoint.
324
+ *
325
+ * Given a `ResponsiveProp` object, this hook returns the value for the highest matching breakpoint.
326
+ * If multiple breakpoints match, the value for the largest (highest) breakpoint is used.
327
+ * If no breakpoints match, `undefined` is returned.
328
+ *
329
+ * @param useListener - Whether to listen for breakpoint changes (default: false).
330
+ * @returns An object with a `responsivePropValue` function that takes a
331
+ * `ResponsiveProp` and returns the resolved value.
332
+ *
333
+ * Usage example:
334
+ * ```ts
335
+ * const { responsivePropValue } = useResponsiveProp();
336
+ * const value = responsivePropValue({ xs: "A", md: "B", xl: "C" });
337
+ * // value will be "C" if xl breakpoint is active, "B" if md is active, etc.
338
+ * ```
339
+ */
340
+ function useResponsiveProp(useListener = false) {
341
+ const bpXsUp = useMediaBreakpointUpXs(useListener);
342
+ const bpSmUp = useMediaBreakpointUpSm(useListener);
343
+ const bpMdUp = useMediaBreakpointUpMd(useListener);
344
+ const bpLgUp = useMediaBreakpointUpLg(useListener);
345
+ const bpXlUp = useMediaBreakpointUpXl(useListener);
346
+ const bpXxlUp = useMediaBreakpointUpXxl(useListener);
347
+ const responsivePropValue = useCallback((prop) => {
348
+ // Pick the highest matched breakpoint value that is defined in prop
349
+ if (prop.xxl !== undefined && bpXxlUp)
350
+ return prop.xxl;
351
+ if (prop.xl !== undefined && bpXlUp)
352
+ return prop.xl;
353
+ if (prop.lg !== undefined && bpLgUp)
354
+ return prop.lg;
355
+ if (prop.md !== undefined && bpMdUp)
356
+ return prop.md;
357
+ if (prop.sm !== undefined && bpSmUp)
358
+ return prop.sm;
359
+ if (prop.xs !== undefined && bpXsUp)
360
+ return prop.xs;
361
+ // Fallback: return undefined if no breakpoint matches
362
+ return undefined;
363
+ }, [bpSmUp, bpMdUp, bpLgUp, bpXlUp, bpXxlUp, bpXsUp]);
364
+ return { responsivePropValue };
365
+ }
366
+
367
+ function DIconBase({ icon, color, style, className, size, useListenerSize = false, hasCircle = false, materialStyle = false, familyClass, familyPrefix, strokeWidth = 2, dataAttributes, }) {
368
+ // If materialStyle is true, use Material Design icons (legacy)
369
+ const useMaterialIcons = materialStyle;
370
+ // Get Lucide icon component
371
+ const LucideIcon = useMemo(() => {
372
+ if (useMaterialIcons)
373
+ return null;
374
+ // Try to find the icon in Lucide (expects PascalCase)
375
+ const icons = LucideIcons;
376
+ return icons[icon] || null;
377
+ }, [icon, useMaterialIcons]);
378
+ const colorStyle = useMemo(() => {
379
+ if (color) {
380
+ return { [`--${PREFIX_BS}icon-component-color`]: `var(--${PREFIX_BS}${color})` };
381
+ }
382
+ return {};
383
+ }, [color]);
384
+ const backgroundStyle = useMemo(() => {
385
+ if (hasCircle) {
386
+ if (color) {
387
+ return { [`--${PREFIX_BS}icon-component-bg-color`]: `rgba(var(--${PREFIX_BS}${color}-rgb), 0.1)` };
388
+ }
389
+ return { [`--${PREFIX_BS}icon-component-bg-color`]: `rgba(var(--${PREFIX_BS}body-color-rgb), 0.1)` };
390
+ }
391
+ return {};
392
+ }, [hasCircle, color]);
393
+ const { responsivePropValue } = useResponsiveProp(useListenerSize);
394
+ const resolvedSize = useMemo(() => {
395
+ if (!size)
396
+ return undefined;
397
+ if (typeof size === 'string')
398
+ return size;
399
+ return responsivePropValue(size);
400
+ }, [responsivePropValue, size]);
401
+ const generateStyleVariables = useMemo(() => (Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, resolvedSize && { [`--${PREFIX_BS}icon-component-size`]: resolvedSize }), colorStyle), backgroundStyle), hasCircle && { [`--${PREFIX_BS}icon-component-padding`]: `calc(var(--${PREFIX_BS}icon-component-size, 24px) * 0.4)` }), style)), [resolvedSize, colorStyle, backgroundStyle, hasCircle, style]);
402
+ const generateClasses = useMemo(() => (Object.assign({ 'd-icon': true }, className && { [className]: true })), [className]);
403
+ const iconSize = useMemo(() => {
404
+ if (resolvedSize) {
405
+ const numSize = parseInt(resolvedSize, 10);
406
+ return !Number.isNaN(numSize) ? numSize : resolvedSize;
407
+ }
408
+ return undefined;
409
+ }, [resolvedSize]);
410
+ // Render Material Design icon (legacy support)
411
+ if (useMaterialIcons) {
412
+ return (jsx("i", Object.assign({ className: classNames(generateClasses, familyClass), style: generateStyleVariables }, dataAttributes, { children: icon })));
413
+ }
414
+ // Render Lucide icon
415
+ if (!LucideIcon) {
416
+ if (familyClass && familyPrefix) {
417
+ return (jsx("i", Object.assign({ className: classNames(generateClasses, familyClass, `${familyPrefix}${icon}`), style: generateStyleVariables }, dataAttributes)));
418
+ }
419
+ // eslint-disable-next-line no-console
420
+ console.warn(`Icon "${icon}" not found in Lucide. Make sure to use PascalCase names (e.g., "Home", "User", "Settings")`);
421
+ return (jsx("span", Object.assign({ className: classNames(generateClasses), style: generateStyleVariables }, dataAttributes, { children: "?" })));
422
+ }
423
+ return (jsx("span", Object.assign({ className: classNames(generateClasses), style: generateStyleVariables }, dataAttributes, { children: jsx(LucideIcon, { size: iconSize || 24, strokeWidth: strokeWidth }) })));
424
+ }
425
+
330
426
  function DIcon(_a) {
331
427
  var { familyClass: propFamilyClass, familyPrefix: propFamilyPrefix, materialStyle: propMaterialStyle } = _a, props = __rest(_a, ["familyClass", "familyPrefix", "materialStyle"]);
332
428
  const { icon: { familyClass, familyPrefix, materialStyle, }, } = useDContext();
@@ -394,7 +490,7 @@ function useProvidedRefOrCreate(providedRef) {
394
490
  }
395
491
 
396
492
  function DInput(_a, ref) {
397
- var { id: idProp, style, className, label = '', 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", "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"]);
493
+ var { id: idProp, style, className, label = '', 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, readonly, onChange, onIconStartClick, onIconEndClick } = _a, inputProps = __rest(_a, ["id", "style", "className", "label", "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", "readonly", "onChange", "onIconStartClick", "onIconEndClick"]);
398
494
  const inputRef = useProvidedRefOrCreate(ref);
399
495
  const innerId = useId();
400
496
  const id = useMemo(() => idProp || innerId, [idProp, innerId]);
@@ -431,7 +527,7 @@ function DInput(_a, ref) {
431
527
  const inputComponent = useMemo(() => (jsx("input", Object.assign({ ref: inputRef, id: id, className: classNames('form-control', {
432
528
  'is-invalid': invalid,
433
529
  'is-valid': valid,
434
- }), disabled: disabled || loading, value: value, onChange: handleOnChange }, (floatingLabel || placeholder) && { placeholder: floatingLabel ? '' : placeholder }, ariaDescribedby && { 'aria-describedby': ariaDescribedby }, inputProps))), [
530
+ }), disabled: disabled || loading, readOnly: readonly, value: value, onChange: handleOnChange }, (floatingLabel || placeholder) && { placeholder: floatingLabel ? '' : placeholder }, ariaDescribedby && { 'aria-describedby': ariaDescribedby }, inputProps))), [
435
531
  ariaDescribedby,
436
532
  disabled,
437
533
  handleOnChange,
@@ -444,6 +540,7 @@ function DInput(_a, ref) {
444
540
  floatingLabel,
445
541
  valid,
446
542
  value,
543
+ readonly,
447
544
  ]);
448
545
  const labelComponent = useMemo(() => (jsx("label", { htmlFor: id, children: label })), [
449
546
  id,
@@ -858,36 +955,69 @@ function DBoxFile(_a) {
858
955
  const { iconMap: { upload } } = useDContext();
859
956
  const icon = useMemo(() => iconProp || upload, [iconProp, upload]);
860
957
  const { inputRef, rootRef, isDragValid, isDragInvalid, acceptAttr, files, handleFileSelect, handleDrop, handleDragEnter, handleDragLeave, handleClick, handleKeyDown, handleRemoveFile, openFileDialog, } = useDBoxFile(props);
861
- return (jsxs(Fragment$1, { children: [jsx("section", Object.assign({ className: classNames('d-box-file', {
958
+ return (jsxs(Fragment, { children: [jsx("section", Object.assign({ className: classNames('d-box-file', {
862
959
  'd-box-file-selected': files.length > 0,
863
960
  'd-box-file-disabled': props.disabled,
864
961
  'd-box-file-valid': isDragValid,
865
962
  'd-box-file-invalid': isDragInvalid,
866
- }, 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'
963
+ }, 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 }), icon && iconProp !== false && (jsx(DIcon, { icon: icon, familyClass: iconFamilyClass, familyPrefix: iconFamilyPrefix, materialStyle: iconMaterialStyle })), jsx("div", { className: "d-box-content", children: typeof children === 'function'
867
964
  ? children(openFileDialog)
868
- : 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} ${index}`))) }))] }));
965
+ : children || (jsx("p", { className: "text-center m-0", children: "Drag and drop some files here, or click to select files" })) })] })) })), !!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} ${index}`))) }))] }));
869
966
  }
870
967
 
871
- function DButton({ color = 'primary', size, variant, state, text = '', children, ariaLabel, iconStart, iconStartFamilyClass, iconStartFamilyPrefix, iconStartMaterialStyle, iconEnd, iconEndFamilyClass, iconEndFamilyPrefix, iconEndMaterialStyle, loadingText, value, type = 'button', loading = false, loadingAriaLabel, disabled = false, stopPropagationEnabled = true, className, style, form, dataAttributes, onClick, }) {
872
- const generateClasses = useMemo(() => {
968
+ const DButton = forwardRef((props, ref) => {
969
+ const { color = 'primary', size, variant, text, children, iconStart, iconStartFamilyClass, iconStartFamilyPrefix, iconStartMaterialStyle, iconEnd, iconEndFamilyClass, iconEndFamilyPrefix, iconEndMaterialStyle, loading = false, loadingText, loadingAriaLabel, disabled = false, className, style, dataAttributes, onClick, type = 'button' } = props, rest = __rest(props, ["color", "size", "variant", "text", "children", "iconStart", "iconStartFamilyClass", "iconStartFamilyPrefix", "iconStartMaterialStyle", "iconEnd", "iconEndFamilyClass", "iconEndFamilyPrefix", "iconEndMaterialStyle", "loading", "loadingText", "loadingAriaLabel", "disabled", "className", "style", "dataAttributes", "onClick", "type"]);
970
+ const [buttonWidth, setButtonWidth] = useState();
971
+ const buttonRef = useRef(null);
972
+ const isDisabled = useMemo(() => disabled || loading, [disabled, loading]);
973
+ const content = useMemo(() => children || text, [children, text]);
974
+ const classes = useMemo(() => {
873
975
  const variantClass = variant
874
976
  ? `btn-${variant}-${color}`
875
977
  : `btn-${color}`;
876
- return Object.assign(Object.assign(Object.assign({ btn: true, [variantClass]: true }, size && { [`btn-${size}`]: true }), (state && state !== 'disabled') && { [state]: true }), { loading });
877
- }, [variant, color, size, state, loading]);
878
- const clickHandler = useCallback((event) => {
879
- if (stopPropagationEnabled) {
880
- event.stopPropagation();
978
+ return {
979
+ btn: true,
980
+ [variantClass]: true,
981
+ [`btn-${size}`]: !!size,
982
+ loading,
983
+ };
984
+ }, [variant, color, size, loading]);
985
+ const ariaLabel = useMemo(() => {
986
+ const ariaLabelProp = rest['aria-label'];
987
+ return loading
988
+ ? loadingAriaLabel || ariaLabelProp || text
989
+ : ariaLabelProp || text;
990
+ }, [loading, loadingAriaLabel, rest, text]);
991
+ const handleClick = useCallback((event) => {
992
+ if (disabled || loading) {
993
+ event.preventDefault();
994
+ return;
881
995
  }
882
996
  onClick === null || onClick === void 0 ? void 0 : onClick(event);
883
- }, [stopPropagationEnabled, onClick]);
884
- const isDisabled = useMemo(() => (state === 'disabled' || loading || disabled), [state, loading, disabled]);
885
- const content = children || text;
886
- const newAriaLabel = useMemo(() => (loading
887
- ? (loadingAriaLabel || ariaLabel || text)
888
- : (ariaLabel || text)), [loading, loadingAriaLabel, ariaLabel, text]);
889
- return (jsxs("button", Object.assign({ className: classNames(generateClasses, className), style: style, type: type, disabled: isDisabled, onClick: clickHandler, "aria-label": newAriaLabel, form: form }, dataAttributes, value && { value }, { children: [iconStart && (jsx(DIcon, { icon: iconStart, familyClass: iconStartFamilyClass, familyPrefix: iconStartFamilyPrefix, materialStyle: iconStartMaterialStyle })), loading && (jsx("span", { className: "spinner-border spinner-border-sm", role: "status", "aria-hidden": "true", children: jsx("span", { className: "visually-hidden", children: "Loading..." }) })), jsx("span", { children: loading && loadingText ? loadingText : content }), iconEnd && (jsx(DIcon, { icon: iconEnd, familyClass: iconEndFamilyClass, familyPrefix: iconEndFamilyPrefix, materialStyle: iconEndMaterialStyle }))] })));
890
- }
997
+ }, [disabled, loading, onClick]);
998
+ useEffect(() => {
999
+ if (!loading && buttonRef.current) {
1000
+ const width = buttonRef.current.offsetWidth;
1001
+ if (width > 0)
1002
+ setButtonWidth(width);
1003
+ }
1004
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1005
+ }, [content, iconEnd, iconStart]);
1006
+ return (jsxs("button", Object.assign({ ref: (node) => {
1007
+ buttonRef.current = node;
1008
+ if (typeof ref === 'function')
1009
+ ref(node);
1010
+ // eslint-disable-next-line max-len
1011
+ // eslint-disable-next-line no-param-reassign, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
1012
+ else if (ref)
1013
+ ref.current = node;
1014
+ },
1015
+ // eslint-disable-next-line react/button-has-type
1016
+ type: type, className: classNames(classes, className), style: Object.assign(Object.assign({}, style), (loading && buttonWidth
1017
+ ? { minWidth: `${buttonWidth}px` }
1018
+ : undefined)), disabled: isDisabled, "aria-label": ariaLabel, "aria-busy": loading, "aria-disabled": isDisabled, onClick: handleClick }, dataAttributes, rest, { children: [loading && (jsxs("span", { className: "btn-loading", children: [jsx("span", { className: "spinner-border spinner-border-sm", "aria-hidden": "true" }), loadingText && jsx("span", { role: "status", children: loadingText })] })), !loading && (jsxs(Fragment, { children: [iconStart && (jsx(DIcon, { icon: iconStart, familyClass: iconStartFamilyClass, familyPrefix: iconStartFamilyPrefix, materialStyle: iconStartMaterialStyle })), content, iconEnd && (jsx(DIcon, { icon: iconEnd, familyClass: iconEndFamilyClass, familyPrefix: iconEndFamilyPrefix, materialStyle: iconEndMaterialStyle }))] }))] })));
1019
+ });
1020
+ DButton.displayName = 'DButton';
891
1021
 
892
1022
  function DButtonIcon({ id, icon, size, className, variant, state, loadingAriaLabel, iconMaterialStyle, ariaLabel, color = 'primary', type = 'button', loading = false, disabled = false, stopPropagationEnabled = true, style, iconFamilyClass, iconFamilyPrefix, dataAttributes, onClick, }) {
893
1023
  const generateClasses = useMemo(() => {
@@ -977,6 +1107,9 @@ function DCollapse({ id, className, style, Component, hasSeparator = false, defa
977
1107
  return next;
978
1108
  });
979
1109
  };
1110
+ useEffect(() => {
1111
+ setCollapsed(defaultCollapsed);
1112
+ }, [defaultCollapsed]);
980
1113
  const { iconMap: { chevronDown, chevronUp, }, } = useDContext();
981
1114
  const iconOpen = useMemo(() => iconOpenProp || chevronDown, [chevronDown, iconOpenProp]);
982
1115
  const iconClose = useMemo(() => iconCloseProp || chevronUp, [chevronUp, iconCloseProp]);
@@ -1022,7 +1155,7 @@ const ForwardedDDatePickerInput = forwardRef(DDatePickerInput);
1022
1155
  ForwardedDDatePickerInput.displayName = 'DDatePickerInput';
1023
1156
 
1024
1157
  function DInputCheck(_a) {
1025
- var { id: idProp, type, name, label, ariaLabel, checked = false, disabled = false, invalid = false, valid = false, indeterminate, value, hint, onChange, className, style, dataAttributes } = _a, props = __rest(_a, ["id", "type", "name", "label", "ariaLabel", "checked", "disabled", "invalid", "valid", "indeterminate", "value", "hint", "onChange", "className", "style", "dataAttributes"]);
1158
+ var { id: idProp, type, name, label, ariaLabel, checked = false, disabled = false, invalid = false, valid = false, indeterminate, inputClassName, value, hint, onChange, className, style, dataAttributes } = _a, props = __rest(_a, ["id", "type", "name", "label", "ariaLabel", "checked", "disabled", "invalid", "valid", "indeterminate", "inputClassName", "value", "hint", "onChange", "className", "style", "dataAttributes"]);
1026
1159
  const innerRef = useRef(null);
1027
1160
  const innerId = useId();
1028
1161
  const id = useMemo(() => idProp || innerId, [idProp, innerId]);
@@ -1050,11 +1183,11 @@ function DInputCheck(_a) {
1050
1183
  const inputComponent = useMemo(() => (jsx("input", Object.assign({ ref: innerRef, onChange: handleChange, className: classNames('form-check-input', {
1051
1184
  'is-invalid': invalid,
1052
1185
  'is-valid': valid,
1053
- }, className), style: style, id: id, disabled: disabled, type: type, name: name, value: value, "aria-label": ariaLabel }, ariaDescribedby && { 'aria-describedby': ariaDescribedby }, props))), [
1186
+ }, inputClassName), style: style, id: id, disabled: disabled, type: type, name: name, value: value, "aria-label": ariaLabel }, ariaDescribedby && { 'aria-describedby': ariaDescribedby }, props))), [
1054
1187
  handleChange,
1055
1188
  invalid,
1056
1189
  valid,
1057
- className,
1190
+ inputClassName,
1058
1191
  style,
1059
1192
  id,
1060
1193
  disabled,
@@ -1068,7 +1201,7 @@ function DInputCheck(_a) {
1068
1201
  if (!label) {
1069
1202
  return inputComponent;
1070
1203
  }
1071
- return (jsxs("div", Object.assign({ className: "form-check" }, dataAttributes, { children: [inputComponent, jsx("label", { className: "form-check-label", htmlFor: id, children: label }), hint && (jsx("div", { className: "form-text", id: `${id}Hint`, children: hint }))] })));
1204
+ return (jsxs("div", Object.assign({ className: classNames('form-check', className) }, dataAttributes, { children: [inputComponent, jsx("label", { className: "form-check-label", htmlFor: id, children: label }), hint && (jsx("div", { className: "form-text", id: `${id}Hint`, children: hint }))] })));
1072
1205
  }
1073
1206
 
1074
1207
  function DSelectOptionCheck(_a) {
@@ -1193,7 +1326,7 @@ var PickerType;
1193
1326
  PickerType["Month"] = "month";
1194
1327
  PickerType["Year"] = "year";
1195
1328
  })(PickerType || (PickerType = {}));
1196
- function DDatePickerHeaderSelector({ date, changeYear, changeMonth, decreaseMonth, increaseMonth, decreaseYear, increaseYear, monthDate, pickerType, prevMonthButtonDisabled, nextMonthButtonDisabled, monthsShown = 1, iconPrev, iconNext, prevYearButtonDisabled, nextYearButtonDisabled, prevMonthAriaLabel = 'decrease month', nextMonthAriaLabel = 'increase month', prevYearAriaLabel = 'decrease year', nextYearAriaLabel = 'increase year', iconSize, style, className, minYearSelect = 1900, maxYearSelect = 2100, showHeaderSelectors = false, customHeaderCount, locale, }) {
1329
+ function DDatePickerHeaderSelector({ date, changeYear, changeMonth, decreaseMonth, increaseMonth, decreaseYear, increaseYear, monthDate, formatHeaderDate = 'EE, LLLL d', pickerType, prevMonthButtonDisabled, nextMonthButtonDisabled, monthsShown = 1, iconPrev, iconNext, prevYearButtonDisabled, nextYearButtonDisabled, prevMonthAriaLabel = 'decrease month', nextMonthAriaLabel = 'increase month', prevYearAriaLabel = 'decrease year', nextYearAriaLabel = 'increase year', iconSize, style, className, minYearSelect = 1900, maxYearSelect = 2100, showHeaderSelectors = false, customHeaderCount, locale, }) {
1197
1330
  const { iconMap: { chevronLeft, chevronRight, }, } = useDContext();
1198
1331
  const arrayYears = useMemo(() => Array.from({ length: maxYearSelect - minYearSelect + 1 }, (_, index) => minYearSelect + index), [maxYearSelect, minYearSelect]);
1199
1332
  const years = useMemo(() => arrayYears.map((year) => ({
@@ -1223,11 +1356,11 @@ function DDatePickerHeaderSelector({ date, changeYear, changeMonth, decreaseMont
1223
1356
  if (pickerType === PickerType.Quarter || pickerType === PickerType.Month) {
1224
1357
  return (jsxs("div", { className: classNames(`react-datepicker__header-selector react-datepicker__header-${pickerType}-selector`, className), style: style, children: [jsx(DButtonIcon, { icon: iconPrev || chevronLeft, size: iconSize, variant: "link", 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(DButtonIcon, { icon: iconNext || chevronRight, size: iconSize, variant: "link", onClick: increaseYear, disabled: nextMonthButtonDisabled, ariaLabel: nextMonthAriaLabel, className: "header-button", style: { visibility: customHeaderCount === monthsShown - 1 ? 'visible' : 'hidden' } })] }));
1225
1358
  }
1226
- return (jsxs(Fragment$1, { children: [jsxs("div", { className: "datepicker-top-header", children: [showHeaderSelectors && (jsx("select", { value: defaultYear === null || defaultYear === void 0 ? void 0 : defaultYear.value, onChange: (e) => changeYear(Number(e.target.value)), className: "custom-year-selector", children: years.map((year) => (jsx("option", { value: year.value, children: year.label }, year.value))) })), jsx("h4", { className: "mb-0 fw-normal", children: format(monthDate, 'LLLL, dd', { locale }) })] }), jsxs("div", { className: classNames('react-datepicker__header-selector react-datepicker__header-day-selector', className), style: style, children: [jsx(DButtonIcon, { icon: iconPrev || chevronLeft, size: iconSize, variant: "link", onClick: decreaseMonth, disabled: prevMonthButtonDisabled, ariaLabel: prevMonthAriaLabel, className: "header-button", style: { visibility: customHeaderCount === 0 ? 'visible' : 'hidden' } }), showHeaderSelectors ? (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("p", { children: `${defaultMonth.label} ${defaultYear === null || defaultYear === void 0 ? void 0 : defaultYear.label}` })), jsx(DButtonIcon, { icon: iconNext || chevronRight, size: iconSize, variant: "link", onClick: increaseMonth, disabled: nextMonthButtonDisabled, ariaLabel: nextMonthAriaLabel, className: "header-button", style: { visibility: customHeaderCount === monthsShown - 1 ? 'visible' : 'hidden' } })] })] }));
1359
+ return (jsxs(Fragment, { children: [jsxs("div", { className: "datepicker-top-header", 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, className: "custom-year-selector" })), jsx("h4", { className: "mb-0 fw-normal", children: format(monthDate, formatHeaderDate, { locale }) })] }), jsxs("div", { className: classNames('react-datepicker__header-selector react-datepicker__header-day-selector', className), style: style, children: [jsx(DButtonIcon, { icon: iconPrev || chevronLeft, size: iconSize, variant: "link", onClick: decreaseMonth, disabled: prevMonthButtonDisabled, ariaLabel: prevMonthAriaLabel, className: "header-button", style: { visibility: customHeaderCount === 0 ? 'visible' : 'hidden' } }), showHeaderSelectors ? (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("p", { children: `${defaultMonth.label} ${defaultYear === null || defaultYear === void 0 ? void 0 : defaultYear.label}` })), jsx(DButtonIcon, { icon: iconNext || chevronRight, size: iconSize, variant: "link", onClick: increaseMonth, disabled: nextMonthButtonDisabled, ariaLabel: nextMonthAriaLabel, className: "header-button", style: { visibility: customHeaderCount === monthsShown - 1 ? 'visible' : 'hidden' } })] })] }));
1227
1360
  }
1228
1361
 
1229
1362
  function DDatePicker(_a) {
1230
- var { inputLabel, inputHint, inputAriaLabel, inputActionAriaLabel = 'open calendar', inputId = 'input-calendar', timeId = 'input-time', timeInputLabel, minYearSelect, maxYearSelect, iconHeaderSize, iconMaterialStyle, iconInput, headerPrevMonthAriaLabel, headerNextMonthAriaLabel, invalid = false, valid = false, renderCustomHeader: renderCustomHeaderProp, className, dateFormatCalendar: dateFormatCalendarProp, style, dataAttributes, placeholder, showHeaderSelectors } = _a, props = __rest(_a, ["inputLabel", "inputHint", "inputAriaLabel", "inputActionAriaLabel", "inputId", "timeId", "timeInputLabel", "minYearSelect", "maxYearSelect", "iconHeaderSize", "iconMaterialStyle", "iconInput", "headerPrevMonthAriaLabel", "headerNextMonthAriaLabel", "invalid", "valid", "renderCustomHeader", "className", "dateFormatCalendar", "style", "dataAttributes", "placeholder", "showHeaderSelectors"]);
1363
+ var { inputLabel, inputHint, inputAriaLabel, inputActionAriaLabel = 'open calendar', inputId = 'input-calendar', timeId = 'input-time', timeInputLabel, minYearSelect, maxYearSelect, iconHeaderSize, iconMaterialStyle, iconInput, headerPrevMonthAriaLabel, headerNextMonthAriaLabel, invalid = false, valid = false, renderCustomHeader: renderCustomHeaderProp, className, dateFormatCalendar: dateFormatCalendarProp, style, dataAttributes, placeholder, showHeaderSelectors, formatHeaderDate } = _a, props = __rest(_a, ["inputLabel", "inputHint", "inputAriaLabel", "inputActionAriaLabel", "inputId", "timeId", "timeInputLabel", "minYearSelect", "maxYearSelect", "iconHeaderSize", "iconMaterialStyle", "iconInput", "headerPrevMonthAriaLabel", "headerNextMonthAriaLabel", "invalid", "valid", "renderCustomHeader", "className", "dateFormatCalendar", "style", "dataAttributes", "placeholder", "showHeaderSelectors", "formatHeaderDate"]);
1231
1364
  const pickerType = useMemo(() => {
1232
1365
  if (props.showQuarterYearPicker)
1233
1366
  return PickerType.Quarter;
@@ -1241,7 +1374,7 @@ function DDatePicker(_a) {
1241
1374
  props.showMonthYearPicker,
1242
1375
  props.showYearPicker,
1243
1376
  ]);
1244
- const DatePickerHeader = useCallback((headerProps) => (jsx(DDatePickerHeaderSelector, Object.assign({}, headerProps, { monthsShown: props.monthsShown, prevMonthAriaLabel: headerPrevMonthAriaLabel, nextMonthAriaLabel: headerNextMonthAriaLabel, iconSize: iconHeaderSize, minYearSelect: minYearSelect, maxYearSelect: maxYearSelect, pickerType: pickerType, showHeaderSelectors: showHeaderSelectors, locale: props.locale }))), [
1377
+ const DatePickerHeader = useCallback((headerProps) => (jsx(DDatePickerHeaderSelector, Object.assign({}, headerProps, { monthsShown: props.monthsShown, prevMonthAriaLabel: headerPrevMonthAriaLabel, nextMonthAriaLabel: headerNextMonthAriaLabel, iconSize: iconHeaderSize, minYearSelect: minYearSelect, maxYearSelect: maxYearSelect, pickerType: pickerType, showHeaderSelectors: showHeaderSelectors, formatHeaderDate: formatHeaderDate, locale: props.locale }))), [
1245
1378
  headerPrevMonthAriaLabel,
1246
1379
  headerNextMonthAriaLabel,
1247
1380
  iconHeaderSize,
@@ -1249,6 +1382,7 @@ function DDatePicker(_a) {
1249
1382
  maxYearSelect,
1250
1383
  pickerType,
1251
1384
  showHeaderSelectors,
1385
+ formatHeaderDate,
1252
1386
  props.monthsShown,
1253
1387
  props.locale,
1254
1388
  ]);
@@ -1268,9 +1402,17 @@ function DLayoutPane({ className, style, children, cols, colsXs, colsSm, colsMd,
1268
1402
  return (jsx("div", Object.assign({ className: classNames(colsClass, colsXsClass, colsSmClass, colsMdClass, colsLgClass, colsXlClass, colsXxlClass, className), style: style }, dataAttributes, { children: children })));
1269
1403
  }
1270
1404
 
1271
- function DLayout({ className, style, children, gap, dataAttributes, }) {
1272
- const gapClass = gap !== undefined ? `gap-${gap}` : undefined;
1273
- return (jsx("div", Object.assign({ style: style, className: classNames('grid', gapClass, className) }, dataAttributes, { children: children })));
1405
+ function DLayout({ className, style, children, gap, columns, gapSm, gapMd, gapLg, gapXl, gapXxl, dataAttributes, }) {
1406
+ const gapClasses = classNames({
1407
+ [`gap-${gap}`]: gap !== undefined,
1408
+ [`gap-sm-${gapSm}`]: gapSm !== undefined,
1409
+ [`gap-md-${gapMd}`]: gapMd !== undefined,
1410
+ [`gap-lg-${gapLg}`]: gapLg !== undefined,
1411
+ [`gap-xl-${gapXl}`]: gapXl !== undefined,
1412
+ [`gap-xxl-${gapXxl}`]: gapXxl !== undefined,
1413
+ });
1414
+ const styleWithColumns = Object.assign(Object.assign({}, style), { '--bs-columns': columns });
1415
+ return (jsx("div", Object.assign({ style: styleWithColumns, className: classNames('grid', gapClasses, className) }, dataAttributes, { children: children })));
1274
1416
  }
1275
1417
  var DLayout$1 = Object.assign(DLayout, {
1276
1418
  Pane: DLayoutPane,
@@ -1380,47 +1522,6 @@ function useItemSelection({ getItemIdentifier: getItemIdentifierProp, previousSe
1380
1522
  };
1381
1523
  }
1382
1524
 
1383
- function subscribeToMediaQuery(query, callback) {
1384
- const mediaQueryList = window.matchMedia(query);
1385
- mediaQueryList.addEventListener('change', callback);
1386
- return () => {
1387
- mediaQueryList.removeEventListener('change', callback);
1388
- };
1389
- }
1390
- function checkMediaQuery(query) {
1391
- return window.matchMedia(query).matches;
1392
- }
1393
-
1394
- function useMediaQuery(mediaQuery, useListener = false) {
1395
- /* eslint-disable-next-line @typescript-eslint/no-unused-vars */
1396
- const noop = (_) => () => { };
1397
- return useSyncExternalStore(useListener ? (cb) => subscribeToMediaQuery(mediaQuery, cb) : noop, () => (mediaQuery ? checkMediaQuery(mediaQuery) : true), () => false);
1398
- }
1399
-
1400
- function useMediaBreakpointUp(breakpoint, useListener = false) {
1401
- const { breakpoints } = useDContext();
1402
- const mediaQuery = useMemo(() => (`(min-width: ${breakpoints[breakpoint]})`), [breakpoint, breakpoints]);
1403
- return useMediaQuery(mediaQuery, useListener);
1404
- }
1405
- function useMediaBreakpointUpXs(useListener = false) {
1406
- return useMediaBreakpointUp('xs', useListener);
1407
- }
1408
- function useMediaBreakpointUpSm(useListener = false) {
1409
- return useMediaBreakpointUp('sm', useListener);
1410
- }
1411
- function useMediaBreakpointUpMd(useListener = false) {
1412
- return useMediaBreakpointUp('md', useListener);
1413
- }
1414
- function useMediaBreakpointUpLg(useListener = false) {
1415
- return useMediaBreakpointUp('lg', useListener);
1416
- }
1417
- function useMediaBreakpointUpXl(useListener = false) {
1418
- return useMediaBreakpointUp('xl', useListener);
1419
- }
1420
- function useMediaBreakpointUpXxl(useListener = false) {
1421
- return useMediaBreakpointUp('xxl', useListener);
1422
- }
1423
-
1424
1525
  function DInputCounter(_a, ref) {
1425
1526
  var { minValue, maxValue, value = minValue, invalid, iconStart: iconStartProp, iconEnd: iconEndProp, iconStartAriaLabel = 'decrease action', iconEndAriaLabel = 'increase action', style, onChange } = _a, props = __rest(_a, ["minValue", "maxValue", "value", "invalid", "iconStart", "iconEnd", "iconStartAriaLabel", "iconEndAriaLabel", "style", "onChange"]);
1426
1527
  const { handleOnWheel, } = useDisableInputWheel(ref);
@@ -1484,6 +1585,86 @@ function DInputPassword(_a, ref) {
1484
1585
  const ForwardedDInputPassword = forwardRef(DInputPassword);
1485
1586
  ForwardedDInputPassword.displayName = 'DInputPassword';
1486
1587
 
1588
+ function PasswordCheckItem({ password, regex, text, }) {
1589
+ const isValid = regex.test(password);
1590
+ return (jsxs("li", { className: "d-flex gap-2 align-items-start small text-gray-600", children: [jsx(DIcon, { className: classNames('flex-shrink-0', isValid ? 'text-success' : 'text-gray-300'), icon: isValid ? 'CircleCheck' : 'Circle', size: "16px" }), jsx("span", { className: classNames({ 'text-success': isValid }), children: text })] }));
1591
+ }
1592
+
1593
+ const getColorClass = (strength, total) => {
1594
+ const percentage = total > 0 ? strength / total : 0;
1595
+ if (percentage === 0)
1596
+ return 'bg-gray-200';
1597
+ if (percentage <= 0.25)
1598
+ return 'bg-danger';
1599
+ if (percentage <= 0.5)
1600
+ return 'bg-warning';
1601
+ if (percentage <= 0.75)
1602
+ return 'bg-info';
1603
+ return 'bg-success';
1604
+ };
1605
+ function PasswordStrengthBar({ strength, total }) {
1606
+ const percentage = total > 0 ? (strength / total) * 100 : 0;
1607
+ return (jsx("div", { className: "w-100 rounded-3 overflow-hidden bg-gray-100 mb-2", style: { height: '8px' }, children: jsx("div", { className: `h-100 ${getColorClass(strength, total)}`, style: {
1608
+ width: `${percentage}%`,
1609
+ transition: 'width 0.3s ease-in-out',
1610
+ } }) }));
1611
+ }
1612
+
1613
+ const CHECK_REGEX = {
1614
+ uppercase: /[A-Z]/,
1615
+ lowercase: /[a-z]/,
1616
+ number: /\d/,
1617
+ specialChar: /[~!@#$^*\-_=[\]{}|;,.?]/,
1618
+ };
1619
+ function PasswordChecksList({ password, validationMessages, enabledChecks, }) {
1620
+ const allChecks = [
1621
+ {
1622
+ key: 'uppercase',
1623
+ regex: CHECK_REGEX.uppercase,
1624
+ text: validationMessages.uppercaseLetter,
1625
+ },
1626
+ {
1627
+ key: 'lowercase',
1628
+ regex: CHECK_REGEX.lowercase,
1629
+ text: validationMessages.lowercaseLetter,
1630
+ },
1631
+ {
1632
+ key: 'number',
1633
+ regex: CHECK_REGEX.number,
1634
+ text: validationMessages.number,
1635
+ },
1636
+ {
1637
+ key: 'specialChar',
1638
+ regex: CHECK_REGEX.specialChar,
1639
+ text: validationMessages.especialChar,
1640
+ },
1641
+ ];
1642
+ const passwordChecks = allChecks.filter((check) => enabledChecks.includes(check.key));
1643
+ const passed = passwordChecks.filter((r) => r.regex.test(password)).length;
1644
+ const total = passwordChecks.length;
1645
+ return (jsxs("div", { className: "mt-2", children: [jsx(PasswordStrengthBar, { strength: passed, total: total }), jsx("ul", { className: "list-unstyled m-0 d-flex flex-column gap-2", children: passwordChecks.map(({ key, regex, text }) => (jsx(PasswordCheckItem, { password: password, regex: regex, text: text }, key))) })] }));
1646
+ }
1647
+
1648
+ const DEFAULT_VALIDATION_MESSAGES = {
1649
+ number: 'At least one number',
1650
+ lowercaseLetter: 'At least one lowercase letter',
1651
+ uppercaseLetter: 'At least one uppercase letter',
1652
+ especialChar: 'At least one of these special characters: ~!@#$^*-_=[]{}|;,.?',
1653
+ notMatch: 'The password confirmation and the new password do not match.',
1654
+ };
1655
+ const DEFAULT_ENABLED_CHECKS = ['uppercase', 'lowercase', 'number', 'specialChar'];
1656
+ function DPasswordStrengthMeter({ id, label = 'Password', placeholder, value = '', name, disabled = false, invalid = false, validationMessages = DEFAULT_VALIDATION_MESSAGES, enabledChecks = DEFAULT_ENABLED_CHECKS, className, style, dataAttributes, onChange, }) {
1657
+ const [password, setPassword] = useState(value);
1658
+ useEffect(() => {
1659
+ setPassword(value);
1660
+ }, [value]);
1661
+ const handleChange = (newValue) => {
1662
+ setPassword(newValue);
1663
+ onChange === null || onChange === void 0 ? void 0 : onChange(newValue);
1664
+ };
1665
+ return (jsxs("div", Object.assign({ className: className, style: style }, dataAttributes, { children: [jsx(ForwardedDInputPassword, { id: id, label: label, placeholder: placeholder, value: password, name: name, disabled: disabled, invalid: invalid, onChange: handleChange }), jsx(PasswordChecksList, { password: password, validationMessages: validationMessages, enabledChecks: enabledChecks })] })));
1666
+ }
1667
+
1487
1668
  function DInputPin({ id: idProp, label = '', placeholder, type = 'text', disabled = false, loading = false, secret = false, characters = 4, innerInputMode = 'text', hint, invalid = false, valid = false, className, style, dataAttributes, onChange, }) {
1488
1669
  const innerId = useId();
1489
1670
  const id = useMemo(() => idProp || innerId, [idProp, innerId]);
@@ -1647,7 +1828,7 @@ function DInputSelect({ id: idProp, name, label = '', className, style, options
1647
1828
  }), children: [iconStart && (jsx("button", { type: "button", className: "input-group-text", id: `${id}Start`, onClick: iconStartClickHandler, disabled: disabled || loading, "aria-label": iconStartAriaLabel, children: iconStart && (jsx(DIcon, { icon: iconStart, familyClass: iconStartFamilyClass, familyPrefix: iconStartFamilyPrefix })) })), dynamicComponent, iconEnd && !loading && (jsx("button", { type: "button", className: "input-group-text", id: `${id}End`, onClick: iconEndClickHandler, disabled: disabled || loading, "aria-label": iconEndAriaLabel, children: iconEnd && (jsx(DIcon, { icon: iconEnd, familyClass: iconEndFamilyClass, familyPrefix: iconEndFamilyPrefix })) })), loading && (jsx("div", { className: "input-group-text form-control-icon loading", children: jsx("span", { className: "spinner-border spinner-border-sm", role: "status", "aria-hidden": "true", children: jsx("span", { className: "visually-hidden", children: "Loading..." }) }) }))] }), hint && (jsx("div", { className: "form-text", id: `${id}Hint`, children: hint }))] })));
1648
1829
  }
1649
1830
 
1650
- function DInputSwitch({ id: idProp, label, ariaLabel, name, checked, disabled, invalid = false, valid = false, readonly, className, style, dataAttributes, onChange, }) {
1831
+ function DInputSwitch({ id: idProp, label, ariaLabel, name, checked, disabled, invalid = false, valid = false, readonly, className, style, dataAttributes, inputClassName, onChange, }) {
1651
1832
  const innerId = useId();
1652
1833
  const id = useMemo(() => idProp || innerId, [idProp, innerId]);
1653
1834
  const [internalIsChecked, setInternalIsChecked] = useState(checked);
@@ -1659,10 +1840,10 @@ function DInputSwitch({ id: idProp, label, ariaLabel, name, checked, disabled, i
1659
1840
  setInternalIsChecked(value);
1660
1841
  onChange === null || onChange === void 0 ? void 0 : onChange(value);
1661
1842
  }, [onChange]);
1662
- return (jsxs("div", Object.assign({ className: "form-check form-switch" }, dataAttributes, { children: [jsx("input", { id: id, name: name, onChange: readonly ? () => false : changeHandler, className: classNames('form-check-input', {
1843
+ return (jsxs("div", Object.assign({ className: classNames('form-check form-switch', className) }, dataAttributes, { children: [jsx("input", { id: id, name: name, onChange: readonly ? () => false : changeHandler, className: classNames('form-check-input', {
1663
1844
  'is-invalid': invalid,
1664
1845
  'is-valid': valid,
1665
- }, className), style: style, type: "checkbox", role: "switch", checked: internalIsChecked, disabled: disabled, "aria-label": ariaLabel }), label && (jsx("label", { className: "form-check-label", htmlFor: id, children: label }))] })));
1846
+ }, inputClassName), style: style, type: "checkbox", role: "switch", checked: internalIsChecked, disabled: disabled, "aria-label": ariaLabel }), label && (jsx("label", { className: "form-check-label", htmlFor: id, children: label }))] })));
1666
1847
  }
1667
1848
 
1668
1849
  function DInputRange(_a, ref) {
@@ -1697,7 +1878,7 @@ function DInputRange(_a, ref) {
1697
1878
  if (!label) {
1698
1879
  return inputComponent;
1699
1880
  }
1700
- return (jsxs(Fragment$1, { children: [jsx("label", { className: "form-label", htmlFor: id, children: label }), inputComponent] }));
1881
+ return (jsxs(Fragment, { children: [jsx("label", { className: "form-label", htmlFor: id, children: label }), inputComponent] }));
1701
1882
  }
1702
1883
  const ForwardedDInputRange = forwardRef(DInputRange);
1703
1884
  ForwardedDInputRange.displayName = 'DInputRange';
@@ -1731,7 +1912,7 @@ function DListGroupItem({ as = 'li', action: actionProp, active, disabled, href,
1731
1912
  }
1732
1913
  return Object.assign(Object.assign({}, active && { 'aria-current': true }), disabled && { 'aria-disabled': true });
1733
1914
  }, [Tag, active, disabled]);
1734
- return (jsxs(Tag, Object.assign({ className: classNames(generateClasses, className), style: style }, Tag === 'a' && href && { href }, onClick && { onClick }, ariaAttributes, dataAttributes, Tag === 'button' && { type: 'button' }, { children: [iconStart && (jsx(DIcon, { icon: iconStart, familyClass: iconStartFamilyClass, familyPrefix: iconStartFamilyPrefix, materialStyle: iconStartMaterialStyle })), jsx("div", { className: "w-100", children: children }), iconEnd && (jsx(DIcon, { icon: iconEnd, familyClass: iconEndFamilyClass, familyPrefix: iconEndFamilyPrefix, materialStyle: iconEndMaterialStyle, className: "ms-auto" }))] })));
1915
+ return (jsxs(Tag, Object.assign({ className: classNames(generateClasses, className), style: style }, Tag === 'a' && href && { href }, onClick && { onClick }, ariaAttributes, dataAttributes, Tag === 'button' && { type: 'button' }, { children: [iconStart && (jsx(DIcon, { icon: iconStart, familyClass: iconStartFamilyClass, familyPrefix: iconStartFamilyPrefix, materialStyle: iconStartMaterialStyle })), children, iconEnd && (jsx(DIcon, { icon: iconEnd, familyClass: iconEndFamilyClass, familyPrefix: iconEndFamilyPrefix, materialStyle: iconEndMaterialStyle, className: "ms-auto" }))] })));
1735
1916
  }
1736
1917
 
1737
1918
  function DListGroup({ as = 'ul', numbered, flush, horizontal, children, className, style, dataAttributes, }) {
@@ -1761,7 +1942,7 @@ var DListGroup$1 = Object.assign(DListGroup, {
1761
1942
  function DModalHeader({ showCloseButton, onClose, children, className, style, iconFamilyClass, iconFamilyPrefix, icon: iconProp, materialStyle = false, }) {
1762
1943
  const { iconMap: { xLg, }, } = useDContext();
1763
1944
  const icon = useMemo(() => iconProp || xLg, [iconProp, xLg]);
1764
- return (jsxs(Fragment$1, { children: [jsxs("div", { className: classNames('modal-header', className), style: style, children: [jsx("div", { children: children }), showCloseButton && (jsx("button", { type: "button", className: "d-close align-self-center", "aria-label": "Close", onClick: onClose, children: jsx(DIcon, { icon: icon, familyClass: iconFamilyClass, familyPrefix: iconFamilyPrefix, materialStyle: materialStyle }) }))] }), jsx("div", { className: "d-modal-separator" })] }));
1945
+ return (jsxs(Fragment, { children: [jsxs("div", { className: classNames('modal-header', className), style: style, children: [jsx("div", { children: children }), showCloseButton && (jsx("button", { type: "button", className: "d-close align-self-center", "aria-label": "Close", onClick: onClose, children: jsx(DIcon, { icon: icon, familyClass: iconFamilyClass, familyPrefix: iconFamilyPrefix, materialStyle: materialStyle }) }))] }), jsx("div", { className: "d-modal-separator" })] }));
1765
1946
  }
1766
1947
 
1767
1948
  function DModalBody({ children, className, style, }) {
@@ -1773,10 +1954,14 @@ function DModalFooter({ className, style, actionPlacement, children, }) {
1773
1954
  'modal-footer': true,
1774
1955
  [`d-modal-action-${actionPlacement}`]: !!actionPlacement,
1775
1956
  }), [actionPlacement]);
1776
- return (jsxs(Fragment$1, { children: [jsx("div", { className: "d-modal-separator" }), jsx("div", { className: classNames(generateClasses, className), style: style, children: children })] }));
1957
+ return (jsxs(Fragment, { children: [jsx("div", { className: "d-modal-separator" }), jsx("div", { className: classNames(generateClasses, className), style: style, children: children })] }));
1777
1958
  }
1778
1959
 
1779
- function DModal({ name, className, style, staticBackdrop, scrollable, centered, fullScreen, fullScreenFrom, size, children, dataAttributes, }) {
1960
+ const defaultTransition$1 = {
1961
+ ease: 'easeInOut',
1962
+ duration: 0.3,
1963
+ };
1964
+ function DModal({ name, className, style, staticBackdrop, scrollable, centered, fullScreen, fullScreenFrom, size, transition, children, dataAttributes, }) {
1780
1965
  const fullScreenClass = useMemo(() => {
1781
1966
  if (fullScreen) {
1782
1967
  if (fullScreenFrom) {
@@ -1787,7 +1972,7 @@ function DModal({ name, className, style, staticBackdrop, scrollable, centered,
1787
1972
  return '';
1788
1973
  }, [fullScreenFrom, fullScreen]);
1789
1974
  const generateModalDialogClasses = useMemo(() => (Object.assign({ 'modal-dialog': true, 'modal-dialog-centered': !!centered, 'modal-dialog-scrollable': !!scrollable, [fullScreenClass]: !!fullScreen }, size && { [`modal-${size}`]: true })), [fullScreenClass, centered, fullScreen, scrollable, size]);
1790
- return (jsx("div", Object.assign({ className: classNames('modal portal fade show', className), id: name, tabIndex: -1, "aria-labelledby": `${name}Label`, "aria-hidden": "false", style: style }, staticBackdrop && ({
1975
+ return (jsx(motion.div, Object.assign({ className: classNames('modal portal show', className), id: name, tabIndex: -1, "aria-labelledby": `${name}Label`, "aria-hidden": "false", style: style, initial: { opacity: 0, scale: 0.95 }, animate: { opacity: 1, scale: 1 }, exit: { opacity: 0, scale: 0.95 }, transition: Object.assign(Object.assign({}, (transition !== null && transition !== void 0 ? transition : defaultTransition$1)), { delay: 0.15 }) }, staticBackdrop && ({
1791
1976
  [`data-${PREFIX_BS}backdrop`]: 'static',
1792
1977
  [`data-${PREFIX_BS}keyboard`]: 'false',
1793
1978
  }), dataAttributes, { children: jsx("div", { className: classNames(generateModalDialogClasses), children: jsx("div", { className: "modal-content", children: children }) }) })));
@@ -1801,7 +1986,7 @@ var DModal$1 = Object.assign(DModal, {
1801
1986
  function DOffcanvasHeader({ showCloseButton, onClose, children, className, style, iconFamilyClass, iconFamilyPrefix, icon: iconProp, materialStyle = false, }) {
1802
1987
  const { iconMap: { xLg, }, } = useDContext();
1803
1988
  const icon = useMemo(() => iconProp || xLg, [iconProp, xLg]);
1804
- return (jsxs(Fragment$1, { children: [jsxs("div", { className: classNames('offcanvas-header', className), style: style, children: [jsx("div", { children: children }), showCloseButton && (jsx("button", { type: "button", className: "d-close align-self-center", "aria-label": "Close", onClick: onClose, children: jsx(DIcon, { icon: icon, familyClass: iconFamilyClass, familyPrefix: iconFamilyPrefix, materialStyle: materialStyle }) }))] }), jsx("div", { className: "d-offcanvas-separator" })] }));
1989
+ return (jsxs(Fragment, { children: [jsxs("div", { className: classNames('offcanvas-header', className), style: style, children: [jsx("div", { children: children }), showCloseButton && (jsx("button", { type: "button", className: "d-close align-self-center", "aria-label": "Close", onClick: onClose, children: jsx(DIcon, { icon: icon, familyClass: iconFamilyClass, familyPrefix: iconFamilyPrefix, materialStyle: materialStyle }) }))] }), jsx("div", { className: "d-offcanvas-separator" })] }));
1805
1990
  }
1806
1991
 
1807
1992
  function DOffcanvasBody({ children, className, style, }) {
@@ -1813,13 +1998,39 @@ function DOffcanvasFooter({ actionPlacement, children, className, style, }) {
1813
1998
  'd-offcanvas-footer': true,
1814
1999
  [`d-offcanvas-action-${actionPlacement}`]: !!actionPlacement,
1815
2000
  }), [actionPlacement]);
1816
- return (jsxs(Fragment$1, { children: [jsx("div", { className: "d-offcanvas-separator" }), jsx("div", { className: classNames(generateClasses, className), style: style, children: children })] }));
2001
+ return (jsxs(Fragment, { children: [jsx("div", { className: "d-offcanvas-separator" }), jsx("div", { className: classNames(generateClasses, className), style: style, children: children })] }));
1817
2002
  }
1818
2003
 
1819
- function DOffcanvas({ name, className, style, staticBackdrop, scrollable, openFrom = 'end', children, dataAttributes, }) {
1820
- return (jsx("div", Object.assign({ className: classNames('offcanvas portal show', {
2004
+ const variants = {
2005
+ hidden: (openFrom) => {
2006
+ const properties = {};
2007
+ if (openFrom === 'start') {
2008
+ properties.x = '-100%';
2009
+ }
2010
+ if (openFrom === 'end') {
2011
+ properties.x = '100%';
2012
+ }
2013
+ if (openFrom === 'top') {
2014
+ properties.y = '-100%';
2015
+ }
2016
+ if (openFrom === 'bottom') {
2017
+ properties.y = '100%';
2018
+ }
2019
+ return properties;
2020
+ },
2021
+ visible: {
2022
+ x: 0,
2023
+ y: 0,
2024
+ },
2025
+ };
2026
+ const defaultTransition = {
2027
+ ease: 'easeInOut',
2028
+ duration: 0.3,
2029
+ };
2030
+ function DOffcanvas({ name, className, style, staticBackdrop, scrollable, openFrom = 'end', transition, children, dataAttributes, }) {
2031
+ return (jsx(motion.div, Object.assign({ className: classNames('offcanvas portal show', {
1821
2032
  [`offcanvas-${openFrom}`]: openFrom,
1822
- }, className), style: style, id: name, tabIndex: -1, "aria-labelledby": `${name}Label`, "aria-hidden": "false" }, staticBackdrop && ({
2033
+ }, className), style: Object.assign(Object.assign({}, style), { transition: 'none' }), id: name, tabIndex: -1, "aria-labelledby": `${name}Label`, "aria-hidden": "false", custom: openFrom, variants: variants, initial: "hidden", animate: "visible", exit: "hidden", transition: Object.assign(Object.assign({}, (transition !== null && transition !== void 0 ? transition : defaultTransition)), { delay: 0.15 }) }, staticBackdrop && ({
1823
2034
  [`data-${PREFIX_BS}backdrop`]: 'static',
1824
2035
  [`data-${PREFIX_BS}keyboard`]: 'false',
1825
2036
  }), scrollable && ({
@@ -1932,7 +2143,7 @@ function DStepper$1({ options, currentStep, className, style, }) {
1932
2143
  from 0deg,
1933
2144
  var(--${PREFIX_BS}step-progress-outter-fill-background-color) ${currentAngle}deg,
1934
2145
  var(--${PREFIX_BS}step-progress-outter-background-color) 0deg)`, [currentAngle]);
1935
- return (jsxs("div", { className: classNames('d-stepper', className), style: style, children: [jsx("div", { className: "d-step-bar", style: { background: progressStyle }, children: jsx("p", { className: "d-step-number", children: `${currentStep}/${options.length}` }) }), jsx("div", { className: "d-step-info", children: Object.keys(currentOption).length > 0 && (jsxs(Fragment$1, { children: [jsx("div", { className: "d-step-label", children: currentOption.label }), jsx("div", { className: "d-step-description", children: currentOption.description || '' })] })) })] }));
2146
+ return (jsxs("div", { className: classNames('d-stepper', className), style: style, children: [jsx("div", { className: "d-step-bar", style: { background: progressStyle }, children: jsx("p", { className: "d-step-number", children: `${currentStep}/${options.length}` }) }), jsx("div", { className: "d-step-info", children: Object.keys(currentOption).length > 0 && (jsxs(Fragment, { children: [jsx("div", { className: "d-step-label", children: currentOption.label }), jsx("div", { className: "d-step-description", children: currentOption.description || '' })] })) })] }));
1936
2147
  }
1937
2148
 
1938
2149
  function DStepper({ options, currentStep, iconSuccess, iconSuccessFamilyClass, iconSuccessFamilyPrefix, iconSuccessMaterialStyle = false, vertical = false, breakpoint = 'lg', className, completed = false, style, dataAttributes, }) {
@@ -1974,7 +2185,7 @@ function DTooltip({ className, childrenClassName, style, offSet = ARROW_HEIGHT +
1974
2185
  role,
1975
2186
  ]);
1976
2187
  const generateClasses = useMemo(() => (Object.assign({ 'tooltip show': true, [`tooltip-${size}`]: !!size }, className && { [className]: true })), [size, className]);
1977
- return (jsxs(Fragment$1, { children: [jsx("div", Object.assign({ className: childrenClassName, ref: refs.setReference }, getReferenceProps(), { children: Component })), jsx(FloatingPortal, { children: isOpen && (jsxs("div", Object.assign({ className: classNames(generateClasses), ref: refs.setFloating, style: Object.assign(Object.assign({}, floatingStyles), style) }, getFloatingProps(), { children: [jsx(FloatingArrow, { ref: arrowRef, context: context, width: ARROW_WIDTH, height: ARROW_HEIGHT }), jsx("div", { className: "tooltip-inner", children: children })] }))) })] }));
2188
+ return (jsxs(Fragment, { children: [jsx("div", Object.assign({ className: childrenClassName, ref: refs.setReference }, getReferenceProps(), { children: Component })), jsx(FloatingPortal, { children: isOpen && (jsxs("div", Object.assign({ className: classNames(generateClasses), ref: refs.setFloating, style: Object.assign(Object.assign({}, floatingStyles), style) }, getFloatingProps(), { children: [jsx(FloatingArrow, { ref: arrowRef, context: context, width: ARROW_WIDTH, height: ARROW_HEIGHT }), jsx("div", { className: "tooltip-inner", children: children })] }))) })] }));
1978
2189
  }
1979
2190
 
1980
2191
  function DTimeline({ className, style, dataAttributes, items, }) {
@@ -2073,19 +2284,6 @@ function useDToast() {
2073
2284
  };
2074
2285
  }
2075
2286
 
2076
- function DTableHead({ className, style, field, label, value = '', onChange, }) {
2077
- const handleOnChange = useCallback(() => {
2078
- if (value === field) {
2079
- return onChange(`-${field}`);
2080
- }
2081
- if (value === `-${field}`) {
2082
- return onChange('');
2083
- }
2084
- return onChange(field);
2085
- }, [field, value, onChange]);
2086
- return (jsx("th", { style: style, className: classNames('d-table-head', className), children: jsxs("button", { type: "button", onClick: handleOnChange, children: [label, value && value.includes(field) && (jsx(DIcon, { icon: value === field ? 'arrow-up' : 'arrow-down' }))] }) }));
2087
- }
2088
-
2089
2287
  async function configureI8n(resources, _a = {}) {
2090
2288
  var { lng = 'en', fallbackLng = 'en' } = _a, config = __rest(_a, ["lng", "fallbackLng"]);
2091
2289
  return i18n
@@ -2299,5 +2497,168 @@ function DDropdown({ actions, dropdownToggle, className, }) {
2299
2497
  }) })] }));
2300
2498
  }
2301
2499
 
2302
- export { DAlert, DAvatar, DBadge, DBox, DBoxFile, DButton, DButtonIcon, DCard$1 as DCard, DCardBody, DCardFooter, DCardHeader, DCarousel$1 as DCarousel, DCarouselSlide, DChip, DCollapse, DContext, DContextProvider, DCreditCard, DCurrencyText, DDatePicker, DDropdown, DIcon, DIconBase, ForwardedDInput as DInput, DInputCheck, ForwardedDInputCounter as DInputCounter, ForwardedDInputCurrency as DInputCurrency, ForwardedDInputMask as DInputMask, ForwardedDInputPassword as DInputPassword, ForwardedDInputPhone as DInputPhone, DInputPin, ForwardedDInputRange as DInputRange, DInputSelect, DInputSwitch, DLayout$1 as DLayout, DLayoutPane, DListGroup$1 as DListGroup, DListGroupItem, DModal$1 as DModal, DModalBody, DModalFooter, DModalHeader, DOffcanvas$1 as DOffcanvas, DOffcanvasBody, DOffcanvasFooter, DOffcanvasHeader, DPaginator, DPopover, DProgress, DSelect$1 as DSelect, DStepper, DStepper$2 as DStepperDesktop, DStepper$1 as DStepperMobile, DTabContent, DTableHead, DTabs$1 as DTabs, DTimeline, DToast$1 as DToast, DToastContainer, DTooltip, changeQueryString, checkMediaQuery, configureI8n as configureI18n, formatCurrency, getCssVariable, getQueryString, subscribeToMediaQuery, useDContext, useDPortalContext, useDToast, useDisableBodyScrollEffect, useDisableInputWheel, useFormatCurrency, useInputCurrency, useItemSelection, useMediaBreakpointUpLg, useMediaBreakpointUpMd, useMediaBreakpointUpSm, useMediaBreakpointUpXl, useMediaBreakpointUpXs, useMediaBreakpointUpXxl, useMediaQuery, usePortal, useProvidedRefOrCreate, useStackState, useTabContext, validatePhoneNumber };
2500
+ function useScreenshot() {
2501
+ const clipRef = useRef(null);
2502
+ const takeBlob = useCallback(async (type) => {
2503
+ if (!clipRef.current) {
2504
+ throw new Error('set the clipRef');
2505
+ }
2506
+ const canvas = await html2canvas(clipRef === null || clipRef === void 0 ? void 0 : clipRef.current, {
2507
+ allowTaint: true,
2508
+ useCORS: true,
2509
+ });
2510
+ return (new Promise((resolve, reject) => {
2511
+ canvas.toBlob((innerBlob) => {
2512
+ if (!innerBlob) {
2513
+ return reject();
2514
+ }
2515
+ return resolve(innerBlob);
2516
+ }, type);
2517
+ }));
2518
+ }, []);
2519
+ return {
2520
+ clipRef,
2521
+ takeBlob,
2522
+ };
2523
+ }
2524
+
2525
+ function useScreenshotDownload() {
2526
+ const { clipRef, takeBlob } = useScreenshot();
2527
+ const download = useCallback(async () => {
2528
+ const blob = await takeBlob();
2529
+ const url = window.URL.createObjectURL(blob);
2530
+ const link = window.document.createElement('a');
2531
+ link.style.display = 'none';
2532
+ link.href = url;
2533
+ link.download = 'voucher.jpg';
2534
+ document.body.appendChild(link);
2535
+ link.click();
2536
+ document.body.removeChild(link);
2537
+ window.URL.revokeObjectURL(url);
2538
+ }, [takeBlob]);
2539
+ return {
2540
+ download,
2541
+ downloadRef: clipRef,
2542
+ };
2543
+ }
2544
+
2545
+ function useScreenshotWebShare() {
2546
+ const { takeBlob, clipRef } = useScreenshot();
2547
+ const share = useCallback(async () => {
2548
+ const blob = await takeBlob();
2549
+ const image = new File([blob], 'voucher.jpeg', { type: 'image/jpeg' });
2550
+ if (!navigator.canShare
2551
+ && (navigator.canShare && !navigator.canShare({ files: [image] }))) {
2552
+ window.print();
2553
+ return;
2554
+ }
2555
+ await navigator.share({ files: [image] });
2556
+ }, [takeBlob]);
2557
+ return {
2558
+ share,
2559
+ shareRef: clipRef,
2560
+ };
2561
+ }
2562
+
2563
+ function DVoucher({ amount, amountDetails, icon = 'CircleCheckBig', color = 'success', title, onError, message, downloadText = 'Download', shareText = 'Share', children, }) {
2564
+ const { shareRef, share } = useScreenshotWebShare();
2565
+ const { downloadRef, download } = useScreenshotDownload();
2566
+ const handleShare = () => {
2567
+ share()
2568
+ .catch(async (err) => {
2569
+ if (onError) {
2570
+ await onError(err);
2571
+ }
2572
+ })
2573
+ .catch(() => {
2574
+ // Error already handled by onError
2575
+ });
2576
+ };
2577
+ const handleDownload = () => {
2578
+ download()
2579
+ .catch(async (err) => {
2580
+ if (onError) {
2581
+ await onError(err);
2582
+ }
2583
+ })
2584
+ .catch(() => {
2585
+ // Error already handled by onError
2586
+ });
2587
+ };
2588
+ return (jsx("div", { className: "d-voucher", ref: (el) => {
2589
+ shareRef.current = el;
2590
+ downloadRef.current = el;
2591
+ }, children: jsxs("div", { children: [jsxs("div", { className: "d-voucher-header", children: [jsx(DIcon, { icon: icon, color: color }), jsxs("div", { className: "text-center", children: [jsx("h3", { className: "mb-2", children: title }), jsx("p", { className: "m-0", children: message })] })] }), amount && (jsxs("div", { className: "d-voucher-amount", children: [jsx("div", { className: classNames('text-center fw-bold fs-3', amountDetails ? 'mb-1' : 'm-0'), children: amount }), amountDetails] })), jsx("hr", { className: "my-4" }), children, jsx("hr", { className: "my-4" }), jsxs("div", { className: "d-voucher-footer", children: [jsx(DButton, { onClick: handleShare, iconStart: "Share2", text: shareText, variant: "outline", size: "sm" }), jsx(DButton, { onClick: handleDownload, iconStart: "Download", text: downloadText, variant: "outline", size: "sm" })] })] }) }));
2592
+ }
2593
+
2594
+ function useCountdown(seconds) {
2595
+ const [secondsLeft, setSecondsLeft] = useState(seconds);
2596
+ const [isActive, setIsActive] = useState(true);
2597
+ const resetCountdown = useCallback((newSeconds = seconds) => {
2598
+ setIsActive(false);
2599
+ setSecondsLeft(newSeconds);
2600
+ }, [seconds]);
2601
+ const restartCountdown = useCallback(() => {
2602
+ resetCountdown(seconds);
2603
+ setIsActive(true);
2604
+ }, [resetCountdown, seconds]);
2605
+ useEffect(() => {
2606
+ if (!isActive) {
2607
+ return () => { };
2608
+ }
2609
+ const interval = setInterval(() => {
2610
+ setSecondsLeft((prevSeconds) => {
2611
+ const newSeconds = prevSeconds - 1;
2612
+ if (newSeconds <= 0) {
2613
+ clearInterval(interval);
2614
+ setIsActive(false);
2615
+ return 0;
2616
+ }
2617
+ return newSeconds;
2618
+ });
2619
+ }, 1000);
2620
+ return () => clearInterval(interval);
2621
+ }, [isActive]);
2622
+ return { secondsLeft, restartCountdown };
2623
+ }
2624
+
2625
+ const defaultMessage = (secs) => (secs > 0
2626
+ ? `Didn't get any code? Resend in: ${secs}s`
2627
+ : "Didn't get any code?");
2628
+ function OtpCountdown({ seconds, resendText, message, }) {
2629
+ const { secondsLeft, restartCountdown } = useCountdown(seconds);
2630
+ return (jsxs("div", { className: "d-flex gap-2 align-items-center", children: [jsx("p", { className: "mb-0", children: message ? message(secondsLeft) : defaultMessage(secondsLeft) }), jsx(DButton, { text: resendText, variant: "link", disabled: secondsLeft > 0, onClick: restartCountdown })] }));
2631
+ }
2632
+
2633
+ const TEXT_PROPS = {
2634
+ resend: 'Resend',
2635
+ resendText: 'Resend code',
2636
+ submit: 'Authorize and continue',
2637
+ title: 'We will send you a 6-digit code to your associated phone number so you can continue with your request.',
2638
+ contact: (jsxs(Fragment, { children: [jsx("span", { children: "Problems with your digital token? Contact us" }), ' ', jsx("a", { href: "https://www.modyo.com", className: "link-primary text-nowrap", target: "_blank", rel: "noreferrer", children: "Contact us" })] })),
2639
+ };
2640
+ function DOtp({ className, action, isLoading, otpSize = 6, texts = TEXT_PROPS, seconds = 15, }) {
2641
+ const [otp, setOtp] = useState('');
2642
+ const [invalid, setInvalid] = useState(false);
2643
+ const handler = useCallback(async () => {
2644
+ if (otp.length < otpSize) {
2645
+ setInvalid(true);
2646
+ return;
2647
+ }
2648
+ setInvalid(false);
2649
+ await action();
2650
+ }, [
2651
+ otp.length,
2652
+ action,
2653
+ otpSize,
2654
+ ]);
2655
+ return (jsxs("div", { className: className, children: [jsx("p", { children: texts.title }), jsxs("div", { className: "d-flex flex-column gap-6 pb-4 px-3", children: [jsxs("div", { className: "d-flex flex-column gap-6", children: [jsx(DInputPin, { className: "modal-otp-pin", characters: otpSize, onChange: (e) => setOtp(e), invalid: invalid && otp.length < otpSize, placeholder: "0" }), jsx(OtpCountdown, { seconds: seconds, resendText: texts.resend })] }), jsx("hr", { className: "m-0" }), jsxs("div", { className: "d-flex flex-column flex-lg-row gap-4 align-items-center", children: [jsx(DButton, { text: texts.submit, onClick: () => {
2656
+ handler().catch((err) => {
2657
+ // eslint-disable-next-line no-console
2658
+ console.error('Error in DOtp action:', err);
2659
+ });
2660
+ }, loading: isLoading }), jsx("p", { className: "small ms-lg-auto mb-0", children: texts.contact })] })] })] }));
2661
+ }
2662
+
2663
+ export { DAlert, DAvatar, DBadge, DBox, DBoxFile, DButton, DButtonIcon, DCard$1 as DCard, DCardBody, DCardFooter, DCardHeader, DCarousel$1 as DCarousel, DCarouselSlide, DChip, DCollapse, DContext, DContextProvider, DCreditCard, DCurrencyText, DDatePicker, DDropdown, DIcon, DIconBase, ForwardedDInput as DInput, DInputCheck, ForwardedDInputCounter as DInputCounter, ForwardedDInputCurrency as DInputCurrency, ForwardedDInputMask as DInputMask, ForwardedDInputPassword as DInputPassword, ForwardedDInputPhone as DInputPhone, DInputPin, ForwardedDInputRange as DInputRange, DInputSelect, DInputSwitch, DLayout$1 as DLayout, DLayoutPane, DListGroup$1 as DListGroup, DListGroupItem, DModal$1 as DModal, DModalBody, DModalFooter, DModalHeader, DOffcanvas$1 as DOffcanvas, DOffcanvasBody, DOffcanvasFooter, DOffcanvasHeader, DOtp, DPaginator, DPasswordStrengthMeter, DPopover, DProgress, DSelect$1 as DSelect, DStepper, DStepper$2 as DStepperDesktop, DStepper$1 as DStepperMobile, DTabContent, DTabs$1 as DTabs, DTimeline, DToast$1 as DToast, DToastContainer, DTooltip, DVoucher, changeQueryString, checkMediaQuery, configureI8n as configureI18n, formatCurrency, getCssVariable, getQueryString, subscribeToMediaQuery, useDContext, useDPortalContext, useDToast, useDisableBodyScrollEffect, useDisableInputWheel, useFormatCurrency, useInputCurrency, useItemSelection, useMediaBreakpointUpLg, useMediaBreakpointUpMd, useMediaBreakpointUpSm, useMediaBreakpointUpXl, useMediaBreakpointUpXs, useMediaBreakpointUpXxl, useMediaQuery, usePortal, useProvidedRefOrCreate, useStackState, useTabContext, validatePhoneNumber };
2303
2664
  //# sourceMappingURL=index.esm.js.map