@dynamic-framework/ui-react 2.5.2 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/css/dynamic-ui.css +44 -12
- package/dist/css/dynamic-ui.min.css +2 -2
- package/dist/index.esm.js +538 -100
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +541 -97
- package/dist/index.js.map +1 -1
- package/dist/types/components/DAlert/DAlert.d.ts +1 -1
- package/dist/types/components/DAvatar/DAvatar.d.ts +2 -1
- package/dist/types/components/DBadge/DBadge.d.ts +2 -1
- package/dist/types/components/DBox/DBox.d.ts +1 -1
- package/dist/types/components/DBoxFile/DBoxFile.d.ts +1 -1
- package/dist/types/components/DButtonIcon/DButtonIcon.d.ts +1 -1
- package/dist/types/components/DCard/DCard.d.ts +1 -1
- package/dist/types/components/DCard/components/DCardBody.d.ts +1 -1
- package/dist/types/components/DCard/components/DCardFooter.d.ts +1 -1
- package/dist/types/components/DCard/components/DCardHeader.d.ts +1 -1
- package/dist/types/components/DCarousel/DCarousel.d.ts +9 -2
- package/dist/types/components/DCarousel/components/DCarouselSlide.d.ts +1 -1
- package/dist/types/components/DChip/DChip.d.ts +2 -1
- package/dist/types/components/DCollapse/DCollapse.d.ts +1 -1
- package/dist/types/components/DConfirmModal/DConfirmModalContainer.d.ts +21 -0
- package/dist/types/components/DConfirmModal/DConfirmModalUI.d.ts +7 -0
- package/dist/types/components/DConfirmModal/confirmModalStore.d.ts +6 -0
- package/dist/types/components/DConfirmModal/types.d.ts +45 -0
- package/dist/types/components/DCreditCard/DCreditCard.d.ts +2 -1
- package/dist/types/components/DCurrencyText/DCurrencyText.d.ts +2 -1
- package/dist/types/components/DDataStateWrapper/DDataStateWrapper.d.ts +8 -1
- package/dist/types/components/DDataStateWrapper/components/EmptyState.d.ts +2 -1
- package/dist/types/components/DDataStateWrapper/components/ErrorState.d.ts +2 -1
- package/dist/types/components/DDataStateWrapper/components/LoadingState.d.ts +2 -1
- package/dist/types/components/DDataStateWrapper/index.d.ts +4 -0
- package/dist/types/components/DDatePicker/DDatePicker.d.ts +2 -1
- package/dist/types/components/DDatePicker/components/DDatePickerHeaderSelector.d.ts +1 -1
- package/dist/types/components/DDatePicker/components/DDatePickerTime.d.ts +1 -1
- package/dist/types/components/DDropdown/DDropdown.d.ts +4 -1
- package/dist/types/components/DErrorBoundary/DErrorBoundary.d.ts +1 -1
- package/dist/types/components/DErrorBoundary/components/DefaultErrorBoundary.d.ts +2 -1
- package/dist/types/components/DIcon/DIcon.d.ts +4 -4
- package/dist/types/components/DIconBase/DIconBase.d.ts +5 -3
- package/dist/types/components/DIconBase/index.d.ts +1 -0
- package/dist/types/components/DInputCheck/DInputCheck.d.ts +1 -1
- package/dist/types/components/DInputPin/DInputPin.d.ts +2 -1
- package/dist/types/components/DInputSearch/DInputSearch.d.ts +11 -0
- package/dist/types/components/DInputSearch/index.d.ts +3 -0
- package/dist/types/components/DInputSelect/DInputSelect.d.ts +1 -1
- package/dist/types/components/DInputSwitch/DInputSwitch.d.ts +2 -1
- package/dist/types/components/DLayout/DLayout.d.ts +1 -1
- package/dist/types/components/DLayout/components/DLayoutPane.d.ts +1 -1
- package/dist/types/components/DListGroup/DListGroup.d.ts +1 -1
- package/dist/types/components/DListGroup/components/DListGroupItem.d.ts +1 -1
- package/dist/types/components/DModal/DModal.d.ts +1 -1
- package/dist/types/components/DModal/components/DModalBody.d.ts +1 -1
- package/dist/types/components/DModal/components/DModalFooter.d.ts +1 -1
- package/dist/types/components/DModal/components/DModalHeader.d.ts +1 -1
- package/dist/types/components/DOffcanvas/DOffcanvas.d.ts +15 -3
- package/dist/types/components/DOffcanvas/components/DOffcanvasBody.d.ts +1 -1
- package/dist/types/components/DOffcanvas/components/DOffcanvasFooter.d.ts +1 -1
- package/dist/types/components/DOffcanvas/components/DOffcanvasHeader.d.ts +1 -1
- package/dist/types/components/DOtp/DOtp.d.ts +1 -1
- package/dist/types/components/DOtp/components/OtpCountdown.d.ts +2 -1
- package/dist/types/components/DPaginator/DPaginator.d.ts +2 -1
- package/dist/types/components/DPasswordStrengthMeter/DPasswordStrengthMeter.d.ts +3 -1
- package/dist/types/components/DPasswordStrengthMeter/PasswordCheckItem.d.ts +2 -1
- package/dist/types/components/DPasswordStrengthMeter/PasswordCheckList.d.ts +2 -1
- package/dist/types/components/DPasswordStrengthMeter/PasswordStrength.d.ts +2 -1
- package/dist/types/components/DPopover/DPopover.d.ts +1 -1
- package/dist/types/components/DProgress/DProgress.d.ts +2 -1
- package/dist/types/components/DSelect/DSelect.d.ts +2 -1
- package/dist/types/components/DSelect/components/DSelectClearIndicator.d.ts +2 -1
- package/dist/types/components/DSelect/components/DSelectDropdownIndicator.d.ts +2 -1
- package/dist/types/components/DSelect/components/DSelectLoadingIndicator.d.ts +2 -1
- package/dist/types/components/DSelect/components/DSelectMultiValueRemove.d.ts +2 -1
- package/dist/types/components/DSelect/components/DSelectOptionCheck.d.ts +2 -1
- package/dist/types/components/DSelect/components/DSelectOptionEmoji.d.ts +2 -1
- package/dist/types/components/DSelect/components/DSelectOptionIcon.d.ts +2 -1
- package/dist/types/components/DSelect/components/DSelectPlaceholder.d.ts +2 -1
- package/dist/types/components/DSelect/components/DSelectSingleValueEmoji.d.ts +2 -1
- package/dist/types/components/DSelect/components/DSelectSingleValueEmojiText.d.ts +2 -1
- package/dist/types/components/DSelect/components/DSelectSingleValueIconText.d.ts +2 -1
- package/dist/types/components/DStepper/DStepper.d.ts +2 -1
- package/dist/types/components/DStepperDesktop/DStepperDesktop.d.ts +2 -1
- package/dist/types/components/DStepperMobile/DStepperMobile.d.ts +2 -1
- package/dist/types/components/DTabs/DTabs.d.ts +1 -1
- package/dist/types/components/DTabs/components/DTabContent.d.ts +1 -1
- package/dist/types/components/DTimeline/DTimeline.d.ts +1 -1
- package/dist/types/components/DToast/DToast.d.ts +1 -1
- package/dist/types/components/DToast/components/DToastBody.d.ts +1 -1
- package/dist/types/components/DToast/components/DToastHeader.d.ts +1 -1
- package/dist/types/components/DToastContainer/DToastContainer.d.ts +1 -1
- package/dist/types/components/DTooltip/DTooltip.d.ts +1 -1
- package/dist/types/components/DVoucher/DVoucher.d.ts +1 -1
- package/dist/types/components/index.d.ts +6 -1
- package/dist/types/components/interface.d.ts +6 -4
- package/dist/types/contexts/DContext.d.ts +27 -4
- package/dist/types/contexts/DPortalContext.d.ts +1 -1
- package/dist/types/hooks/index.d.ts +2 -0
- package/dist/types/hooks/useConfirmModal.d.ts +34 -0
- package/package.json +6 -2
- package/src/style/_shame.scss +13 -0
- package/src/style/abstracts/variables/_forms.scss +1 -1
- package/src/style/abstracts/variables/_list-group.scss +1 -1
- package/src/style/abstracts/variables/_offcanvas.scss +8 -0
- package/src/style/base/_backdrop.scss +7 -0
- package/src/style/components/_d-carousel.scss +20 -2
- package/src/style/components/_d-modal.scss +8 -0
- package/src/style/root/_root.scss +31 -0
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ var classNames = require('classnames');
|
|
|
5
5
|
var React = require('react');
|
|
6
6
|
var tslib = require('tslib');
|
|
7
7
|
var LucideIcons = require('lucide-react');
|
|
8
|
+
var reactIs = require('react-is');
|
|
8
9
|
var reactDom = require('react-dom');
|
|
9
10
|
var framerMotion = require('framer-motion');
|
|
10
11
|
var fileSelector = require('file-selector');
|
|
@@ -78,7 +79,7 @@ function useDisableBodyScrollEffect(disable) {
|
|
|
78
79
|
timer = window.setTimeout(() => {
|
|
79
80
|
unlock();
|
|
80
81
|
observer === null || observer === void 0 ? void 0 : observer.disconnect();
|
|
81
|
-
},
|
|
82
|
+
}, 300);
|
|
82
83
|
}
|
|
83
84
|
else {
|
|
84
85
|
unlock();
|
|
@@ -163,7 +164,7 @@ function getKeyboardFocusableElements(container) {
|
|
|
163
164
|
const DPortalContext = React.createContext(undefined);
|
|
164
165
|
function DPortalContextProvider({ portalName, children, availablePortals, }) {
|
|
165
166
|
const { created } = usePortal(portalName);
|
|
166
|
-
const [stack, { push, pop
|
|
167
|
+
const [stack, { push, pop }] = useStackState([]);
|
|
167
168
|
useDisableBodyScrollEffect(Boolean(stack.length));
|
|
168
169
|
const openPortal = React.useCallback(
|
|
169
170
|
// eslint-disable-next-line prefer-arrow-callback
|
|
@@ -184,11 +185,9 @@ function DPortalContextProvider({ portalName, children, availablePortals, }) {
|
|
|
184
185
|
(_a = document.activeElement) === null || _a === void 0 ? void 0 : _a.blur();
|
|
185
186
|
}, [availablePortals, push]);
|
|
186
187
|
const closePortal = React.useCallback(() => {
|
|
187
|
-
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
188
|
+
// pop() is safe on empty stacks, so close remains idempotent.
|
|
190
189
|
pop();
|
|
191
|
-
}, [
|
|
190
|
+
}, [pop]);
|
|
192
191
|
const publicStack = React.useMemo(() => stack.map(({ name, payload }) => ({ name, payload })), [stack]);
|
|
193
192
|
const value = React.useMemo(() => ({
|
|
194
193
|
stack: publicStack,
|
|
@@ -279,6 +278,40 @@ function useDPortalContext() {
|
|
|
279
278
|
return context;
|
|
280
279
|
}
|
|
281
280
|
|
|
281
|
+
function createConfirmModalStore() {
|
|
282
|
+
const listeners = new Set();
|
|
283
|
+
let entries = [];
|
|
284
|
+
function notify() {
|
|
285
|
+
listeners.forEach((listener) => listener([...entries]));
|
|
286
|
+
}
|
|
287
|
+
const store = {
|
|
288
|
+
subscribe(listener) {
|
|
289
|
+
listeners.add(listener);
|
|
290
|
+
listener([...entries]);
|
|
291
|
+
return () => {
|
|
292
|
+
listeners.delete(listener);
|
|
293
|
+
};
|
|
294
|
+
},
|
|
295
|
+
push(entry) {
|
|
296
|
+
entries = [...entries, entry];
|
|
297
|
+
notify();
|
|
298
|
+
},
|
|
299
|
+
remove(id) {
|
|
300
|
+
entries = entries.filter((e) => e.id !== id);
|
|
301
|
+
notify();
|
|
302
|
+
},
|
|
303
|
+
};
|
|
304
|
+
return store;
|
|
305
|
+
}
|
|
306
|
+
const ConfirmModalStoreContext = React.createContext(null);
|
|
307
|
+
function useConfirmModalStore() {
|
|
308
|
+
const store = React.useContext(ConfirmModalStoreContext);
|
|
309
|
+
if (!store) {
|
|
310
|
+
throw new Error('useConfirmModal must be used within a <DContextProvider>.');
|
|
311
|
+
}
|
|
312
|
+
return store;
|
|
313
|
+
}
|
|
314
|
+
|
|
282
315
|
function getCssVariable(variable) {
|
|
283
316
|
const computedStyle = getComputedStyle(document.documentElement);
|
|
284
317
|
return computedStyle.getPropertyValue(variable).trim();
|
|
@@ -297,6 +330,7 @@ const DEFAULT_STATE = {
|
|
|
297
330
|
familyPrefix: 'bi-',
|
|
298
331
|
materialStyle: false,
|
|
299
332
|
},
|
|
333
|
+
iconRegistry: undefined,
|
|
300
334
|
iconMap: {
|
|
301
335
|
x: 'X',
|
|
302
336
|
xLg: 'X',
|
|
@@ -337,14 +371,37 @@ const DContext = React.createContext(DEFAULT_STATE);
|
|
|
337
371
|
* component to configure icons, currency, language, and portal settings
|
|
338
372
|
* for all descendant Dynamic UI components.
|
|
339
373
|
*
|
|
374
|
+
* To enable confirmation modals you must also mount `DConfirmModalContainer`
|
|
375
|
+
* somewhere inside this provider (typically right before the closing tag of
|
|
376
|
+
* your root layout), similar to how `DToastContainer` works:
|
|
377
|
+
*
|
|
378
|
+
* ```tsx
|
|
379
|
+
* // Default: portalName="d-portal"
|
|
380
|
+
* <DContextProvider>
|
|
381
|
+
* <App />
|
|
382
|
+
* <DConfirmModalContainer nodeId="d-portal" />
|
|
383
|
+
* </DContextProvider>
|
|
384
|
+
* ```
|
|
385
|
+
*
|
|
386
|
+
* If you customize `portalName`, match it in `DConfirmModalContainer.nodeId`:
|
|
387
|
+
*
|
|
388
|
+
* ```tsx
|
|
389
|
+
* // Custom portalName
|
|
390
|
+
* <DContextProvider portalName="my-custom-portal">
|
|
391
|
+
* <App />
|
|
392
|
+
* <DConfirmModalContainer nodeId="my-custom-portal" />
|
|
393
|
+
* </DContextProvider>
|
|
394
|
+
* ```
|
|
395
|
+
*
|
|
340
396
|
* @template T - Map of portal name → payload shape (e.g. `{ modal: { title: string } }`).
|
|
341
397
|
* Pass it once at the top level: `<DContextProvider<MyPortals> ...>`.
|
|
342
398
|
*/
|
|
343
|
-
function DContextProvider({ language = DEFAULT_STATE.language, currency = DEFAULT_STATE.currency, icon = DEFAULT_STATE.icon, iconMap = DEFAULT_STATE.iconMap, portalName = 'd-portal', availablePortals, children, }) {
|
|
399
|
+
function DContextProvider({ language = DEFAULT_STATE.language, currency = DEFAULT_STATE.currency, icon = DEFAULT_STATE.icon, iconRegistry = DEFAULT_STATE.iconRegistry, iconMap = DEFAULT_STATE.iconMap, portalName = 'd-portal', availablePortals, children, }) {
|
|
344
400
|
const [internalContext, setInternalContext,] = React.useState({
|
|
345
401
|
language,
|
|
346
402
|
currency,
|
|
347
403
|
icon,
|
|
404
|
+
iconRegistry,
|
|
348
405
|
iconMap,
|
|
349
406
|
breakpoints: DEFAULT_STATE.breakpoints,
|
|
350
407
|
});
|
|
@@ -362,7 +419,8 @@ function DContextProvider({ language = DEFAULT_STATE.language, currency = DEFAUL
|
|
|
362
419
|
});
|
|
363
420
|
}, [setContext]);
|
|
364
421
|
const value = React.useMemo(() => (Object.assign(Object.assign({}, internalContext), { setContext })), [internalContext, setContext]);
|
|
365
|
-
|
|
422
|
+
const confirmStore = React.useMemo(() => createConfirmModalStore(), []);
|
|
423
|
+
return (jsxRuntime.jsx(ConfirmModalStoreContext.Provider, { value: confirmStore, children: jsxRuntime.jsx(DContext.Provider, { value: value, children: jsxRuntime.jsx(DPortalContextProvider, { portalName: portalName, availablePortals: availablePortals, children: children }) }) }));
|
|
366
424
|
}
|
|
367
425
|
/**
|
|
368
426
|
* Returns the Dynamic UI context value set by `DContextProvider`.
|
|
@@ -460,17 +518,21 @@ function useResponsiveProp(useListener = false) {
|
|
|
460
518
|
return { responsivePropValue };
|
|
461
519
|
}
|
|
462
520
|
|
|
521
|
+
function isIconComponent(value) {
|
|
522
|
+
return typeof value !== 'string' && reactIs.isValidElementType(value);
|
|
523
|
+
}
|
|
463
524
|
function DIconBase({ icon, color, style, className, size, useListenerSize = false, hasCircle = false, materialStyle = false, familyClass, familyPrefix, strokeWidth = 2, dataAttributes, }) {
|
|
464
525
|
// If materialStyle is true, use Material Design icons (legacy)
|
|
465
|
-
const
|
|
526
|
+
const isStringIcon = typeof icon === 'string';
|
|
527
|
+
const useMaterialIcons = materialStyle && isStringIcon;
|
|
466
528
|
// Get Lucide icon component
|
|
467
529
|
const LucideIcon = React.useMemo(() => {
|
|
468
|
-
if (useMaterialIcons)
|
|
530
|
+
if (!isStringIcon || useMaterialIcons)
|
|
469
531
|
return null;
|
|
470
532
|
// Try to find the icon in Lucide (expects PascalCase)
|
|
471
533
|
const icons = LucideIcons__namespace;
|
|
472
534
|
return icons[icon] || null;
|
|
473
|
-
}, [icon, useMaterialIcons]);
|
|
535
|
+
}, [icon, isStringIcon, useMaterialIcons]);
|
|
474
536
|
const { responsivePropValue } = useResponsiveProp(useListenerSize);
|
|
475
537
|
const resolvedSize = React.useMemo(() => {
|
|
476
538
|
if (!size)
|
|
@@ -490,24 +552,35 @@ function DIconBase({ icon, color, style, className, size, useListenerSize = fals
|
|
|
490
552
|
}, [resolvedSize]);
|
|
491
553
|
// Render Material Design icon (legacy support)
|
|
492
554
|
if (useMaterialIcons) {
|
|
493
|
-
return (jsxRuntime.jsx("i", Object.assign({ className: classNames(generateClasses, familyClass), style: generateStyleVariables }, dataAttributes, { children: icon })));
|
|
555
|
+
return (jsxRuntime.jsx("i", Object.assign({ className: classNames(generateClasses, familyClass), style: generateStyleVariables }, dataAttributes, { children: isStringIcon ? icon : null })));
|
|
556
|
+
}
|
|
557
|
+
if (isIconComponent(icon)) {
|
|
558
|
+
return (jsxRuntime.jsx("span", Object.assign({ className: classNames(generateClasses), style: generateStyleVariables }, dataAttributes, { children: React.createElement(icon, {
|
|
559
|
+
width: resolvedSize || 24,
|
|
560
|
+
height: resolvedSize || 24,
|
|
561
|
+
strokeWidth,
|
|
562
|
+
}) })));
|
|
494
563
|
}
|
|
495
564
|
// Render Lucide icon
|
|
496
565
|
if (!LucideIcon) {
|
|
497
|
-
if (familyClass && familyPrefix) {
|
|
566
|
+
if (isStringIcon && familyClass && familyPrefix) {
|
|
498
567
|
return (jsxRuntime.jsx("i", Object.assign({ className: classNames(generateClasses, familyClass, `${familyPrefix}${icon}`), style: generateStyleVariables }, dataAttributes)));
|
|
499
568
|
}
|
|
500
569
|
// eslint-disable-next-line no-console
|
|
501
|
-
console.warn(`Icon "${icon}" not found in Lucide. Make sure to use PascalCase names (e.g., "Home", "User", "Settings")`);
|
|
570
|
+
console.warn(`Icon "${String(icon)}" not found in Lucide. Make sure to use PascalCase names (e.g., "Home", "User", "Settings")`);
|
|
502
571
|
return (jsxRuntime.jsx("span", Object.assign({ className: classNames(generateClasses), style: generateStyleVariables }, dataAttributes, { children: "?" })));
|
|
503
572
|
}
|
|
504
573
|
return (jsxRuntime.jsx("span", Object.assign({ className: classNames(generateClasses), style: generateStyleVariables }, dataAttributes, { children: jsxRuntime.jsx(LucideIcon, { size: iconSize || 24, strokeWidth: strokeWidth }) })));
|
|
505
574
|
}
|
|
506
575
|
|
|
507
576
|
function DIcon(_a) {
|
|
508
|
-
var { familyClass: propFamilyClass, familyPrefix: propFamilyPrefix, materialStyle: propMaterialStyle } = _a, props = tslib.__rest(_a, ["familyClass", "familyPrefix", "materialStyle"]);
|
|
509
|
-
const { icon: { familyClass, familyPrefix, materialStyle, }, } = useDContext();
|
|
510
|
-
|
|
577
|
+
var { icon, familyClass: propFamilyClass, familyPrefix: propFamilyPrefix, materialStyle: propMaterialStyle } = _a, props = tslib.__rest(_a, ["icon", "familyClass", "familyPrefix", "materialStyle"]);
|
|
578
|
+
const { icon: { familyClass, familyPrefix, materialStyle, }, iconRegistry, } = useDContext();
|
|
579
|
+
const registryIcon = typeof icon === 'string'
|
|
580
|
+
? iconRegistry === null || iconRegistry === void 0 ? void 0 : iconRegistry[icon]
|
|
581
|
+
: undefined;
|
|
582
|
+
const resolvedIcon = registryIcon || icon;
|
|
583
|
+
return (jsxRuntime.jsx(DIconBase, Object.assign({ icon: resolvedIcon, familyClass: propFamilyClass !== null && propFamilyClass !== void 0 ? propFamilyClass : familyClass, familyPrefix: propFamilyPrefix !== null && propFamilyPrefix !== void 0 ? propFamilyPrefix : familyPrefix, materialStyle: propMaterialStyle !== null && propMaterialStyle !== void 0 ? propMaterialStyle : materialStyle }, props)));
|
|
511
584
|
}
|
|
512
585
|
|
|
513
586
|
function DAlert({ color = 'success', icon: iconProp, iconFamilyClass, iconFamilyPrefix, iconMaterialStyle = false, iconClose: iconCloseProp, iconCloseFamilyClass, iconCloseFamilyPrefix, iconCloseMaterialStyle = false, showClose, onClose, children, id, className, style, dataAttributes, }) {
|
|
@@ -1057,7 +1130,7 @@ function DBoxFile(_a) {
|
|
|
1057
1130
|
}
|
|
1058
1131
|
|
|
1059
1132
|
const DButton = React.forwardRef((props, ref) => {
|
|
1060
|
-
const { color = 'primary', size, variant, text, children, iconStart, iconStartFamilyClass, iconStartFamilyPrefix, iconStartMaterialStyle, iconEnd, iconEndFamilyClass, iconEndFamilyPrefix, iconEndMaterialStyle, loading = false, loadingText, loadingAriaLabel, disabled = false, className, style, dataAttributes, onClick, type = 'button', target, rel, href, 'aria-label': ariaLabelProp } = props, rest = 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", "target", "rel", "href", 'aria-label']);
|
|
1133
|
+
const { color = 'primary', size, variant = 'solid', text, children, iconStart, iconStartFamilyClass, iconStartFamilyPrefix, iconStartMaterialStyle, iconEnd, iconEndFamilyClass, iconEndFamilyPrefix, iconEndMaterialStyle, loading = false, loadingText, loadingAriaLabel, disabled = false, className, style, dataAttributes, onClick, type = 'button', target, rel, href, 'aria-label': ariaLabelProp } = props, rest = 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", "target", "rel", "href", 'aria-label']);
|
|
1061
1134
|
// Responsive size resolution using useResponsiveProp
|
|
1062
1135
|
const { responsivePropValue } = useResponsiveProp(true);
|
|
1063
1136
|
const resolvedSize = React.useMemo(() => {
|
|
@@ -1072,9 +1145,9 @@ const DButton = React.forwardRef((props, ref) => {
|
|
|
1072
1145
|
const isDisabled = React.useMemo(() => disabled || loading, [disabled, loading]);
|
|
1073
1146
|
const content = React.useMemo(() => children || text, [children, text]);
|
|
1074
1147
|
const classes = React.useMemo(() => {
|
|
1075
|
-
const variantClass = variant
|
|
1076
|
-
? `btn-${
|
|
1077
|
-
: `btn-${color}`;
|
|
1148
|
+
const variantClass = variant === 'solid'
|
|
1149
|
+
? `btn-${color}`
|
|
1150
|
+
: `btn-${variant}-${color}`;
|
|
1078
1151
|
return {
|
|
1079
1152
|
btn: true,
|
|
1080
1153
|
[variantClass]: true,
|
|
@@ -1132,9 +1205,9 @@ DButton.displayName = 'DButton';
|
|
|
1132
1205
|
function DButtonIcon(_a) {
|
|
1133
1206
|
var { id, icon, size, className, variant, state, loadingAriaLabel, iconMaterialStyle, disabled = false, color = 'primary', loading = false, href, target, rel, stopPropagationEnabled = true, style, iconFamilyClass, iconFamilyPrefix, dataAttributes, onClick, 'aria-label': ariaLabelProp } = _a, rest = tslib.__rest(_a, ["id", "icon", "size", "className", "variant", "state", "loadingAriaLabel", "iconMaterialStyle", "disabled", "color", "loading", "href", "target", "rel", "stopPropagationEnabled", "style", "iconFamilyClass", "iconFamilyPrefix", "dataAttributes", "onClick", 'aria-label']);
|
|
1134
1207
|
const generateClasses = React.useMemo(() => {
|
|
1135
|
-
const variantClass = variant
|
|
1136
|
-
? `btn-${
|
|
1137
|
-
: `btn-${color}`;
|
|
1208
|
+
const variantClass = !variant || variant === 'solid'
|
|
1209
|
+
? `btn-${color}`
|
|
1210
|
+
: `btn-${variant}-${color}`;
|
|
1138
1211
|
return Object.assign(Object.assign(Object.assign({ 'btn d-button-icon': true, [variantClass]: true }, size && { [`btn-${size}`]: true }), (state && state !== 'disabled') && { [state]: true }), { loading });
|
|
1139
1212
|
}, [variant, color, size, state, loading]);
|
|
1140
1213
|
const isDisabled = React.useMemo(() => (state === 'disabled' || loading || disabled), [state, loading, disabled]);
|
|
@@ -1187,8 +1260,14 @@ function DCarouselSlide(_a) {
|
|
|
1187
1260
|
return (jsxRuntime.jsx(reactSplide.SplideSlide, Object.assign({ className: classNames('d-carousel-slide', className) }, props)));
|
|
1188
1261
|
}
|
|
1189
1262
|
|
|
1263
|
+
const DEFAULT_ARROW_PATH = 'm15.5 0.932-4.3 4.38 14.5 14.6-14.5 14.5 4.3 4.4 14.6-14.6 4.4-4.3-4.4-4.4-14.6-14.6z';
|
|
1264
|
+
function DefaultArrowIcon() {
|
|
1265
|
+
return (jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 40 40", width: 40, height: 40, focusable: "false", "aria-hidden": "true", children: jsxRuntime.jsx("path", { d: DEFAULT_ARROW_PATH }) }));
|
|
1266
|
+
}
|
|
1190
1267
|
function DCarousel$1(_a, ref) {
|
|
1191
|
-
var { children, className, style, options, dataAttributes } = _a, props = tslib.__rest(_a, ["children", "className", "style", "options", "dataAttributes"]);
|
|
1268
|
+
var { children, className, style, options, dataAttributes, iconArrowLeft, iconArrowRight, hasTrack: propsHasTrack } = _a, props = tslib.__rest(_a, ["children", "className", "style", "options", "dataAttributes", "iconArrowLeft", "iconArrowRight", "hasTrack"]);
|
|
1269
|
+
// Explicit `options.arrows === false` always wins, even when icon props are set.
|
|
1270
|
+
const hasCustomArrows = Boolean((iconArrowLeft || iconArrowRight) && (options === null || options === void 0 ? void 0 : options.arrows) !== false);
|
|
1192
1271
|
return (jsxRuntime.jsx(reactSplide.Splide, Object.assign({ className: classNames('d-carousel', className), style: style, ref: ref, options: Object.assign(Object.assign({}, options), { classes: {
|
|
1193
1272
|
// Arrows
|
|
1194
1273
|
arrows: 'splide__arrows d-carousel-arrows',
|
|
@@ -1198,7 +1277,11 @@ function DCarousel$1(_a, ref) {
|
|
|
1198
1277
|
// Paginator
|
|
1199
1278
|
pagination: 'splide__pagination d-carousel-pagination',
|
|
1200
1279
|
page: 'splide__pagination__page d-carousel-pagination-page',
|
|
1201
|
-
} }) }, dataAttributes, props, {
|
|
1280
|
+
} }) }, dataAttributes, props, {
|
|
1281
|
+
// Rendering our own arrows requires taking over the track wrapper, so this
|
|
1282
|
+
// must be applied after `...props` to prevent a consumer-provided `hasTrack`
|
|
1283
|
+
// from re-enabling Splide's automatic track when custom arrows are active.
|
|
1284
|
+
hasTrack: hasCustomArrows ? false : propsHasTrack, children: hasCustomArrows ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(reactSplide.SplideTrack, { children: children }), jsxRuntime.jsxs("div", { className: "splide__arrows d-carousel-arrows", children: [jsxRuntime.jsx("button", { type: "button", className: "splide__arrow splide__arrow--prev d-carousel-arrow d-carousel-arrow-prev", children: iconArrowLeft ? jsxRuntime.jsx(DIcon, Object.assign({}, iconArrowLeft)) : jsxRuntime.jsx(DefaultArrowIcon, {}) }), jsxRuntime.jsx("button", { type: "button", className: "splide__arrow splide__arrow--next d-carousel-arrow d-carousel-arrow-next", children: iconArrowRight ? jsxRuntime.jsx(DIcon, Object.assign({}, iconArrowRight)) : jsxRuntime.jsx(DefaultArrowIcon, {}) })] })] })) : children })));
|
|
1202
1285
|
}
|
|
1203
1286
|
const ForwardedDCarousel = React.forwardRef(DCarousel$1);
|
|
1204
1287
|
ForwardedDCarousel.displayName = 'DCarousel';
|
|
@@ -1426,6 +1509,18 @@ function DDatePickerHeaderSelector({ date, changeYear, changeMonth, decreaseMont
|
|
|
1426
1509
|
|
|
1427
1510
|
function DDatePicker(_a) {
|
|
1428
1511
|
var { inputLabel, inputHint, inputAriaLabel, ariaLabelInputTime, inputActionAriaLabel = 'open calendar', inputId = 'input-calendar', timeId = 'input-time', timeInputLabel, minYearSelect, maxYearSelect, iconHeaderSize, iconMaterialStyle, iconInput, headerPrevMonthAriaLabel, headerNextMonthAriaLabel, invalid = false, valid = false, renderCustomHeader: renderCustomHeaderProp, className, dateFormatCalendar: dateFormatCalendarProp, style, dataAttributes, placeholder, showHeaderSelectors, formatHeaderDate } = _a, props = tslib.__rest(_a, ["inputLabel", "inputHint", "inputAriaLabel", "ariaLabelInputTime", "inputActionAriaLabel", "inputId", "timeId", "timeInputLabel", "minYearSelect", "maxYearSelect", "iconHeaderSize", "iconMaterialStyle", "iconInput", "headerPrevMonthAriaLabel", "headerNextMonthAriaLabel", "invalid", "valid", "renderCustomHeader", "className", "dateFormatCalendar", "style", "dataAttributes", "placeholder", "showHeaderSelectors", "formatHeaderDate"]);
|
|
1512
|
+
// Some test runtimes can resolve react-datepicker as a module object.
|
|
1513
|
+
// Normalize to a renderable component for both function and { default } shapes.
|
|
1514
|
+
const SafeDatePicker = React.useMemo(() => {
|
|
1515
|
+
const interopDefault = DatePicker.default;
|
|
1516
|
+
if (interopDefault !== undefined) {
|
|
1517
|
+
return interopDefault;
|
|
1518
|
+
}
|
|
1519
|
+
if (typeof DatePicker === 'function') {
|
|
1520
|
+
return DatePicker;
|
|
1521
|
+
}
|
|
1522
|
+
return DatePicker;
|
|
1523
|
+
}, []);
|
|
1429
1524
|
const pickerType = React.useMemo(() => {
|
|
1430
1525
|
if (props.showQuarterYearPicker)
|
|
1431
1526
|
return PickerType.Quarter;
|
|
@@ -1453,7 +1548,7 @@ function DDatePicker(_a) {
|
|
|
1453
1548
|
]);
|
|
1454
1549
|
const defaultRenderCustomHeader = React.useCallback((headerProps) => (jsxRuntime.jsx(DatePickerHeader, Object.assign({}, headerProps))), [DatePickerHeader]);
|
|
1455
1550
|
const renderCustomHeader = React.useMemo(() => (renderCustomHeaderProp || defaultRenderCustomHeader), [defaultRenderCustomHeader, renderCustomHeaderProp]);
|
|
1456
|
-
return (jsxRuntime.jsx(
|
|
1551
|
+
return (jsxRuntime.jsx(SafeDatePicker, Object.assign({}, dataAttributes, props, { calendarClassName: "d-date-picker", renderCustomHeader: renderCustomHeader, placeholderText: placeholder, customInput: (jsxRuntime.jsx(ForwardedDDatePickerInput, { id: inputId, "aria-label": inputAriaLabel, iconEndAriaLabel: inputActionAriaLabel, iconMaterialStyle: iconMaterialStyle, iconEnd: iconInput, inputLabel: inputLabel, className: className, style: style, invalid: invalid, valid: valid, hint: inputHint })), customTimeInput: (jsxRuntime.jsx(DDatePickerTime, { id: timeId, "aria-label": ariaLabelInputTime })) })));
|
|
1457
1552
|
}
|
|
1458
1553
|
|
|
1459
1554
|
function DLayoutPane({ className, style, children, cols, colsXs, colsSm, colsMd, colsLg, colsXl, colsXxl, dataAttributes, }) {
|
|
@@ -1483,6 +1578,55 @@ var DLayout = Object.assign(DLayout$1, {
|
|
|
1483
1578
|
Pane: DLayoutPane,
|
|
1484
1579
|
});
|
|
1485
1580
|
|
|
1581
|
+
function normalizeValue(value) {
|
|
1582
|
+
return value !== null && value !== void 0 ? value : '';
|
|
1583
|
+
}
|
|
1584
|
+
function DInputSearch(_a, ref) {
|
|
1585
|
+
var { debounceMs = 300, onChange, onImmediateChange, value, defaultValue, placeholder = 'Search...' } = _a, props = tslib.__rest(_a, ["debounceMs", "onChange", "onImmediateChange", "value", "defaultValue", "placeholder"]);
|
|
1586
|
+
const inputRef = useProvidedRefOrCreate(ref);
|
|
1587
|
+
const isControlled = value !== undefined;
|
|
1588
|
+
const onChangeRef = React.useRef(onChange);
|
|
1589
|
+
onChangeRef.current = onChange;
|
|
1590
|
+
const [internalValue, setInternalValue] = React.useState(normalizeValue(isControlled ? value : defaultValue));
|
|
1591
|
+
// null = no keystroke has occurred yet (skip debounce on mount)
|
|
1592
|
+
const [pendingValue, setPendingValue] = React.useState(null);
|
|
1593
|
+
React.useEffect(() => {
|
|
1594
|
+
if (!isControlled)
|
|
1595
|
+
return;
|
|
1596
|
+
setInternalValue(normalizeValue(value));
|
|
1597
|
+
}, [isControlled, value]);
|
|
1598
|
+
const handleChange = React.useCallback((nextValue) => {
|
|
1599
|
+
if (!isControlled) {
|
|
1600
|
+
setInternalValue(nextValue);
|
|
1601
|
+
}
|
|
1602
|
+
setPendingValue(nextValue);
|
|
1603
|
+
onImmediateChange === null || onImmediateChange === void 0 ? void 0 : onImmediateChange(nextValue);
|
|
1604
|
+
}, [isControlled, onImmediateChange]);
|
|
1605
|
+
React.useEffect(() => {
|
|
1606
|
+
var _a;
|
|
1607
|
+
let timeoutId;
|
|
1608
|
+
if (pendingValue !== null) {
|
|
1609
|
+
if (debounceMs <= 0) {
|
|
1610
|
+
(_a = onChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onChangeRef, pendingValue);
|
|
1611
|
+
setPendingValue(null);
|
|
1612
|
+
}
|
|
1613
|
+
else {
|
|
1614
|
+
timeoutId = window.setTimeout(() => {
|
|
1615
|
+
var _a;
|
|
1616
|
+
(_a = onChangeRef.current) === null || _a === void 0 ? void 0 : _a.call(onChangeRef, pendingValue);
|
|
1617
|
+
setPendingValue(null);
|
|
1618
|
+
}, debounceMs);
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
return () => {
|
|
1622
|
+
window.clearTimeout(timeoutId);
|
|
1623
|
+
};
|
|
1624
|
+
}, [debounceMs, pendingValue]);
|
|
1625
|
+
return (jsxRuntime.jsx(ForwardedDInput, Object.assign({ ref: inputRef }, props, { type: "search", value: internalValue, onChange: handleChange, placeholder: placeholder })));
|
|
1626
|
+
}
|
|
1627
|
+
const ForwardedDInputSearch = React.forwardRef(DInputSearch);
|
|
1628
|
+
ForwardedDInputSearch.displayName = 'DInputSearch';
|
|
1629
|
+
|
|
1486
1630
|
function DInputMask(props, ref) {
|
|
1487
1631
|
return (jsxRuntime.jsx(mask.InputMask, Object.assign({ ref: ref, component: ForwardedDInput }, props)));
|
|
1488
1632
|
}
|
|
@@ -1587,6 +1731,64 @@ function useItemSelection({ getItemIdentifier: getItemIdentifierProp, previousSe
|
|
|
1587
1731
|
};
|
|
1588
1732
|
}
|
|
1589
1733
|
|
|
1734
|
+
/**
|
|
1735
|
+
* Hook to display a confirmation modal.
|
|
1736
|
+
*
|
|
1737
|
+
* Renders into the portal node specified by `DConfirmModalContainer` (typically `#d-portal`).
|
|
1738
|
+
* The confirm modal floats above the portal stack and handles its own Escape key,
|
|
1739
|
+
* preventing interference with underlying modals.
|
|
1740
|
+
*
|
|
1741
|
+
* Requires both `DContextProvider` wrapping your application AND an explicit
|
|
1742
|
+
* `<DConfirmModalContainer nodeId="d-portal" />` mounted in your app.
|
|
1743
|
+
*
|
|
1744
|
+
* @example
|
|
1745
|
+
* function App() {
|
|
1746
|
+
* return (
|
|
1747
|
+
* <DContextProvider>
|
|
1748
|
+
* <YourContent />
|
|
1749
|
+
* <DConfirmModalContainer nodeId="d-portal" />
|
|
1750
|
+
* </DContextProvider>
|
|
1751
|
+
* );
|
|
1752
|
+
* }
|
|
1753
|
+
*
|
|
1754
|
+
* function MyComponent() {
|
|
1755
|
+
* const confirm = useConfirmModal({
|
|
1756
|
+
* title: 'Delete Account',
|
|
1757
|
+
* message: 'This action cannot be undone.',
|
|
1758
|
+
* critical: { code: 'DELETE ACCOUNT' },
|
|
1759
|
+
* onConfirm: async () => { await deleteAccount(); },
|
|
1760
|
+
* });
|
|
1761
|
+
*
|
|
1762
|
+
* return <DButton onClick={confirm.open} text="Delete" color="danger" />;
|
|
1763
|
+
* }
|
|
1764
|
+
*/
|
|
1765
|
+
function useConfirmModal(config) {
|
|
1766
|
+
const store = useConfirmModalStore();
|
|
1767
|
+
const idRef = React.useRef(`confirm-modal-${Math.random().toString(36).slice(2)}`);
|
|
1768
|
+
const close = React.useCallback(() => {
|
|
1769
|
+
store.remove(idRef.current);
|
|
1770
|
+
queueMicrotask(() => {
|
|
1771
|
+
var _a;
|
|
1772
|
+
(_a = config.onClose) === null || _a === void 0 ? void 0 : _a.call(config);
|
|
1773
|
+
});
|
|
1774
|
+
}, [store, config]);
|
|
1775
|
+
const open = React.useCallback(() => {
|
|
1776
|
+
const handleConfirmAction = async () => {
|
|
1777
|
+
try {
|
|
1778
|
+
await config.onConfirm();
|
|
1779
|
+
store.remove(idRef.current);
|
|
1780
|
+
}
|
|
1781
|
+
catch (_a) {
|
|
1782
|
+
// Keep modal open on error
|
|
1783
|
+
}
|
|
1784
|
+
};
|
|
1785
|
+
// Remove any existing entry with this id to prevent duplicates on re-entrancy
|
|
1786
|
+
store.remove(idRef.current);
|
|
1787
|
+
store.push(Object.assign(Object.assign({}, config), { id: idRef.current, onConfirmAction: handleConfirmAction, onCloseAction: close }));
|
|
1788
|
+
}, [store, config, close]);
|
|
1789
|
+
return { open };
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1590
1792
|
function DInputCounter(_a, ref) {
|
|
1591
1793
|
var { minValue, maxValue, value = minValue, invalid, iconStart: iconStartProp, iconEnd: iconEndProp, iconStartAriaLabel = 'decrease action', iconEndAriaLabel = 'increase action', style, onChange } = _a, props = tslib.__rest(_a, ["minValue", "maxValue", "value", "invalid", "iconStart", "iconEnd", "iconStartAriaLabel", "iconEndAriaLabel", "style", "onChange"]);
|
|
1592
1794
|
const { handleOnWheel, } = useDisableInputWheel(ref);
|
|
@@ -1718,7 +1920,7 @@ const DEFAULT_VALIDATION_MESSAGES = {
|
|
|
1718
1920
|
notMatch: 'The password confirmation and the new password do not match.',
|
|
1719
1921
|
};
|
|
1720
1922
|
const DEFAULT_ENABLED_CHECKS = ['uppercase', 'lowercase', 'number', 'specialChar'];
|
|
1721
|
-
function DPasswordStrengthMeter({ id, label = 'Password', placeholder, value = '', name, disabled = false, invalid = false, validationMessages = DEFAULT_VALIDATION_MESSAGES, enabledChecks = DEFAULT_ENABLED_CHECKS, className, style, dataAttributes, onChange, }) {
|
|
1923
|
+
function DPasswordStrengthMeter({ id, label = 'Password', placeholder, value = '', name, disabled = false, invalid = false, validationMessages = DEFAULT_VALIDATION_MESSAGES, enabledChecks = DEFAULT_ENABLED_CHECKS, className, style, dataAttributes, onChange, readonly = false, }) {
|
|
1722
1924
|
const [password, setPassword] = React.useState(value);
|
|
1723
1925
|
React.useEffect(() => {
|
|
1724
1926
|
setPassword(value);
|
|
@@ -1727,7 +1929,7 @@ function DPasswordStrengthMeter({ id, label = 'Password', placeholder, value = '
|
|
|
1727
1929
|
setPassword(newValue);
|
|
1728
1930
|
onChange === null || onChange === void 0 ? void 0 : onChange(newValue);
|
|
1729
1931
|
};
|
|
1730
|
-
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 })] })));
|
|
1932
|
+
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, readonly: readonly }), jsxRuntime.jsx(PasswordChecksList, { password: password, validationMessages: validationMessages, enabledChecks: enabledChecks })] })));
|
|
1731
1933
|
}
|
|
1732
1934
|
|
|
1733
1935
|
function DInputCheck(_a) {
|
|
@@ -2142,10 +2344,37 @@ const defaultTransition = {
|
|
|
2142
2344
|
ease: 'easeInOut',
|
|
2143
2345
|
duration: 0.3,
|
|
2144
2346
|
};
|
|
2145
|
-
function DOffcanvas$1({ name, className, style, staticBackdrop, scrollable, openFrom = 'end', transition, children, dataAttributes, }) {
|
|
2347
|
+
function DOffcanvas$1({ name, className, style, staticBackdrop, scrollable, openFrom = 'end', width, height, transition, children, dataAttributes, }) {
|
|
2348
|
+
// Only subscribe to breakpoint-change listeners when a responsive object is
|
|
2349
|
+
// actually provided, avoiding unnecessary matchMedia subscriptions for the
|
|
2350
|
+
// common case of plain string values.
|
|
2351
|
+
const hasResponsiveProp = typeof openFrom === 'object'
|
|
2352
|
+
|| typeof width === 'object'
|
|
2353
|
+
|| typeof height === 'object';
|
|
2354
|
+
const { responsivePropValue } = useResponsiveProp(hasResponsiveProp);
|
|
2355
|
+
const resolvedOpenFrom = React.useMemo(() => {
|
|
2356
|
+
var _a;
|
|
2357
|
+
if (typeof openFrom === 'string')
|
|
2358
|
+
return openFrom;
|
|
2359
|
+
return (_a = responsivePropValue(openFrom)) !== null && _a !== void 0 ? _a : 'end';
|
|
2360
|
+
}, [responsivePropValue, openFrom]);
|
|
2361
|
+
const resolvedWidth = React.useMemo(() => {
|
|
2362
|
+
if (!width)
|
|
2363
|
+
return undefined;
|
|
2364
|
+
if (typeof width === 'string')
|
|
2365
|
+
return width;
|
|
2366
|
+
return responsivePropValue(width);
|
|
2367
|
+
}, [responsivePropValue, width]);
|
|
2368
|
+
const resolvedHeight = React.useMemo(() => {
|
|
2369
|
+
if (!height)
|
|
2370
|
+
return undefined;
|
|
2371
|
+
if (typeof height === 'string')
|
|
2372
|
+
return height;
|
|
2373
|
+
return responsivePropValue(height);
|
|
2374
|
+
}, [responsivePropValue, height]);
|
|
2146
2375
|
return (jsxRuntime.jsx(framerMotion.motion.div, Object.assign({ className: classNames('offcanvas portal show', {
|
|
2147
|
-
[`offcanvas-${
|
|
2148
|
-
}, className), style: Object.assign(Object.assign({}, style), { transition: 'none' }), id: name, tabIndex: -1, "aria-labelledby": `${name}Label`, "aria-hidden": "false", custom:
|
|
2376
|
+
[`offcanvas-${resolvedOpenFrom}`]: resolvedOpenFrom,
|
|
2377
|
+
}, className), style: Object.assign(Object.assign(Object.assign(Object.assign({}, style), { transition: 'none' }), (resolvedWidth && { [`--${PREFIX_BS}offcanvas-width`]: resolvedWidth })), (resolvedHeight && { [`--${PREFIX_BS}offcanvas-height`]: resolvedHeight })), id: name, tabIndex: -1, "aria-labelledby": `${name}Label`, "aria-hidden": "false", custom: resolvedOpenFrom, variants: variants, initial: "hidden", animate: "visible", exit: "hidden", transition: Object.assign(Object.assign({}, (transition !== null && transition !== void 0 ? transition : defaultTransition)), { delay: 0.15 }) }, staticBackdrop && ({
|
|
2149
2378
|
[`data-${PREFIX_BS}backdrop`]: 'static',
|
|
2150
2379
|
[`data-${PREFIX_BS}keyboard`]: 'false',
|
|
2151
2380
|
}), scrollable && ({
|
|
@@ -2631,82 +2860,210 @@ function DCreditCard({ brand = 'visa', name, number, holderText = 'Card Holder',
|
|
|
2631
2860
|
return (jsxRuntime.jsxs("div", { className: classNames('d-credit-card', isVertical && 'is-vertical', className), children: [jsxRuntime.jsxs("div", { className: "d-credit-card-header", children: [jsxRuntime.jsx("img", { src: logoImage || BRAND_LOGOS[brand] || DEFAULT_IMAGE, alt: brand, className: "d-credit-card-logo", width: 100 }), isChipVisible && (jsxRuntime.jsx("div", { className: "d-credit-card-chip", children: jsxRuntime.jsx("img", { src: CHIP_IMAGE, alt: "chip", width: 30, className: "d-credit-card-chip-image" }) }))] }), jsxRuntime.jsxs("div", { className: "d-credit-card-details", children: [jsxRuntime.jsx("div", { className: "d-credit-card-number", children: number }), jsxRuntime.jsx("small", { className: "d-credit-card-holder-text", children: holderText }), jsxRuntime.jsx("span", { className: "d-credit-card-name", children: name })] })] }));
|
|
2632
2861
|
}
|
|
2633
2862
|
|
|
2634
|
-
const getItemClass = (action) => {
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
return base;
|
|
2641
|
-
};
|
|
2642
|
-
function DDropdown({ actions, dropdownToggle, className, classNameMenu, }) {
|
|
2863
|
+
const getItemClass = (action) => classNames({
|
|
2864
|
+
'dropdown-item d-flex align-items-center': true,
|
|
2865
|
+
[`dropdown-item-${action.color}`]: !!action.color,
|
|
2866
|
+
disabled: action.disabled,
|
|
2867
|
+
});
|
|
2868
|
+
function DDropdown({ actions, dropdownToggle, className, classNameMenu, asPortal = false, placement = 'auto', }) {
|
|
2643
2869
|
const [open, setOpen] = React.useState(false);
|
|
2870
|
+
const [position, setPosition] = React.useState('down');
|
|
2871
|
+
const [menuCoords, setMenuCoords] = React.useState(null);
|
|
2872
|
+
// Used in default (non-portal) mode: wraps the entire dropdown
|
|
2644
2873
|
const dropdownRef = React.useRef(null);
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2874
|
+
// Used in portal mode: ref on the toggle wrapper to read its viewport coords
|
|
2875
|
+
const toggleRef = React.useRef(null);
|
|
2876
|
+
// Ref on the rendered <ul> — used for outside-click detection in portal mode
|
|
2877
|
+
const menuRef = React.useRef(null);
|
|
2878
|
+
const toggle = () => {
|
|
2879
|
+
setMenuCoords(null);
|
|
2880
|
+
setOpen((prev) => !prev);
|
|
2881
|
+
};
|
|
2882
|
+
const resolvedInlinePosition = placement === 'auto' ? position : placement;
|
|
2883
|
+
// Compute fixed coords from the toggle's bounding rect (portal mode only)
|
|
2884
|
+
const computePortalCoords = React.useCallback(() => {
|
|
2885
|
+
if (!toggleRef.current)
|
|
2886
|
+
return;
|
|
2887
|
+
const rect = toggleRef.current.getBoundingClientRect();
|
|
2888
|
+
const spaceRight = window.innerWidth - rect.right;
|
|
2889
|
+
const spaceBottom = window.innerHeight - rect.bottom;
|
|
2890
|
+
const spaceTop = rect.top;
|
|
2891
|
+
let resolvedPlacement;
|
|
2892
|
+
if (placement === 'auto') {
|
|
2661
2893
|
if (spaceBottom < 150) {
|
|
2662
|
-
|
|
2894
|
+
resolvedPlacement = 'up';
|
|
2663
2895
|
}
|
|
2664
2896
|
else if (spaceRight < 150) {
|
|
2665
|
-
|
|
2897
|
+
resolvedPlacement = 'start';
|
|
2666
2898
|
}
|
|
2667
2899
|
else {
|
|
2668
|
-
|
|
2900
|
+
resolvedPlacement = 'down';
|
|
2669
2901
|
}
|
|
2670
2902
|
}
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2903
|
+
else {
|
|
2904
|
+
resolvedPlacement = placement;
|
|
2905
|
+
}
|
|
2906
|
+
const openStart = resolvedPlacement === 'start';
|
|
2907
|
+
const openEnd = resolvedPlacement === 'end';
|
|
2908
|
+
const openUp = resolvedPlacement === 'up';
|
|
2909
|
+
let availableHeight = spaceBottom;
|
|
2910
|
+
if (openUp) {
|
|
2911
|
+
availableHeight = spaceTop;
|
|
2912
|
+
}
|
|
2913
|
+
else if (openStart || openEnd) {
|
|
2914
|
+
availableHeight = window.innerHeight - rect.top;
|
|
2915
|
+
}
|
|
2916
|
+
const verticalCoords = openUp
|
|
2917
|
+
? { bottom: window.innerHeight - rect.top + 4 }
|
|
2918
|
+
: { top: openStart || openEnd ? rect.top : rect.bottom + 4 };
|
|
2919
|
+
let horizontalCoords;
|
|
2920
|
+
if (openStart) {
|
|
2921
|
+
horizontalCoords = { right: window.innerWidth - rect.left + 4 };
|
|
2922
|
+
}
|
|
2923
|
+
else if (openEnd) {
|
|
2924
|
+
horizontalCoords = { left: rect.right + 4 };
|
|
2676
2925
|
}
|
|
2677
2926
|
else {
|
|
2678
|
-
|
|
2927
|
+
horizontalCoords = { left: rect.left };
|
|
2679
2928
|
}
|
|
2929
|
+
setMenuCoords(Object.assign(Object.assign(Object.assign({}, verticalCoords), horizontalCoords), { minWidth: Math.max(rect.width, 160), maxHeight: `${Math.max(availableHeight - 12, 120)}px` }));
|
|
2930
|
+
}, [placement]);
|
|
2931
|
+
// Outside-click: default mode
|
|
2932
|
+
React.useEffect(() => {
|
|
2933
|
+
if (asPortal)
|
|
2934
|
+
return () => { };
|
|
2935
|
+
const handler = (event) => {
|
|
2936
|
+
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
2937
|
+
setOpen(false);
|
|
2938
|
+
}
|
|
2939
|
+
};
|
|
2940
|
+
document.addEventListener('mousedown', handler);
|
|
2941
|
+
return () => document.removeEventListener('mousedown', handler);
|
|
2942
|
+
}, [asPortal]);
|
|
2943
|
+
// Outside-click: portal mode (must check both toggle and floating menu)
|
|
2944
|
+
React.useEffect(() => {
|
|
2945
|
+
if (!asPortal || !open)
|
|
2946
|
+
return () => { };
|
|
2947
|
+
const handler = (event) => {
|
|
2948
|
+
var _a, _b;
|
|
2949
|
+
const target = event.target;
|
|
2950
|
+
if (!((_a = toggleRef.current) === null || _a === void 0 ? void 0 : _a.contains(target)) && !((_b = menuRef.current) === null || _b === void 0 ? void 0 : _b.contains(target))) {
|
|
2951
|
+
setOpen(false);
|
|
2952
|
+
}
|
|
2953
|
+
};
|
|
2954
|
+
document.addEventListener('mousedown', handler);
|
|
2955
|
+
return () => document.removeEventListener('mousedown', handler);
|
|
2956
|
+
}, [asPortal, open]);
|
|
2957
|
+
// Auto-position: default mode
|
|
2958
|
+
React.useEffect(() => {
|
|
2959
|
+
if (asPortal || !open || !dropdownRef.current || placement !== 'auto')
|
|
2960
|
+
return;
|
|
2961
|
+
const rect = dropdownRef.current.getBoundingClientRect();
|
|
2962
|
+
const spaceBottom = window.innerHeight - rect.bottom;
|
|
2963
|
+
const spaceRight = window.innerWidth - rect.right;
|
|
2964
|
+
if (spaceBottom < 150)
|
|
2965
|
+
setPosition('up');
|
|
2966
|
+
else if (spaceRight < 150)
|
|
2967
|
+
setPosition('start');
|
|
2968
|
+
else
|
|
2969
|
+
setPosition('down');
|
|
2970
|
+
}, [asPortal, open, placement]);
|
|
2971
|
+
// Compute + track coords: portal mode
|
|
2972
|
+
// Re-runs whenever the menu opens and keeps coords fresh on scroll/resize
|
|
2973
|
+
React.useEffect(() => {
|
|
2974
|
+
if (!asPortal || !open)
|
|
2975
|
+
return () => { };
|
|
2976
|
+
computePortalCoords();
|
|
2977
|
+
const update = () => computePortalCoords();
|
|
2978
|
+
window.addEventListener('scroll', update, { passive: true, capture: true });
|
|
2979
|
+
window.addEventListener('resize', update, { passive: true });
|
|
2980
|
+
return () => {
|
|
2981
|
+
window.removeEventListener('scroll', update, { capture: true });
|
|
2982
|
+
window.removeEventListener('resize', update);
|
|
2983
|
+
};
|
|
2984
|
+
}, [asPortal, open, computePortalCoords]);
|
|
2985
|
+
let ToggleElement;
|
|
2986
|
+
if (dropdownToggle) {
|
|
2987
|
+
ToggleElement = typeof dropdownToggle === 'function'
|
|
2988
|
+
? dropdownToggle({ open, toggle })
|
|
2989
|
+
: dropdownToggle;
|
|
2680
2990
|
}
|
|
2681
2991
|
else {
|
|
2682
|
-
ToggleElement = (jsxRuntime.jsx(DButtonIcon, { variant: "link", stopPropagationEnabled: false, "aria-label": "Toggle Dropdown", "aria-haspopup": "menu", "aria-expanded": open, onClick:
|
|
2992
|
+
ToggleElement = (jsxRuntime.jsx(DButtonIcon, { variant: "link", stopPropagationEnabled: false, "aria-label": "Toggle Dropdown", "aria-haspopup": "menu", "aria-expanded": open, onClick: toggle, icon: "MoreVertical" }));
|
|
2683
2993
|
}
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2994
|
+
const portalMenuStyle = asPortal && menuCoords
|
|
2995
|
+
? {
|
|
2996
|
+
position: 'fixed',
|
|
2997
|
+
top: menuCoords.top,
|
|
2998
|
+
bottom: menuCoords.bottom,
|
|
2999
|
+
left: menuCoords.left,
|
|
3000
|
+
right: menuCoords.right,
|
|
3001
|
+
minWidth: menuCoords.minWidth,
|
|
3002
|
+
maxHeight: menuCoords.maxHeight,
|
|
3003
|
+
overflowY: 'auto',
|
|
3004
|
+
zIndex: 1050,
|
|
3005
|
+
transform: 'none',
|
|
3006
|
+
}
|
|
3007
|
+
: undefined;
|
|
3008
|
+
let inlineTop = '100%';
|
|
3009
|
+
if (resolvedInlinePosition === 'up') {
|
|
3010
|
+
inlineTop = 'auto';
|
|
3011
|
+
}
|
|
3012
|
+
else if (resolvedInlinePosition === 'start' || resolvedInlinePosition === 'end') {
|
|
3013
|
+
inlineTop = 0;
|
|
3014
|
+
}
|
|
3015
|
+
let inlineLeft = 0;
|
|
3016
|
+
if (resolvedInlinePosition === 'start') {
|
|
3017
|
+
inlineLeft = 'auto';
|
|
3018
|
+
}
|
|
3019
|
+
else if (resolvedInlinePosition === 'end') {
|
|
3020
|
+
inlineLeft = '100%';
|
|
3021
|
+
}
|
|
3022
|
+
let inlineRight = 'auto';
|
|
3023
|
+
if (resolvedInlinePosition === 'start') {
|
|
3024
|
+
inlineRight = '100%';
|
|
3025
|
+
}
|
|
3026
|
+
let inlineTransform = 'translateY(4px)';
|
|
3027
|
+
if (resolvedInlinePosition === 'up') {
|
|
3028
|
+
inlineTransform = 'translateY(-4px)';
|
|
3029
|
+
}
|
|
3030
|
+
else if (resolvedInlinePosition === 'start') {
|
|
3031
|
+
inlineTransform = 'translateX(-4px)';
|
|
3032
|
+
}
|
|
3033
|
+
else if (resolvedInlinePosition === 'end') {
|
|
3034
|
+
inlineTransform = 'translateX(4px)';
|
|
3035
|
+
}
|
|
3036
|
+
const inlineMenuStyle = {
|
|
3037
|
+
position: 'absolute',
|
|
3038
|
+
top: inlineTop,
|
|
3039
|
+
bottom: resolvedInlinePosition === 'up' ? '100%' : 'auto',
|
|
3040
|
+
left: inlineLeft,
|
|
3041
|
+
right: inlineRight,
|
|
3042
|
+
transform: inlineTransform,
|
|
3043
|
+
};
|
|
3044
|
+
const menuItems = (jsxRuntime.jsx("ul", { ref: menuRef, role: "menu", className: classNames('dropdown-menu p-2', { show: open }, classNameMenu), style: portalMenuStyle !== null && portalMenuStyle !== void 0 ? portalMenuStyle : inlineMenuStyle, children: actions.map((action, index) => {
|
|
3045
|
+
if (action.isDivider) {
|
|
3046
|
+
return jsxRuntime.jsx("hr", { className: "dropdown-divider" }, index);
|
|
3047
|
+
}
|
|
3048
|
+
return (jsxRuntime.jsx("li", { children: action.href ? (jsxRuntime.jsxs("a", { className: getItemClass(action), href: action.href, onClick: (e) => {
|
|
3049
|
+
if (action.disabled) {
|
|
3050
|
+
e.preventDefault();
|
|
3051
|
+
}
|
|
3052
|
+
else {
|
|
3053
|
+
setOpen(false);
|
|
3054
|
+
}
|
|
3055
|
+
}, children: [action.icon && jsxRuntime.jsx(DIcon, { icon: action.icon, className: "me-2", size: "1rem" }), action.label] })) : (jsxRuntime.jsxs("button", { className: getItemClass(action), type: "button", onClick: () => {
|
|
3056
|
+
var _a;
|
|
3057
|
+
if (!action.disabled) {
|
|
3058
|
+
(_a = action.onClick) === null || _a === void 0 ? void 0 : _a.call(action);
|
|
3059
|
+
setOpen(false);
|
|
3060
|
+
}
|
|
3061
|
+
}, disabled: action.disabled, children: [action.icon && jsxRuntime.jsx(DIcon, { icon: action.icon, className: "me-2", size: "1rem" }), action.label] })) }, index));
|
|
3062
|
+
}) }));
|
|
3063
|
+
if (asPortal) {
|
|
3064
|
+
return (jsxRuntime.jsxs("div", { ref: toggleRef, className: classNames('dropdown', className), children: [ToggleElement, open && menuCoords && reactDom.createPortal(menuItems, document.body)] }));
|
|
3065
|
+
}
|
|
3066
|
+
return (jsxRuntime.jsxs("div", { className: classNames(`dropdown drop-${resolvedInlinePosition}`, className), ref: dropdownRef, children: [ToggleElement, menuItems] }));
|
|
2710
3067
|
}
|
|
2711
3068
|
|
|
2712
3069
|
function useScreenshot() {
|
|
@@ -2922,29 +3279,110 @@ function render(renderable) {
|
|
|
2922
3279
|
return null;
|
|
2923
3280
|
return typeof renderable === 'function' ? renderable() : renderable;
|
|
2924
3281
|
}
|
|
2925
|
-
function DDataStateWrapper({ isLoading, isError, data, onRetry, renderLoading, renderEmpty, renderError, children, }) {
|
|
3282
|
+
function DDataStateWrapper({ isLoading, isError, data, onRetry, messages, renderLoading, renderEmpty, renderError, children, }) {
|
|
2926
3283
|
// 1. Loading
|
|
2927
3284
|
if (isLoading) {
|
|
2928
3285
|
if (renderLoading)
|
|
2929
3286
|
return render(renderLoading);
|
|
2930
|
-
return jsxRuntime.jsx(LoadingState, {});
|
|
3287
|
+
return jsxRuntime.jsx(LoadingState, { ariaLabel: messages === null || messages === void 0 ? void 0 : messages.loading });
|
|
2931
3288
|
}
|
|
2932
3289
|
// 2. Error
|
|
2933
3290
|
if (isError) {
|
|
2934
3291
|
if (renderError)
|
|
2935
3292
|
return render(renderError);
|
|
2936
|
-
return (jsxRuntime.jsx(ErrorState, { onRetry: onRetry }));
|
|
3293
|
+
return (jsxRuntime.jsx(ErrorState, { onRetry: onRetry, message: messages === null || messages === void 0 ? void 0 : messages.error, retryMessage: messages === null || messages === void 0 ? void 0 : messages.retry }));
|
|
2937
3294
|
}
|
|
2938
3295
|
// 3. Empty
|
|
2939
3296
|
if (!(data === null || data === void 0 ? void 0 : data.length)) {
|
|
2940
3297
|
if (renderEmpty)
|
|
2941
3298
|
return render(renderEmpty);
|
|
2942
|
-
return (jsxRuntime.jsx(EmptyState, {}));
|
|
3299
|
+
return (jsxRuntime.jsx(EmptyState, { message: messages === null || messages === void 0 ? void 0 : messages.empty }));
|
|
2943
3300
|
}
|
|
2944
3301
|
// 4. Success
|
|
2945
3302
|
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: children(data) });
|
|
2946
3303
|
}
|
|
2947
3304
|
|
|
3305
|
+
function DConfirmModalUI({ entry }) {
|
|
3306
|
+
const { title = 'Are you sure you want to proceed?', message = 'Please confirm if you want to continue with this action.', confirmLabel = 'Confirm', cancelLabel = 'Cancel', confirmColor = 'primary', critical, onConfirmAction, onCloseAction, } = entry;
|
|
3307
|
+
const [confirmationCode, setConfirmationCode] = React.useState('');
|
|
3308
|
+
const [internalLoading, setInternalLoading] = React.useState(false);
|
|
3309
|
+
const isMountedRef = React.useRef(true);
|
|
3310
|
+
React.useEffect(() => {
|
|
3311
|
+
const cleanup = () => {
|
|
3312
|
+
isMountedRef.current = false;
|
|
3313
|
+
};
|
|
3314
|
+
return cleanup;
|
|
3315
|
+
}, []);
|
|
3316
|
+
const handleClose = React.useCallback(() => {
|
|
3317
|
+
onCloseAction();
|
|
3318
|
+
}, [onCloseAction]);
|
|
3319
|
+
const isConfirmDisabled = Boolean(internalLoading
|
|
3320
|
+
|| (critical && confirmationCode !== critical.code));
|
|
3321
|
+
const handleConfirmClick = React.useCallback(() => {
|
|
3322
|
+
setInternalLoading(true);
|
|
3323
|
+
onConfirmAction()
|
|
3324
|
+
.catch(() => undefined)
|
|
3325
|
+
.finally(() => {
|
|
3326
|
+
// Only update state if the component is still mounted.
|
|
3327
|
+
// onConfirmAction() removes the entry on success, which unmounts this component.
|
|
3328
|
+
if (isMountedRef.current) {
|
|
3329
|
+
setInternalLoading(false);
|
|
3330
|
+
}
|
|
3331
|
+
});
|
|
3332
|
+
}, [onConfirmAction]);
|
|
3333
|
+
return (jsxRuntime.jsxs(DModal, { name: entry.id, size: "lg", className: `confirm-modal ${critical ? 'critical-modal' : ''}`, children: [jsxRuntime.jsx(DModal.Header, { onClose: handleClose, showCloseButton: true, children: jsxRuntime.jsx("h5", { className: "fw-bold", children: title }) }), jsxRuntime.jsxs(DModal.Body, { className: "py-3 px-5", children: [jsxRuntime.jsx("p", { className: "mb-4", children: message }), critical && (jsxRuntime.jsx(ForwardedDInput, { type: "text", label: critical.codeLabel || 'Confirmation code', placeholder: critical.inputPlaceholder, value: confirmationCode, onChange: (value) => setConfirmationCode(value), className: "mb-4", autoFocus: true }))] }), jsxRuntime.jsxs(DModal.Footer, { children: [jsxRuntime.jsx(DButton, { text: cancelLabel, variant: "outline", color: "secondary", onClick: handleClose, disabled: internalLoading }), jsxRuntime.jsx(DButton, { text: confirmLabel, color: confirmColor, onClick: handleConfirmClick, disabled: isConfirmDisabled, loading: internalLoading })] })] }));
|
|
3334
|
+
}
|
|
3335
|
+
|
|
3336
|
+
/**
|
|
3337
|
+
* Container that renders confirm modals into the specified portal node.
|
|
3338
|
+
*
|
|
3339
|
+
* Must be explicitly mounted by the user (typically as a sibling of app content
|
|
3340
|
+
* within `DContextProvider`). The container floats above the portal stack and
|
|
3341
|
+
* intercepts Escape key events to close the top confirm modal without affecting
|
|
3342
|
+
* underlying modals or overlays.
|
|
3343
|
+
*
|
|
3344
|
+
* @example
|
|
3345
|
+
* <DContextProvider>
|
|
3346
|
+
* <App />
|
|
3347
|
+
* <DConfirmModalContainer nodeId="d-portal" />
|
|
3348
|
+
* </DContextProvider>
|
|
3349
|
+
*/
|
|
3350
|
+
function DConfirmModalContainer({ nodeId }) {
|
|
3351
|
+
const store = useConfirmModalStore();
|
|
3352
|
+
const [entries, setEntries] = React.useState([]);
|
|
3353
|
+
React.useEffect(() => {
|
|
3354
|
+
const unsubscribe = store.subscribe((next) => {
|
|
3355
|
+
setEntries(next);
|
|
3356
|
+
});
|
|
3357
|
+
return unsubscribe;
|
|
3358
|
+
}, [store]);
|
|
3359
|
+
// Capture Escape keydown to close the top confirm modal without affecting
|
|
3360
|
+
// the underlying portal stack (which also handles Escape).
|
|
3361
|
+
React.useEffect(() => {
|
|
3362
|
+
if (entries.length === 0) {
|
|
3363
|
+
return () => { };
|
|
3364
|
+
}
|
|
3365
|
+
const handleEscapeCapture = (event) => {
|
|
3366
|
+
if (event.key === 'Escape') {
|
|
3367
|
+
// Close the top (last) confirm modal
|
|
3368
|
+
entries[entries.length - 1].onCloseAction();
|
|
3369
|
+
// Prevent the event from reaching other handlers (e.g., DPortalContextProvider)
|
|
3370
|
+
event.stopPropagation();
|
|
3371
|
+
event.preventDefault();
|
|
3372
|
+
}
|
|
3373
|
+
};
|
|
3374
|
+
document.addEventListener('keydown', handleEscapeCapture, true);
|
|
3375
|
+
return () => {
|
|
3376
|
+
document.removeEventListener('keydown', handleEscapeCapture, true);
|
|
3377
|
+
};
|
|
3378
|
+
}, [entries]);
|
|
3379
|
+
const portalNode = document.getElementById(nodeId);
|
|
3380
|
+
if (!portalNode || entries.length === 0) {
|
|
3381
|
+
return null;
|
|
3382
|
+
}
|
|
3383
|
+
return reactDom.createPortal(jsxRuntime.jsx(framerMotion.AnimatePresence, { children: entries.map((entry) => (jsxRuntime.jsxs(framerMotion.motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0, transition: { delay: 0.3 } }, transition: { duration: 0.15, ease: 'linear' }, children: [jsxRuntime.jsx("div", { className: "backdrop backdrop-confirm-modal", onClick: entry.onCloseAction, role: "presentation" }), jsxRuntime.jsx(DConfirmModalUI, { entry: entry })] }, entry.id))) }), portalNode);
|
|
3384
|
+
}
|
|
3385
|
+
|
|
2948
3386
|
Object.defineProperty(exports, "getErrorMessage", {
|
|
2949
3387
|
enumerable: true,
|
|
2950
3388
|
get: function () { return reactErrorBoundary.getErrorMessage; }
|
|
@@ -2968,6 +3406,7 @@ exports.DCarousel = DCarousel;
|
|
|
2968
3406
|
exports.DCarouselSlide = DCarouselSlide;
|
|
2969
3407
|
exports.DChip = DChip;
|
|
2970
3408
|
exports.DCollapse = DCollapse;
|
|
3409
|
+
exports.DConfirmModalContainer = DConfirmModalContainer;
|
|
2971
3410
|
exports.DContext = DContext;
|
|
2972
3411
|
exports.DContextProvider = DContextProvider;
|
|
2973
3412
|
exports.DCreditCard = DCreditCard;
|
|
@@ -2987,6 +3426,7 @@ exports.DInputPassword = ForwardedDInputPassword;
|
|
|
2987
3426
|
exports.DInputPhone = ForwardedDInputPhone;
|
|
2988
3427
|
exports.DInputPin = DInputPin;
|
|
2989
3428
|
exports.DInputRange = ForwardedDInputRange;
|
|
3429
|
+
exports.DInputSearch = ForwardedDInputSearch;
|
|
2990
3430
|
exports.DInputSelect = DInputSelect;
|
|
2991
3431
|
exports.DInputSwitch = DInputSwitch;
|
|
2992
3432
|
exports.DLayout = DLayout;
|
|
@@ -3017,6 +3457,9 @@ exports.DToast = DToast;
|
|
|
3017
3457
|
exports.DToastContainer = DToastContainer;
|
|
3018
3458
|
exports.DTooltip = DTooltip;
|
|
3019
3459
|
exports.DVoucher = DVoucher;
|
|
3460
|
+
exports.EmptyState = EmptyState;
|
|
3461
|
+
exports.ErrorState = ErrorState;
|
|
3462
|
+
exports.LoadingState = LoadingState;
|
|
3020
3463
|
exports.changeQueryString = changeQueryString;
|
|
3021
3464
|
exports.checkMediaQuery = checkMediaQuery;
|
|
3022
3465
|
exports.configureI18n = configureI8n;
|
|
@@ -3024,6 +3467,7 @@ exports.formatCurrency = formatCurrency;
|
|
|
3024
3467
|
exports.getCssVariable = getCssVariable;
|
|
3025
3468
|
exports.getQueryString = getQueryString;
|
|
3026
3469
|
exports.subscribeToMediaQuery = subscribeToMediaQuery;
|
|
3470
|
+
exports.useConfirmModal = useConfirmModal;
|
|
3027
3471
|
exports.useDContext = useDContext;
|
|
3028
3472
|
exports.useDPortalContext = useDPortalContext;
|
|
3029
3473
|
exports.useDToast = useDToast;
|