@dynamic-framework/ui-react 2.1.1 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/README.md +8 -0
  2. package/dist/css/dynamic-ui.css +15518 -1105
  3. package/dist/css/dynamic-ui.min.css +3 -3
  4. package/dist/index.esm.js +338 -137
  5. package/dist/index.esm.js.map +1 -1
  6. package/dist/index.js +345 -135
  7. package/dist/index.js.map +1 -1
  8. package/dist/types/components/DBadge/DBadge.d.ts +3 -2
  9. package/dist/types/components/DButton/DButton.d.ts +7 -3
  10. package/dist/types/components/DButtonIcon/DButtonIcon.d.ts +7 -8
  11. package/dist/types/components/DCollapse/DCollapse.d.ts +1 -2
  12. package/dist/types/components/DCreditCard/DCreditCard.d.ts +2 -1
  13. package/dist/types/components/DDataStateWrapper/DDataStateWrapper.d.ts +14 -0
  14. package/dist/types/components/DDataStateWrapper/components/EmptyState.d.ts +8 -0
  15. package/dist/types/components/DDataStateWrapper/components/ErrorState.d.ts +8 -0
  16. package/dist/types/components/DDataStateWrapper/components/LoadingState.d.ts +6 -0
  17. package/dist/types/components/DDataStateWrapper/index.d.ts +2 -0
  18. package/dist/types/components/DDatePicker/DDatePicker.d.ts +2 -1
  19. package/dist/types/components/DDatePicker/components/DDatePickerTime.d.ts +4 -6
  20. package/dist/types/components/DErrorBoundary/DErrorBoundary.d.ts +11 -0
  21. package/dist/types/components/DErrorBoundary/components/DefaultErrorBoundary.d.ts +6 -0
  22. package/dist/types/components/DErrorBoundary/index.d.ts +3 -0
  23. package/dist/types/components/DInputPin/DInputPin.d.ts +2 -1
  24. package/dist/types/components/DPopover/DPopover.d.ts +2 -7
  25. package/dist/types/components/DSelect/DSelect.d.ts +2 -1
  26. package/dist/types/components/DSelect/components/DSelectOptionCheck.d.ts +1 -1
  27. package/dist/types/components/DTabs/DTabs.d.ts +3 -1
  28. package/dist/types/components/DVoucher/DVoucher.d.ts +5 -4
  29. package/dist/types/components/index.d.ts +2 -0
  30. package/package.json +18 -21
  31. package/src/style/_shame.scss +2 -2
  32. package/src/style/abstracts/_mixins.scss +4 -4
  33. package/src/style/abstracts/_utilities-dark.scss +72 -0
  34. package/src/style/abstracts/_utilities.scss +76 -8
  35. package/src/style/abstracts/variables/_+import.scss +2 -6
  36. package/src/style/abstracts/variables/_alerts.scss +1 -1
  37. package/src/style/abstracts/variables/_border.scss +9 -0
  38. package/src/style/abstracts/variables/_buttons.scss +1 -1
  39. package/src/style/abstracts/variables/_carousel.scss +13 -1
  40. package/src/style/abstracts/variables/_colors.scss +2 -2
  41. package/src/style/abstracts/variables/_input-phone.scss +1 -1
  42. package/src/style/abstracts/variables/_navs.scss +23 -27
  43. package/src/style/abstracts/variables/_tooltip.scss +2 -2
  44. package/src/style/abstracts/variables/_typography.scss +0 -40
  45. package/src/style/base/_+import.scss +1 -0
  46. package/src/style/base/_badge.scss +2 -2
  47. package/src/style/base/_carousel.scss +44 -0
  48. package/src/style/base/_collapse.scss +21 -8
  49. package/src/style/base/_nav.scss +10 -59
  50. package/src/style/base/_type.scss +7 -6
  51. package/src/style/components/_+import.scss +0 -1
  52. package/src/style/components/_d-avatar.scss +2 -2
  53. package/src/style/components/_d-carousel.scss +26 -4
  54. package/src/style/components/_d-chip.scss +13 -3
  55. package/src/style/components/_d-credit-card.scss +22 -12
  56. package/src/style/components/_d-icon.scss +17 -0
  57. package/src/style/components/_d-select.scss +59 -25
  58. package/src/style/components/_d-stepper-desktop.scss +2 -2
  59. package/src/style/components/_d-tabs.scss +7 -18
  60. package/src/style/components/_d-timeline.scss +6 -5
  61. package/src/style/components/_d-voucher.scss +2 -1
  62. package/src/style/dynamic-ui.scss +2 -0
  63. package/src/style/helpers/_+import.scss +1 -0
  64. package/src/style/helpers/_animations.scss +13 -0
  65. package/src/style/helpers/_color-bg.scss +1 -3
  66. package/src/style/root/_root.scss +8 -9
  67. package/dist/css/dynamic-ui-non-root.css +0 -37666
  68. package/dist/css/dynamic-ui-non-root.min.css +0 -6
  69. package/dist/css/dynamic-ui-root.css +0 -1132
  70. package/dist/css/dynamic-ui-root.min.css +0 -6
  71. package/src/style/abstracts/variables/_quick-action-button.scss +0 -31
  72. package/src/style/abstracts/variables/_quick-action-check.scss +0 -22
  73. package/src/style/abstracts/variables/_quick-action-select.scss +0 -16
  74. package/src/style/abstracts/variables/_quick-action-switch.scss +0 -19
  75. package/src/style/components/_d-collapse-icon-text.scss +0 -16
  76. package/src/style/dynamic-ui-non-root.scss +0 -15
  77. package/src/style/dynamic-ui-root.scss +0 -5
package/dist/index.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
2
  import classNames from 'classnames';
3
- import React, { useEffect, useState, useCallback, useMemo, useContext, createContext, useLayoutEffect, useSyncExternalStore, forwardRef, useId, useRef } from 'react';
3
+ import React, { useEffect, useState, useCallback, useMemo, useContext, createContext, useLayoutEffect, useSyncExternalStore, forwardRef, useId, useRef, isValidElement, cloneElement, createRef } from 'react';
4
4
  import { __rest } from 'tslib';
5
5
  import * as LucideIcons from 'lucide-react';
6
6
  import { createPortal } from 'react-dom';
@@ -11,28 +11,65 @@ import currency from 'currency.js';
11
11
  import DatePicker from 'react-datepicker';
12
12
  import { getYear, format, getMonth } from 'date-fns';
13
13
  import Select, { components } from 'react-select';
14
+ import { getErrorMessage, ErrorBoundary } from 'react-error-boundary';
15
+ export { getErrorMessage, useErrorBoundary } from 'react-error-boundary';
14
16
  import { InputMask } from '@react-input/mask';
17
+ import { defaultCountries, parseCountry, usePhoneInput, CountrySelector } from 'react-international-phone';
18
+ import { PhoneNumberUtil } from 'google-libphonenumber';
15
19
  import ResponsivePagination from 'react-responsive-pagination';
16
20
  import { useFloating, autoUpdate, offset, flip, shift, useClick, useDismiss, useRole, useInteractions, useId as useId$1, FloatingFocusManager, arrow, useHover, useFocus, FloatingPortal, FloatingArrow } from '@floating-ui/react';
17
21
  import { Toaster, toast } from 'react-hot-toast';
18
- import { defaultCountries, parseCountry, usePhoneInput, CountrySelector } from 'react-international-phone';
19
- import { PhoneNumberUtil } from 'google-libphonenumber';
20
22
  import html2canvas from 'html2canvas';
21
23
  import i18n from 'i18next';
22
24
  import { initReactI18next } from 'react-i18next';
23
25
 
24
26
  const PREFIX_BS = 'bs-';
25
27
 
28
+ /* eslint-disable no-lonely-if */
26
29
  function useDisableBodyScrollEffect(disable) {
27
30
  useEffect(() => {
28
- if (disable) {
31
+ let observer;
32
+ let timer;
33
+ const lock = () => {
34
+ const { clientWidth } = document.documentElement;
35
+ const { innerWidth } = window;
36
+ const scrollbarWidth = clientWidth ? innerWidth - clientWidth : 0;
29
37
  document.body.style.overflow = 'hidden';
30
- document.body.style.paddingRight = '0';
38
+ document.body.style.paddingRight = `${Math.max(0, scrollbarWidth)}px`;
39
+ };
40
+ const unlock = () => {
41
+ document.body.style.overflow = 'unset';
42
+ document.body.style.paddingRight = '0px';
43
+ };
44
+ if (disable) {
45
+ lock();
31
46
  }
32
47
  else {
33
- document.body.style.overflow = 'unset';
34
- document.body.style.paddingRight = 'unset';
48
+ // Wait until all portal elements are removed (exit animations done)
49
+ if (document.querySelector('.portal')) {
50
+ observer = new MutationObserver(() => {
51
+ if (!document.querySelector('.portal')) {
52
+ unlock();
53
+ observer === null || observer === void 0 ? void 0 : observer.disconnect();
54
+ }
55
+ });
56
+ observer.observe(document.body, { childList: true, subtree: true });
57
+ // Fallback in case observer misses changes
58
+ timer = window.setTimeout(() => {
59
+ unlock();
60
+ observer === null || observer === void 0 ? void 0 : observer.disconnect();
61
+ }, 3000);
62
+ }
63
+ else {
64
+ unlock();
65
+ }
35
66
  }
67
+ return () => {
68
+ if (observer)
69
+ observer.disconnect();
70
+ if (timer)
71
+ window.clearTimeout(timer);
72
+ };
36
73
  }, [disable]);
37
74
  }
38
75
 
@@ -375,21 +412,6 @@ function DIconBase({ icon, color, style, className, size, useListenerSize = fals
375
412
  const icons = LucideIcons;
376
413
  return icons[icon] || null;
377
414
  }, [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
415
  const { responsivePropValue } = useResponsiveProp(useListenerSize);
394
416
  const resolvedSize = useMemo(() => {
395
417
  if (!size)
@@ -398,8 +420,8 @@ function DIconBase({ icon, color, style, className, size, useListenerSize = fals
398
420
  return size;
399
421
  return responsivePropValue(size);
400
422
  }, [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]);
423
+ const generateStyleVariables = useMemo(() => (Object.assign(Object.assign(Object.assign({}, resolvedSize && { [`--${PREFIX_BS}icon-component-size`]: resolvedSize }), hasCircle && { [`--${PREFIX_BS}icon-component-padding`]: `calc(var(--${PREFIX_BS}icon-component-size, 24px) * 0.4)` }), style)), [resolvedSize, hasCircle, style]);
424
+ const generateClasses = useMemo(() => (Object.assign(Object.assign(Object.assign({ 'd-icon': true }, className && { [className]: true }), { 'd-icon-has-circle': hasCircle }), color && { [`d-icon-color-${color}`]: true })), [className, hasCircle, color]);
403
425
  const iconSize = useMemo(() => {
404
426
  if (resolvedSize) {
405
427
  const numSize = parseInt(resolvedSize, 10);
@@ -454,14 +476,24 @@ function DAvatar({ id, size, image, name: nameProp, useNameAsInitials = false, c
454
476
  return (jsxs("div", Object.assign({ className: classNames(generateClasses, className), style: style, id: id }, dataAttributes, { children: [image && jsx("img", { src: image, alt: nameProp, className: "d-avatar-img" }), (name && !image) && jsx("span", { className: "d-avatar-name", children: name })] })));
455
477
  }
456
478
 
457
- function DBadge({ text, soft = false, color = 'primary', id, rounded, className, size, style, iconStart, iconEnd, iconMaterialStyle, iconFamilyClass, iconFamilyPrefix, dataAttributes, }) {
479
+ function DBadge(props) {
480
+ const { text, soft = false, color = 'primary', id, rounded, className, size, style, iconStart, iconEnd, iconMaterialStyle, iconFamilyClass, iconFamilyPrefix, dataAttributes, } = props;
481
+ // Responsive size resolution using useResponsiveProp
482
+ const { responsivePropValue } = useResponsiveProp(true);
483
+ const resolvedSize = useMemo(() => {
484
+ if (!size)
485
+ return undefined;
486
+ if (typeof size === 'string')
487
+ return size;
488
+ return responsivePropValue(size);
489
+ }, [responsivePropValue, size]);
458
490
  const generateClasses = useMemo(() => ({
459
491
  badge: true,
460
492
  [`badge-${color}`]: !!color && !soft,
461
493
  [`badge-soft-${color}`]: !!color && soft,
462
494
  'rounded-pill': !!rounded,
463
- [`badge-${size}`]: !!size,
464
- }), [rounded, soft, color, size]);
495
+ [`badge-${resolvedSize}`]: !!resolvedSize,
496
+ }), [rounded, soft, color, resolvedSize]);
465
497
  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 }))] })));
466
498
  }
467
499
 
@@ -556,7 +588,7 @@ function DInput(_a, ref) {
556
588
  [`input-group-${size}`]: !!size,
557
589
  'input-group': true,
558
590
  'has-validation': invalid || valid,
559
- }), 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", "data-testid": "loading-spinner", 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 }))] })));
591
+ }), children: [!!inputStart && (jsx("div", { className: "input-group-text", id: `${id}InputStart`, children: inputStart })), iconStart && (onIconStartClick ? (jsx("button", { type: "button", className: "input-group-text", id: `${id}Start`, onClick: handleOnIconStartClick, disabled: disabled || loading || iconStartDisabled, "aria-label": iconStartAriaLabel || (typeof iconStart === 'string' ? iconStart : 'start icon'), tabIndex: iconStartTabIndex, children: jsx(DIcon, { icon: iconStart, familyClass: iconStartFamilyClass, familyPrefix: iconStartFamilyPrefix, materialStyle: iconStartMaterialStyle }) })) : (jsx("div", { className: "input-group-text", id: `${id}Start`, "aria-hidden": "true", tabIndex: -1, children: jsx(DIcon, { icon: iconStart, familyClass: iconStartFamilyClass, familyPrefix: iconStartFamilyPrefix, materialStyle: iconStartMaterialStyle }) }))), dynamicComponent, (iconEnd && !loading) && (onIconEndClick ? (jsx("button", { type: "button", className: "input-group-text", id: `${id}End`, onClick: handleOnIconEndClick, disabled: disabled || loading || iconEndDisabled, "aria-label": iconEndAriaLabel || (typeof iconEnd === 'string' ? iconEnd : 'end icon'), tabIndex: iconEndTabIndex, children: jsx(DIcon, { icon: iconEnd, familyClass: iconEndFamilyClass, familyPrefix: iconEndFamilyPrefix, materialStyle: iconEndMaterialStyle }) })) : (jsx("div", { className: "input-group-text", id: `${id}End`, "aria-hidden": "true", tabIndex: -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", "data-testid": "loading-spinner", 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 }))] })));
560
592
  }
561
593
  const ForwardedDInput = forwardRef(DInput);
562
594
  ForwardedDInput.displayName = 'DInput';
@@ -966,7 +998,16 @@ function DBoxFile(_a) {
966
998
  }
967
999
 
968
1000
  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"]);
1001
+ 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', target, rel, href, 'aria-label': ariaLabelProp } = 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", "target", "rel", "href", 'aria-label']);
1002
+ // Responsive size resolution using useResponsiveProp
1003
+ const { responsivePropValue } = useResponsiveProp(true);
1004
+ const resolvedSize = useMemo(() => {
1005
+ if (!size)
1006
+ return undefined;
1007
+ if (typeof size === 'string')
1008
+ return size;
1009
+ return responsivePropValue(size);
1010
+ }, [responsivePropValue, size]);
970
1011
  const [buttonWidth, setButtonWidth] = useState();
971
1012
  const buttonRef = useRef(null);
972
1013
  const isDisabled = useMemo(() => disabled || loading, [disabled, loading]);
@@ -978,16 +1019,13 @@ const DButton = forwardRef((props, ref) => {
978
1019
  return {
979
1020
  btn: true,
980
1021
  [variantClass]: true,
981
- [`btn-${size}`]: !!size,
1022
+ [`btn-${resolvedSize}`]: !!resolvedSize,
982
1023
  loading,
983
1024
  };
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]);
1025
+ }, [variant, color, loading, resolvedSize]);
1026
+ const ariaLabel = useMemo(() => (loading
1027
+ ? loadingAriaLabel || ariaLabelProp || text
1028
+ : ariaLabelProp || text), [loading, loadingAriaLabel, text, ariaLabelProp]);
991
1029
  const handleClick = useCallback((event) => {
992
1030
  if (disabled || loading) {
993
1031
  event.preventDefault();
@@ -1003,6 +1041,19 @@ const DButton = forwardRef((props, ref) => {
1003
1041
  }
1004
1042
  // eslint-disable-next-line react-hooks/exhaustive-deps
1005
1043
  }, [content, iconEnd, iconStart]);
1044
+ if (href) {
1045
+ return (jsxs("a", Object.assign({ href: href, target: target, rel: rel, ref: (node) => {
1046
+ buttonRef.current = node;
1047
+ if (typeof ref === 'function')
1048
+ ref(node);
1049
+ // eslint-disable-next-line max-len
1050
+ // eslint-disable-next-line no-param-reassign, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
1051
+ else if (ref)
1052
+ ref.current = node;
1053
+ }, className: classNames(classes, className), style: Object.assign(Object.assign({}, style), (loading && buttonWidth
1054
+ ? { minWidth: `${buttonWidth}px` }
1055
+ : undefined)), "aria-label": ariaLabel, "aria-busy": loading, "aria-disabled": isDisabled, onClick: handleClick }, dataAttributes, { 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 }))] }))] })));
1056
+ }
1006
1057
  return (jsxs("button", Object.assign({ ref: (node) => {
1007
1058
  buttonRef.current = node;
1008
1059
  if (typeof ref === 'function')
@@ -1019,24 +1070,34 @@ const DButton = forwardRef((props, ref) => {
1019
1070
  });
1020
1071
  DButton.displayName = 'DButton';
1021
1072
 
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, }) {
1073
+ function DButtonIcon(_a) {
1074
+ var { id, icon, size, className, variant, state, loadingAriaLabel, iconMaterialStyle, disabled = false, color = 'primary', loading = false, href, target, rel, stopPropagationEnabled = true, style, iconFamilyClass, iconFamilyPrefix, dataAttributes, onClick, 'aria-label': ariaLabelProp } = _a, rest = __rest(_a, ["id", "icon", "size", "className", "variant", "state", "loadingAriaLabel", "iconMaterialStyle", "disabled", "color", "loading", "href", "target", "rel", "stopPropagationEnabled", "style", "iconFamilyClass", "iconFamilyPrefix", "dataAttributes", "onClick", 'aria-label']);
1023
1075
  const generateClasses = useMemo(() => {
1024
1076
  const variantClass = variant
1025
1077
  ? `btn-${variant}-${color}`
1026
1078
  : `btn-${color}`;
1027
1079
  return Object.assign(Object.assign(Object.assign({ 'btn d-button-icon': true, [variantClass]: true }, size && { [`btn-${size}`]: true }), (state && state !== 'disabled') && { [state]: true }), { loading });
1028
1080
  }, [variant, color, size, state, loading]);
1081
+ const isDisabled = useMemo(() => (state === 'disabled' || loading || disabled), [state, loading, disabled]);
1029
1082
  const clickHandler = useCallback((event) => {
1030
1083
  if (stopPropagationEnabled) {
1031
1084
  event.stopPropagation();
1032
1085
  }
1086
+ if (isDisabled) {
1087
+ event.preventDefault();
1088
+ return;
1089
+ }
1033
1090
  onClick === null || onClick === void 0 ? void 0 : onClick(event);
1034
- }, [stopPropagationEnabled, onClick]);
1035
- const isDisabled = useMemo(() => (state === 'disabled' || loading || disabled), [state, loading, disabled]);
1036
- const newAriaLabel = useMemo(() => (loading
1037
- ? (loadingAriaLabel || ariaLabel)
1038
- : (ariaLabel)), [ariaLabel, loading, loadingAriaLabel]);
1039
- return (jsx("button", Object.assign({ className: classNames(generateClasses, className), style: style, type: type, disabled: isDisabled, onClick: clickHandler, "aria-label": newAriaLabel, id: id }, dataAttributes, { children: loading
1091
+ }, [stopPropagationEnabled, onClick, isDisabled]);
1092
+ const ariaLabel = useMemo(() => (loading
1093
+ ? loadingAriaLabel || ariaLabelProp
1094
+ : ariaLabelProp), [loading, loadingAriaLabel, ariaLabelProp]);
1095
+ if (href) {
1096
+ return (jsx("a", Object.assign({ id: id, href: href, target: target, rel: rel, className: classNames(generateClasses, className), style: style, onClick: clickHandler, "aria-label": ariaLabel, "aria-disabled": isDisabled }, dataAttributes, { children: loading
1097
+ ? (jsx("span", { className: "spinner-border spinner-border-sm", role: "status", "aria-hidden": "true", children: jsx("span", { className: "visually-hidden", children: "Loading..." }) }))
1098
+ : (jsx(DIcon, { icon: icon, familyClass: iconFamilyClass, familyPrefix: iconFamilyPrefix, materialStyle: iconMaterialStyle })) })));
1099
+ }
1100
+ return (jsx("button", Object.assign({ className: classNames(generateClasses, className), style: style, disabled: state === 'disabled' || loading, onClick: clickHandler, "aria-label": ariaLabel }, dataAttributes, rest, { children: loading
1040
1101
  ? (jsx("span", { className: "spinner-border spinner-border-sm", role: "status", "aria-hidden": "true", children: jsx("span", { className: "visually-hidden", children: "Loading..." }) }))
1041
1102
  : (jsx(DIcon, { icon: icon, familyClass: iconFamilyClass, familyPrefix: iconFamilyPrefix, materialStyle: iconMaterialStyle })) })));
1042
1103
  }
@@ -1096,7 +1157,7 @@ function DChip({ color = 'primary', text, icon, iconFamilyClass, iconFamilyPrefi
1096
1157
  return (jsxs("span", Object.assign({ className: classNames(generateClasses, className), style: style }, dataAttributes, { children: [icon && (jsx("div", { className: "d-chip-icon-container", children: jsx(DIcon, { icon: icon, familyClass: iconFamilyClass, familyPrefix: iconFamilyPrefix, materialStyle: iconMaterialStyle }) })), jsx("span", { children: text }), showClose && (jsx("button", { type: "button", className: "d-chip-icon-container", onClick: onClose, "aria-label": closeAriaLabel, children: jsx(DIcon, { icon: iconClose, familyClass: iconCloseFamilyClass, familyPrefix: iconCloseFamilyPrefix, materialStyle: iconCloseMaterialStyle }) }))] })));
1097
1158
  }
1098
1159
 
1099
- function DCollapse({ id, className, style, Component, hasSeparator = false, defaultCollapsed = true, onChange, children, iconOpen: iconOpenProp, iconClose: iconCloseProp, iconFamilyClass, iconFamilyPrefix, iconMaterialStyle = false, dataAttributes, }) {
1160
+ function DCollapse({ id, className, style, Component, defaultCollapsed = true, onChange, children, iconOpen: iconOpenProp, iconClose: iconCloseProp, iconFamilyClass, iconFamilyPrefix, iconMaterialStyle = false, dataAttributes, }) {
1100
1161
  const [collapsed, setCollapsed] = useState(defaultCollapsed);
1101
1162
  const onChangeCollapse = () => {
1102
1163
  setCollapsed((prev) => {
@@ -1113,12 +1174,9 @@ function DCollapse({ id, className, style, Component, hasSeparator = false, defa
1113
1174
  const { iconMap: { chevronDown, chevronUp, }, } = useDContext();
1114
1175
  const iconOpen = useMemo(() => iconOpenProp || chevronDown, [chevronDown, iconOpenProp]);
1115
1176
  const iconClose = useMemo(() => iconCloseProp || chevronUp, [chevronUp, iconCloseProp]);
1116
- const generateStyles = useMemo(() => ({
1117
- [`--${PREFIX_BS}collapse-separator-display`]: hasSeparator ? 'block' : 'none',
1118
- }), [hasSeparator]);
1119
- return (jsxs("div", Object.assign({ id: id, className: classNames('collapse-container', className), style: style }, dataAttributes, { children: [jsxs("button", { className: "collapse-button", type: "button", onClick: onChangeCollapse, children: [jsx("div", { className: "flex-grow-1", children: Component }), jsx(DIcon, { color: "gray", size: "1rem", icon: collapsed ? iconOpen : iconClose, familyClass: iconFamilyClass, familyPrefix: iconFamilyPrefix, materialStyle: iconMaterialStyle })] }), !collapsed && (jsx("div", { className: classNames({
1120
- 'collapse-body': true,
1121
- }), style: generateStyles, children: children }))] })));
1177
+ return (jsxs("div", Object.assign({ id: id, className: classNames('collapse-container', className), style: style }, dataAttributes, { children: [jsxs("button", { className: "collapse-button", type: "button", onClick: onChangeCollapse, children: [jsx("div", { className: "flex-grow-1", children: Component }), jsx(DIcon, { color: "primary", size: "1.25rem", icon: collapsed ? iconOpen : iconClose, familyClass: iconFamilyClass, familyPrefix: iconFamilyPrefix, materialStyle: iconMaterialStyle })] }), jsx("div", { className: classNames('collapse-body-wrapper', {
1178
+ show: !collapsed,
1179
+ }), children: jsx("div", { className: "collapse-body", children: children }) })] })));
1122
1180
  }
1123
1181
 
1124
1182
  function formatCurrency(amount, options) {
@@ -1140,10 +1198,9 @@ function DCurrencyText({ value, className, style, dataAttributes, }) {
1140
1198
  return (jsx("span", Object.assign({ className: className, style: style }, dataAttributes, { children: valueFormatted })));
1141
1199
  }
1142
1200
 
1143
- function DDatePickerTime({ value, onChange, id, }) {
1144
- return (jsx(ForwardedDInput, { className: "d-datepicker-time", type: "time", value: value, id: id, onChange: (time) => {
1145
- onChange === null || onChange === void 0 ? void 0 : onChange(time);
1146
- } }));
1201
+ function DDatePickerTime(_a) {
1202
+ var rest = __rest(_a, []);
1203
+ return (jsx(ForwardedDInput, Object.assign({ className: "d-datepicker-time", type: "time" }, rest)));
1147
1204
  }
1148
1205
 
1149
1206
  function DDatePickerInput(_a, ref) {
@@ -1154,62 +1211,11 @@ function DDatePickerInput(_a, ref) {
1154
1211
  const ForwardedDDatePickerInput = forwardRef(DDatePickerInput);
1155
1212
  ForwardedDDatePickerInput.displayName = 'DDatePickerInput';
1156
1213
 
1157
- function DInputCheck(_a) {
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"]);
1159
- const innerRef = useRef(null);
1160
- const innerId = useId();
1161
- const id = useMemo(() => idProp || innerId, [idProp, innerId]);
1162
- const handleChange = useCallback((event) => {
1163
- onChange === null || onChange === void 0 ? void 0 : onChange(event);
1164
- }, [onChange]);
1165
- const ariaDescribedby = useMemo(() => ([
1166
- !!hint && `${id}Hint`,
1167
- ]
1168
- .filter(Boolean)
1169
- .join(' ')), [
1170
- id,
1171
- hint,
1172
- ]);
1173
- useEffect(() => {
1174
- if (innerRef.current) {
1175
- innerRef.current.indeterminate = Boolean(indeterminate);
1176
- }
1177
- }, [indeterminate]);
1178
- useEffect(() => {
1179
- if (innerRef.current) {
1180
- innerRef.current.checked = checked;
1181
- }
1182
- }, [checked]);
1183
- const inputComponent = useMemo(() => (jsx("input", Object.assign({ ref: innerRef, onChange: handleChange, className: classNames('form-check-input', {
1184
- 'is-invalid': invalid,
1185
- 'is-valid': valid,
1186
- }, inputClassName), style: style, id: id, disabled: disabled, type: type, name: name, value: value, "aria-label": ariaLabel }, ariaDescribedby && { 'aria-describedby': ariaDescribedby }, props))), [
1187
- handleChange,
1188
- invalid,
1189
- valid,
1190
- inputClassName,
1191
- style,
1192
- id,
1193
- disabled,
1194
- type,
1195
- name,
1196
- value,
1197
- ariaLabel,
1198
- ariaDescribedby,
1199
- props,
1200
- ]);
1201
- if (!label) {
1202
- return inputComponent;
1203
- }
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 }))] })));
1205
- }
1206
-
1207
1214
  function DSelectOptionCheck(_a) {
1208
- var { innerProps, children, isSelected } = _a, props = __rest(_a, ["innerProps", "children", "isSelected"]);
1209
- return (jsx(components.Option, Object.assign({ className: classNames({
1210
- 'd-select__option': true,
1211
- 'd-select__option--is-checkbox': true,
1212
- }), isSelected: isSelected, innerProps: innerProps }, props, { children: jsxs("label", { htmlFor: `${innerProps.id}Check`, children: [jsx(DInputCheck, { type: "checkbox", checked: isSelected, id: `${innerProps.id}Check` }), children] }) })));
1215
+ var { children, isSelected } = _a, props = __rest(_a, ["children", "isSelected"]);
1216
+ return (jsxs(components.Option, Object.assign({}, props, { isSelected: isSelected, className: classNames('d-select__option'), children: [jsx("span", { className: classNames('d-select__check', {
1217
+ 'd-select__check--selected': isSelected,
1218
+ }), "aria-hidden": "true" }), jsx("span", { className: "d-select__label", children: children })] })));
1213
1219
  }
1214
1220
 
1215
1221
  function DSelectOptionIcon(_a) {
@@ -1280,7 +1286,7 @@ function DSelectPlaceholder(_a) {
1280
1286
  }
1281
1287
 
1282
1288
  function DSelect(_a) {
1283
- var { id: idProp, className, style, label, hint, iconFamilyClass, iconFamilyPrefix, iconStart, iconStartFamilyClass, iconStartFamilyPrefix, iconStartAriaLabel, iconStartTabIndex, iconEnd, iconEndFamilyClass, iconEndFamilyPrefix, iconEndAriaLabel, iconEndTabIndex, invalid, valid, menuWithMaxContent = false, disabled, clearable, loading, floatingLabel = false, rtl, searchable, multi, components, defaultValue, placeholder, onIconStartClick, onIconEndClick, dataAttributes } = _a, props = __rest(_a, ["id", "className", "style", "label", "hint", "iconFamilyClass", "iconFamilyPrefix", "iconStart", "iconStartFamilyClass", "iconStartFamilyPrefix", "iconStartAriaLabel", "iconStartTabIndex", "iconEnd", "iconEndFamilyClass", "iconEndFamilyPrefix", "iconEndAriaLabel", "iconEndTabIndex", "invalid", "valid", "menuWithMaxContent", "disabled", "clearable", "loading", "floatingLabel", "rtl", "searchable", "multi", "components", "defaultValue", "placeholder", "onIconStartClick", "onIconEndClick", "dataAttributes"]);
1289
+ var { id: idProp, className, style, label, hint, iconFamilyClass, iconFamilyPrefix, iconStart, iconStartFamilyClass, iconStartFamilyPrefix, iconStartAriaLabel, iconStartTabIndex, iconEnd, iconEndFamilyClass, iconEndFamilyPrefix, iconEndAriaLabel, iconEndTabIndex, invalid, valid, menuWithMaxContent = false, disabled, clearable, loading, floatingLabel = false, rtl, searchable, multi, components, defaultValue, placeholder, onIconStartClick, onIconEndClick, dataAttributes, ariaLabel = 'Search for an option' } = _a, props = __rest(_a, ["id", "className", "style", "label", "hint", "iconFamilyClass", "iconFamilyPrefix", "iconStart", "iconStartFamilyClass", "iconStartFamilyPrefix", "iconStartAriaLabel", "iconStartTabIndex", "iconEnd", "iconEndFamilyClass", "iconEndFamilyPrefix", "iconEndAriaLabel", "iconEndTabIndex", "invalid", "valid", "menuWithMaxContent", "disabled", "clearable", "loading", "floatingLabel", "rtl", "searchable", "multi", "components", "defaultValue", "placeholder", "onIconStartClick", "onIconEndClick", "dataAttributes", "ariaLabel"]);
1284
1290
  const innerId = useId();
1285
1291
  const id = useMemo(() => idProp || innerId, [idProp, innerId]);
1286
1292
  const handleOnIconStartClick = useCallback(() => {
@@ -1296,7 +1302,7 @@ function DSelect(_a) {
1296
1302
  'input-group': true,
1297
1303
  'has-validation': invalid,
1298
1304
  disabled: disabled || loading,
1299
- }), children: [iconStart && (jsx("button", { type: "button", className: "input-group-text", id: `${id}Start`, onClick: handleOnIconStartClick, disabled: disabled || loading, "aria-label": iconStartAriaLabel, tabIndex: iconStartTabIndex, children: jsx(DIcon, { icon: iconStart, familyClass: iconStartFamilyClass, familyPrefix: iconStartFamilyPrefix }) })), jsx(Select, Object.assign({ id: `${id}Container`, inputId: id, styles: {
1305
+ }), children: [iconStart && (jsx("button", { type: "button", className: "input-group-text", id: `${id}Start`, onClick: handleOnIconStartClick, disabled: disabled || loading, "aria-label": iconStartAriaLabel, tabIndex: iconStartTabIndex, children: jsx(DIcon, { icon: iconStart, familyClass: iconStartFamilyClass, familyPrefix: iconStartFamilyPrefix }) })), jsx(Select, Object.assign({ id: `${id}Container`, inputId: id, "aria-label": ariaLabel, styles: {
1300
1306
  control: (base) => (Object.assign(Object.assign({}, base), { minHeight: 'unset' })),
1301
1307
  container: (base) => (Object.assign(Object.assign({}, base), { flex: 1 })),
1302
1308
  menu: (base) => (Object.assign(Object.assign({}, base), { width: menuWithMaxContent ? 'max-context' : '100%', zIndex: 1000 })),
@@ -1351,16 +1357,16 @@ function DDatePickerHeaderSelector({ date, changeYear, changeMonth, decreaseMont
1351
1357
  }, [date]);
1352
1358
  const [startYear, endYear] = getYearRange();
1353
1359
  if (pickerType === PickerType.Year) {
1354
- return (jsxs("div", { className: classNames('react-datepicker__header-selector react-datepicker__header-year-selector', className), style: style, children: [jsx(DButtonIcon, { icon: iconPrev || chevronLeft, size: iconSize, variant: "link", onClick: decreaseYear, disabled: prevYearButtonDisabled, ariaLabel: prevYearAriaLabel, className: "header-button" }), jsx("p", { children: `${startYear} - ${endYear}` }), jsx(DButtonIcon, { icon: iconNext || chevronRight, size: iconSize, variant: "link", onClick: increaseYear, disabled: nextYearButtonDisabled, ariaLabel: nextYearAriaLabel, className: "header-button" })] }));
1360
+ return (jsxs("div", { className: classNames('react-datepicker__header-selector react-datepicker__header-year-selector', className), style: style, children: [jsx(DButtonIcon, { icon: iconPrev || chevronLeft, size: iconSize, variant: "link", onClick: decreaseYear, disabled: prevYearButtonDisabled, "aria-label": prevYearAriaLabel, className: "header-button" }), jsx("p", { children: `${startYear} - ${endYear}` }), jsx(DButtonIcon, { icon: iconNext || chevronRight, size: iconSize, variant: "link", onClick: increaseYear, disabled: nextYearButtonDisabled, "aria-label": nextYearAriaLabel, className: "header-button" })] }));
1355
1361
  }
1356
1362
  if (pickerType === PickerType.Quarter || pickerType === PickerType.Month) {
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' } })] }));
1363
+ 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, "aria-label": 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, "aria-label": nextMonthAriaLabel, className: "header-button", style: { visibility: customHeaderCount === monthsShown - 1 ? 'visible' : 'hidden' } })] }));
1358
1364
  }
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' } })] })] }));
1365
+ 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, "aria-label": 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, "aria-label": nextMonthAriaLabel, className: "header-button", style: { visibility: customHeaderCount === monthsShown - 1 ? 'visible' : 'hidden' } })] })] }));
1360
1366
  }
1361
1367
 
1362
1368
  function DDatePicker(_a) {
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"]);
1369
+ var { inputLabel, inputHint, inputAriaLabel, ariaLabelInputTime, 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", "ariaLabelInputTime", "inputActionAriaLabel", "inputId", "timeId", "timeInputLabel", "minYearSelect", "maxYearSelect", "iconHeaderSize", "iconMaterialStyle", "iconInput", "headerPrevMonthAriaLabel", "headerNextMonthAriaLabel", "invalid", "valid", "renderCustomHeader", "className", "dateFormatCalendar", "style", "dataAttributes", "placeholder", "showHeaderSelectors", "formatHeaderDate"]);
1364
1370
  const pickerType = useMemo(() => {
1365
1371
  if (props.showQuarterYearPicker)
1366
1372
  return PickerType.Quarter;
@@ -1388,7 +1394,7 @@ function DDatePicker(_a) {
1388
1394
  ]);
1389
1395
  const defaultRenderCustomHeader = useCallback((headerProps) => (jsx(DatePickerHeader, Object.assign({}, headerProps))), [DatePickerHeader]);
1390
1396
  const renderCustomHeader = useMemo(() => (renderCustomHeaderProp || defaultRenderCustomHeader), [defaultRenderCustomHeader, renderCustomHeaderProp]);
1391
- return (jsx(DatePicker, Object.assign({}, dataAttributes, props, { calendarClassName: "d-date-picker", renderCustomHeader: renderCustomHeader, placeholderText: placeholder, 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 })) })));
1397
+ return (jsx(DatePicker, Object.assign({}, dataAttributes, props, { calendarClassName: "d-date-picker", renderCustomHeader: renderCustomHeader, placeholderText: placeholder, 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, "aria-label": ariaLabelInputTime })) })));
1392
1398
  }
1393
1399
 
1394
1400
  function DLayoutPane({ className, style, children, cols, colsXs, colsSm, colsMd, colsLg, colsXl, colsXxl, dataAttributes, }) {
@@ -1665,7 +1671,57 @@ function DPasswordStrengthMeter({ id, label = 'Password', placeholder, value = '
1665
1671
  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
1672
  }
1667
1673
 
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, }) {
1674
+ function DInputCheck(_a) {
1675
+ 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"]);
1676
+ const innerRef = useRef(null);
1677
+ const innerId = useId();
1678
+ const id = useMemo(() => idProp || innerId, [idProp, innerId]);
1679
+ const handleChange = useCallback((event) => {
1680
+ onChange === null || onChange === void 0 ? void 0 : onChange(event);
1681
+ }, [onChange]);
1682
+ const ariaDescribedby = useMemo(() => ([
1683
+ !!hint && `${id}Hint`,
1684
+ ]
1685
+ .filter(Boolean)
1686
+ .join(' ')), [
1687
+ id,
1688
+ hint,
1689
+ ]);
1690
+ useEffect(() => {
1691
+ if (innerRef.current) {
1692
+ innerRef.current.indeterminate = Boolean(indeterminate);
1693
+ }
1694
+ }, [indeterminate]);
1695
+ useEffect(() => {
1696
+ if (innerRef.current) {
1697
+ innerRef.current.checked = checked;
1698
+ }
1699
+ }, [checked]);
1700
+ const inputComponent = useMemo(() => (jsx("input", Object.assign({ ref: innerRef, onChange: handleChange, className: classNames('form-check-input', {
1701
+ 'is-invalid': invalid,
1702
+ 'is-valid': valid,
1703
+ }, inputClassName), style: style, id: id, disabled: disabled, type: type, name: name, value: value, "aria-label": ariaLabel }, ariaDescribedby && { 'aria-describedby': ariaDescribedby }, props))), [
1704
+ handleChange,
1705
+ invalid,
1706
+ valid,
1707
+ inputClassName,
1708
+ style,
1709
+ id,
1710
+ disabled,
1711
+ type,
1712
+ name,
1713
+ value,
1714
+ ariaLabel,
1715
+ ariaDescribedby,
1716
+ props,
1717
+ ]);
1718
+ if (!label) {
1719
+ return inputComponent;
1720
+ }
1721
+ 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 }))] })));
1722
+ }
1723
+
1724
+ 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, 'aria-label': ariaLabel = 'Pin character number', }) {
1669
1725
  const innerId = useId();
1670
1726
  const id = useMemo(() => idProp || innerId, [idProp, innerId]);
1671
1727
  const [pattern, setPattern] = useState('');
@@ -1742,7 +1798,7 @@ function DInputPin({ id: idProp, label = '', placeholder, type = 'text', disable
1742
1798
  'form-control': true,
1743
1799
  'is-invalid': invalid,
1744
1800
  'is-valid': valid,
1745
- }), value: activeInput[index], type: secret ? 'password' : type, "aria-describedby": `${id}State`, inputMode: innerInputMode, id: `pinIndex${index}`, name: `pin-${index}`, maxLength: 1, onInput: (event) => nextInput(event, index), onKeyDown: (event) => prevInput(event, index), onFocus: () => focusInput(index), onWheel: wheelInput, onClick: (event) => event.preventDefault(), onPaste: (event) => handlePaste(event), autoComplete: "off", placeholder: placeholder, disabled: disabled || loading, required: true }, type === 'number' && ({ min: 0, max: 9 })), index))), loading && (jsx("div", { className: "input-group-text", 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 }))] })));
1801
+ }), value: activeInput[index], type: secret ? 'password' : type, "aria-label": `${ariaLabel} ${index + 1} of ${characters}`, inputMode: innerInputMode, id: `pinIndex${index}`, name: `pin-${index}`, maxLength: 1, onInput: (event) => nextInput(event, index), onKeyDown: (event) => prevInput(event, index), onFocus: () => focusInput(index), onWheel: wheelInput, onClick: (event) => event.preventDefault(), onPaste: (event) => handlePaste(event), autoComplete: "off", placeholder: placeholder, disabled: disabled || loading, required: true }, type === 'number' && ({ min: 0, max: 9 })), index))), loading && (jsx("div", { className: "input-group-text", 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 }))] })));
1746
1802
  }
1747
1803
 
1748
1804
  function DInputSelect({ id: idProp, name, label = '', className, style, options = [], disabled = false, loading = false, iconStart, iconStartFamilyClass, iconStartFamilyPrefix, iconStartAriaLabel, iconEnd, iconEndFamilyClass, iconEndFamilyPrefix, iconEndAriaLabel, hint, value, size, floatingLabel = false, invalid = false, valid = false, dataAttributes, valueExtractor, labelExtractor, onChange, onBlur, onIconStartClick, onIconEndClick, }) {
@@ -2056,9 +2112,7 @@ function DPopover({ children, renderComponent, open, setOpen, adjustContentToRen
2056
2112
  }, [open]);
2057
2113
  const onOpenChange = useCallback((value) => {
2058
2114
  setIsOpen(value);
2059
- if (setOpen) {
2060
- setOpen(value);
2061
- }
2115
+ setOpen === null || setOpen === void 0 ? void 0 : setOpen(value);
2062
2116
  }, [setOpen]);
2063
2117
  const { refs, floatingStyles, context, } = useFloating({
2064
2118
  open: isOpen,
@@ -2082,7 +2136,12 @@ function DPopover({ children, renderComponent, open, setOpen, adjustContentToRen
2082
2136
  const generateStyleVariables = useMemo(() => (Object.assign(Object.assign({}, style), (adjustContentToRender && {
2083
2137
  [`--${PREFIX_BS}popover-component-min-width`]: 'auto',
2084
2138
  }))), [style, adjustContentToRender]);
2085
- return (jsxs("div", Object.assign({ className: classNames('d-popover', className), style: generateStyleVariables }, dataAttributes, { children: [jsx("div", Object.assign({ ref: refs.setReference }, getReferenceProps(), { children: renderComponent(isOpen) })), isOpen && (jsx(FloatingFocusManager, { context: context, modal: false, children: jsx("div", Object.assign({ className: classNames('d-popover-content', {
2139
+ const triggerElement = renderComponent(isOpen);
2140
+ if (!isValidElement(triggerElement)) {
2141
+ throw new Error('renderComponent must return a valid React element');
2142
+ }
2143
+ const reference = cloneElement(triggerElement, Object.assign({ ref: refs.setReference }, getReferenceProps(triggerElement.props)));
2144
+ return (jsxs("div", Object.assign({ className: classNames('d-popover', className), style: generateStyleVariables }, dataAttributes, { children: [reference, isOpen && (jsx(FloatingFocusManager, { context: context, modal: false, children: jsx("div", Object.assign({ className: classNames('d-popover-content', {
2086
2145
  'w-100': adjustContentToRender,
2087
2146
  }), ref: refs.setFloating, style: floatingStyles, "aria-labelledby": headingId }, getFloatingProps(), { children: children })) }))] })));
2088
2147
  }
@@ -2191,7 +2250,7 @@ function DTooltip({ className, childrenClassName, style, offSet = ARROW_HEIGHT +
2191
2250
  function DTimeline({ className, style, dataAttributes, items, }) {
2192
2251
  return (jsx("div", Object.assign({ style: style, className: classNames('d-timeline', className) }, dataAttributes, { children: items.map((item, index) => (jsxs("div", { className: classNames('d-timeline-item', {
2193
2252
  [`d-timeline-item-${item.status}`]: item.status,
2194
- }), children: [jsx("div", { className: "d-timeline-item-connector" }), jsx("div", { className: "d-timeline-item-icon", children: jsx("i", { className: `bi bi-${item.icon || 'check'}` }) }), jsxs("div", { className: "d-timeline-item-content", children: [jsx("div", { className: "d-timeline-item-title", children: item.title }), item.description && jsx("div", { className: "d-timeline-item-description", children: item.description }), item.time && jsx("div", { className: "d-timeline-item-time", children: item.time }), item.children] })] }, index))) })));
2253
+ }), children: [jsx("div", { className: "d-timeline-item-connector" }), jsx("div", { className: "d-timeline-item-icon", children: jsx(DIcon, { icon: item.icon || 'check', size: "1rem" }) }), jsxs("div", { className: "d-timeline-item-content", children: [jsx("div", { className: "d-timeline-item-title", children: item.title }), item.description && jsx("div", { className: "d-timeline-item-description", children: item.description }), item.time && jsx("div", { className: "d-timeline-item-time", children: item.time }), item.children] })] }, index))) })));
2195
2254
  }
2196
2255
 
2197
2256
  const TabContext = createContext(undefined);
@@ -2211,7 +2270,7 @@ function DTabContent({ tab, children, className, style, }) {
2211
2270
  return (jsx("div", { className: classNames('tab-pane fade show active', className), id: `${tab}Pane`, role: "tabpanel", tabIndex: 0, "aria-labelledby": `${tab}Tab`, style: style, children: children }));
2212
2271
  }
2213
2272
 
2214
- function DTabs({ children, defaultSelected, onChange, options, className, classNameTab, style, vertical, variant = 'underline', dataAttributes, }) {
2273
+ function DTabs({ children, defaultSelected, onChange, options, className, classNameTab, style, vertical, variant = 'underline', dataAttributes, ariaLabel, ariaLabelledBy, }) {
2215
2274
  const [selected, setSelected] = useState(defaultSelected);
2216
2275
  const onSelect = useCallback((option) => {
2217
2276
  if (option.tab) {
@@ -2222,17 +2281,83 @@ function DTabs({ children, defaultSelected, onChange, options, className, classN
2222
2281
  useEffect(() => {
2223
2282
  setSelected(defaultSelected);
2224
2283
  }, [defaultSelected]);
2284
+ const generateClasses = useMemo(() => (Object.assign({ nav: true, 'flex-column align-items-center': vertical && variant !== 'tabs', [`nav-${variant}`]: true }, className && { [className]: true })), [vertical, variant, className]);
2285
+ const tabRefs = useRef([]);
2286
+ useEffect(() => {
2287
+ tabRefs.current = options.map((_, i) => tabRefs.current[i] || createRef());
2288
+ }, [options]);
2289
+ // Ensure selected is never disabled
2290
+ useEffect(() => {
2291
+ if (options.length === 0)
2292
+ return;
2293
+ const selectedOption = options.find((opt) => opt.tab === selected);
2294
+ if (selectedOption && selectedOption.disabled) {
2295
+ const firstEnabled = options.find((opt) => !opt.disabled);
2296
+ if (firstEnabled)
2297
+ setSelected(firstEnabled.tab);
2298
+ }
2299
+ }, [options, selected]);
2300
+ // Declarative focus management
2301
+ const focusTab = (idx) => {
2302
+ var _a;
2303
+ if ((_a = tabRefs.current[idx]) === null || _a === void 0 ? void 0 : _a.current) {
2304
+ tabRefs.current[idx].current.focus();
2305
+ }
2306
+ };
2307
+ // Focus selected tab when selected changes
2308
+ useEffect(() => {
2309
+ const idx = options.findIndex((opt) => opt.tab === selected && !opt.disabled);
2310
+ if (idx !== -1) {
2311
+ focusTab(idx);
2312
+ }
2313
+ }, [selected, options]);
2314
+ const handleKeyDown = useCallback((idx, e) => {
2315
+ const count = options.length;
2316
+ if (count === 0)
2317
+ return;
2318
+ let next = idx;
2319
+ let prev = idx;
2320
+ if (e.key === 'ArrowRight' || (vertical && e.key === 'ArrowDown')) {
2321
+ e.preventDefault();
2322
+ for (let i = 0; i < count; i += 1) {
2323
+ next = (next + 1) % count;
2324
+ if (!options[next].disabled) {
2325
+ focusTab(next);
2326
+ setSelected(options[next].tab);
2327
+ break;
2328
+ }
2329
+ }
2330
+ }
2331
+ if (e.key === 'ArrowLeft' || (vertical && e.key === 'ArrowUp')) {
2332
+ e.preventDefault();
2333
+ for (let i = 0; i < count; i += 1) {
2334
+ prev = (prev - 1 + count) % count;
2335
+ if (!options[prev].disabled) {
2336
+ focusTab(prev);
2337
+ setSelected(options[prev].tab);
2338
+ break;
2339
+ }
2340
+ }
2341
+ }
2342
+ }, [options, vertical]);
2343
+ let tablistProps = {};
2344
+ if (ariaLabelledBy) {
2345
+ tablistProps = { 'aria-labelledby': ariaLabelledBy };
2346
+ }
2347
+ else if (ariaLabel) {
2348
+ tablistProps = { 'aria-label': ariaLabel };
2349
+ }
2225
2350
  const isSelected = useCallback((tab) => (selected === tab), [selected]);
2226
2351
  const value = useMemo(() => ({
2227
2352
  isSelected,
2228
2353
  }), [isSelected]);
2229
- const generateClasses = useMemo(() => (Object.assign({ nav: true, 'flex-column align-items-center': vertical && variant !== 'tabs', [`nav-${variant}`]: true }, className && { [className]: true })), [vertical, variant, className]);
2230
2354
  return (jsx(TabContext.Provider, { value: value, children: jsxs("div", Object.assign({ className: classNames({
2231
2355
  'd-flex w-100': true,
2232
2356
  'flex-column': !vertical || variant === 'tabs',
2233
- }), style: style }, dataAttributes, { children: [jsx("nav", { className: classNames(generateClasses), children: options.map((option) => (jsx("button", { id: `${option.tab}Tab`, className: classNames('nav-link', {
2234
- active: option.tab === selected,
2235
- }, classNameTab), type: "button", role: "tab", "aria-controls": `${option.tab}Pane`, "aria-selected": option.tab === selected, disabled: option.disabled, onClick: () => onSelect(option), children: option.label }, option.tab))) }), jsx("div", { className: "tab-content w-100", children: children })] })) }));
2357
+ }), style: style }, dataAttributes, { children: [jsx("ul", Object.assign({ className: classNames(generateClasses), role: "tablist", "aria-orientation": vertical ? 'vertical' : undefined }, tablistProps, { children: options.map((option, idx) => {
2358
+ const isTabSelected = !!option.tab && option.tab === selected;
2359
+ return (jsx("li", { role: "presentation", className: "nav-item", children: jsx("button", { ref: tabRefs.current[idx], id: `${option.tab}Tab`, className: classNames('nav-link', { active: isTabSelected }, classNameTab), type: "button", role: "tab", "aria-controls": `${option.tab}Pane`, "aria-selected": isTabSelected, tabIndex: isTabSelected ? 0 : -1, disabled: option.disabled, onClick: () => onSelect(option), onKeyDown: (e) => handleKeyDown(idx, e), children: option.label }) }, option.tab));
2360
+ }) })), jsx("div", { className: "tab-content w-100", children: children })] })) }));
2236
2361
  }
2237
2362
  var DTabs$1 = Object.assign(DTabs, {
2238
2363
  Tab: DTabContent,
@@ -2417,8 +2542,12 @@ ForwardedDInputPhone.displayName = 'DInputPhone';
2417
2542
 
2418
2543
  const DEFAULT_IMAGE = 'https://cdn.modyo.cloud/uploads/06b434f7-b943-4f54-9543-84a904e189aa/original/Visa_Logo_1_.png';
2419
2544
  const CHIP_IMAGE = 'https://cdn.modyo.cloud/uploads/4660ad00-e5d8-477e-8919-52b53d0a26fb/original/chip-debit-svgrepo-com_1_.png';
2545
+ const BRAND_LOGOS = {
2546
+ visa: DEFAULT_IMAGE,
2547
+ mastercard: 'https://cdn.modyo.cloud/uploads/f686b9aa-65ab-4369-9db3-89ceece84f29/original/mastercard.png',
2548
+ };
2420
2549
  function DCreditCard({ brand = 'visa', name, number, holderText = 'Card Holder', logoImage, isChipVisible = true, className, isVertical = false, }) {
2421
- return (jsxs("div", { className: classNames('d-credit-card overflow-hidden text-white', 'position-relative rounded-3', 'd-none d-lg-flex', isVertical && 'is-vertical', className), children: [jsxs("div", { className: "d-credit-card-header", children: [jsx("img", { src: logoImage || DEFAULT_IMAGE, alt: brand, className: "d-credit-card-logo", width: 100 }), isChipVisible && (jsx("div", { className: "d-credit-card-chip p-2 rounded-2", children: jsx("img", { src: CHIP_IMAGE, alt: "chip", width: 30, className: "d-credit-card-chip-image" }) }))] }), jsxs("div", { className: "d-credit-card-details mt-auto d-none d-sm-block", children: [jsx("div", { className: "d-credit-card-number d-none d-sm-block mb-4", children: number }), jsx("small", { className: "d-block opacity-50", children: holderText }), jsx("span", { className: "name", children: name })] })] }));
2550
+ return (jsxs("div", { className: classNames('d-credit-card', isVertical && 'is-vertical', className), children: [jsxs("div", { className: "d-credit-card-header", children: [jsx("img", { src: logoImage || BRAND_LOGOS[brand] || DEFAULT_IMAGE, alt: brand, className: "d-credit-card-logo", width: 100 }), isChipVisible && (jsx("div", { className: "d-credit-card-chip", children: jsx("img", { src: CHIP_IMAGE, alt: "chip", width: 30, className: "d-credit-card-chip-image" }) }))] }), jsxs("div", { className: "d-credit-card-details", children: [jsx("div", { className: "d-credit-card-number", children: number }), jsx("small", { className: "d-credit-card-holder-text", children: holderText }), jsx("span", { className: "d-credit-card-name", children: name })] })] }));
2422
2551
  }
2423
2552
 
2424
2553
  const getItemClass = (action) => {
@@ -2440,7 +2569,6 @@ function DDropdown({ actions, dropdownToggle, className, }) {
2440
2569
  document.addEventListener('mousedown', handleClickOutside);
2441
2570
  return () => document.removeEventListener('mousedown', handleClickOutside);
2442
2571
  }, []);
2443
- // 🆕 Calcular posición del menú al abrir
2444
2572
  useEffect(() => {
2445
2573
  if (open && dropdownRef.current) {
2446
2574
  const rect = dropdownRef.current.getBoundingClientRect();
@@ -2467,7 +2595,7 @@ function DDropdown({ actions, dropdownToggle, className, }) {
2467
2595
  }
2468
2596
  }
2469
2597
  else {
2470
- ToggleElement = (jsx(DButtonIcon, { variant: "link", stopPropagationEnabled: false, onClick: () => setOpen(!open), icon: "MoreVertical" }));
2598
+ ToggleElement = (jsx(DButtonIcon, { variant: "link", stopPropagationEnabled: false, "aria-label": "Toggle Dropdown", "aria-haspopup": "menu", "aria-expanded": open, onClick: () => setOpen(!open), icon: "MoreVertical" }));
2471
2599
  }
2472
2600
  return (jsxs("div", { className: `dropdown position-relative drop-${position} ${className}`, ref: dropdownRef, children: [ToggleElement, jsx("ul", { style: {
2473
2601
  position: 'absolute',
@@ -2560,7 +2688,7 @@ function useScreenshotWebShare() {
2560
2688
  };
2561
2689
  }
2562
2690
 
2563
- function DVoucher({ amount, amountDetails, icon = 'CircleCheckBig', color = 'success', title, onError, message, downloadText = 'Download', shareText = 'Share', children, }) {
2691
+ function DVoucher({ amount, amountDetails, icon, title, onError, message, downloadText = 'Download', shareText = 'Share', className, children, }) {
2564
2692
  const { shareRef, share } = useScreenshotWebShare();
2565
2693
  const { downloadRef, download } = useScreenshotDownload();
2566
2694
  const handleShare = () => {
@@ -2585,10 +2713,25 @@ function DVoucher({ amount, amountDetails, icon = 'CircleCheckBig', color = 'suc
2585
2713
  // Error already handled by onError
2586
2714
  });
2587
2715
  };
2588
- return (jsx("div", { className: "d-voucher", ref: (el) => {
2716
+ const defaultIconProps = {
2717
+ icon: 'CircleCheckBig',
2718
+ color: 'success',
2719
+ size: '2rem',
2720
+ hasCircle: true,
2721
+ };
2722
+ const resolvedIconProps = (() => {
2723
+ if (icon === false || icon == null)
2724
+ return null;
2725
+ if (typeof icon === 'string')
2726
+ return Object.assign(Object.assign({}, defaultIconProps), { icon });
2727
+ if (typeof icon === 'object')
2728
+ return Object.assign(Object.assign({}, defaultIconProps), icon);
2729
+ return defaultIconProps;
2730
+ })();
2731
+ return (jsx("div", { className: classNames('d-voucher', className), ref: (el) => {
2589
2732
  shareRef.current = el;
2590
2733
  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" })] })] }) }));
2734
+ }, children: jsxs("div", { children: [jsxs("div", { className: "d-voucher-header", children: [resolvedIconProps && (jsx(DIcon, Object.assign({}, resolvedIconProps))), 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
2735
  }
2593
2736
 
2594
2737
  function useCountdown(seconds) {
@@ -2627,7 +2770,7 @@ const defaultMessage = (secs) => (secs > 0
2627
2770
  : "Didn't get any code?");
2628
2771
  function OtpCountdown({ seconds, resendText, message, }) {
2629
2772
  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 })] }));
2773
+ return (jsxs("div", { className: "d-flex gap-2 align-items-center", children: [jsx("p", { className: "mb-0 flex-1", children: message ? message(secondsLeft) : defaultMessage(secondsLeft) }), jsx(DButton, { text: resendText, variant: "link", className: "text-nowrap", disabled: secondsLeft > 0, onClick: restartCountdown })] }));
2631
2774
  }
2632
2775
 
2633
2776
  const TEXT_PROPS = {
@@ -2660,5 +2803,63 @@ function DOtp({ className, action, isLoading, otpSize = 6, texts = TEXT_PROPS, s
2660
2803
  }, loading: isLoading }), jsx("p", { className: "small ms-lg-auto mb-0", children: texts.contact })] })] })] }));
2661
2804
  }
2662
2805
 
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 };
2806
+ function DefaultErrorBoundary({ resetErrorBoundary }) {
2807
+ return (jsx(DAlert, { color: "danger", showClose: false, children: jsxs("div", { className: "d-flex align-items-center gap-2", children: [jsx("span", { children: "An unexpected error occurred." }), jsx(DButton, { color: "secondary", variant: "outline", size: "sm", onClick: resetErrorBoundary, children: "Retry" })] }) }));
2808
+ }
2809
+
2810
+ function DErrorBoundary({ name, fallback, resetKeys, onReset, onError, children, }) {
2811
+ const handleError = useCallback((error, info) => {
2812
+ // eslint-disable-next-line no-console
2813
+ console.error(`[DErrorBoundary${name ? `:${name}` : ''}]`, getErrorMessage(error), info);
2814
+ onError === null || onError === void 0 ? void 0 : onError(error, info);
2815
+ }, [name, onError]);
2816
+ const FallbackRender = useCallback((props) => {
2817
+ if (fallback)
2818
+ return fallback(props);
2819
+ return (jsx(DefaultErrorBoundary, { resetErrorBoundary: props.resetErrorBoundary }));
2820
+ }, [fallback]);
2821
+ return (jsx(ErrorBoundary, { resetKeys: resetKeys, onReset: onReset, onError: handleError, fallbackRender: FallbackRender, children: children }));
2822
+ }
2823
+
2824
+ function ErrorState({ message, onRetry, retryMessage = 'Retry', color = 'danger', }) {
2825
+ return (jsxs(DAlert, { color: color, className: "d-flex align-items-center gap-3", children: [jsx("div", { className: "flex-grow-1", children: jsx("p", { className: "mb-0", children: message !== null && message !== void 0 ? message : 'An unexpected error occurred.' }) }), onRetry && (jsx(DButton, { onClick: onRetry, text: retryMessage, variant: "outline", iconStart: "RefreshCw" }))] }));
2826
+ }
2827
+
2828
+ function EmptyState({ message, icon = 'FileText', actionText, onAction, }) {
2829
+ return (jsxs("div", { className: "d-flex flex-column align-items-center justify-content-center p-5 text-center", children: [jsx(DIcon, { icon: icon, size: "3rem", className: "text-secondary mb-3" }), jsx("p", { className: "text-secondary mb-3", children: message !== null && message !== void 0 ? message : 'No data available.' }), actionText && onAction && (jsx(DButton, { onClick: onAction, text: actionText, variant: "outline" }))] }));
2830
+ }
2831
+
2832
+ function LoadingState({ ariaLabel = 'Loading...', className }) {
2833
+ return (jsx("div", { className: `d-flex align-items-center justify-content-center p-4 ${className || ''}`.trim(), "aria-busy": "true", "aria-live": "polite", children: jsx("span", { className: "spinner-border", role: "status", "aria-label": ariaLabel }) }));
2834
+ }
2835
+
2836
+ function render(renderable) {
2837
+ if (renderable === undefined)
2838
+ return null;
2839
+ return typeof renderable === 'function' ? renderable() : renderable;
2840
+ }
2841
+ function DDataStateWrapper({ isLoading, isError, data, onRetry, renderLoading, renderEmpty, renderError, children, }) {
2842
+ // 1. Loading
2843
+ if (isLoading) {
2844
+ if (renderLoading)
2845
+ return render(renderLoading);
2846
+ return jsx(LoadingState, {});
2847
+ }
2848
+ // 2. Error
2849
+ if (isError) {
2850
+ if (renderError)
2851
+ return render(renderError);
2852
+ return (jsx(ErrorState, { onRetry: onRetry }));
2853
+ }
2854
+ // 3. Empty
2855
+ if (!(data === null || data === void 0 ? void 0 : data.length)) {
2856
+ if (renderEmpty)
2857
+ return render(renderEmpty);
2858
+ return (jsx(EmptyState, {}));
2859
+ }
2860
+ // 4. Success
2861
+ return jsx(Fragment, { children: children(data) });
2862
+ }
2863
+
2864
+ 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, DDataStateWrapper, DDatePicker, DDropdown, DErrorBoundary, 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 };
2664
2865
  //# sourceMappingURL=index.esm.js.map