@dynamic-framework/ui-react 2.0.0-dev.3 → 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.
- package/dist/css/dynamic-ui-non-root.css +294 -46
- package/dist/css/dynamic-ui-non-root.min.css +3 -3
- package/dist/css/dynamic-ui-root.css +2 -2
- package/dist/css/dynamic-ui-root.min.css +2 -2
- package/dist/css/dynamic-ui.css +294 -46
- package/dist/css/dynamic-ui.min.css +3 -3
- package/dist/index.esm.js +234 -25
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +268 -57
- package/dist/index.js.map +1 -1
- package/dist/types/components/DButton/DButton.d.ts +7 -17
- package/dist/types/components/DInputCheck/DInputCheck.d.ts +2 -1
- package/dist/types/components/DInputMask/DInputMask.d.ts +7 -17
- package/dist/types/components/DInputSwitch/DInputSwitch.d.ts +2 -1
- package/dist/types/components/DLayout/DLayout.d.ts +2 -1
- package/dist/types/components/DPasswordStrengthMeter/DPasswordStrengthMeter.d.ts +23 -0
- package/dist/types/components/DPasswordStrengthMeter/PasswordCheckItem.d.ts +7 -0
- package/dist/types/components/DPasswordStrengthMeter/PasswordCheckList.d.ts +14 -0
- package/dist/types/components/DPasswordStrengthMeter/PasswordStrength.d.ts +6 -0
- package/dist/types/components/DPasswordStrengthMeter/index.d.ts +3 -0
- package/dist/types/components/DVoucher/DVoucher.d.ts +14 -0
- package/dist/types/components/DVoucher/hooks/useScreenshot.d.ts +5 -0
- package/dist/types/components/DVoucher/hooks/useScreenshotDownload.d.ts +5 -0
- package/dist/types/components/DVoucher/hooks/useScreenshotWebShare.d.ts +5 -0
- package/dist/types/components/DVoucher/index.d.ts +2 -0
- package/dist/types/components/index.d.ts +3 -0
- package/jest/setup.js +0 -2
- package/package.json +35 -29
- package/src/style/abstracts/_utilities.scss +19 -0
- package/src/style/abstracts/variables/_buttons.scss +2 -0
- package/src/style/base/_buttons.scss +56 -65
- package/src/style/components/_+import.scss +1 -0
- package/src/style/components/_d-voucher.scss +30 -0
package/dist/index.esm.js
CHANGED
|
@@ -16,6 +16,7 @@ import { useFloating, autoUpdate, offset, flip, shift, useClick, useDismiss, use
|
|
|
16
16
|
import { Toaster, toast } from 'react-hot-toast';
|
|
17
17
|
import { defaultCountries, parseCountry, usePhoneInput, CountrySelector } from 'react-international-phone';
|
|
18
18
|
import { PhoneNumberUtil } from 'google-libphonenumber';
|
|
19
|
+
import html2canvas from 'html2canvas';
|
|
19
20
|
import i18n from 'i18next';
|
|
20
21
|
import { initReactI18next } from 'react-i18next';
|
|
21
22
|
|
|
@@ -868,26 +869,59 @@ function DBoxFile(_a) {
|
|
|
868
869
|
: 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}`))) }))] }));
|
|
869
870
|
}
|
|
870
871
|
|
|
871
|
-
|
|
872
|
-
const
|
|
872
|
+
const DButton = forwardRef((props, ref) => {
|
|
873
|
+
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"]);
|
|
874
|
+
const [buttonWidth, setButtonWidth] = useState();
|
|
875
|
+
const buttonRef = useRef(null);
|
|
876
|
+
const isDisabled = useMemo(() => disabled || loading, [disabled, loading]);
|
|
877
|
+
const content = useMemo(() => children || text, [children, text]);
|
|
878
|
+
const classes = useMemo(() => {
|
|
873
879
|
const variantClass = variant
|
|
874
880
|
? `btn-${variant}-${color}`
|
|
875
881
|
: `btn-${color}`;
|
|
876
|
-
return
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
882
|
+
return {
|
|
883
|
+
btn: true,
|
|
884
|
+
[variantClass]: true,
|
|
885
|
+
[`btn-${size}`]: !!size,
|
|
886
|
+
loading,
|
|
887
|
+
};
|
|
888
|
+
}, [variant, color, size, loading]);
|
|
889
|
+
const ariaLabel = useMemo(() => {
|
|
890
|
+
const ariaLabelProp = rest['aria-label'];
|
|
891
|
+
return loading
|
|
892
|
+
? loadingAriaLabel || ariaLabelProp || text
|
|
893
|
+
: ariaLabelProp || text;
|
|
894
|
+
}, [loading, loadingAriaLabel, rest, text]);
|
|
895
|
+
const handleClick = useCallback((event) => {
|
|
896
|
+
if (disabled || loading) {
|
|
897
|
+
event.preventDefault();
|
|
898
|
+
return;
|
|
881
899
|
}
|
|
882
900
|
onClick === null || onClick === void 0 ? void 0 : onClick(event);
|
|
883
|
-
}, [
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
901
|
+
}, [disabled, loading, onClick]);
|
|
902
|
+
useEffect(() => {
|
|
903
|
+
if (!loading && buttonRef.current) {
|
|
904
|
+
const width = buttonRef.current.offsetWidth;
|
|
905
|
+
if (width > 0)
|
|
906
|
+
setButtonWidth(width);
|
|
907
|
+
}
|
|
908
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
909
|
+
}, [content, iconEnd, iconStart]);
|
|
910
|
+
return (jsxs("button", Object.assign({ ref: (node) => {
|
|
911
|
+
buttonRef.current = node;
|
|
912
|
+
if (typeof ref === 'function')
|
|
913
|
+
ref(node);
|
|
914
|
+
// eslint-disable-next-line max-len
|
|
915
|
+
// eslint-disable-next-line no-param-reassign, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
|
|
916
|
+
else if (ref)
|
|
917
|
+
ref.current = node;
|
|
918
|
+
},
|
|
919
|
+
// eslint-disable-next-line react/button-has-type
|
|
920
|
+
type: type, className: classNames(classes, className), style: Object.assign(Object.assign({}, style), (loading && buttonWidth
|
|
921
|
+
? { minWidth: `${buttonWidth}px` }
|
|
922
|
+
: 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$1, { children: [iconStart && (jsx(DIcon, { icon: iconStart, familyClass: iconStartFamilyClass, familyPrefix: iconStartFamilyPrefix, materialStyle: iconStartMaterialStyle })), content, iconEnd && (jsx(DIcon, { icon: iconEnd, familyClass: iconEndFamilyClass, familyPrefix: iconEndFamilyPrefix, materialStyle: iconEndMaterialStyle }))] }))] })));
|
|
923
|
+
});
|
|
924
|
+
DButton.displayName = 'DButton';
|
|
891
925
|
|
|
892
926
|
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
927
|
const generateClasses = useMemo(() => {
|
|
@@ -1022,7 +1056,7 @@ const ForwardedDDatePickerInput = forwardRef(DDatePickerInput);
|
|
|
1022
1056
|
ForwardedDDatePickerInput.displayName = 'DDatePickerInput';
|
|
1023
1057
|
|
|
1024
1058
|
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"]);
|
|
1059
|
+
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
1060
|
const innerRef = useRef(null);
|
|
1027
1061
|
const innerId = useId();
|
|
1028
1062
|
const id = useMemo(() => idProp || innerId, [idProp, innerId]);
|
|
@@ -1050,11 +1084,11 @@ function DInputCheck(_a) {
|
|
|
1050
1084
|
const inputComponent = useMemo(() => (jsx("input", Object.assign({ ref: innerRef, onChange: handleChange, className: classNames('form-check-input', {
|
|
1051
1085
|
'is-invalid': invalid,
|
|
1052
1086
|
'is-valid': valid,
|
|
1053
|
-
},
|
|
1087
|
+
}, inputClassName), style: style, id: id, disabled: disabled, type: type, name: name, value: value, "aria-label": ariaLabel }, ariaDescribedby && { 'aria-describedby': ariaDescribedby }, props))), [
|
|
1054
1088
|
handleChange,
|
|
1055
1089
|
invalid,
|
|
1056
1090
|
valid,
|
|
1057
|
-
|
|
1091
|
+
inputClassName,
|
|
1058
1092
|
style,
|
|
1059
1093
|
id,
|
|
1060
1094
|
disabled,
|
|
@@ -1068,7 +1102,7 @@ function DInputCheck(_a) {
|
|
|
1068
1102
|
if (!label) {
|
|
1069
1103
|
return inputComponent;
|
|
1070
1104
|
}
|
|
1071
|
-
return (jsxs("div", Object.assign({ className:
|
|
1105
|
+
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
1106
|
}
|
|
1073
1107
|
|
|
1074
1108
|
function DSelectOptionCheck(_a) {
|
|
@@ -1268,7 +1302,7 @@ function DLayoutPane({ className, style, children, cols, colsXs, colsSm, colsMd,
|
|
|
1268
1302
|
return (jsx("div", Object.assign({ className: classNames(colsClass, colsXsClass, colsSmClass, colsMdClass, colsLgClass, colsXlClass, colsXxlClass, className), style: style }, dataAttributes, { children: children })));
|
|
1269
1303
|
}
|
|
1270
1304
|
|
|
1271
|
-
function DLayout({ className, style, children, gap, gapSm, gapMd, gapLg, gapXl, gapXxl, dataAttributes, }) {
|
|
1305
|
+
function DLayout({ className, style, children, gap, columns, gapSm, gapMd, gapLg, gapXl, gapXxl, dataAttributes, }) {
|
|
1272
1306
|
const gapClasses = classNames({
|
|
1273
1307
|
[`gap-${gap}`]: gap !== undefined,
|
|
1274
1308
|
[`gap-sm-${gapSm}`]: gapSm !== undefined,
|
|
@@ -1277,7 +1311,8 @@ function DLayout({ className, style, children, gap, gapSm, gapMd, gapLg, gapXl,
|
|
|
1277
1311
|
[`gap-xl-${gapXl}`]: gapXl !== undefined,
|
|
1278
1312
|
[`gap-xxl-${gapXxl}`]: gapXxl !== undefined,
|
|
1279
1313
|
});
|
|
1280
|
-
|
|
1314
|
+
const styleWithColumns = Object.assign(Object.assign({}, style), { '--bs-columns': columns });
|
|
1315
|
+
return (jsx("div", Object.assign({ style: styleWithColumns, className: classNames('grid', gapClasses, className) }, dataAttributes, { children: children })));
|
|
1281
1316
|
}
|
|
1282
1317
|
var DLayout$1 = Object.assign(DLayout, {
|
|
1283
1318
|
Pane: DLayoutPane,
|
|
@@ -1491,6 +1526,86 @@ function DInputPassword(_a, ref) {
|
|
|
1491
1526
|
const ForwardedDInputPassword = forwardRef(DInputPassword);
|
|
1492
1527
|
ForwardedDInputPassword.displayName = 'DInputPassword';
|
|
1493
1528
|
|
|
1529
|
+
function PasswordCheckItem({ password, regex, text, }) {
|
|
1530
|
+
const isValid = regex.test(password);
|
|
1531
|
+
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 })] }));
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
const getColorClass = (strength, total) => {
|
|
1535
|
+
const percentage = total > 0 ? strength / total : 0;
|
|
1536
|
+
if (percentage === 0)
|
|
1537
|
+
return 'bg-gray-200';
|
|
1538
|
+
if (percentage <= 0.25)
|
|
1539
|
+
return 'bg-danger';
|
|
1540
|
+
if (percentage <= 0.5)
|
|
1541
|
+
return 'bg-warning';
|
|
1542
|
+
if (percentage <= 0.75)
|
|
1543
|
+
return 'bg-info';
|
|
1544
|
+
return 'bg-success';
|
|
1545
|
+
};
|
|
1546
|
+
function PasswordStrengthBar({ strength, total }) {
|
|
1547
|
+
const percentage = total > 0 ? (strength / total) * 100 : 0;
|
|
1548
|
+
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: {
|
|
1549
|
+
width: `${percentage}%`,
|
|
1550
|
+
transition: 'width 0.3s ease-in-out',
|
|
1551
|
+
} }) }));
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
const CHECK_REGEX = {
|
|
1555
|
+
uppercase: /[A-Z]/,
|
|
1556
|
+
lowercase: /[a-z]/,
|
|
1557
|
+
number: /\d/,
|
|
1558
|
+
specialChar: /[~!@#$^*\-_=[\]{}|;,.?]/,
|
|
1559
|
+
};
|
|
1560
|
+
function PasswordChecksList({ password, validationMessages, enabledChecks, }) {
|
|
1561
|
+
const allChecks = [
|
|
1562
|
+
{
|
|
1563
|
+
key: 'uppercase',
|
|
1564
|
+
regex: CHECK_REGEX.uppercase,
|
|
1565
|
+
text: validationMessages.uppercaseLetter,
|
|
1566
|
+
},
|
|
1567
|
+
{
|
|
1568
|
+
key: 'lowercase',
|
|
1569
|
+
regex: CHECK_REGEX.lowercase,
|
|
1570
|
+
text: validationMessages.lowercaseLetter,
|
|
1571
|
+
},
|
|
1572
|
+
{
|
|
1573
|
+
key: 'number',
|
|
1574
|
+
regex: CHECK_REGEX.number,
|
|
1575
|
+
text: validationMessages.number,
|
|
1576
|
+
},
|
|
1577
|
+
{
|
|
1578
|
+
key: 'specialChar',
|
|
1579
|
+
regex: CHECK_REGEX.specialChar,
|
|
1580
|
+
text: validationMessages.especialChar,
|
|
1581
|
+
},
|
|
1582
|
+
];
|
|
1583
|
+
const passwordChecks = allChecks.filter((check) => enabledChecks.includes(check.key));
|
|
1584
|
+
const passed = passwordChecks.filter((r) => r.regex.test(password)).length;
|
|
1585
|
+
const total = passwordChecks.length;
|
|
1586
|
+
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))) })] }));
|
|
1587
|
+
}
|
|
1588
|
+
|
|
1589
|
+
const DEFAULT_VALIDATION_MESSAGES = {
|
|
1590
|
+
number: 'At least one number',
|
|
1591
|
+
lowercaseLetter: 'At least one lowercase letter',
|
|
1592
|
+
uppercaseLetter: 'At least one uppercase letter',
|
|
1593
|
+
especialChar: 'At least one of these special characters: ~!@#$^*-_=[]{}|;,.?',
|
|
1594
|
+
notMatch: 'The password confirmation and the new password do not match.',
|
|
1595
|
+
};
|
|
1596
|
+
const DEFAULT_ENABLED_CHECKS = ['uppercase', 'lowercase', 'number', 'specialChar'];
|
|
1597
|
+
function DPasswordStrengthMeter({ id, label = 'Password', placeholder, value = '', name, disabled = false, invalid = false, validationMessages = DEFAULT_VALIDATION_MESSAGES, enabledChecks = DEFAULT_ENABLED_CHECKS, className, style, dataAttributes, onChange, }) {
|
|
1598
|
+
const [password, setPassword] = useState(value);
|
|
1599
|
+
useEffect(() => {
|
|
1600
|
+
setPassword(value);
|
|
1601
|
+
}, [value]);
|
|
1602
|
+
const handleChange = (newValue) => {
|
|
1603
|
+
setPassword(newValue);
|
|
1604
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(newValue);
|
|
1605
|
+
};
|
|
1606
|
+
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 })] })));
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1494
1609
|
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, }) {
|
|
1495
1610
|
const innerId = useId();
|
|
1496
1611
|
const id = useMemo(() => idProp || innerId, [idProp, innerId]);
|
|
@@ -1654,7 +1769,7 @@ function DInputSelect({ id: idProp, name, label = '', className, style, options
|
|
|
1654
1769
|
}), 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 }))] })));
|
|
1655
1770
|
}
|
|
1656
1771
|
|
|
1657
|
-
function DInputSwitch({ id: idProp, label, ariaLabel, name, checked, disabled, invalid = false, valid = false, readonly, className, style, dataAttributes, onChange, }) {
|
|
1772
|
+
function DInputSwitch({ id: idProp, label, ariaLabel, name, checked, disabled, invalid = false, valid = false, readonly, className, style, dataAttributes, inputClassName, onChange, }) {
|
|
1658
1773
|
const innerId = useId();
|
|
1659
1774
|
const id = useMemo(() => idProp || innerId, [idProp, innerId]);
|
|
1660
1775
|
const [internalIsChecked, setInternalIsChecked] = useState(checked);
|
|
@@ -1666,10 +1781,10 @@ function DInputSwitch({ id: idProp, label, ariaLabel, name, checked, disabled, i
|
|
|
1666
1781
|
setInternalIsChecked(value);
|
|
1667
1782
|
onChange === null || onChange === void 0 ? void 0 : onChange(value);
|
|
1668
1783
|
}, [onChange]);
|
|
1669
|
-
return (jsxs("div", Object.assign({ className:
|
|
1784
|
+
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', {
|
|
1670
1785
|
'is-invalid': invalid,
|
|
1671
1786
|
'is-valid': valid,
|
|
1672
|
-
},
|
|
1787
|
+
}, 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 }))] })));
|
|
1673
1788
|
}
|
|
1674
1789
|
|
|
1675
1790
|
function DInputRange(_a, ref) {
|
|
@@ -2306,5 +2421,99 @@ function DDropdown({ actions, dropdownToggle, className, }) {
|
|
|
2306
2421
|
}) })] }));
|
|
2307
2422
|
}
|
|
2308
2423
|
|
|
2309
|
-
|
|
2424
|
+
function useScreenshot() {
|
|
2425
|
+
const clipRef = useRef(null);
|
|
2426
|
+
const takeBlob = useCallback(async (type) => {
|
|
2427
|
+
if (!clipRef.current) {
|
|
2428
|
+
throw new Error('set the clipRef');
|
|
2429
|
+
}
|
|
2430
|
+
const canvas = await html2canvas(clipRef === null || clipRef === void 0 ? void 0 : clipRef.current, {
|
|
2431
|
+
allowTaint: true,
|
|
2432
|
+
useCORS: true,
|
|
2433
|
+
});
|
|
2434
|
+
return (new Promise((resolve, reject) => {
|
|
2435
|
+
canvas.toBlob((innerBlob) => {
|
|
2436
|
+
if (!innerBlob) {
|
|
2437
|
+
return reject();
|
|
2438
|
+
}
|
|
2439
|
+
return resolve(innerBlob);
|
|
2440
|
+
}, type);
|
|
2441
|
+
}));
|
|
2442
|
+
}, []);
|
|
2443
|
+
return {
|
|
2444
|
+
clipRef,
|
|
2445
|
+
takeBlob,
|
|
2446
|
+
};
|
|
2447
|
+
}
|
|
2448
|
+
|
|
2449
|
+
function useScreenshotDownload() {
|
|
2450
|
+
const { clipRef, takeBlob } = useScreenshot();
|
|
2451
|
+
const download = useCallback(async () => {
|
|
2452
|
+
const blob = await takeBlob();
|
|
2453
|
+
const url = window.URL.createObjectURL(blob);
|
|
2454
|
+
const link = window.document.createElement('a');
|
|
2455
|
+
link.style.display = 'none';
|
|
2456
|
+
link.href = url;
|
|
2457
|
+
link.download = 'voucher.jpg';
|
|
2458
|
+
document.body.appendChild(link);
|
|
2459
|
+
link.click();
|
|
2460
|
+
document.body.removeChild(link);
|
|
2461
|
+
window.URL.revokeObjectURL(url);
|
|
2462
|
+
}, [takeBlob]);
|
|
2463
|
+
return {
|
|
2464
|
+
download,
|
|
2465
|
+
downloadRef: clipRef,
|
|
2466
|
+
};
|
|
2467
|
+
}
|
|
2468
|
+
|
|
2469
|
+
function useScreenshotWebShare() {
|
|
2470
|
+
const { takeBlob, clipRef } = useScreenshot();
|
|
2471
|
+
const share = useCallback(async () => {
|
|
2472
|
+
const blob = await takeBlob();
|
|
2473
|
+
const image = new File([blob], 'voucher.jpeg', { type: 'image/jpeg' });
|
|
2474
|
+
if (!navigator.canShare
|
|
2475
|
+
&& (navigator.canShare && !navigator.canShare({ files: [image] }))) {
|
|
2476
|
+
window.print();
|
|
2477
|
+
return;
|
|
2478
|
+
}
|
|
2479
|
+
await navigator.share({ files: [image] });
|
|
2480
|
+
}, [takeBlob]);
|
|
2481
|
+
return {
|
|
2482
|
+
share,
|
|
2483
|
+
shareRef: clipRef,
|
|
2484
|
+
};
|
|
2485
|
+
}
|
|
2486
|
+
|
|
2487
|
+
function DVoucher({ amount, amountDetails, icon = 'CircleCheckBig', color = 'success', title, onError, message, downloadText = 'Download', shareText = 'Share', children, }) {
|
|
2488
|
+
const { shareRef, share } = useScreenshotWebShare();
|
|
2489
|
+
const { downloadRef, download } = useScreenshotDownload();
|
|
2490
|
+
const handleShare = () => {
|
|
2491
|
+
share()
|
|
2492
|
+
.catch(async (err) => {
|
|
2493
|
+
if (onError) {
|
|
2494
|
+
await onError(err);
|
|
2495
|
+
}
|
|
2496
|
+
})
|
|
2497
|
+
.catch(() => {
|
|
2498
|
+
// Error already handled by onError
|
|
2499
|
+
});
|
|
2500
|
+
};
|
|
2501
|
+
const handleDownload = () => {
|
|
2502
|
+
download()
|
|
2503
|
+
.catch(async (err) => {
|
|
2504
|
+
if (onError) {
|
|
2505
|
+
await onError(err);
|
|
2506
|
+
}
|
|
2507
|
+
})
|
|
2508
|
+
.catch(() => {
|
|
2509
|
+
// Error already handled by onError
|
|
2510
|
+
});
|
|
2511
|
+
};
|
|
2512
|
+
return (jsx("div", { className: "d-voucher", ref: (el) => {
|
|
2513
|
+
shareRef.current = el;
|
|
2514
|
+
downloadRef.current = el;
|
|
2515
|
+
}, 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" })] })] }) }));
|
|
2516
|
+
}
|
|
2517
|
+
|
|
2518
|
+
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, DTableHead, 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 };
|
|
2310
2519
|
//# sourceMappingURL=index.esm.js.map
|