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

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 (30) hide show
  1. package/dist/css/dynamic-ui-non-root.css +65 -45
  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 +65 -45
  6. package/dist/css/dynamic-ui.min.css +2 -2
  7. package/dist/index.esm.js +231 -23
  8. package/dist/index.esm.js.map +1 -1
  9. package/dist/index.js +232 -22
  10. package/dist/index.js.map +1 -1
  11. package/dist/types/components/DButton/DButton.d.ts +7 -17
  12. package/dist/types/components/DInputCheck/DInputCheck.d.ts +2 -1
  13. package/dist/types/components/DInputSwitch/DInputSwitch.d.ts +2 -1
  14. package/dist/types/components/DPasswordStrengthMeter/DPasswordStrengthMeter.d.ts +23 -0
  15. package/dist/types/components/DPasswordStrengthMeter/PasswordCheckItem.d.ts +7 -0
  16. package/dist/types/components/DPasswordStrengthMeter/PasswordCheckList.d.ts +14 -0
  17. package/dist/types/components/DPasswordStrengthMeter/PasswordStrength.d.ts +6 -0
  18. package/dist/types/components/DPasswordStrengthMeter/index.d.ts +3 -0
  19. package/dist/types/components/DVoucher/DVoucher.d.ts +14 -0
  20. package/dist/types/components/DVoucher/hooks/useScreenshot.d.ts +5 -0
  21. package/dist/types/components/DVoucher/hooks/useScreenshotDownload.d.ts +5 -0
  22. package/dist/types/components/DVoucher/hooks/useScreenshotWebShare.d.ts +5 -0
  23. package/dist/types/components/DVoucher/index.d.ts +2 -0
  24. package/dist/types/components/index.d.ts +3 -0
  25. package/jest/setup.js +0 -2
  26. package/package.json +6 -4
  27. package/src/style/abstracts/variables/_buttons.scss +2 -0
  28. package/src/style/base/_buttons.scss +56 -65
  29. package/src/style/components/_+import.scss +1 -0
  30. package/src/style/components/_d-voucher.scss +30 -0
package/dist/index.js CHANGED
@@ -18,6 +18,7 @@ var react = require('@floating-ui/react');
18
18
  var reactHotToast = require('react-hot-toast');
19
19
  var reactInternationalPhone = require('react-international-phone');
20
20
  var googleLibphonenumber = require('google-libphonenumber');
21
+ var html2canvas = require('html2canvas');
21
22
  var i18n = require('i18next');
22
23
  var reactI18next = require('react-i18next');
23
24
 
@@ -889,26 +890,59 @@ function DBoxFile(_a) {
889
890
  : children })] })) })), !!files.length && (jsxRuntime.jsx("ul", { className: "d-box-files", children: files.map((file, index) => (jsxRuntime.jsx(ForwardedDInput, { value: file.name, iconStart: "paperclip", iconEnd: "trash", readOnly: true, onIconEndClick: () => handleRemoveFile(index) }, `${file.name} ${index}`))) }))] }));
890
891
  }
891
892
 
892
- 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, }) {
893
- const generateClasses = React.useMemo(() => {
893
+ const DButton = React.forwardRef((props, ref) => {
894
+ 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 = tslib.__rest(props, ["color", "size", "variant", "text", "children", "iconStart", "iconStartFamilyClass", "iconStartFamilyPrefix", "iconStartMaterialStyle", "iconEnd", "iconEndFamilyClass", "iconEndFamilyPrefix", "iconEndMaterialStyle", "loading", "loadingText", "loadingAriaLabel", "disabled", "className", "style", "dataAttributes", "onClick", "type"]);
895
+ const [buttonWidth, setButtonWidth] = React.useState();
896
+ const buttonRef = React.useRef(null);
897
+ const isDisabled = React.useMemo(() => disabled || loading, [disabled, loading]);
898
+ const content = React.useMemo(() => children || text, [children, text]);
899
+ const classes = React.useMemo(() => {
894
900
  const variantClass = variant
895
901
  ? `btn-${variant}-${color}`
896
902
  : `btn-${color}`;
897
- return Object.assign(Object.assign(Object.assign({ btn: true, [variantClass]: true }, size && { [`btn-${size}`]: true }), (state && state !== 'disabled') && { [state]: true }), { loading });
898
- }, [variant, color, size, state, loading]);
899
- const clickHandler = React.useCallback((event) => {
900
- if (stopPropagationEnabled) {
901
- event.stopPropagation();
903
+ return {
904
+ btn: true,
905
+ [variantClass]: true,
906
+ [`btn-${size}`]: !!size,
907
+ loading,
908
+ };
909
+ }, [variant, color, size, loading]);
910
+ const ariaLabel = React.useMemo(() => {
911
+ const ariaLabelProp = rest['aria-label'];
912
+ return loading
913
+ ? loadingAriaLabel || ariaLabelProp || text
914
+ : ariaLabelProp || text;
915
+ }, [loading, loadingAriaLabel, rest, text]);
916
+ const handleClick = React.useCallback((event) => {
917
+ if (disabled || loading) {
918
+ event.preventDefault();
919
+ return;
902
920
  }
903
921
  onClick === null || onClick === void 0 ? void 0 : onClick(event);
904
- }, [stopPropagationEnabled, onClick]);
905
- const isDisabled = React.useMemo(() => (state === 'disabled' || loading || disabled), [state, loading, disabled]);
906
- const content = children || text;
907
- const newAriaLabel = React.useMemo(() => (loading
908
- ? (loadingAriaLabel || ariaLabel || text)
909
- : (ariaLabel || text)), [loading, loadingAriaLabel, ariaLabel, text]);
910
- return (jsxRuntime.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 && (jsxRuntime.jsx(DIcon, { icon: iconStart, familyClass: iconStartFamilyClass, familyPrefix: iconStartFamilyPrefix, materialStyle: iconStartMaterialStyle })), loading && (jsxRuntime.jsx("span", { className: "spinner-border spinner-border-sm", role: "status", "aria-hidden": "true", children: jsxRuntime.jsx("span", { className: "visually-hidden", children: "Loading..." }) })), jsxRuntime.jsx("span", { children: loading && loadingText ? loadingText : content }), iconEnd && (jsxRuntime.jsx(DIcon, { icon: iconEnd, familyClass: iconEndFamilyClass, familyPrefix: iconEndFamilyPrefix, materialStyle: iconEndMaterialStyle }))] })));
911
- }
922
+ }, [disabled, loading, onClick]);
923
+ React.useEffect(() => {
924
+ if (!loading && buttonRef.current) {
925
+ const width = buttonRef.current.offsetWidth;
926
+ if (width > 0)
927
+ setButtonWidth(width);
928
+ }
929
+ // eslint-disable-next-line react-hooks/exhaustive-deps
930
+ }, [content, iconEnd, iconStart]);
931
+ return (jsxRuntime.jsxs("button", Object.assign({ ref: (node) => {
932
+ buttonRef.current = node;
933
+ if (typeof ref === 'function')
934
+ ref(node);
935
+ // eslint-disable-next-line max-len
936
+ // eslint-disable-next-line no-param-reassign, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
937
+ else if (ref)
938
+ ref.current = node;
939
+ },
940
+ // eslint-disable-next-line react/button-has-type
941
+ type: type, className: classNames(classes, className), style: Object.assign(Object.assign({}, style), (loading && buttonWidth
942
+ ? { minWidth: `${buttonWidth}px` }
943
+ : undefined)), disabled: isDisabled, "aria-label": ariaLabel, "aria-busy": loading, "aria-disabled": isDisabled, onClick: handleClick }, dataAttributes, rest, { children: [loading && (jsxRuntime.jsxs("span", { className: "btn-loading", children: [jsxRuntime.jsx("span", { className: "spinner-border spinner-border-sm", "aria-hidden": "true" }), loadingText && jsxRuntime.jsx("span", { role: "status", children: loadingText })] })), !loading && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [iconStart && (jsxRuntime.jsx(DIcon, { icon: iconStart, familyClass: iconStartFamilyClass, familyPrefix: iconStartFamilyPrefix, materialStyle: iconStartMaterialStyle })), content, iconEnd && (jsxRuntime.jsx(DIcon, { icon: iconEnd, familyClass: iconEndFamilyClass, familyPrefix: iconEndFamilyPrefix, materialStyle: iconEndMaterialStyle }))] }))] })));
944
+ });
945
+ DButton.displayName = 'DButton';
912
946
 
913
947
  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, }) {
914
948
  const generateClasses = React.useMemo(() => {
@@ -1043,7 +1077,7 @@ const ForwardedDDatePickerInput = React.forwardRef(DDatePickerInput);
1043
1077
  ForwardedDDatePickerInput.displayName = 'DDatePickerInput';
1044
1078
 
1045
1079
  function DInputCheck(_a) {
1046
- var { id: idProp, type, name, label, ariaLabel, checked = false, disabled = false, invalid = false, valid = false, indeterminate, value, hint, onChange, className, style, dataAttributes } = _a, props = tslib.__rest(_a, ["id", "type", "name", "label", "ariaLabel", "checked", "disabled", "invalid", "valid", "indeterminate", "value", "hint", "onChange", "className", "style", "dataAttributes"]);
1080
+ 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 = tslib.__rest(_a, ["id", "type", "name", "label", "ariaLabel", "checked", "disabled", "invalid", "valid", "indeterminate", "inputClassName", "value", "hint", "onChange", "className", "style", "dataAttributes"]);
1047
1081
  const innerRef = React.useRef(null);
1048
1082
  const innerId = React.useId();
1049
1083
  const id = React.useMemo(() => idProp || innerId, [idProp, innerId]);
@@ -1071,11 +1105,11 @@ function DInputCheck(_a) {
1071
1105
  const inputComponent = React.useMemo(() => (jsxRuntime.jsx("input", Object.assign({ ref: innerRef, onChange: handleChange, className: classNames('form-check-input', {
1072
1106
  'is-invalid': invalid,
1073
1107
  'is-valid': valid,
1074
- }, className), style: style, id: id, disabled: disabled, type: type, name: name, value: value, "aria-label": ariaLabel }, ariaDescribedby && { 'aria-describedby': ariaDescribedby }, props))), [
1108
+ }, inputClassName), style: style, id: id, disabled: disabled, type: type, name: name, value: value, "aria-label": ariaLabel }, ariaDescribedby && { 'aria-describedby': ariaDescribedby }, props))), [
1075
1109
  handleChange,
1076
1110
  invalid,
1077
1111
  valid,
1078
- className,
1112
+ inputClassName,
1079
1113
  style,
1080
1114
  id,
1081
1115
  disabled,
@@ -1089,7 +1123,7 @@ function DInputCheck(_a) {
1089
1123
  if (!label) {
1090
1124
  return inputComponent;
1091
1125
  }
1092
- return (jsxRuntime.jsxs("div", Object.assign({ className: "form-check" }, dataAttributes, { children: [inputComponent, jsxRuntime.jsx("label", { className: "form-check-label", htmlFor: id, children: label }), hint && (jsxRuntime.jsx("div", { className: "form-text", id: `${id}Hint`, children: hint }))] })));
1126
+ return (jsxRuntime.jsxs("div", Object.assign({ className: classNames('form-check', className) }, dataAttributes, { children: [inputComponent, jsxRuntime.jsx("label", { className: "form-check-label", htmlFor: id, children: label }), hint && (jsxRuntime.jsx("div", { className: "form-text", id: `${id}Hint`, children: hint }))] })));
1093
1127
  }
1094
1128
 
1095
1129
  function DSelectOptionCheck(_a) {
@@ -1513,6 +1547,86 @@ function DInputPassword(_a, ref) {
1513
1547
  const ForwardedDInputPassword = React.forwardRef(DInputPassword);
1514
1548
  ForwardedDInputPassword.displayName = 'DInputPassword';
1515
1549
 
1550
+ function PasswordCheckItem({ password, regex, text, }) {
1551
+ const isValid = regex.test(password);
1552
+ return (jsxRuntime.jsxs("li", { className: "d-flex gap-2 align-items-start small text-gray-600", children: [jsxRuntime.jsx(DIcon, { className: classNames('flex-shrink-0', isValid ? 'text-success' : 'text-gray-300'), icon: isValid ? 'CircleCheck' : 'Circle', size: "16px" }), jsxRuntime.jsx("span", { className: classNames({ 'text-success': isValid }), children: text })] }));
1553
+ }
1554
+
1555
+ const getColorClass = (strength, total) => {
1556
+ const percentage = total > 0 ? strength / total : 0;
1557
+ if (percentage === 0)
1558
+ return 'bg-gray-200';
1559
+ if (percentage <= 0.25)
1560
+ return 'bg-danger';
1561
+ if (percentage <= 0.5)
1562
+ return 'bg-warning';
1563
+ if (percentage <= 0.75)
1564
+ return 'bg-info';
1565
+ return 'bg-success';
1566
+ };
1567
+ function PasswordStrengthBar({ strength, total }) {
1568
+ const percentage = total > 0 ? (strength / total) * 100 : 0;
1569
+ return (jsxRuntime.jsx("div", { className: "w-100 rounded-3 overflow-hidden bg-gray-100 mb-2", style: { height: '8px' }, children: jsxRuntime.jsx("div", { className: `h-100 ${getColorClass(strength, total)}`, style: {
1570
+ width: `${percentage}%`,
1571
+ transition: 'width 0.3s ease-in-out',
1572
+ } }) }));
1573
+ }
1574
+
1575
+ const CHECK_REGEX = {
1576
+ uppercase: /[A-Z]/,
1577
+ lowercase: /[a-z]/,
1578
+ number: /\d/,
1579
+ specialChar: /[~!@#$^*\-_=[\]{}|;,.?]/,
1580
+ };
1581
+ function PasswordChecksList({ password, validationMessages, enabledChecks, }) {
1582
+ const allChecks = [
1583
+ {
1584
+ key: 'uppercase',
1585
+ regex: CHECK_REGEX.uppercase,
1586
+ text: validationMessages.uppercaseLetter,
1587
+ },
1588
+ {
1589
+ key: 'lowercase',
1590
+ regex: CHECK_REGEX.lowercase,
1591
+ text: validationMessages.lowercaseLetter,
1592
+ },
1593
+ {
1594
+ key: 'number',
1595
+ regex: CHECK_REGEX.number,
1596
+ text: validationMessages.number,
1597
+ },
1598
+ {
1599
+ key: 'specialChar',
1600
+ regex: CHECK_REGEX.specialChar,
1601
+ text: validationMessages.especialChar,
1602
+ },
1603
+ ];
1604
+ const passwordChecks = allChecks.filter((check) => enabledChecks.includes(check.key));
1605
+ const passed = passwordChecks.filter((r) => r.regex.test(password)).length;
1606
+ const total = passwordChecks.length;
1607
+ return (jsxRuntime.jsxs("div", { className: "mt-2", children: [jsxRuntime.jsx(PasswordStrengthBar, { strength: passed, total: total }), jsxRuntime.jsx("ul", { className: "list-unstyled m-0 d-flex flex-column gap-2", children: passwordChecks.map(({ key, regex, text }) => (jsxRuntime.jsx(PasswordCheckItem, { password: password, regex: regex, text: text }, key))) })] }));
1608
+ }
1609
+
1610
+ const DEFAULT_VALIDATION_MESSAGES = {
1611
+ number: 'At least one number',
1612
+ lowercaseLetter: 'At least one lowercase letter',
1613
+ uppercaseLetter: 'At least one uppercase letter',
1614
+ especialChar: 'At least one of these special characters: ~!@#$^*-_=[]{}|;,.?',
1615
+ notMatch: 'The password confirmation and the new password do not match.',
1616
+ };
1617
+ const DEFAULT_ENABLED_CHECKS = ['uppercase', 'lowercase', 'number', 'specialChar'];
1618
+ function DPasswordStrengthMeter({ id, label = 'Password', placeholder, value = '', name, disabled = false, invalid = false, validationMessages = DEFAULT_VALIDATION_MESSAGES, enabledChecks = DEFAULT_ENABLED_CHECKS, className, style, dataAttributes, onChange, }) {
1619
+ const [password, setPassword] = React.useState(value);
1620
+ React.useEffect(() => {
1621
+ setPassword(value);
1622
+ }, [value]);
1623
+ const handleChange = (newValue) => {
1624
+ setPassword(newValue);
1625
+ onChange === null || onChange === void 0 ? void 0 : onChange(newValue);
1626
+ };
1627
+ return (jsxRuntime.jsxs("div", Object.assign({ className: className, style: style }, dataAttributes, { children: [jsxRuntime.jsx(ForwardedDInputPassword, { id: id, label: label, placeholder: placeholder, value: password, name: name, disabled: disabled, invalid: invalid, onChange: handleChange }), jsxRuntime.jsx(PasswordChecksList, { password: password, validationMessages: validationMessages, enabledChecks: enabledChecks })] })));
1628
+ }
1629
+
1516
1630
  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, }) {
1517
1631
  const innerId = React.useId();
1518
1632
  const id = React.useMemo(() => idProp || innerId, [idProp, innerId]);
@@ -1676,7 +1790,7 @@ function DInputSelect({ id: idProp, name, label = '', className, style, options
1676
1790
  }), children: [iconStart && (jsxRuntime.jsx("button", { type: "button", className: "input-group-text", id: `${id}Start`, onClick: iconStartClickHandler, disabled: disabled || loading, "aria-label": iconStartAriaLabel, children: iconStart && (jsxRuntime.jsx(DIcon, { icon: iconStart, familyClass: iconStartFamilyClass, familyPrefix: iconStartFamilyPrefix })) })), dynamicComponent, iconEnd && !loading && (jsxRuntime.jsx("button", { type: "button", className: "input-group-text", id: `${id}End`, onClick: iconEndClickHandler, disabled: disabled || loading, "aria-label": iconEndAriaLabel, children: iconEnd && (jsxRuntime.jsx(DIcon, { icon: iconEnd, familyClass: iconEndFamilyClass, familyPrefix: iconEndFamilyPrefix })) })), loading && (jsxRuntime.jsx("div", { className: "input-group-text form-control-icon loading", children: jsxRuntime.jsx("span", { className: "spinner-border spinner-border-sm", role: "status", "aria-hidden": "true", children: jsxRuntime.jsx("span", { className: "visually-hidden", children: "Loading..." }) }) }))] }), hint && (jsxRuntime.jsx("div", { className: "form-text", id: `${id}Hint`, children: hint }))] })));
1677
1791
  }
1678
1792
 
1679
- function DInputSwitch({ id: idProp, label, ariaLabel, name, checked, disabled, invalid = false, valid = false, readonly, className, style, dataAttributes, onChange, }) {
1793
+ function DInputSwitch({ id: idProp, label, ariaLabel, name, checked, disabled, invalid = false, valid = false, readonly, className, style, dataAttributes, inputClassName, onChange, }) {
1680
1794
  const innerId = React.useId();
1681
1795
  const id = React.useMemo(() => idProp || innerId, [idProp, innerId]);
1682
1796
  const [internalIsChecked, setInternalIsChecked] = React.useState(checked);
@@ -1688,10 +1802,10 @@ function DInputSwitch({ id: idProp, label, ariaLabel, name, checked, disabled, i
1688
1802
  setInternalIsChecked(value);
1689
1803
  onChange === null || onChange === void 0 ? void 0 : onChange(value);
1690
1804
  }, [onChange]);
1691
- return (jsxRuntime.jsxs("div", Object.assign({ className: "form-check form-switch" }, dataAttributes, { children: [jsxRuntime.jsx("input", { id: id, name: name, onChange: readonly ? () => false : changeHandler, className: classNames('form-check-input', {
1805
+ return (jsxRuntime.jsxs("div", Object.assign({ className: classNames('form-check', className) }, dataAttributes, { children: [jsxRuntime.jsx("input", { id: id, name: name, onChange: readonly ? () => false : changeHandler, className: classNames('form-check-input', {
1692
1806
  'is-invalid': invalid,
1693
1807
  'is-valid': valid,
1694
- }, className), style: style, type: "checkbox", role: "switch", checked: internalIsChecked, disabled: disabled, "aria-label": ariaLabel }), label && (jsxRuntime.jsx("label", { className: "form-check-label", htmlFor: id, children: label }))] })));
1808
+ }, inputClassName), style: style, type: "checkbox", role: "switch", checked: internalIsChecked, disabled: disabled, "aria-label": ariaLabel }), label && (jsxRuntime.jsx("label", { className: "form-check-label", htmlFor: id, children: label }))] })));
1695
1809
  }
1696
1810
 
1697
1811
  function DInputRange(_a, ref) {
@@ -2328,6 +2442,100 @@ function DDropdown({ actions, dropdownToggle, className, }) {
2328
2442
  }) })] }));
2329
2443
  }
2330
2444
 
2445
+ function useScreenshot() {
2446
+ const clipRef = React.useRef(null);
2447
+ const takeBlob = React.useCallback(async (type) => {
2448
+ if (!clipRef.current) {
2449
+ throw new Error('set the clipRef');
2450
+ }
2451
+ const canvas = await html2canvas(clipRef === null || clipRef === void 0 ? void 0 : clipRef.current, {
2452
+ allowTaint: true,
2453
+ useCORS: true,
2454
+ });
2455
+ return (new Promise((resolve, reject) => {
2456
+ canvas.toBlob((innerBlob) => {
2457
+ if (!innerBlob) {
2458
+ return reject();
2459
+ }
2460
+ return resolve(innerBlob);
2461
+ }, type);
2462
+ }));
2463
+ }, []);
2464
+ return {
2465
+ clipRef,
2466
+ takeBlob,
2467
+ };
2468
+ }
2469
+
2470
+ function useScreenshotDownload() {
2471
+ const { clipRef, takeBlob } = useScreenshot();
2472
+ const download = React.useCallback(async () => {
2473
+ const blob = await takeBlob();
2474
+ const url = window.URL.createObjectURL(blob);
2475
+ const link = window.document.createElement('a');
2476
+ link.style.display = 'none';
2477
+ link.href = url;
2478
+ link.download = 'voucher.jpg';
2479
+ document.body.appendChild(link);
2480
+ link.click();
2481
+ document.body.removeChild(link);
2482
+ window.URL.revokeObjectURL(url);
2483
+ }, [takeBlob]);
2484
+ return {
2485
+ download,
2486
+ downloadRef: clipRef,
2487
+ };
2488
+ }
2489
+
2490
+ function useScreenshotWebShare() {
2491
+ const { takeBlob, clipRef } = useScreenshot();
2492
+ const share = React.useCallback(async () => {
2493
+ const blob = await takeBlob();
2494
+ const image = new File([blob], 'voucher.jpeg', { type: 'image/jpeg' });
2495
+ if (!navigator.canShare
2496
+ && (navigator.canShare && !navigator.canShare({ files: [image] }))) {
2497
+ window.print();
2498
+ return;
2499
+ }
2500
+ await navigator.share({ files: [image] });
2501
+ }, [takeBlob]);
2502
+ return {
2503
+ share,
2504
+ shareRef: clipRef,
2505
+ };
2506
+ }
2507
+
2508
+ function DVoucher({ amount, amountDetails, icon = 'CircleCheckBig', color = 'success', title, onError, message, downloadText = 'Download', shareText = 'Share', children, }) {
2509
+ const { shareRef, share } = useScreenshotWebShare();
2510
+ const { downloadRef, download } = useScreenshotDownload();
2511
+ const handleShare = () => {
2512
+ share()
2513
+ .catch(async (err) => {
2514
+ if (onError) {
2515
+ await onError(err);
2516
+ }
2517
+ })
2518
+ .catch(() => {
2519
+ // Error already handled by onError
2520
+ });
2521
+ };
2522
+ const handleDownload = () => {
2523
+ download()
2524
+ .catch(async (err) => {
2525
+ if (onError) {
2526
+ await onError(err);
2527
+ }
2528
+ })
2529
+ .catch(() => {
2530
+ // Error already handled by onError
2531
+ });
2532
+ };
2533
+ return (jsxRuntime.jsx("div", { className: "d-voucher", ref: (el) => {
2534
+ shareRef.current = el;
2535
+ downloadRef.current = el;
2536
+ }, children: jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs("div", { className: "d-voucher-header", children: [jsxRuntime.jsx(DIcon, { icon: icon, color: color }), jsxRuntime.jsxs("div", { className: "text-center", children: [jsxRuntime.jsx("h3", { className: "mb-2", children: title }), jsxRuntime.jsx("p", { className: "m-0", children: message })] })] }), amount && (jsxRuntime.jsxs("div", { className: "d-voucher-amount", children: [jsxRuntime.jsx("div", { className: classNames('text-center fw-bold fs-3', amountDetails ? 'mb-1' : 'm-0'), children: amount }), amountDetails] })), jsxRuntime.jsx("hr", { className: "my-4" }), children, jsxRuntime.jsx("hr", { className: "my-4" }), jsxRuntime.jsxs("div", { className: "d-voucher-footer", children: [jsxRuntime.jsx(DButton, { onClick: handleShare, iconStart: "Share2", text: shareText, variant: "outline", size: "sm" }), jsxRuntime.jsx(DButton, { onClick: handleDownload, iconStart: "Download", text: downloadText, variant: "outline", size: "sm" })] })] }) }));
2537
+ }
2538
+
2331
2539
  exports.DAlert = DAlert;
2332
2540
  exports.DAvatar = DAvatar;
2333
2541
  exports.DBadge = DBadge;
@@ -2375,6 +2583,7 @@ exports.DOffcanvasBody = DOffcanvasBody;
2375
2583
  exports.DOffcanvasFooter = DOffcanvasFooter;
2376
2584
  exports.DOffcanvasHeader = DOffcanvasHeader;
2377
2585
  exports.DPaginator = DPaginator;
2586
+ exports.DPasswordStrengthMeter = DPasswordStrengthMeter;
2378
2587
  exports.DPopover = DPopover;
2379
2588
  exports.DProgress = DProgress;
2380
2589
  exports.DSelect = DSelect;
@@ -2388,6 +2597,7 @@ exports.DTimeline = DTimeline;
2388
2597
  exports.DToast = DToast;
2389
2598
  exports.DToastContainer = DToastContainer;
2390
2599
  exports.DTooltip = DTooltip;
2600
+ exports.DVoucher = DVoucher;
2391
2601
  exports.changeQueryString = changeQueryString;
2392
2602
  exports.checkMediaQuery = checkMediaQuery;
2393
2603
  exports.configureI18n = configureI8n;