@dynamic-framework/ui-react 2.0.0-dev.4 → 2.0.0-dev.6

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 (37) hide show
  1. package/dist/css/dynamic-ui-non-root.css +66 -46
  2. package/dist/css/dynamic-ui-non-root.min.css +2 -2
  3. package/dist/css/dynamic-ui-root.css +1 -1
  4. package/dist/css/dynamic-ui-root.min.css +1 -1
  5. package/dist/css/dynamic-ui.css +66 -46
  6. package/dist/css/dynamic-ui.min.css +2 -2
  7. package/dist/index.esm.js +290 -64
  8. package/dist/index.esm.js.map +1 -1
  9. package/dist/index.js +280 -53
  10. package/dist/index.js.map +1 -1
  11. package/dist/types/components/DBoxFile/DBoxFile.d.ts +1 -1
  12. package/dist/types/components/DButton/DButton.d.ts +7 -17
  13. package/dist/types/components/DIconBase/DIconBase.d.ts +1 -1
  14. package/dist/types/components/DInputCheck/DInputCheck.d.ts +2 -1
  15. package/dist/types/components/DInputSwitch/DInputSwitch.d.ts +2 -1
  16. package/dist/types/components/DModal/DModal.d.ts +3 -1
  17. package/dist/types/components/DOffcanvas/DOffcanvas.d.ts +3 -1
  18. package/dist/types/components/DPasswordStrengthMeter/DPasswordStrengthMeter.d.ts +23 -0
  19. package/dist/types/components/DPasswordStrengthMeter/PasswordCheckItem.d.ts +7 -0
  20. package/dist/types/components/DPasswordStrengthMeter/PasswordCheckList.d.ts +14 -0
  21. package/dist/types/components/DPasswordStrengthMeter/PasswordStrength.d.ts +6 -0
  22. package/dist/types/components/DPasswordStrengthMeter/index.d.ts +3 -0
  23. package/dist/types/components/DVoucher/DVoucher.d.ts +14 -0
  24. package/dist/types/components/DVoucher/hooks/useScreenshot.d.ts +5 -0
  25. package/dist/types/components/DVoucher/hooks/useScreenshotDownload.d.ts +5 -0
  26. package/dist/types/components/DVoucher/hooks/useScreenshotWebShare.d.ts +5 -0
  27. package/dist/types/components/DVoucher/index.d.ts +2 -0
  28. package/dist/types/components/index.d.ts +3 -1
  29. package/jest/setup.js +0 -2
  30. package/package.json +7 -4
  31. package/src/style/abstracts/variables/_buttons.scss +2 -0
  32. package/src/style/base/_buttons.scss +56 -65
  33. package/src/style/components/_+import.scss +1 -0
  34. package/src/style/components/_d-box-file.scss +1 -1
  35. package/src/style/components/_d-voucher.scss +30 -0
  36. package/dist/types/components/DTableHead/DTableHead.d.ts +0 -9
  37. 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 { jsx, jsxs, 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, { useMemo, useEffect, useState, useCallback, useContext, createContext, useLayoutEffect, forwardRef, useId, useRef, useSyncExternalStore } 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,12 +17,13 @@ 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, }) {
26
+ function DIconBase({ icon, color, style, className, size, hasCircle = false, materialStyle = false, familyClass, familyPrefix, strokeWidth = 2, dataAttributes, }) {
25
27
  // If materialStyle is true, use Material Design icons (legacy)
26
28
  const useMaterialIcons = materialStyle;
27
29
  // Get Lucide icon component
@@ -48,13 +50,7 @@ function DIconBase({ icon, color, style, className, size, hasCircle = false, mat
48
50
  return {};
49
51
  }, [hasCircle, color]);
50
52
  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
- ]);
53
+ const generateClasses = useMemo(() => (Object.assign({ 'd-icon': true }, className && { [className]: true })), [className]);
58
54
  const iconSize = useMemo(() => {
59
55
  if (size) {
60
56
  const numSize = parseInt(size, 10);
@@ -64,10 +60,13 @@ function DIconBase({ icon, color, style, className, size, hasCircle = false, mat
64
60
  }, [size]);
65
61
  // Render Material Design icon (legacy support)
66
62
  if (useMaterialIcons) {
67
- return (jsx("i", Object.assign({ className: classNames(generateClasses), style: generateStyleVariables }, dataAttributes, { children: icon })));
63
+ return (jsx("i", Object.assign({ className: classNames(generateClasses, familyClass), style: generateStyleVariables }, dataAttributes, { children: icon })));
68
64
  }
69
65
  // Render Lucide icon
70
66
  if (!LucideIcon) {
67
+ if (familyClass && familyPrefix) {
68
+ return (jsx("i", Object.assign({ className: classNames(generateClasses, familyClass, `${familyPrefix}${icon}`), style: generateStyleVariables }, dataAttributes)));
69
+ }
71
70
  // eslint-disable-next-line no-console
72
71
  console.warn(`Icon "${icon}" not found in Lucide. Make sure to use PascalCase names (e.g., "Home", "User", "Settings")`);
73
72
  return (jsx("span", Object.assign({ className: classNames(generateClasses), style: generateStyleVariables }, dataAttributes, { children: "?" })));
@@ -231,7 +230,10 @@ function DPortalContextProvider({ portalName, children, availablePortals, }) {
231
230
  return (jsxs(DPortalContext.Provider, { value: value, children: [children, created && createPortal(
232
231
  // eslint-disable-next-line max-len
233
232
  // 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))] }));
233
+ jsx("div", { onClick: ({ target }) => handleClose(target), onKeyDown: () => { }, children: jsx(AnimatePresence, { children: stack.flatMap(({ Component, name, payload, }) => [
234
+ 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`),
235
+ jsx(Component, { name: name, payload: payload }, name),
236
+ ]) }) }), document.getElementById(portalName))] }));
235
237
  }
236
238
  function useDPortalContext() {
237
239
  const context = useContext(DPortalContext);
@@ -858,36 +860,69 @@ function DBoxFile(_a) {
858
860
  const { iconMap: { upload } } = useDContext();
859
861
  const icon = useMemo(() => iconProp || upload, [iconProp, upload]);
860
862
  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', {
863
+ return (jsxs(Fragment, { children: [jsx("section", Object.assign({ className: classNames('d-box-file', {
862
864
  'd-box-file-selected': files.length > 0,
863
865
  'd-box-file-disabled': props.disabled,
864
866
  'd-box-file-valid': isDragValid,
865
867
  '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'
868
+ }, 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
869
  ? 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}`))) }))] }));
870
+ : 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
871
  }
870
872
 
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(() => {
873
+ const DButton = forwardRef((props, ref) => {
874
+ 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"]);
875
+ const [buttonWidth, setButtonWidth] = useState();
876
+ const buttonRef = useRef(null);
877
+ const isDisabled = useMemo(() => disabled || loading, [disabled, loading]);
878
+ const content = useMemo(() => children || text, [children, text]);
879
+ const classes = useMemo(() => {
873
880
  const variantClass = variant
874
881
  ? `btn-${variant}-${color}`
875
882
  : `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();
883
+ return {
884
+ btn: true,
885
+ [variantClass]: true,
886
+ [`btn-${size}`]: !!size,
887
+ loading,
888
+ };
889
+ }, [variant, color, size, loading]);
890
+ const ariaLabel = useMemo(() => {
891
+ const ariaLabelProp = rest['aria-label'];
892
+ return loading
893
+ ? loadingAriaLabel || ariaLabelProp || text
894
+ : ariaLabelProp || text;
895
+ }, [loading, loadingAriaLabel, rest, text]);
896
+ const handleClick = useCallback((event) => {
897
+ if (disabled || loading) {
898
+ event.preventDefault();
899
+ return;
881
900
  }
882
901
  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
- }
902
+ }, [disabled, loading, onClick]);
903
+ useEffect(() => {
904
+ if (!loading && buttonRef.current) {
905
+ const width = buttonRef.current.offsetWidth;
906
+ if (width > 0)
907
+ setButtonWidth(width);
908
+ }
909
+ // eslint-disable-next-line react-hooks/exhaustive-deps
910
+ }, [content, iconEnd, iconStart]);
911
+ return (jsxs("button", Object.assign({ ref: (node) => {
912
+ buttonRef.current = node;
913
+ if (typeof ref === 'function')
914
+ ref(node);
915
+ // eslint-disable-next-line max-len
916
+ // eslint-disable-next-line no-param-reassign, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
917
+ else if (ref)
918
+ ref.current = node;
919
+ },
920
+ // eslint-disable-next-line react/button-has-type
921
+ type: type, className: classNames(classes, className), style: Object.assign(Object.assign({}, style), (loading && buttonWidth
922
+ ? { minWidth: `${buttonWidth}px` }
923
+ : 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 }))] }))] })));
924
+ });
925
+ DButton.displayName = 'DButton';
891
926
 
892
927
  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
928
  const generateClasses = useMemo(() => {
@@ -1022,7 +1057,7 @@ const ForwardedDDatePickerInput = forwardRef(DDatePickerInput);
1022
1057
  ForwardedDDatePickerInput.displayName = 'DDatePickerInput';
1023
1058
 
1024
1059
  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"]);
1060
+ 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
1061
  const innerRef = useRef(null);
1027
1062
  const innerId = useId();
1028
1063
  const id = useMemo(() => idProp || innerId, [idProp, innerId]);
@@ -1050,11 +1085,11 @@ function DInputCheck(_a) {
1050
1085
  const inputComponent = useMemo(() => (jsx("input", Object.assign({ ref: innerRef, onChange: handleChange, className: classNames('form-check-input', {
1051
1086
  'is-invalid': invalid,
1052
1087
  '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))), [
1088
+ }, inputClassName), style: style, id: id, disabled: disabled, type: type, name: name, value: value, "aria-label": ariaLabel }, ariaDescribedby && { 'aria-describedby': ariaDescribedby }, props))), [
1054
1089
  handleChange,
1055
1090
  invalid,
1056
1091
  valid,
1057
- className,
1092
+ inputClassName,
1058
1093
  style,
1059
1094
  id,
1060
1095
  disabled,
@@ -1068,7 +1103,7 @@ function DInputCheck(_a) {
1068
1103
  if (!label) {
1069
1104
  return inputComponent;
1070
1105
  }
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 }))] })));
1106
+ 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
1107
  }
1073
1108
 
1074
1109
  function DSelectOptionCheck(_a) {
@@ -1223,7 +1258,7 @@ function DDatePickerHeaderSelector({ date, changeYear, changeMonth, decreaseMont
1223
1258
  if (pickerType === PickerType.Quarter || pickerType === PickerType.Month) {
1224
1259
  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
1260
  }
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' } })] })] }));
1261
+ return (jsxs(Fragment, { 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' } })] })] }));
1227
1262
  }
1228
1263
 
1229
1264
  function DDatePicker(_a) {
@@ -1492,6 +1527,86 @@ function DInputPassword(_a, ref) {
1492
1527
  const ForwardedDInputPassword = forwardRef(DInputPassword);
1493
1528
  ForwardedDInputPassword.displayName = 'DInputPassword';
1494
1529
 
1530
+ function PasswordCheckItem({ password, regex, text, }) {
1531
+ const isValid = regex.test(password);
1532
+ 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 })] }));
1533
+ }
1534
+
1535
+ const getColorClass = (strength, total) => {
1536
+ const percentage = total > 0 ? strength / total : 0;
1537
+ if (percentage === 0)
1538
+ return 'bg-gray-200';
1539
+ if (percentage <= 0.25)
1540
+ return 'bg-danger';
1541
+ if (percentage <= 0.5)
1542
+ return 'bg-warning';
1543
+ if (percentage <= 0.75)
1544
+ return 'bg-info';
1545
+ return 'bg-success';
1546
+ };
1547
+ function PasswordStrengthBar({ strength, total }) {
1548
+ const percentage = total > 0 ? (strength / total) * 100 : 0;
1549
+ 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: {
1550
+ width: `${percentage}%`,
1551
+ transition: 'width 0.3s ease-in-out',
1552
+ } }) }));
1553
+ }
1554
+
1555
+ const CHECK_REGEX = {
1556
+ uppercase: /[A-Z]/,
1557
+ lowercase: /[a-z]/,
1558
+ number: /\d/,
1559
+ specialChar: /[~!@#$^*\-_=[\]{}|;,.?]/,
1560
+ };
1561
+ function PasswordChecksList({ password, validationMessages, enabledChecks, }) {
1562
+ const allChecks = [
1563
+ {
1564
+ key: 'uppercase',
1565
+ regex: CHECK_REGEX.uppercase,
1566
+ text: validationMessages.uppercaseLetter,
1567
+ },
1568
+ {
1569
+ key: 'lowercase',
1570
+ regex: CHECK_REGEX.lowercase,
1571
+ text: validationMessages.lowercaseLetter,
1572
+ },
1573
+ {
1574
+ key: 'number',
1575
+ regex: CHECK_REGEX.number,
1576
+ text: validationMessages.number,
1577
+ },
1578
+ {
1579
+ key: 'specialChar',
1580
+ regex: CHECK_REGEX.specialChar,
1581
+ text: validationMessages.especialChar,
1582
+ },
1583
+ ];
1584
+ const passwordChecks = allChecks.filter((check) => enabledChecks.includes(check.key));
1585
+ const passed = passwordChecks.filter((r) => r.regex.test(password)).length;
1586
+ const total = passwordChecks.length;
1587
+ 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))) })] }));
1588
+ }
1589
+
1590
+ const DEFAULT_VALIDATION_MESSAGES = {
1591
+ number: 'At least one number',
1592
+ lowercaseLetter: 'At least one lowercase letter',
1593
+ uppercaseLetter: 'At least one uppercase letter',
1594
+ especialChar: 'At least one of these special characters: ~!@#$^*-_=[]{}|;,.?',
1595
+ notMatch: 'The password confirmation and the new password do not match.',
1596
+ };
1597
+ const DEFAULT_ENABLED_CHECKS = ['uppercase', 'lowercase', 'number', 'specialChar'];
1598
+ function DPasswordStrengthMeter({ id, label = 'Password', placeholder, value = '', name, disabled = false, invalid = false, validationMessages = DEFAULT_VALIDATION_MESSAGES, enabledChecks = DEFAULT_ENABLED_CHECKS, className, style, dataAttributes, onChange, }) {
1599
+ const [password, setPassword] = useState(value);
1600
+ useEffect(() => {
1601
+ setPassword(value);
1602
+ }, [value]);
1603
+ const handleChange = (newValue) => {
1604
+ setPassword(newValue);
1605
+ onChange === null || onChange === void 0 ? void 0 : onChange(newValue);
1606
+ };
1607
+ 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 })] })));
1608
+ }
1609
+
1495
1610
  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, }) {
1496
1611
  const innerId = useId();
1497
1612
  const id = useMemo(() => idProp || innerId, [idProp, innerId]);
@@ -1655,7 +1770,7 @@ function DInputSelect({ id: idProp, name, label = '', className, style, options
1655
1770
  }), 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 }))] })));
1656
1771
  }
1657
1772
 
1658
- function DInputSwitch({ id: idProp, label, ariaLabel, name, checked, disabled, invalid = false, valid = false, readonly, className, style, dataAttributes, onChange, }) {
1773
+ function DInputSwitch({ id: idProp, label, ariaLabel, name, checked, disabled, invalid = false, valid = false, readonly, className, style, dataAttributes, inputClassName, onChange, }) {
1659
1774
  const innerId = useId();
1660
1775
  const id = useMemo(() => idProp || innerId, [idProp, innerId]);
1661
1776
  const [internalIsChecked, setInternalIsChecked] = useState(checked);
@@ -1667,10 +1782,10 @@ function DInputSwitch({ id: idProp, label, ariaLabel, name, checked, disabled, i
1667
1782
  setInternalIsChecked(value);
1668
1783
  onChange === null || onChange === void 0 ? void 0 : onChange(value);
1669
1784
  }, [onChange]);
1670
- 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', {
1785
+ return (jsxs("div", Object.assign({ className: classNames('form-check', className) }, dataAttributes, { children: [jsx("input", { id: id, name: name, onChange: readonly ? () => false : changeHandler, className: classNames('form-check-input', {
1671
1786
  'is-invalid': invalid,
1672
1787
  'is-valid': valid,
1673
- }, 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 }))] })));
1788
+ }, 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 }))] })));
1674
1789
  }
1675
1790
 
1676
1791
  function DInputRange(_a, ref) {
@@ -1705,7 +1820,7 @@ function DInputRange(_a, ref) {
1705
1820
  if (!label) {
1706
1821
  return inputComponent;
1707
1822
  }
1708
- return (jsxs(Fragment$1, { children: [jsx("label", { className: "form-label", htmlFor: id, children: label }), inputComponent] }));
1823
+ return (jsxs(Fragment, { children: [jsx("label", { className: "form-label", htmlFor: id, children: label }), inputComponent] }));
1709
1824
  }
1710
1825
  const ForwardedDInputRange = forwardRef(DInputRange);
1711
1826
  ForwardedDInputRange.displayName = 'DInputRange';
@@ -1769,7 +1884,7 @@ var DListGroup$1 = Object.assign(DListGroup, {
1769
1884
  function DModalHeader({ showCloseButton, onClose, children, className, style, iconFamilyClass, iconFamilyPrefix, icon: iconProp, materialStyle = false, }) {
1770
1885
  const { iconMap: { xLg, }, } = useDContext();
1771
1886
  const icon = useMemo(() => iconProp || xLg, [iconProp, xLg]);
1772
- 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" })] }));
1887
+ 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" })] }));
1773
1888
  }
1774
1889
 
1775
1890
  function DModalBody({ children, className, style, }) {
@@ -1781,10 +1896,14 @@ function DModalFooter({ className, style, actionPlacement, children, }) {
1781
1896
  'modal-footer': true,
1782
1897
  [`d-modal-action-${actionPlacement}`]: !!actionPlacement,
1783
1898
  }), [actionPlacement]);
1784
- return (jsxs(Fragment$1, { children: [jsx("div", { className: "d-modal-separator" }), jsx("div", { className: classNames(generateClasses, className), style: style, children: children })] }));
1899
+ return (jsxs(Fragment, { children: [jsx("div", { className: "d-modal-separator" }), jsx("div", { className: classNames(generateClasses, className), style: style, children: children })] }));
1785
1900
  }
1786
1901
 
1787
- function DModal({ name, className, style, staticBackdrop, scrollable, centered, fullScreen, fullScreenFrom, size, children, dataAttributes, }) {
1902
+ const defaultTransition$1 = {
1903
+ ease: 'easeInOut',
1904
+ duration: 0.3,
1905
+ };
1906
+ function DModal({ name, className, style, staticBackdrop, scrollable, centered, fullScreen, fullScreenFrom, size, transition, children, dataAttributes, }) {
1788
1907
  const fullScreenClass = useMemo(() => {
1789
1908
  if (fullScreen) {
1790
1909
  if (fullScreenFrom) {
@@ -1795,7 +1914,7 @@ function DModal({ name, className, style, staticBackdrop, scrollable, centered,
1795
1914
  return '';
1796
1915
  }, [fullScreenFrom, fullScreen]);
1797
1916
  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]);
1798
- 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 && ({
1917
+ 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 && ({
1799
1918
  [`data-${PREFIX_BS}backdrop`]: 'static',
1800
1919
  [`data-${PREFIX_BS}keyboard`]: 'false',
1801
1920
  }), dataAttributes, { children: jsx("div", { className: classNames(generateModalDialogClasses), children: jsx("div", { className: "modal-content", children: children }) }) })));
@@ -1809,7 +1928,7 @@ var DModal$1 = Object.assign(DModal, {
1809
1928
  function DOffcanvasHeader({ showCloseButton, onClose, children, className, style, iconFamilyClass, iconFamilyPrefix, icon: iconProp, materialStyle = false, }) {
1810
1929
  const { iconMap: { xLg, }, } = useDContext();
1811
1930
  const icon = useMemo(() => iconProp || xLg, [iconProp, xLg]);
1812
- 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" })] }));
1931
+ 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" })] }));
1813
1932
  }
1814
1933
 
1815
1934
  function DOffcanvasBody({ children, className, style, }) {
@@ -1821,13 +1940,39 @@ function DOffcanvasFooter({ actionPlacement, children, className, style, }) {
1821
1940
  'd-offcanvas-footer': true,
1822
1941
  [`d-offcanvas-action-${actionPlacement}`]: !!actionPlacement,
1823
1942
  }), [actionPlacement]);
1824
- return (jsxs(Fragment$1, { children: [jsx("div", { className: "d-offcanvas-separator" }), jsx("div", { className: classNames(generateClasses, className), style: style, children: children })] }));
1943
+ return (jsxs(Fragment, { children: [jsx("div", { className: "d-offcanvas-separator" }), jsx("div", { className: classNames(generateClasses, className), style: style, children: children })] }));
1825
1944
  }
1826
1945
 
1827
- function DOffcanvas({ name, className, style, staticBackdrop, scrollable, openFrom = 'end', children, dataAttributes, }) {
1828
- return (jsx("div", Object.assign({ className: classNames('offcanvas portal show', {
1946
+ const variants = {
1947
+ hidden: (openFrom) => {
1948
+ const properties = {};
1949
+ if (openFrom === 'start') {
1950
+ properties.x = '-100%';
1951
+ }
1952
+ if (openFrom === 'end') {
1953
+ properties.x = '100%';
1954
+ }
1955
+ if (openFrom === 'top') {
1956
+ properties.y = '-100%';
1957
+ }
1958
+ if (openFrom === 'bottom') {
1959
+ properties.y = '100%';
1960
+ }
1961
+ return properties;
1962
+ },
1963
+ visible: {
1964
+ x: 0,
1965
+ y: 0,
1966
+ },
1967
+ };
1968
+ const defaultTransition = {
1969
+ ease: 'easeInOut',
1970
+ duration: 0.3,
1971
+ };
1972
+ function DOffcanvas({ name, className, style, staticBackdrop, scrollable, openFrom = 'end', transition, children, dataAttributes, }) {
1973
+ return (jsx(motion.div, Object.assign({ className: classNames('offcanvas portal show', {
1829
1974
  [`offcanvas-${openFrom}`]: openFrom,
1830
- }, className), style: style, id: name, tabIndex: -1, "aria-labelledby": `${name}Label`, "aria-hidden": "false" }, staticBackdrop && ({
1975
+ }, 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 && ({
1831
1976
  [`data-${PREFIX_BS}backdrop`]: 'static',
1832
1977
  [`data-${PREFIX_BS}keyboard`]: 'false',
1833
1978
  }), scrollable && ({
@@ -1940,7 +2085,7 @@ function DStepper$1({ options, currentStep, className, style, }) {
1940
2085
  from 0deg,
1941
2086
  var(--${PREFIX_BS}step-progress-outter-fill-background-color) ${currentAngle}deg,
1942
2087
  var(--${PREFIX_BS}step-progress-outter-background-color) 0deg)`, [currentAngle]);
1943
- 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 || '' })] })) })] }));
2088
+ 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 || '' })] })) })] }));
1944
2089
  }
1945
2090
 
1946
2091
  function DStepper({ options, currentStep, iconSuccess, iconSuccessFamilyClass, iconSuccessFamilyPrefix, iconSuccessMaterialStyle = false, vertical = false, breakpoint = 'lg', className, completed = false, style, dataAttributes, }) {
@@ -1982,7 +2127,7 @@ function DTooltip({ className, childrenClassName, style, offSet = ARROW_HEIGHT +
1982
2127
  role,
1983
2128
  ]);
1984
2129
  const generateClasses = useMemo(() => (Object.assign({ 'tooltip show': true, [`tooltip-${size}`]: !!size }, className && { [className]: true })), [size, className]);
1985
- 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 })] }))) })] }));
2130
+ 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 })] }))) })] }));
1986
2131
  }
1987
2132
 
1988
2133
  function DTimeline({ className, style, dataAttributes, items, }) {
@@ -2081,19 +2226,6 @@ function useDToast() {
2081
2226
  };
2082
2227
  }
2083
2228
 
2084
- function DTableHead({ className, style, field, label, value = '', onChange, }) {
2085
- const handleOnChange = useCallback(() => {
2086
- if (value === field) {
2087
- return onChange(`-${field}`);
2088
- }
2089
- if (value === `-${field}`) {
2090
- return onChange('');
2091
- }
2092
- return onChange(field);
2093
- }, [field, value, onChange]);
2094
- 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' }))] }) }));
2095
- }
2096
-
2097
2229
  async function configureI8n(resources, _a = {}) {
2098
2230
  var { lng = 'en', fallbackLng = 'en' } = _a, config = __rest(_a, ["lng", "fallbackLng"]);
2099
2231
  return i18n
@@ -2307,5 +2439,99 @@ function DDropdown({ actions, dropdownToggle, className, }) {
2307
2439
  }) })] }));
2308
2440
  }
2309
2441
 
2310
- 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 };
2442
+ function useScreenshot() {
2443
+ const clipRef = useRef(null);
2444
+ const takeBlob = useCallback(async (type) => {
2445
+ if (!clipRef.current) {
2446
+ throw new Error('set the clipRef');
2447
+ }
2448
+ const canvas = await html2canvas(clipRef === null || clipRef === void 0 ? void 0 : clipRef.current, {
2449
+ allowTaint: true,
2450
+ useCORS: true,
2451
+ });
2452
+ return (new Promise((resolve, reject) => {
2453
+ canvas.toBlob((innerBlob) => {
2454
+ if (!innerBlob) {
2455
+ return reject();
2456
+ }
2457
+ return resolve(innerBlob);
2458
+ }, type);
2459
+ }));
2460
+ }, []);
2461
+ return {
2462
+ clipRef,
2463
+ takeBlob,
2464
+ };
2465
+ }
2466
+
2467
+ function useScreenshotDownload() {
2468
+ const { clipRef, takeBlob } = useScreenshot();
2469
+ const download = useCallback(async () => {
2470
+ const blob = await takeBlob();
2471
+ const url = window.URL.createObjectURL(blob);
2472
+ const link = window.document.createElement('a');
2473
+ link.style.display = 'none';
2474
+ link.href = url;
2475
+ link.download = 'voucher.jpg';
2476
+ document.body.appendChild(link);
2477
+ link.click();
2478
+ document.body.removeChild(link);
2479
+ window.URL.revokeObjectURL(url);
2480
+ }, [takeBlob]);
2481
+ return {
2482
+ download,
2483
+ downloadRef: clipRef,
2484
+ };
2485
+ }
2486
+
2487
+ function useScreenshotWebShare() {
2488
+ const { takeBlob, clipRef } = useScreenshot();
2489
+ const share = useCallback(async () => {
2490
+ const blob = await takeBlob();
2491
+ const image = new File([blob], 'voucher.jpeg', { type: 'image/jpeg' });
2492
+ if (!navigator.canShare
2493
+ && (navigator.canShare && !navigator.canShare({ files: [image] }))) {
2494
+ window.print();
2495
+ return;
2496
+ }
2497
+ await navigator.share({ files: [image] });
2498
+ }, [takeBlob]);
2499
+ return {
2500
+ share,
2501
+ shareRef: clipRef,
2502
+ };
2503
+ }
2504
+
2505
+ function DVoucher({ amount, amountDetails, icon = 'CircleCheckBig', color = 'success', title, onError, message, downloadText = 'Download', shareText = 'Share', children, }) {
2506
+ const { shareRef, share } = useScreenshotWebShare();
2507
+ const { downloadRef, download } = useScreenshotDownload();
2508
+ const handleShare = () => {
2509
+ share()
2510
+ .catch(async (err) => {
2511
+ if (onError) {
2512
+ await onError(err);
2513
+ }
2514
+ })
2515
+ .catch(() => {
2516
+ // Error already handled by onError
2517
+ });
2518
+ };
2519
+ const handleDownload = () => {
2520
+ download()
2521
+ .catch(async (err) => {
2522
+ if (onError) {
2523
+ await onError(err);
2524
+ }
2525
+ })
2526
+ .catch(() => {
2527
+ // Error already handled by onError
2528
+ });
2529
+ };
2530
+ return (jsx("div", { className: "d-voucher", ref: (el) => {
2531
+ shareRef.current = el;
2532
+ downloadRef.current = el;
2533
+ }, 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" })] })] }) }));
2534
+ }
2535
+
2536
+ 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, 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 };
2311
2537
  //# sourceMappingURL=index.esm.js.map