@jobber/components 8.21.1 → 8.22.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/Dialog.d.ts +1 -0
- package/Dialog.js +17 -0
- package/dist/BottomSheet-cjs.js +34 -7
- package/dist/BottomSheet-es.js +34 -8
- package/dist/Card/index.cjs +1 -0
- package/dist/Card/index.mjs +1 -0
- package/dist/ComboboxChipRemove-es.js +3 -3
- package/dist/DataDump/index.cjs +1 -0
- package/dist/DataDump/index.mjs +1 -0
- package/dist/Dialog/Dialog.d.ts +3 -0
- package/dist/Dialog/Dialog.types.d.ts +205 -0
- package/dist/Dialog/DialogBottomSheet.d.ts +28 -0
- package/dist/Dialog/DialogModal.d.ts +20 -0
- package/dist/Dialog/constants.d.ts +1 -0
- package/dist/Dialog/dialogComposableShared.d.ts +53 -0
- package/dist/Dialog/dialogReturnFocus.d.ts +43 -0
- package/dist/Dialog/index.cjs +32 -0
- package/dist/Dialog/index.d.ts +4 -0
- package/dist/Dialog/index.mjs +24 -0
- package/dist/DrawerDescription-cjs.js +409 -0
- package/dist/DrawerDescription-es.js +382 -0
- package/dist/DrawerTitle-cjs.js +116 -0
- package/dist/DrawerTitle-es.js +92 -0
- package/dist/InputNumberExperimental-es.js +1 -1
- package/dist/InternalBackdrop-es.js +2 -2
- package/dist/Menu/index.cjs +1 -0
- package/dist/Menu/index.mjs +1 -0
- package/dist/Menu-cjs.js +5 -3
- package/dist/Menu-es.js +5 -3
- package/dist/MenuSubmenuTrigger-cjs.js +49 -91
- package/dist/MenuSubmenuTrigger-es.js +51 -91
- package/dist/NumberFieldInput-es.js +1 -1
- package/dist/Page/index.cjs +1 -0
- package/dist/Page/index.mjs +1 -0
- package/dist/ScrollAreaViewport-cjs.js +938 -935
- package/dist/ScrollAreaViewport-es.js +938 -938
- package/dist/dialogReturnFocus-cjs.js +427 -0
- package/dist/dialogReturnFocus-es.js +423 -0
- package/dist/index.cjs +13 -7
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +10 -7
- package/dist/primitives/BottomSheet/BottomSheet.d.ts +19 -1
- package/dist/primitives/BottomSheet/BottomSheet.types.d.ts +8 -0
- package/dist/primitives/BottomSheet/index.cjs +1 -0
- package/dist/primitives/BottomSheet/index.d.ts +1 -1
- package/dist/primitives/BottomSheet/index.mjs +1 -1
- package/dist/primitives/index.cjs +1 -0
- package/dist/primitives/index.mjs +1 -1
- package/dist/styles.css +360 -0
- package/dist/unstyledPrimitives/index.cjs +32 -249
- package/dist/unstyledPrimitives/index.d.ts +1 -0
- package/dist/unstyledPrimitives/index.mjs +30 -248
- package/dist/useButton-es.js +1 -1
- package/dist/useCompositeListItem-es.js +2 -2
- package/dist/useLabel-es.js +1 -1
- package/dist/utils/meta/meta.json +11 -1
- package/package.json +2 -2
|
@@ -414,179 +414,6 @@ function useDialogRootContext(optional) {
|
|
|
414
414
|
return dialogRootContext;
|
|
415
415
|
}
|
|
416
416
|
|
|
417
|
-
let DrawerPopupCssVars = /*#__PURE__*/function (DrawerPopupCssVars) {
|
|
418
|
-
/**
|
|
419
|
-
* The number of nested drawers that are currently open.
|
|
420
|
-
* @type {number}
|
|
421
|
-
*/
|
|
422
|
-
DrawerPopupCssVars["nestedDrawers"] = "--nested-drawers";
|
|
423
|
-
/**
|
|
424
|
-
* The height of the drawer popup.
|
|
425
|
-
* @type {CSS length}
|
|
426
|
-
*/
|
|
427
|
-
DrawerPopupCssVars["height"] = "--drawer-height";
|
|
428
|
-
/**
|
|
429
|
-
* The height of the frontmost open drawer in the current nested drawer stack.
|
|
430
|
-
* @type {CSS length}
|
|
431
|
-
*/
|
|
432
|
-
DrawerPopupCssVars["frontmostHeight"] = "--drawer-frontmost-height";
|
|
433
|
-
/**
|
|
434
|
-
* The swipe movement on the X axis.
|
|
435
|
-
* @type {CSS length}
|
|
436
|
-
*/
|
|
437
|
-
DrawerPopupCssVars["swipeMovementX"] = "--drawer-swipe-movement-x";
|
|
438
|
-
/**
|
|
439
|
-
* The swipe movement on the Y axis.
|
|
440
|
-
* @type {CSS length}
|
|
441
|
-
*/
|
|
442
|
-
DrawerPopupCssVars["swipeMovementY"] = "--drawer-swipe-movement-y";
|
|
443
|
-
/**
|
|
444
|
-
* The snap point offset used for translating the drawer.
|
|
445
|
-
* @type {CSS length}
|
|
446
|
-
*/
|
|
447
|
-
DrawerPopupCssVars["snapPointOffset"] = "--drawer-snap-point-offset";
|
|
448
|
-
/**
|
|
449
|
-
* A scalar (0.1-1) used to scale the swipe release transition duration in CSS.
|
|
450
|
-
* @type {number}
|
|
451
|
-
*/
|
|
452
|
-
DrawerPopupCssVars["swipeStrength"] = "--drawer-swipe-strength";
|
|
453
|
-
return DrawerPopupCssVars;
|
|
454
|
-
}({});
|
|
455
|
-
|
|
456
|
-
let DrawerBackdropCssVars = /*#__PURE__*/function (DrawerBackdropCssVars) {
|
|
457
|
-
/**
|
|
458
|
-
* The swipe progress of the drawer gesture.
|
|
459
|
-
* @type {number}
|
|
460
|
-
*/
|
|
461
|
-
DrawerBackdropCssVars["swipeProgress"] = "--drawer-swipe-progress";
|
|
462
|
-
return DrawerBackdropCssVars;
|
|
463
|
-
}({});
|
|
464
|
-
|
|
465
|
-
const stateAttributesMapping$1 = {
|
|
466
|
-
...InternalBackdrop.popupStateMapping,
|
|
467
|
-
...useButton.transitionStatusMapping
|
|
468
|
-
};
|
|
469
|
-
|
|
470
|
-
/**
|
|
471
|
-
* An overlay displayed beneath the popup.
|
|
472
|
-
* Renders a `<div>` element.
|
|
473
|
-
*
|
|
474
|
-
* Documentation: [Base UI Drawer](https://base-ui.com/react/components/drawer)
|
|
475
|
-
*/
|
|
476
|
-
const DrawerBackdrop = /*#__PURE__*/React__namespace.forwardRef(function DrawerBackdrop(componentProps, forwardedRef) {
|
|
477
|
-
const {
|
|
478
|
-
render,
|
|
479
|
-
className,
|
|
480
|
-
forceRender = false,
|
|
481
|
-
...elementProps
|
|
482
|
-
} = componentProps;
|
|
483
|
-
const {
|
|
484
|
-
store
|
|
485
|
-
} = useDialogRootContext();
|
|
486
|
-
const open = store.useState('open');
|
|
487
|
-
const nested = store.useState('nested');
|
|
488
|
-
const mounted = store.useState('mounted');
|
|
489
|
-
const transitionStatus = store.useState('transitionStatus');
|
|
490
|
-
const state = {
|
|
491
|
-
open,
|
|
492
|
-
transitionStatus
|
|
493
|
-
};
|
|
494
|
-
return useRenderElement.useRenderElement('div', componentProps, {
|
|
495
|
-
state,
|
|
496
|
-
ref: [store.context.backdropRef, forwardedRef],
|
|
497
|
-
stateAttributesMapping: stateAttributesMapping$1,
|
|
498
|
-
props: [{
|
|
499
|
-
role: 'presentation',
|
|
500
|
-
hidden: !mounted,
|
|
501
|
-
style: {
|
|
502
|
-
pointerEvents: !open ? 'none' : undefined,
|
|
503
|
-
userSelect: 'none',
|
|
504
|
-
WebkitUserSelect: 'none',
|
|
505
|
-
[DrawerBackdropCssVars.swipeProgress]: '0',
|
|
506
|
-
[DrawerPopupCssVars.swipeStrength]: '1'
|
|
507
|
-
}
|
|
508
|
-
}, elementProps],
|
|
509
|
-
enabled: forceRender || !nested
|
|
510
|
-
});
|
|
511
|
-
});
|
|
512
|
-
if (process.env.NODE_ENV !== "production") DrawerBackdrop.displayName = "DrawerBackdrop";
|
|
513
|
-
|
|
514
|
-
const DRAWER_CONTENT_ATTRIBUTE = 'data-drawer-content';
|
|
515
|
-
|
|
516
|
-
/**
|
|
517
|
-
* A container for the drawer contents.
|
|
518
|
-
* Renders a `<div>` element.
|
|
519
|
-
*
|
|
520
|
-
* Documentation: [Base UI Drawer](https://base-ui.com/react/components/drawer)
|
|
521
|
-
*/
|
|
522
|
-
const DrawerContent = /*#__PURE__*/React__namespace.forwardRef(function DrawerContent(componentProps, forwardedRef) {
|
|
523
|
-
const {
|
|
524
|
-
render,
|
|
525
|
-
className,
|
|
526
|
-
...elementProps
|
|
527
|
-
} = componentProps;
|
|
528
|
-
useDialogRootContext();
|
|
529
|
-
return useRenderElement.useRenderElement('div', componentProps, {
|
|
530
|
-
ref: forwardedRef,
|
|
531
|
-
props: [{
|
|
532
|
-
[DRAWER_CONTENT_ATTRIBUTE]: ''
|
|
533
|
-
}, elementProps]
|
|
534
|
-
});
|
|
535
|
-
});
|
|
536
|
-
if (process.env.NODE_ENV !== "production") DrawerContent.displayName = "DrawerContent";
|
|
537
|
-
|
|
538
|
-
const DrawerProviderContext = /*#__PURE__*/React__namespace.createContext(undefined);
|
|
539
|
-
if (process.env.NODE_ENV !== "production") DrawerProviderContext.displayName = "DrawerProviderContext";
|
|
540
|
-
function useDrawerProviderContext(optional) {
|
|
541
|
-
const context = React__namespace.useContext(DrawerProviderContext);
|
|
542
|
-
return context;
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
let DrawerPopupDataAttributes = function (DrawerPopupDataAttributes) {
|
|
546
|
-
/**
|
|
547
|
-
* Present when the drawer is open.
|
|
548
|
-
*/
|
|
549
|
-
DrawerPopupDataAttributes[DrawerPopupDataAttributes["open"] = InternalBackdrop.CommonPopupDataAttributes.open] = "open";
|
|
550
|
-
/**
|
|
551
|
-
* Present when the drawer is closed.
|
|
552
|
-
*/
|
|
553
|
-
DrawerPopupDataAttributes[DrawerPopupDataAttributes["closed"] = InternalBackdrop.CommonPopupDataAttributes.closed] = "closed";
|
|
554
|
-
/**
|
|
555
|
-
* Present when the drawer is animating in.
|
|
556
|
-
*/
|
|
557
|
-
DrawerPopupDataAttributes[DrawerPopupDataAttributes["startingStyle"] = InternalBackdrop.CommonPopupDataAttributes.startingStyle] = "startingStyle";
|
|
558
|
-
/**
|
|
559
|
-
* Present when the drawer is animating out.
|
|
560
|
-
*/
|
|
561
|
-
DrawerPopupDataAttributes[DrawerPopupDataAttributes["endingStyle"] = InternalBackdrop.CommonPopupDataAttributes.endingStyle] = "endingStyle";
|
|
562
|
-
/**
|
|
563
|
-
* Present when the drawer is at the expanded (full-height) snap point.
|
|
564
|
-
*/
|
|
565
|
-
DrawerPopupDataAttributes["expanded"] = "data-expanded";
|
|
566
|
-
/**
|
|
567
|
-
* Present when a nested drawer is open.
|
|
568
|
-
*/
|
|
569
|
-
DrawerPopupDataAttributes["nestedDrawerOpen"] = "data-nested-drawer-open";
|
|
570
|
-
/**
|
|
571
|
-
* Present when a nested drawer is being swiped.
|
|
572
|
-
*/
|
|
573
|
-
DrawerPopupDataAttributes["nestedDrawerSwiping"] = "data-nested-drawer-swiping";
|
|
574
|
-
/**
|
|
575
|
-
* Present when the drawer is dismissed by swiping.
|
|
576
|
-
*/
|
|
577
|
-
DrawerPopupDataAttributes["swipeDismiss"] = "data-swipe-dismiss";
|
|
578
|
-
/**
|
|
579
|
-
* Indicates the swipe direction.
|
|
580
|
-
* @type {'up' | 'down' | 'left' | 'right'}
|
|
581
|
-
*/
|
|
582
|
-
DrawerPopupDataAttributes["swipeDirection"] = "data-swipe-direction";
|
|
583
|
-
/**
|
|
584
|
-
* Present when the drawer is being swiped.
|
|
585
|
-
*/
|
|
586
|
-
DrawerPopupDataAttributes["swiping"] = "data-swiping";
|
|
587
|
-
return DrawerPopupDataAttributes;
|
|
588
|
-
}({});
|
|
589
|
-
|
|
590
417
|
const DialogPortalContext = /*#__PURE__*/React__namespace.createContext(undefined);
|
|
591
418
|
if (process.env.NODE_ENV !== "production") DialogPortalContext.displayName = "DialogPortalContext";
|
|
592
419
|
function useDialogPortalContext() {
|
|
@@ -609,852 +436,1025 @@ const ARROW_KEYS = new Set([...HORIZONTAL_KEYS, ...VERTICAL_KEYS]);
|
|
|
609
436
|
new Set([...ARROW_KEYS, HOME, END]);
|
|
610
437
|
const COMPOSITE_KEYS = new Set([ARROW_UP, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT, HOME, END]);
|
|
611
438
|
|
|
612
|
-
const
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
throw new Error(process.env.NODE_ENV !== "production" ? 'Base UI: DrawerRootContext is missing. Drawer parts must be placed within <Drawer.Root>.' : useRenderElement.formatErrorMessage(90));
|
|
618
|
-
}
|
|
619
|
-
return drawerRootContext;
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
function resolveSnapPointValue(snapPoint, viewportHeight, rootFontSize) {
|
|
623
|
-
if (!Number.isFinite(viewportHeight) || viewportHeight <= 0) {
|
|
624
|
-
return null;
|
|
625
|
-
}
|
|
626
|
-
if (typeof snapPoint === 'number') {
|
|
627
|
-
if (!Number.isFinite(snapPoint)) {
|
|
628
|
-
return null;
|
|
629
|
-
}
|
|
630
|
-
if (snapPoint <= 1) {
|
|
631
|
-
return clamp.clamp(snapPoint, 0, 1) * viewportHeight;
|
|
632
|
-
}
|
|
633
|
-
return snapPoint;
|
|
634
|
-
}
|
|
635
|
-
const trimmed = snapPoint.trim();
|
|
636
|
-
if (trimmed.endsWith('px')) {
|
|
637
|
-
const value = Number.parseFloat(trimmed);
|
|
638
|
-
return Number.isFinite(value) ? value : null;
|
|
639
|
-
}
|
|
640
|
-
if (trimmed.endsWith('rem')) {
|
|
641
|
-
const value = Number.parseFloat(trimmed);
|
|
642
|
-
return Number.isFinite(value) ? value * rootFontSize : null;
|
|
643
|
-
}
|
|
644
|
-
return null;
|
|
645
|
-
}
|
|
646
|
-
function findClosestSnapPoint(height, points) {
|
|
647
|
-
let closest = null;
|
|
648
|
-
let closestDistance = Infinity;
|
|
649
|
-
for (const point of points) {
|
|
650
|
-
const distance = Math.abs(point.height - height);
|
|
651
|
-
if (distance < closestDistance) {
|
|
652
|
-
closestDistance = distance;
|
|
653
|
-
closest = point;
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
return closest;
|
|
657
|
-
}
|
|
658
|
-
function useDrawerSnapPoints() {
|
|
439
|
+
const DialogPortal = /*#__PURE__*/React__namespace.forwardRef(function DialogPortal(props, forwardedRef) {
|
|
440
|
+
const {
|
|
441
|
+
keepMounted = false,
|
|
442
|
+
...portalProps
|
|
443
|
+
} = props;
|
|
659
444
|
const {
|
|
660
445
|
store
|
|
661
446
|
} = useDialogRootContext();
|
|
447
|
+
const mounted = store.useState('mounted');
|
|
448
|
+
const modal = store.useState('modal');
|
|
449
|
+
const open = store.useState('open');
|
|
450
|
+
const shouldRender = mounted || keepMounted;
|
|
451
|
+
if (!shouldRender) {
|
|
452
|
+
return null;
|
|
453
|
+
}
|
|
454
|
+
return /*#__PURE__*/jsxRuntime.jsx(DialogPortalContext.Provider, {
|
|
455
|
+
value: keepMounted,
|
|
456
|
+
children: /*#__PURE__*/jsxRuntime.jsxs(InternalBackdrop.FloatingPortal, {
|
|
457
|
+
ref: forwardedRef,
|
|
458
|
+
...portalProps,
|
|
459
|
+
children: [mounted && modal === true && /*#__PURE__*/jsxRuntime.jsx(InternalBackdrop.InternalBackdrop, {
|
|
460
|
+
ref: store.context.internalBackdropRef,
|
|
461
|
+
inert: InternalBackdrop.inertValue(!open)
|
|
462
|
+
}), props.children]
|
|
463
|
+
})
|
|
464
|
+
});
|
|
465
|
+
});
|
|
466
|
+
if (process.env.NODE_ENV !== "production") DialogPortal.displayName = "DialogPortal";
|
|
467
|
+
|
|
468
|
+
function useDialogRoot(params) {
|
|
662
469
|
const {
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
const
|
|
669
|
-
const
|
|
670
|
-
const
|
|
671
|
-
const
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
const
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
}
|
|
684
|
-
});
|
|
685
|
-
useButton.useIsoLayoutEffect(() => {
|
|
686
|
-
measureViewportHeight();
|
|
687
|
-
if (!viewportElement || typeof ResizeObserver !== 'function') {
|
|
688
|
-
return undefined;
|
|
689
|
-
}
|
|
690
|
-
const resizeObserver = new ResizeObserver(measureViewportHeight);
|
|
691
|
-
resizeObserver.observe(viewportElement);
|
|
692
|
-
return () => {
|
|
693
|
-
resizeObserver.disconnect();
|
|
470
|
+
store,
|
|
471
|
+
parentContext,
|
|
472
|
+
actionsRef
|
|
473
|
+
} = params;
|
|
474
|
+
const open = store.useState('open');
|
|
475
|
+
const disablePointerDismissal = store.useState('disablePointerDismissal');
|
|
476
|
+
const modal = store.useState('modal');
|
|
477
|
+
const popupElement = store.useState('popupElement');
|
|
478
|
+
const {
|
|
479
|
+
openMethod,
|
|
480
|
+
triggerProps
|
|
481
|
+
} = InternalBackdrop.useOpenInteractionType(open);
|
|
482
|
+
useImplicitActiveTrigger(store);
|
|
483
|
+
const {
|
|
484
|
+
forceUnmount
|
|
485
|
+
} = useOpenStateTransitions(open, store);
|
|
486
|
+
const createDialogEventDetails = useButton.useStableCallback(reason => {
|
|
487
|
+
const details = useButton.createChangeEventDetails(reason);
|
|
488
|
+
details.preventUnmountOnClose = () => {
|
|
489
|
+
store.set('preventUnmountingOnClose', true);
|
|
694
490
|
};
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
491
|
+
return details;
|
|
492
|
+
});
|
|
493
|
+
const handleImperativeClose = React__namespace.useCallback(() => {
|
|
494
|
+
store.setOpen(false, createDialogEventDetails(useButton.imperativeAction));
|
|
495
|
+
}, [store, createDialogEventDetails]);
|
|
496
|
+
React__namespace.useImperativeHandle(actionsRef, () => ({
|
|
497
|
+
unmount: forceUnmount,
|
|
498
|
+
close: handleImperativeClose
|
|
499
|
+
}), [forceUnmount, handleImperativeClose]);
|
|
500
|
+
const floatingRootContext = useSyncedFloatingRootContext({
|
|
501
|
+
popupStore: store,
|
|
502
|
+
onOpenChange: store.setOpen,
|
|
503
|
+
treatPopupAsFloatingElement: true,
|
|
504
|
+
noEmit: true
|
|
505
|
+
});
|
|
506
|
+
const [ownNestedOpenDialogs, setOwnNestedOpenDialogs] = React__namespace.useState(0);
|
|
507
|
+
const isTopmost = ownNestedOpenDialogs === 0;
|
|
508
|
+
const role = useRole(floatingRootContext);
|
|
509
|
+
const dismiss = InternalBackdrop.useDismiss(floatingRootContext, {
|
|
510
|
+
outsidePressEvent() {
|
|
511
|
+
if (store.context.internalBackdropRef.current || store.context.backdropRef.current) {
|
|
512
|
+
return 'intentional';
|
|
708
513
|
}
|
|
709
|
-
|
|
514
|
+
// Ensure `aria-hidden` on outside elements is removed immediately
|
|
515
|
+
// on outside press when trapping focus.
|
|
710
516
|
return {
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
offset: Math.max(0, popupHeight - clampedHeight)
|
|
517
|
+
mouse: modal === 'trap-focus' ? 'sloppy' : 'intentional',
|
|
518
|
+
touch: 'sloppy'
|
|
714
519
|
};
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
const deduped = [];
|
|
720
|
-
const seenHeights = [];
|
|
721
|
-
for (let index = resolved.length - 1; index >= 0; index -= 1) {
|
|
722
|
-
const point = resolved[index];
|
|
723
|
-
const isDuplicate = seenHeights.some(height => Math.abs(height - point.height) <= 1);
|
|
724
|
-
if (isDuplicate) {
|
|
725
|
-
continue;
|
|
520
|
+
},
|
|
521
|
+
outsidePress(event) {
|
|
522
|
+
if (!store.context.outsidePressEnabledRef.current) {
|
|
523
|
+
return false;
|
|
726
524
|
}
|
|
727
|
-
|
|
728
|
-
|
|
525
|
+
|
|
526
|
+
// For mouse events, only accept left button (button 0)
|
|
527
|
+
// For touch events, a single touch is equivalent to left button
|
|
528
|
+
if ('button' in event && event.button !== 0) {
|
|
529
|
+
return false;
|
|
530
|
+
}
|
|
531
|
+
if ('touches' in event && event.touches.length !== 1) {
|
|
532
|
+
return false;
|
|
533
|
+
}
|
|
534
|
+
const target = useButton.getTarget(event);
|
|
535
|
+
if (isTopmost && !disablePointerDismissal) {
|
|
536
|
+
const eventTarget = target;
|
|
537
|
+
// Only close if the click occurred on the dialog's owning backdrop.
|
|
538
|
+
// This supports multiple modal dialogs that aren't nested in the React tree:
|
|
539
|
+
// https://github.com/mui/base-ui/issues/1320
|
|
540
|
+
if (modal) {
|
|
541
|
+
return store.context.internalBackdropRef.current || store.context.backdropRef.current ? store.context.internalBackdropRef.current === eventTarget || store.context.backdropRef.current === eventTarget || useButton.contains(eventTarget, popupElement) && !eventTarget?.hasAttribute('data-base-ui-portal') : true;
|
|
542
|
+
}
|
|
543
|
+
return true;
|
|
544
|
+
}
|
|
545
|
+
return false;
|
|
546
|
+
},
|
|
547
|
+
escapeKey: isTopmost
|
|
548
|
+
});
|
|
549
|
+
InternalBackdrop.useScrollLock(open && modal === true, popupElement);
|
|
550
|
+
const {
|
|
551
|
+
getReferenceProps,
|
|
552
|
+
getFloatingProps,
|
|
553
|
+
getTriggerProps
|
|
554
|
+
} = InternalBackdrop.useInteractions([role, dismiss]);
|
|
555
|
+
|
|
556
|
+
// Listen for nested open/close events on this store to maintain the count
|
|
557
|
+
store.useContextCallback('onNestedDialogOpen', ownChildrenCount => {
|
|
558
|
+
setOwnNestedOpenDialogs(ownChildrenCount + 1);
|
|
559
|
+
});
|
|
560
|
+
store.useContextCallback('onNestedDialogClose', () => {
|
|
561
|
+
setOwnNestedOpenDialogs(0);
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
// Notify parent of our open/close state using parent callbacks, if any
|
|
565
|
+
React__namespace.useEffect(() => {
|
|
566
|
+
if (parentContext?.onNestedDialogOpen && open) {
|
|
567
|
+
parentContext.onNestedDialogOpen(ownNestedOpenDialogs);
|
|
729
568
|
}
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
}, [popupHeight, rootFontSize, snapPoints, viewportHeight]);
|
|
733
|
-
const resolvedActiveSnapPoint = React__namespace.useMemo(() => {
|
|
734
|
-
if (activeSnapPoint === undefined) {
|
|
735
|
-
return resolvedSnapPoints[0];
|
|
569
|
+
if (parentContext?.onNestedDialogClose && !open) {
|
|
570
|
+
parentContext.onNestedDialogClose();
|
|
736
571
|
}
|
|
737
|
-
|
|
738
|
-
|
|
572
|
+
return () => {
|
|
573
|
+
if (parentContext?.onNestedDialogClose && open) {
|
|
574
|
+
parentContext.onNestedDialogClose();
|
|
575
|
+
}
|
|
576
|
+
};
|
|
577
|
+
}, [open, parentContext, ownNestedOpenDialogs]);
|
|
578
|
+
const activeTriggerProps = React__namespace.useMemo(() => getReferenceProps(triggerProps), [getReferenceProps, triggerProps]);
|
|
579
|
+
const inactiveTriggerProps = React__namespace.useMemo(() => getTriggerProps(triggerProps), [getTriggerProps, triggerProps]);
|
|
580
|
+
const popupProps = React__namespace.useMemo(() => getFloatingProps(), [getFloatingProps]);
|
|
581
|
+
store.useSyncedValues({
|
|
582
|
+
openMethod,
|
|
583
|
+
activeTriggerProps,
|
|
584
|
+
inactiveTriggerProps,
|
|
585
|
+
popupProps,
|
|
586
|
+
floatingRootContext,
|
|
587
|
+
nestedOpenDialogCount: ownNestedOpenDialogs
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
const selectors = {
|
|
592
|
+
...popupStoreSelectors,
|
|
593
|
+
modal: InternalBackdrop.createSelector(state => state.modal),
|
|
594
|
+
nested: InternalBackdrop.createSelector(state => state.nested),
|
|
595
|
+
nestedOpenDialogCount: InternalBackdrop.createSelector(state => state.nestedOpenDialogCount),
|
|
596
|
+
disablePointerDismissal: InternalBackdrop.createSelector(state => state.disablePointerDismissal),
|
|
597
|
+
openMethod: InternalBackdrop.createSelector(state => state.openMethod),
|
|
598
|
+
descriptionElementId: InternalBackdrop.createSelector(state => state.descriptionElementId),
|
|
599
|
+
titleElementId: InternalBackdrop.createSelector(state => state.titleElementId),
|
|
600
|
+
viewportElement: InternalBackdrop.createSelector(state => state.viewportElement),
|
|
601
|
+
role: InternalBackdrop.createSelector(state => state.role)
|
|
602
|
+
};
|
|
603
|
+
class DialogStore extends InternalBackdrop.ReactStore {
|
|
604
|
+
constructor(initialState) {
|
|
605
|
+
super(createInitialState(initialState), {
|
|
606
|
+
popupRef: /*#__PURE__*/React__namespace.createRef(),
|
|
607
|
+
backdropRef: /*#__PURE__*/React__namespace.createRef(),
|
|
608
|
+
internalBackdropRef: /*#__PURE__*/React__namespace.createRef(),
|
|
609
|
+
outsidePressEnabledRef: {
|
|
610
|
+
current: true
|
|
611
|
+
},
|
|
612
|
+
triggerElements: new InternalBackdrop.PopupTriggerMap(),
|
|
613
|
+
onOpenChange: undefined,
|
|
614
|
+
onOpenChangeComplete: undefined
|
|
615
|
+
}, selectors);
|
|
616
|
+
}
|
|
617
|
+
setOpen = (nextOpen, eventDetails) => {
|
|
618
|
+
eventDetails.preventUnmountOnClose = () => {
|
|
619
|
+
this.set('preventUnmountingOnClose', true);
|
|
620
|
+
};
|
|
621
|
+
if (!nextOpen && eventDetails.trigger == null && this.state.activeTriggerId != null) {
|
|
622
|
+
// When closing the dialog, pass the old trigger to the onOpenChange event
|
|
623
|
+
// so it's not reset too early (potentially causing focus issues in controlled scenarios).
|
|
624
|
+
eventDetails.trigger = this.state.activeTriggerElement ?? undefined;
|
|
739
625
|
}
|
|
740
|
-
|
|
741
|
-
if (
|
|
742
|
-
return
|
|
626
|
+
this.context.onOpenChange?.(nextOpen, eventDetails);
|
|
627
|
+
if (eventDetails.isCanceled) {
|
|
628
|
+
return;
|
|
743
629
|
}
|
|
744
|
-
const
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
630
|
+
const details = {
|
|
631
|
+
open: nextOpen,
|
|
632
|
+
nativeEvent: eventDetails.event,
|
|
633
|
+
reason: eventDetails.reason,
|
|
634
|
+
nested: this.state.nested
|
|
635
|
+
};
|
|
636
|
+
this.state.floatingRootContext.context.events?.emit('openchange', details);
|
|
637
|
+
const updatedState = {
|
|
638
|
+
open: nextOpen
|
|
639
|
+
};
|
|
640
|
+
|
|
641
|
+
// If a popup is closing, the `trigger` may be null.
|
|
642
|
+
// We want to keep the previous value so that exit animations are played and focus is returned correctly.
|
|
643
|
+
const newTriggerId = eventDetails.trigger?.id ?? null;
|
|
644
|
+
if (newTriggerId || nextOpen) {
|
|
645
|
+
updatedState.activeTriggerId = newTriggerId;
|
|
646
|
+
updatedState.activeTriggerElement = eventDetails.trigger ?? null;
|
|
748
647
|
}
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
648
|
+
this.update(updatedState);
|
|
649
|
+
};
|
|
650
|
+
}
|
|
651
|
+
function createInitialState(initialState = {}) {
|
|
652
|
+
return {
|
|
653
|
+
...createInitialPopupStoreState(),
|
|
654
|
+
modal: true,
|
|
655
|
+
disablePointerDismissal: false,
|
|
656
|
+
popupElement: null,
|
|
657
|
+
viewportElement: null,
|
|
658
|
+
descriptionElementId: undefined,
|
|
659
|
+
titleElementId: undefined,
|
|
660
|
+
openMethod: null,
|
|
661
|
+
nested: false,
|
|
662
|
+
nestedOpenDialogCount: 0,
|
|
663
|
+
role: 'dialog',
|
|
664
|
+
...initialState
|
|
760
665
|
};
|
|
761
666
|
}
|
|
762
|
-
|
|
763
|
-
const DrawerViewportContext = /*#__PURE__*/React__namespace.createContext(null);
|
|
764
|
-
if (process.env.NODE_ENV !== "production") DrawerViewportContext.displayName = "DrawerViewportContext";
|
|
765
|
-
function useDrawerViewportContext(optional) {
|
|
766
|
-
const context = React__namespace.useContext(DrawerViewportContext);
|
|
767
|
-
return context;
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
let drawerSwipeVarsRegistered = false;
|
|
771
667
|
|
|
772
668
|
/**
|
|
773
|
-
*
|
|
774
|
-
*
|
|
775
|
-
*
|
|
776
|
-
*
|
|
777
|
-
* under the "Improving CSS variable performance" section.
|
|
669
|
+
* Groups all parts of the dialog.
|
|
670
|
+
* Doesn’t render its own HTML element.
|
|
671
|
+
*
|
|
672
|
+
* Documentation: [Base UI Dialog](https://base-ui.com/react/components/dialog)
|
|
778
673
|
*/
|
|
779
|
-
function
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
}, {
|
|
805
|
-
name: DrawerPopupCssVars.swipeStrength,
|
|
806
|
-
initialValue: '1'
|
|
807
|
-
}].forEach(({
|
|
808
|
-
name,
|
|
809
|
-
initialValue
|
|
810
|
-
}) => {
|
|
811
|
-
try {
|
|
812
|
-
CSS.registerProperty({
|
|
813
|
-
name,
|
|
814
|
-
syntax: '<number>',
|
|
815
|
-
inherits: false,
|
|
816
|
-
initialValue
|
|
817
|
-
});
|
|
818
|
-
} catch {
|
|
819
|
-
/* ignore already-registered */
|
|
820
|
-
}
|
|
674
|
+
function DialogRoot(props) {
|
|
675
|
+
const {
|
|
676
|
+
children,
|
|
677
|
+
open: openProp,
|
|
678
|
+
defaultOpen = false,
|
|
679
|
+
onOpenChange,
|
|
680
|
+
onOpenChangeComplete,
|
|
681
|
+
disablePointerDismissal = false,
|
|
682
|
+
modal = true,
|
|
683
|
+
actionsRef,
|
|
684
|
+
handle,
|
|
685
|
+
triggerId: triggerIdProp,
|
|
686
|
+
defaultTriggerId: defaultTriggerIdProp = null
|
|
687
|
+
} = props;
|
|
688
|
+
const parentDialogRootContext = useDialogRootContext(true);
|
|
689
|
+
const nested = Boolean(parentDialogRootContext);
|
|
690
|
+
const store = useRenderElement.useRefWithInit(() => {
|
|
691
|
+
return handle?.store ?? new DialogStore({
|
|
692
|
+
open: defaultOpen,
|
|
693
|
+
openProp,
|
|
694
|
+
activeTriggerId: defaultTriggerIdProp,
|
|
695
|
+
triggerIdProp,
|
|
696
|
+
modal,
|
|
697
|
+
disablePointerDismissal,
|
|
698
|
+
nested
|
|
821
699
|
});
|
|
822
|
-
}
|
|
823
|
-
|
|
700
|
+
}).current;
|
|
701
|
+
|
|
702
|
+
// Support initially open state when uncontrolled
|
|
703
|
+
InternalBackdrop.useOnFirstRender(() => {
|
|
704
|
+
if (openProp === undefined && store.state.open === false && defaultOpen === true) {
|
|
705
|
+
store.update({
|
|
706
|
+
open: true,
|
|
707
|
+
activeTriggerId: defaultTriggerIdProp
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
});
|
|
711
|
+
store.useControlledProp('openProp', openProp);
|
|
712
|
+
store.useControlledProp('triggerIdProp', triggerIdProp);
|
|
713
|
+
store.useSyncedValues({
|
|
714
|
+
disablePointerDismissal,
|
|
715
|
+
nested,
|
|
716
|
+
modal
|
|
717
|
+
});
|
|
718
|
+
store.useContextCallback('onOpenChange', onOpenChange);
|
|
719
|
+
store.useContextCallback('onOpenChangeComplete', onOpenChangeComplete);
|
|
720
|
+
const payload = store.useState('payload');
|
|
721
|
+
useDialogRoot({
|
|
722
|
+
store,
|
|
723
|
+
actionsRef,
|
|
724
|
+
parentContext: parentDialogRootContext?.store.context,
|
|
725
|
+
onOpenChange,
|
|
726
|
+
triggerIdProp
|
|
727
|
+
});
|
|
728
|
+
const contextValue = React__namespace.useMemo(() => ({
|
|
729
|
+
store
|
|
730
|
+
}), [store]);
|
|
731
|
+
return /*#__PURE__*/jsxRuntime.jsx(DialogRootContext.Provider, {
|
|
732
|
+
value: contextValue,
|
|
733
|
+
children: typeof children === 'function' ? children({
|
|
734
|
+
payload
|
|
735
|
+
}) : children
|
|
736
|
+
});
|
|
824
737
|
}
|
|
825
|
-
const stateAttributesMapping = {
|
|
826
|
-
...InternalBackdrop.popupStateMapping,
|
|
827
|
-
...useButton.transitionStatusMapping,
|
|
828
|
-
expanded(value) {
|
|
829
|
-
return value ? {
|
|
830
|
-
[DrawerPopupDataAttributes.expanded]: ''
|
|
831
|
-
} : null;
|
|
832
|
-
},
|
|
833
|
-
nestedDrawerOpen(value) {
|
|
834
|
-
return value ? {
|
|
835
|
-
[DrawerPopupDataAttributes.nestedDrawerOpen]: ''
|
|
836
|
-
} : null;
|
|
837
|
-
},
|
|
838
|
-
nestedDrawerSwiping(value) {
|
|
839
|
-
return value ? {
|
|
840
|
-
[DrawerPopupDataAttributes.nestedDrawerSwiping]: ''
|
|
841
|
-
} : null;
|
|
842
|
-
},
|
|
843
|
-
swipeDirection(value) {
|
|
844
|
-
return value ? {
|
|
845
|
-
[DrawerPopupDataAttributes.swipeDirection]: value
|
|
846
|
-
} : null;
|
|
847
|
-
},
|
|
848
|
-
swiping(value) {
|
|
849
|
-
return value ? {
|
|
850
|
-
[DrawerPopupDataAttributes.swiping]: ''
|
|
851
|
-
} : null;
|
|
852
|
-
}
|
|
853
|
-
};
|
|
854
738
|
|
|
855
739
|
/**
|
|
856
|
-
* A
|
|
857
|
-
* Renders a `<
|
|
740
|
+
* A button that opens the dialog.
|
|
741
|
+
* Renders a `<button>` element.
|
|
858
742
|
*
|
|
859
|
-
* Documentation: [Base UI
|
|
743
|
+
* Documentation: [Base UI Dialog](https://base-ui.com/react/components/dialog)
|
|
860
744
|
*/
|
|
861
|
-
const
|
|
745
|
+
const DialogTrigger = /*#__PURE__*/React__namespace.forwardRef(function DialogTrigger(componentProps, forwardedRef) {
|
|
862
746
|
const {
|
|
863
|
-
className,
|
|
864
|
-
finalFocus,
|
|
865
|
-
initialFocus,
|
|
866
747
|
render,
|
|
748
|
+
className,
|
|
749
|
+
disabled = false,
|
|
750
|
+
nativeButton = true,
|
|
751
|
+
id: idProp,
|
|
752
|
+
payload,
|
|
753
|
+
handle,
|
|
867
754
|
...elementProps
|
|
868
755
|
} = componentProps;
|
|
756
|
+
const dialogRootContext = useDialogRootContext(true);
|
|
757
|
+
const store = handle?.store ?? dialogRootContext?.store;
|
|
758
|
+
if (!store) {
|
|
759
|
+
throw new Error(process.env.NODE_ENV !== "production" ? 'Base UI: <Dialog.Trigger> must be used within <Dialog.Root> or provided with a handle.' : useRenderElement.formatErrorMessage(79));
|
|
760
|
+
}
|
|
761
|
+
const thisTriggerId = useButton.useBaseUiId(idProp);
|
|
762
|
+
const floatingContext = store.useState('floatingRootContext');
|
|
763
|
+
const isOpenedByThisTrigger = store.useState('isOpenedByTrigger', thisTriggerId);
|
|
764
|
+
const triggerElementRef = React__namespace.useRef(null);
|
|
869
765
|
const {
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
frontmostHeight,
|
|
875
|
-
hasNestedDrawer,
|
|
876
|
-
nestedSwiping,
|
|
877
|
-
nestedSwipeProgressStore,
|
|
878
|
-
onPopupHeightChange,
|
|
879
|
-
notifyParentFrontmostHeight,
|
|
880
|
-
notifyParentHasNestedDrawer
|
|
881
|
-
} = useDrawerRootContext();
|
|
882
|
-
const descriptionElementId = store.useState('descriptionElementId');
|
|
883
|
-
const disablePointerDismissal = store.useState('disablePointerDismissal');
|
|
884
|
-
const floatingRootContext = store.useState('floatingRootContext');
|
|
885
|
-
const rootPopupProps = store.useState('popupProps');
|
|
886
|
-
const modal = store.useState('modal');
|
|
887
|
-
const mounted = store.useState('mounted');
|
|
888
|
-
const nested = store.useState('nested');
|
|
889
|
-
const nestedOpenDialogCount = store.useState('nestedOpenDialogCount');
|
|
890
|
-
const transitionStatus = store.useState('transitionStatus');
|
|
891
|
-
const open = store.useState('open');
|
|
892
|
-
const openMethod = store.useState('openMethod');
|
|
893
|
-
const titleElementId = store.useState('titleElementId');
|
|
894
|
-
const role = store.useState('role');
|
|
895
|
-
const nestedDrawerOpen = nestedOpenDialogCount > 0;
|
|
896
|
-
const swipe = useDrawerViewportContext();
|
|
897
|
-
const swiping = swipe?.swiping ?? false;
|
|
898
|
-
const swipeStrength = swipe?.swipeStrength ?? null;
|
|
899
|
-
const {
|
|
900
|
-
snapPoints,
|
|
901
|
-
activeSnapPoint,
|
|
902
|
-
activeSnapPointOffset
|
|
903
|
-
} = useDrawerSnapPoints();
|
|
904
|
-
useDialogPortalContext();
|
|
905
|
-
const [popupHeight, setPopupHeight] = React__namespace.useState(0);
|
|
906
|
-
const popupHeightRef = React__namespace.useRef(0);
|
|
907
|
-
const measureHeight = useButton.useStableCallback(() => {
|
|
908
|
-
const popupElement = store.context.popupRef.current;
|
|
909
|
-
if (!popupElement) {
|
|
910
|
-
return;
|
|
911
|
-
}
|
|
912
|
-
const offsetHeight = popupElement.offsetHeight;
|
|
913
|
-
|
|
914
|
-
// Only skip while the element is still actually stretched beyond its last measured height.
|
|
915
|
-
if (popupHeightRef.current > 0 && frontmostHeight > popupHeightRef.current && offsetHeight > popupHeightRef.current) {
|
|
916
|
-
return;
|
|
917
|
-
}
|
|
918
|
-
const keepHeightWhileNested = popupHeightRef.current > 0 && hasNestedDrawer;
|
|
919
|
-
if (keepHeightWhileNested) {
|
|
920
|
-
const oldHeight = popupHeightRef.current;
|
|
921
|
-
setPopupHeight(oldHeight);
|
|
922
|
-
onPopupHeightChange(oldHeight);
|
|
923
|
-
return;
|
|
924
|
-
}
|
|
925
|
-
const nextHeight = offsetHeight;
|
|
926
|
-
if (nextHeight === popupHeightRef.current) {
|
|
927
|
-
return;
|
|
928
|
-
}
|
|
929
|
-
popupHeightRef.current = nextHeight;
|
|
930
|
-
setPopupHeight(nextHeight);
|
|
931
|
-
onPopupHeightChange(nextHeight);
|
|
766
|
+
registerTrigger,
|
|
767
|
+
isMountedByThisTrigger
|
|
768
|
+
} = useTriggerDataForwarding(thisTriggerId, triggerElementRef, store, {
|
|
769
|
+
payload
|
|
932
770
|
});
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
}
|
|
940
|
-
const popupElement = store.context.popupRef.current;
|
|
941
|
-
if (!popupElement) {
|
|
942
|
-
return undefined;
|
|
943
|
-
}
|
|
944
|
-
removeCSSVariableInheritance$1();
|
|
945
|
-
measureHeight();
|
|
946
|
-
if (typeof ResizeObserver !== 'function') {
|
|
947
|
-
return undefined;
|
|
948
|
-
}
|
|
949
|
-
const resizeObserver = new ResizeObserver(measureHeight);
|
|
950
|
-
resizeObserver.observe(popupElement);
|
|
951
|
-
return () => {
|
|
952
|
-
resizeObserver.disconnect();
|
|
953
|
-
};
|
|
954
|
-
}, [measureHeight, mounted, nestedDrawerOpen, onPopupHeightChange, store.context.popupRef]);
|
|
955
|
-
useButton.useIsoLayoutEffect(() => {
|
|
956
|
-
const popupRef = store.context.popupRef;
|
|
957
|
-
const syncNestedSwipeProgress = () => {
|
|
958
|
-
const popupElement = popupRef.current;
|
|
959
|
-
if (!popupElement) {
|
|
960
|
-
return;
|
|
961
|
-
}
|
|
962
|
-
const progress = nestedSwipeProgressStore.getSnapshot();
|
|
963
|
-
if (progress > 0) {
|
|
964
|
-
popupElement.style.setProperty(DrawerBackdropCssVars.swipeProgress, `${progress}`);
|
|
965
|
-
} else {
|
|
966
|
-
popupElement.style.setProperty(DrawerBackdropCssVars.swipeProgress, '0');
|
|
967
|
-
}
|
|
968
|
-
};
|
|
969
|
-
syncNestedSwipeProgress();
|
|
970
|
-
const unsubscribe = nestedSwipeProgressStore.subscribe(syncNestedSwipeProgress);
|
|
971
|
-
return () => {
|
|
972
|
-
unsubscribe();
|
|
973
|
-
const popupElement = popupRef.current;
|
|
974
|
-
if (popupElement) {
|
|
975
|
-
popupElement.style.setProperty(DrawerBackdropCssVars.swipeProgress, '0');
|
|
976
|
-
}
|
|
977
|
-
};
|
|
978
|
-
}, [nestedSwipeProgressStore, store.context.popupRef]);
|
|
979
|
-
React__namespace.useEffect(() => {
|
|
980
|
-
if (!open) {
|
|
981
|
-
return undefined;
|
|
982
|
-
}
|
|
983
|
-
notifyParentFrontmostHeight?.(frontmostHeight);
|
|
984
|
-
return () => {
|
|
985
|
-
notifyParentFrontmostHeight?.(0);
|
|
986
|
-
};
|
|
987
|
-
}, [frontmostHeight, open, notifyParentFrontmostHeight]);
|
|
988
|
-
React__namespace.useEffect(() => {
|
|
989
|
-
if (!notifyParentHasNestedDrawer) {
|
|
990
|
-
return undefined;
|
|
991
|
-
}
|
|
992
|
-
const present = open || transitionStatus === 'ending';
|
|
993
|
-
notifyParentHasNestedDrawer(present);
|
|
994
|
-
return () => {
|
|
995
|
-
notifyParentHasNestedDrawer(false);
|
|
996
|
-
};
|
|
997
|
-
}, [notifyParentHasNestedDrawer, open, transitionStatus]);
|
|
998
|
-
useButton.useOpenChangeComplete({
|
|
999
|
-
open,
|
|
1000
|
-
ref: store.context.popupRef,
|
|
1001
|
-
onComplete() {
|
|
1002
|
-
if (open) {
|
|
1003
|
-
store.context.onOpenChangeComplete?.(true);
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
771
|
+
const {
|
|
772
|
+
getButtonProps,
|
|
773
|
+
buttonRef
|
|
774
|
+
} = useButton.useButton({
|
|
775
|
+
disabled,
|
|
776
|
+
native: nativeButton
|
|
1006
777
|
});
|
|
1007
|
-
const
|
|
778
|
+
const click = InternalBackdrop.useClick(floatingContext, {
|
|
779
|
+
enabled: floatingContext != null
|
|
780
|
+
});
|
|
781
|
+
const localInteractionProps = InternalBackdrop.useInteractions([click]);
|
|
1008
782
|
const state = {
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
transitionStatus,
|
|
1012
|
-
expanded: activeSnapPoint === 1,
|
|
1013
|
-
nestedDrawerOpen,
|
|
1014
|
-
nestedDrawerSwiping: nestedSwiping,
|
|
1015
|
-
swipeDirection,
|
|
1016
|
-
swiping
|
|
783
|
+
disabled,
|
|
784
|
+
open: isOpenedByThisTrigger
|
|
1017
785
|
};
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
if (popupHeight && !shouldUseAutoHeight) {
|
|
1021
|
-
popupHeightCssVarValue = `${popupHeight}px`;
|
|
1022
|
-
}
|
|
1023
|
-
const shouldApplySnapPoints = snapPoints && snapPoints.length > 0 && (swipeDirection === 'down' || swipeDirection === 'up');
|
|
1024
|
-
let snapPointOffsetValue = null;
|
|
1025
|
-
if (shouldApplySnapPoints && activeSnapPointOffset !== null) {
|
|
1026
|
-
snapPointOffsetValue = swipeDirection === 'up' ? -activeSnapPointOffset : activeSnapPointOffset;
|
|
1027
|
-
}
|
|
1028
|
-
let dragStyles = swipe ? swipe.getDragStyles() : useRenderElement.EMPTY_OBJECT;
|
|
1029
|
-
if (shouldApplySnapPoints && swipeDirection === 'down') {
|
|
1030
|
-
const baseOffset = activeSnapPointOffset ?? 0;
|
|
1031
|
-
const movementValue = Number.parseFloat(String(dragStyles[DrawerPopupCssVars.swipeMovementY] ?? 0));
|
|
1032
|
-
const nextOffset = Number.isFinite(movementValue) ? baseOffset + movementValue : baseOffset;
|
|
1033
|
-
const shouldDamp = nextOffset < 0;
|
|
1034
|
-
if (swiping && shouldDamp && Number.isFinite(movementValue)) {
|
|
1035
|
-
const overshoot = Math.abs(nextOffset);
|
|
1036
|
-
const dampedOffset = -Math.sqrt(overshoot);
|
|
1037
|
-
const dampedMovement = dampedOffset - baseOffset;
|
|
1038
|
-
dragStyles = {
|
|
1039
|
-
...dragStyles,
|
|
1040
|
-
transform: undefined,
|
|
1041
|
-
[DrawerPopupCssVars.swipeMovementY]: `${dampedMovement}px`
|
|
1042
|
-
};
|
|
1043
|
-
} else {
|
|
1044
|
-
dragStyles = {
|
|
1045
|
-
...dragStyles,
|
|
1046
|
-
transform: undefined
|
|
1047
|
-
};
|
|
1048
|
-
}
|
|
1049
|
-
}
|
|
1050
|
-
const element = useRenderElement.useRenderElement('div', componentProps, {
|
|
786
|
+
const rootTriggerProps = store.useState('triggerProps', isMountedByThisTrigger);
|
|
787
|
+
return useRenderElement.useRenderElement('button', componentProps, {
|
|
1051
788
|
state,
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
'
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
onKeyDown(event) {
|
|
1059
|
-
if (COMPOSITE_KEYS.has(event.key)) {
|
|
1060
|
-
event.stopPropagation();
|
|
1061
|
-
}
|
|
1062
|
-
},
|
|
1063
|
-
style: {
|
|
1064
|
-
...dragStyles,
|
|
1065
|
-
[DrawerBackdropCssVars.swipeProgress]: '0',
|
|
1066
|
-
[DrawerPopupCssVars.nestedDrawers]: nestedOpenDialogCount,
|
|
1067
|
-
[DrawerPopupCssVars.height]: popupHeightCssVarValue,
|
|
1068
|
-
[DrawerPopupCssVars.snapPointOffset]: typeof snapPointOffsetValue === 'number' ? `${snapPointOffsetValue}px` : '0px',
|
|
1069
|
-
[DrawerPopupCssVars.frontmostHeight]: frontmostHeight ? `${frontmostHeight}px` : undefined,
|
|
1070
|
-
[DrawerPopupCssVars.swipeStrength]: typeof swipeStrength === 'number' && Number.isFinite(swipeStrength) && swipeStrength > 0 ? `${swipeStrength}` : '1'
|
|
1071
|
-
}
|
|
1072
|
-
}, elementProps],
|
|
1073
|
-
ref: [forwardedRef, store.context.popupRef, store.useStateSetter('popupElement')],
|
|
1074
|
-
stateAttributesMapping
|
|
1075
|
-
});
|
|
1076
|
-
return /*#__PURE__*/jsxRuntime.jsx(InternalBackdrop.FloatingFocusManager, {
|
|
1077
|
-
context: floatingRootContext,
|
|
1078
|
-
openInteractionType: openMethod,
|
|
1079
|
-
disabled: !mounted,
|
|
1080
|
-
closeOnFocusOut: !disablePointerDismissal,
|
|
1081
|
-
initialFocus: resolvedInitialFocus,
|
|
1082
|
-
returnFocus: finalFocus,
|
|
1083
|
-
modal: modal !== false,
|
|
1084
|
-
restoreFocus: "popup",
|
|
1085
|
-
children: element
|
|
789
|
+
ref: [buttonRef, forwardedRef, registerTrigger, triggerElementRef],
|
|
790
|
+
props: [localInteractionProps.getReferenceProps(), rootTriggerProps, {
|
|
791
|
+
[InternalBackdrop.CLICK_TRIGGER_IDENTIFIER]: '',
|
|
792
|
+
id: thisTriggerId
|
|
793
|
+
}, elementProps, getButtonProps],
|
|
794
|
+
stateAttributesMapping: InternalBackdrop.triggerOpenStateMapping
|
|
1086
795
|
});
|
|
1087
796
|
});
|
|
1088
|
-
if (process.env.NODE_ENV !== "production")
|
|
797
|
+
if (process.env.NODE_ENV !== "production") DialogTrigger.displayName = "DialogTrigger";
|
|
1089
798
|
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
799
|
+
let DrawerPopupCssVars = /*#__PURE__*/function (DrawerPopupCssVars) {
|
|
800
|
+
/**
|
|
801
|
+
* The number of nested drawers that are currently open.
|
|
802
|
+
* @type {number}
|
|
803
|
+
*/
|
|
804
|
+
DrawerPopupCssVars["nestedDrawers"] = "--nested-drawers";
|
|
805
|
+
/**
|
|
806
|
+
* The height of the drawer popup.
|
|
807
|
+
* @type {CSS length}
|
|
808
|
+
*/
|
|
809
|
+
DrawerPopupCssVars["height"] = "--drawer-height";
|
|
810
|
+
/**
|
|
811
|
+
* The height of the frontmost open drawer in the current nested drawer stack.
|
|
812
|
+
* @type {CSS length}
|
|
813
|
+
*/
|
|
814
|
+
DrawerPopupCssVars["frontmostHeight"] = "--drawer-frontmost-height";
|
|
815
|
+
/**
|
|
816
|
+
* The swipe movement on the X axis.
|
|
817
|
+
* @type {CSS length}
|
|
818
|
+
*/
|
|
819
|
+
DrawerPopupCssVars["swipeMovementX"] = "--drawer-swipe-movement-x";
|
|
820
|
+
/**
|
|
821
|
+
* The swipe movement on the Y axis.
|
|
822
|
+
* @type {CSS length}
|
|
823
|
+
*/
|
|
824
|
+
DrawerPopupCssVars["swipeMovementY"] = "--drawer-swipe-movement-y";
|
|
825
|
+
/**
|
|
826
|
+
* The snap point offset used for translating the drawer.
|
|
827
|
+
* @type {CSS length}
|
|
828
|
+
*/
|
|
829
|
+
DrawerPopupCssVars["snapPointOffset"] = "--drawer-snap-point-offset";
|
|
830
|
+
/**
|
|
831
|
+
* A scalar (0.1-1) used to scale the swipe release transition duration in CSS.
|
|
832
|
+
* @type {number}
|
|
833
|
+
*/
|
|
834
|
+
DrawerPopupCssVars["swipeStrength"] = "--drawer-swipe-strength";
|
|
835
|
+
return DrawerPopupCssVars;
|
|
836
|
+
}({});
|
|
837
|
+
|
|
838
|
+
let DrawerBackdropCssVars = /*#__PURE__*/function (DrawerBackdropCssVars) {
|
|
839
|
+
/**
|
|
840
|
+
* The swipe progress of the drawer gesture.
|
|
841
|
+
* @type {number}
|
|
842
|
+
*/
|
|
843
|
+
DrawerBackdropCssVars["swipeProgress"] = "--drawer-swipe-progress";
|
|
844
|
+
return DrawerBackdropCssVars;
|
|
845
|
+
}({});
|
|
846
|
+
|
|
847
|
+
const stateAttributesMapping$1 = {
|
|
848
|
+
...InternalBackdrop.popupStateMapping,
|
|
849
|
+
...useButton.transitionStatusMapping
|
|
850
|
+
};
|
|
1118
851
|
|
|
1119
852
|
/**
|
|
1120
|
-
*
|
|
1121
|
-
* By default, the portal element is appended to `<body>`.
|
|
853
|
+
* An overlay displayed beneath the popup.
|
|
1122
854
|
* Renders a `<div>` element.
|
|
1123
855
|
*
|
|
1124
856
|
* Documentation: [Base UI Drawer](https://base-ui.com/react/components/drawer)
|
|
1125
857
|
*/
|
|
1126
|
-
const
|
|
1127
|
-
|
|
1128
|
-
function useDialogRoot(params) {
|
|
858
|
+
const DrawerBackdrop = /*#__PURE__*/React__namespace.forwardRef(function DrawerBackdrop(componentProps, forwardedRef) {
|
|
1129
859
|
const {
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
const disablePointerDismissal = store.useState('disablePointerDismissal');
|
|
1136
|
-
const modal = store.useState('modal');
|
|
1137
|
-
const popupElement = store.useState('popupElement');
|
|
1138
|
-
const {
|
|
1139
|
-
openMethod,
|
|
1140
|
-
triggerProps
|
|
1141
|
-
} = InternalBackdrop.useOpenInteractionType(open);
|
|
1142
|
-
useImplicitActiveTrigger(store);
|
|
860
|
+
render,
|
|
861
|
+
className,
|
|
862
|
+
forceRender = false,
|
|
863
|
+
...elementProps
|
|
864
|
+
} = componentProps;
|
|
1143
865
|
const {
|
|
1144
|
-
|
|
1145
|
-
} =
|
|
1146
|
-
const
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
const isTopmost = ownNestedOpenDialogs === 0;
|
|
1168
|
-
const role = useRole(floatingRootContext);
|
|
1169
|
-
const dismiss = InternalBackdrop.useDismiss(floatingRootContext, {
|
|
1170
|
-
outsidePressEvent() {
|
|
1171
|
-
if (store.context.internalBackdropRef.current || store.context.backdropRef.current) {
|
|
1172
|
-
return 'intentional';
|
|
1173
|
-
}
|
|
1174
|
-
// Ensure `aria-hidden` on outside elements is removed immediately
|
|
1175
|
-
// on outside press when trapping focus.
|
|
1176
|
-
return {
|
|
1177
|
-
mouse: modal === 'trap-focus' ? 'sloppy' : 'intentional',
|
|
1178
|
-
touch: 'sloppy'
|
|
1179
|
-
};
|
|
1180
|
-
},
|
|
1181
|
-
outsidePress(event) {
|
|
1182
|
-
if (!store.context.outsidePressEnabledRef.current) {
|
|
1183
|
-
return false;
|
|
1184
|
-
}
|
|
1185
|
-
|
|
1186
|
-
// For mouse events, only accept left button (button 0)
|
|
1187
|
-
// For touch events, a single touch is equivalent to left button
|
|
1188
|
-
if ('button' in event && event.button !== 0) {
|
|
1189
|
-
return false;
|
|
1190
|
-
}
|
|
1191
|
-
if ('touches' in event && event.touches.length !== 1) {
|
|
1192
|
-
return false;
|
|
1193
|
-
}
|
|
1194
|
-
const target = useButton.getTarget(event);
|
|
1195
|
-
if (isTopmost && !disablePointerDismissal) {
|
|
1196
|
-
const eventTarget = target;
|
|
1197
|
-
// Only close if the click occurred on the dialog's owning backdrop.
|
|
1198
|
-
// This supports multiple modal dialogs that aren't nested in the React tree:
|
|
1199
|
-
// https://github.com/mui/base-ui/issues/1320
|
|
1200
|
-
if (modal) {
|
|
1201
|
-
return store.context.internalBackdropRef.current || store.context.backdropRef.current ? store.context.internalBackdropRef.current === eventTarget || store.context.backdropRef.current === eventTarget || useButton.contains(eventTarget, popupElement) && !eventTarget?.hasAttribute('data-base-ui-portal') : true;
|
|
1202
|
-
}
|
|
1203
|
-
return true;
|
|
866
|
+
store
|
|
867
|
+
} = useDialogRootContext();
|
|
868
|
+
const open = store.useState('open');
|
|
869
|
+
const nested = store.useState('nested');
|
|
870
|
+
const mounted = store.useState('mounted');
|
|
871
|
+
const transitionStatus = store.useState('transitionStatus');
|
|
872
|
+
const state = {
|
|
873
|
+
open,
|
|
874
|
+
transitionStatus
|
|
875
|
+
};
|
|
876
|
+
return useRenderElement.useRenderElement('div', componentProps, {
|
|
877
|
+
state,
|
|
878
|
+
ref: [store.context.backdropRef, forwardedRef],
|
|
879
|
+
stateAttributesMapping: stateAttributesMapping$1,
|
|
880
|
+
props: [{
|
|
881
|
+
role: 'presentation',
|
|
882
|
+
hidden: !mounted,
|
|
883
|
+
style: {
|
|
884
|
+
pointerEvents: !open ? 'none' : undefined,
|
|
885
|
+
userSelect: 'none',
|
|
886
|
+
WebkitUserSelect: 'none',
|
|
887
|
+
[DrawerBackdropCssVars.swipeProgress]: '0',
|
|
888
|
+
[DrawerPopupCssVars.swipeStrength]: '1'
|
|
1204
889
|
}
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
escapeKey: isTopmost
|
|
890
|
+
}, elementProps],
|
|
891
|
+
enabled: forceRender || !nested
|
|
1208
892
|
});
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
getReferenceProps,
|
|
1212
|
-
getFloatingProps,
|
|
1213
|
-
getTriggerProps
|
|
1214
|
-
} = InternalBackdrop.useInteractions([role, dismiss]);
|
|
893
|
+
});
|
|
894
|
+
if (process.env.NODE_ENV !== "production") DrawerBackdrop.displayName = "DrawerBackdrop";
|
|
1215
895
|
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
896
|
+
const DRAWER_CONTENT_ATTRIBUTE = 'data-drawer-content';
|
|
897
|
+
|
|
898
|
+
/**
|
|
899
|
+
* A container for the drawer contents.
|
|
900
|
+
* Renders a `<div>` element.
|
|
901
|
+
*
|
|
902
|
+
* Documentation: [Base UI Drawer](https://base-ui.com/react/components/drawer)
|
|
903
|
+
*/
|
|
904
|
+
const DrawerContent = /*#__PURE__*/React__namespace.forwardRef(function DrawerContent(componentProps, forwardedRef) {
|
|
905
|
+
const {
|
|
906
|
+
render,
|
|
907
|
+
className,
|
|
908
|
+
...elementProps
|
|
909
|
+
} = componentProps;
|
|
910
|
+
useDialogRootContext();
|
|
911
|
+
return useRenderElement.useRenderElement('div', componentProps, {
|
|
912
|
+
ref: forwardedRef,
|
|
913
|
+
props: [{
|
|
914
|
+
[DRAWER_CONTENT_ATTRIBUTE]: ''
|
|
915
|
+
}, elementProps]
|
|
1222
916
|
});
|
|
917
|
+
});
|
|
918
|
+
if (process.env.NODE_ENV !== "production") DrawerContent.displayName = "DrawerContent";
|
|
1223
919
|
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
920
|
+
const DrawerProviderContext = /*#__PURE__*/React__namespace.createContext(undefined);
|
|
921
|
+
if (process.env.NODE_ENV !== "production") DrawerProviderContext.displayName = "DrawerProviderContext";
|
|
922
|
+
function useDrawerProviderContext(optional) {
|
|
923
|
+
const context = React__namespace.useContext(DrawerProviderContext);
|
|
924
|
+
return context;
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
let DrawerPopupDataAttributes = function (DrawerPopupDataAttributes) {
|
|
928
|
+
/**
|
|
929
|
+
* Present when the drawer is open.
|
|
930
|
+
*/
|
|
931
|
+
DrawerPopupDataAttributes[DrawerPopupDataAttributes["open"] = InternalBackdrop.CommonPopupDataAttributes.open] = "open";
|
|
932
|
+
/**
|
|
933
|
+
* Present when the drawer is closed.
|
|
934
|
+
*/
|
|
935
|
+
DrawerPopupDataAttributes[DrawerPopupDataAttributes["closed"] = InternalBackdrop.CommonPopupDataAttributes.closed] = "closed";
|
|
936
|
+
/**
|
|
937
|
+
* Present when the drawer is animating in.
|
|
938
|
+
*/
|
|
939
|
+
DrawerPopupDataAttributes[DrawerPopupDataAttributes["startingStyle"] = InternalBackdrop.CommonPopupDataAttributes.startingStyle] = "startingStyle";
|
|
940
|
+
/**
|
|
941
|
+
* Present when the drawer is animating out.
|
|
942
|
+
*/
|
|
943
|
+
DrawerPopupDataAttributes[DrawerPopupDataAttributes["endingStyle"] = InternalBackdrop.CommonPopupDataAttributes.endingStyle] = "endingStyle";
|
|
944
|
+
/**
|
|
945
|
+
* Present when the drawer is at the expanded (full-height) snap point.
|
|
946
|
+
*/
|
|
947
|
+
DrawerPopupDataAttributes["expanded"] = "data-expanded";
|
|
948
|
+
/**
|
|
949
|
+
* Present when a nested drawer is open.
|
|
950
|
+
*/
|
|
951
|
+
DrawerPopupDataAttributes["nestedDrawerOpen"] = "data-nested-drawer-open";
|
|
952
|
+
/**
|
|
953
|
+
* Present when a nested drawer is being swiped.
|
|
954
|
+
*/
|
|
955
|
+
DrawerPopupDataAttributes["nestedDrawerSwiping"] = "data-nested-drawer-swiping";
|
|
956
|
+
/**
|
|
957
|
+
* Present when the drawer is dismissed by swiping.
|
|
958
|
+
*/
|
|
959
|
+
DrawerPopupDataAttributes["swipeDismiss"] = "data-swipe-dismiss";
|
|
960
|
+
/**
|
|
961
|
+
* Indicates the swipe direction.
|
|
962
|
+
* @type {'up' | 'down' | 'left' | 'right'}
|
|
963
|
+
*/
|
|
964
|
+
DrawerPopupDataAttributes["swipeDirection"] = "data-swipe-direction";
|
|
965
|
+
/**
|
|
966
|
+
* Present when the drawer is being swiped.
|
|
967
|
+
*/
|
|
968
|
+
DrawerPopupDataAttributes["swiping"] = "data-swiping";
|
|
969
|
+
return DrawerPopupDataAttributes;
|
|
970
|
+
}({});
|
|
971
|
+
|
|
972
|
+
const DrawerRootContext = /*#__PURE__*/React__namespace.createContext(undefined);
|
|
973
|
+
if (process.env.NODE_ENV !== "production") DrawerRootContext.displayName = "DrawerRootContext";
|
|
974
|
+
function useDrawerRootContext(optional) {
|
|
975
|
+
const drawerRootContext = React__namespace.useContext(DrawerRootContext);
|
|
976
|
+
if (optional === false && drawerRootContext === undefined) {
|
|
977
|
+
throw new Error(process.env.NODE_ENV !== "production" ? 'Base UI: DrawerRootContext is missing. Drawer parts must be placed within <Drawer.Root>.' : useRenderElement.formatErrorMessage(90));
|
|
978
|
+
}
|
|
979
|
+
return drawerRootContext;
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
function resolveSnapPointValue(snapPoint, viewportHeight, rootFontSize) {
|
|
983
|
+
if (!Number.isFinite(viewportHeight) || viewportHeight <= 0) {
|
|
984
|
+
return null;
|
|
985
|
+
}
|
|
986
|
+
if (typeof snapPoint === 'number') {
|
|
987
|
+
if (!Number.isFinite(snapPoint)) {
|
|
988
|
+
return null;
|
|
1228
989
|
}
|
|
1229
|
-
if (
|
|
1230
|
-
|
|
990
|
+
if (snapPoint <= 1) {
|
|
991
|
+
return clamp.clamp(snapPoint, 0, 1) * viewportHeight;
|
|
1231
992
|
}
|
|
1232
|
-
return
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
inactiveTriggerProps,
|
|
1245
|
-
popupProps,
|
|
1246
|
-
floatingRootContext,
|
|
1247
|
-
nestedOpenDialogCount: ownNestedOpenDialogs
|
|
1248
|
-
});
|
|
993
|
+
return snapPoint;
|
|
994
|
+
}
|
|
995
|
+
const trimmed = snapPoint.trim();
|
|
996
|
+
if (trimmed.endsWith('px')) {
|
|
997
|
+
const value = Number.parseFloat(trimmed);
|
|
998
|
+
return Number.isFinite(value) ? value : null;
|
|
999
|
+
}
|
|
1000
|
+
if (trimmed.endsWith('rem')) {
|
|
1001
|
+
const value = Number.parseFloat(trimmed);
|
|
1002
|
+
return Number.isFinite(value) ? value * rootFontSize : null;
|
|
1003
|
+
}
|
|
1004
|
+
return null;
|
|
1249
1005
|
}
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
titleElementId: InternalBackdrop.createSelector(state => state.titleElementId),
|
|
1260
|
-
viewportElement: InternalBackdrop.createSelector(state => state.viewportElement),
|
|
1261
|
-
role: InternalBackdrop.createSelector(state => state.role)
|
|
1262
|
-
};
|
|
1263
|
-
class DialogStore extends InternalBackdrop.ReactStore {
|
|
1264
|
-
constructor(initialState) {
|
|
1265
|
-
super(createInitialState(initialState), {
|
|
1266
|
-
popupRef: /*#__PURE__*/React__namespace.createRef(),
|
|
1267
|
-
backdropRef: /*#__PURE__*/React__namespace.createRef(),
|
|
1268
|
-
internalBackdropRef: /*#__PURE__*/React__namespace.createRef(),
|
|
1269
|
-
outsidePressEnabledRef: {
|
|
1270
|
-
current: true
|
|
1271
|
-
},
|
|
1272
|
-
triggerElements: new InternalBackdrop.PopupTriggerMap(),
|
|
1273
|
-
onOpenChange: undefined,
|
|
1274
|
-
onOpenChangeComplete: undefined
|
|
1275
|
-
}, selectors);
|
|
1006
|
+
function findClosestSnapPoint(height, points) {
|
|
1007
|
+
let closest = null;
|
|
1008
|
+
let closestDistance = Infinity;
|
|
1009
|
+
for (const point of points) {
|
|
1010
|
+
const distance = Math.abs(point.height - height);
|
|
1011
|
+
if (distance < closestDistance) {
|
|
1012
|
+
closestDistance = distance;
|
|
1013
|
+
closest = point;
|
|
1014
|
+
}
|
|
1276
1015
|
}
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1016
|
+
return closest;
|
|
1017
|
+
}
|
|
1018
|
+
function useDrawerSnapPoints() {
|
|
1019
|
+
const {
|
|
1020
|
+
store
|
|
1021
|
+
} = useDialogRootContext();
|
|
1022
|
+
const {
|
|
1023
|
+
snapPoints,
|
|
1024
|
+
activeSnapPoint,
|
|
1025
|
+
setActiveSnapPoint,
|
|
1026
|
+
popupHeight
|
|
1027
|
+
} = useDrawerRootContext();
|
|
1028
|
+
const viewportElement = store.useState('viewportElement');
|
|
1029
|
+
const [viewportHeight, setViewportHeight] = React__namespace.useState(0);
|
|
1030
|
+
const [rootFontSize, setRootFontSize] = React__namespace.useState(16);
|
|
1031
|
+
const measureViewportHeight = useButton.useStableCallback(() => {
|
|
1032
|
+
const doc = useButton.ownerDocument(viewportElement);
|
|
1033
|
+
const html = doc.documentElement;
|
|
1034
|
+
if (viewportElement) {
|
|
1035
|
+
setViewportHeight(viewportElement.offsetHeight);
|
|
1036
|
+
}
|
|
1037
|
+
if (!viewportElement) {
|
|
1038
|
+
setViewportHeight(html.clientHeight);
|
|
1039
|
+
}
|
|
1040
|
+
const fontSize = parseFloat(getComputedStyle(html).fontSize);
|
|
1041
|
+
if (Number.isFinite(fontSize)) {
|
|
1042
|
+
setRootFontSize(fontSize);
|
|
1043
|
+
}
|
|
1044
|
+
});
|
|
1045
|
+
useButton.useIsoLayoutEffect(() => {
|
|
1046
|
+
measureViewportHeight();
|
|
1047
|
+
if (!viewportElement || typeof ResizeObserver !== 'function') {
|
|
1048
|
+
return undefined;
|
|
1049
|
+
}
|
|
1050
|
+
const resizeObserver = new ResizeObserver(measureViewportHeight);
|
|
1051
|
+
resizeObserver.observe(viewportElement);
|
|
1052
|
+
return () => {
|
|
1053
|
+
resizeObserver.disconnect();
|
|
1280
1054
|
};
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1055
|
+
}, [measureViewportHeight, viewportElement]);
|
|
1056
|
+
const resolvedSnapPoints = React__namespace.useMemo(() => {
|
|
1057
|
+
if (!snapPoints || snapPoints.length === 0 || viewportHeight <= 0 || popupHeight <= 0) {
|
|
1058
|
+
return [];
|
|
1059
|
+
}
|
|
1060
|
+
const maxHeight = Math.min(popupHeight, viewportHeight);
|
|
1061
|
+
if (!Number.isFinite(maxHeight) || maxHeight <= 0) {
|
|
1062
|
+
return [];
|
|
1285
1063
|
}
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1064
|
+
const resolved = snapPoints.map(value => {
|
|
1065
|
+
const resolvedHeight = resolveSnapPointValue(value, viewportHeight, rootFontSize);
|
|
1066
|
+
if (resolvedHeight === null || !Number.isFinite(resolvedHeight)) {
|
|
1067
|
+
return null;
|
|
1068
|
+
}
|
|
1069
|
+
const clampedHeight = clamp.clamp(resolvedHeight, 0, maxHeight);
|
|
1070
|
+
return {
|
|
1071
|
+
value,
|
|
1072
|
+
height: clampedHeight,
|
|
1073
|
+
offset: Math.max(0, popupHeight - clampedHeight)
|
|
1074
|
+
};
|
|
1075
|
+
}).filter(point => Boolean(point));
|
|
1076
|
+
if (resolved.length <= 1) {
|
|
1077
|
+
return resolved;
|
|
1289
1078
|
}
|
|
1290
|
-
const
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
// If a popup is closing, the `trigger` may be null.
|
|
1302
|
-
// We want to keep the previous value so that exit animations are played and focus is returned correctly.
|
|
1303
|
-
const newTriggerId = eventDetails.trigger?.id ?? null;
|
|
1304
|
-
if (newTriggerId || nextOpen) {
|
|
1305
|
-
updatedState.activeTriggerId = newTriggerId;
|
|
1306
|
-
updatedState.activeTriggerElement = eventDetails.trigger ?? null;
|
|
1079
|
+
const deduped = [];
|
|
1080
|
+
const seenHeights = [];
|
|
1081
|
+
for (let index = resolved.length - 1; index >= 0; index -= 1) {
|
|
1082
|
+
const point = resolved[index];
|
|
1083
|
+
const isDuplicate = seenHeights.some(height => Math.abs(height - point.height) <= 1);
|
|
1084
|
+
if (isDuplicate) {
|
|
1085
|
+
continue;
|
|
1086
|
+
}
|
|
1087
|
+
seenHeights.push(point.height);
|
|
1088
|
+
deduped.push(point);
|
|
1307
1089
|
}
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
}
|
|
1311
|
-
|
|
1090
|
+
deduped.reverse();
|
|
1091
|
+
return deduped;
|
|
1092
|
+
}, [popupHeight, rootFontSize, snapPoints, viewportHeight]);
|
|
1093
|
+
const resolvedActiveSnapPoint = React__namespace.useMemo(() => {
|
|
1094
|
+
if (activeSnapPoint === undefined) {
|
|
1095
|
+
return resolvedSnapPoints[0];
|
|
1096
|
+
}
|
|
1097
|
+
if (activeSnapPoint === null) {
|
|
1098
|
+
return undefined;
|
|
1099
|
+
}
|
|
1100
|
+
const exactMatch = resolvedSnapPoints.find(point => Object.is(point.value, activeSnapPoint));
|
|
1101
|
+
if (exactMatch) {
|
|
1102
|
+
return exactMatch;
|
|
1103
|
+
}
|
|
1104
|
+
const maxHeight = Math.min(popupHeight, viewportHeight);
|
|
1105
|
+
const resolvedHeight = resolveSnapPointValue(activeSnapPoint, viewportHeight, rootFontSize);
|
|
1106
|
+
if (resolvedHeight === null || !Number.isFinite(resolvedHeight)) {
|
|
1107
|
+
return undefined;
|
|
1108
|
+
}
|
|
1109
|
+
const clampedHeight = clamp.clamp(resolvedHeight, 0, maxHeight);
|
|
1110
|
+
return findClosestSnapPoint(clampedHeight, resolvedSnapPoints) ?? undefined;
|
|
1111
|
+
}, [activeSnapPoint, popupHeight, resolvedSnapPoints, rootFontSize, viewportHeight]);
|
|
1312
1112
|
return {
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
openMethod: null,
|
|
1321
|
-
nested: false,
|
|
1322
|
-
nestedOpenDialogCount: 0,
|
|
1323
|
-
role: 'dialog',
|
|
1324
|
-
...initialState
|
|
1113
|
+
snapPoints,
|
|
1114
|
+
activeSnapPoint,
|
|
1115
|
+
setActiveSnapPoint,
|
|
1116
|
+
popupHeight,
|
|
1117
|
+
viewportHeight,
|
|
1118
|
+
resolvedSnapPoints,
|
|
1119
|
+
activeSnapPointOffset: resolvedActiveSnapPoint?.offset ?? null
|
|
1325
1120
|
};
|
|
1326
1121
|
}
|
|
1327
1122
|
|
|
1123
|
+
const DrawerViewportContext = /*#__PURE__*/React__namespace.createContext(null);
|
|
1124
|
+
if (process.env.NODE_ENV !== "production") DrawerViewportContext.displayName = "DrawerViewportContext";
|
|
1125
|
+
function useDrawerViewportContext(optional) {
|
|
1126
|
+
const context = React__namespace.useContext(DrawerViewportContext);
|
|
1127
|
+
return context;
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
let drawerSwipeVarsRegistered = false;
|
|
1131
|
+
|
|
1328
1132
|
/**
|
|
1329
|
-
*
|
|
1330
|
-
*
|
|
1331
|
-
*
|
|
1332
|
-
*
|
|
1133
|
+
* Removes inheritance of high-frequency drawer swipe CSS variables, which
|
|
1134
|
+
* reduces style recalculation cost in complex drawers with deep subtrees.
|
|
1135
|
+
* Child elements that need these values can still opt-in by using `inherit`.
|
|
1136
|
+
* See https://motion.dev/blog/web-animation-performance-tier-list
|
|
1137
|
+
* under the "Improving CSS variable performance" section.
|
|
1333
1138
|
*/
|
|
1334
|
-
function
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
defaultOpen = false,
|
|
1339
|
-
onOpenChange,
|
|
1340
|
-
onOpenChangeComplete,
|
|
1341
|
-
disablePointerDismissal = false,
|
|
1342
|
-
modal = true,
|
|
1343
|
-
actionsRef,
|
|
1344
|
-
handle,
|
|
1345
|
-
triggerId: triggerIdProp,
|
|
1346
|
-
defaultTriggerId: defaultTriggerIdProp = null
|
|
1347
|
-
} = props;
|
|
1348
|
-
const parentDialogRootContext = useDialogRootContext(true);
|
|
1349
|
-
const nested = Boolean(parentDialogRootContext);
|
|
1350
|
-
const store = useRenderElement.useRefWithInit(() => {
|
|
1351
|
-
return handle?.store ?? new DialogStore({
|
|
1352
|
-
open: defaultOpen,
|
|
1353
|
-
openProp,
|
|
1354
|
-
activeTriggerId: defaultTriggerIdProp,
|
|
1355
|
-
triggerIdProp,
|
|
1356
|
-
modal,
|
|
1357
|
-
disablePointerDismissal,
|
|
1358
|
-
nested
|
|
1359
|
-
});
|
|
1360
|
-
}).current;
|
|
1139
|
+
function removeCSSVariableInheritance$1() {
|
|
1140
|
+
if (drawerSwipeVarsRegistered) {
|
|
1141
|
+
return;
|
|
1142
|
+
}
|
|
1361
1143
|
|
|
1362
|
-
//
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1144
|
+
// Intentionally keep inheritance disabled on WebKit as well. Safari doesn't support
|
|
1145
|
+
// opting descendants back in via `--var: inherit` for custom properties registered
|
|
1146
|
+
// with `inherits: false`, but Drawer does not rely on descendant access to these vars
|
|
1147
|
+
// (unlike ScrollArea), so we keep the performance optimization enabled.
|
|
1148
|
+
if (typeof CSS !== 'undefined' && 'registerProperty' in CSS) {
|
|
1149
|
+
[DrawerPopupCssVars.swipeMovementX, DrawerPopupCssVars.swipeMovementY, DrawerPopupCssVars.snapPointOffset].forEach(name => {
|
|
1150
|
+
try {
|
|
1151
|
+
CSS.registerProperty({
|
|
1152
|
+
name,
|
|
1153
|
+
syntax: '<length>',
|
|
1154
|
+
inherits: false,
|
|
1155
|
+
initialValue: '0px'
|
|
1156
|
+
});
|
|
1157
|
+
} catch {
|
|
1158
|
+
/* ignore already-registered */
|
|
1159
|
+
}
|
|
1160
|
+
});
|
|
1161
|
+
[{
|
|
1162
|
+
name: DrawerBackdropCssVars.swipeProgress,
|
|
1163
|
+
initialValue: '0'
|
|
1164
|
+
}, {
|
|
1165
|
+
name: DrawerPopupCssVars.swipeStrength,
|
|
1166
|
+
initialValue: '1'
|
|
1167
|
+
}].forEach(({
|
|
1168
|
+
name,
|
|
1169
|
+
initialValue
|
|
1170
|
+
}) => {
|
|
1171
|
+
try {
|
|
1172
|
+
CSS.registerProperty({
|
|
1173
|
+
name,
|
|
1174
|
+
syntax: '<number>',
|
|
1175
|
+
inherits: false,
|
|
1176
|
+
initialValue
|
|
1177
|
+
});
|
|
1178
|
+
} catch {
|
|
1179
|
+
/* ignore already-registered */
|
|
1180
|
+
}
|
|
1181
|
+
});
|
|
1182
|
+
}
|
|
1183
|
+
drawerSwipeVarsRegistered = true;
|
|
1397
1184
|
}
|
|
1185
|
+
const stateAttributesMapping = {
|
|
1186
|
+
...InternalBackdrop.popupStateMapping,
|
|
1187
|
+
...useButton.transitionStatusMapping,
|
|
1188
|
+
expanded(value) {
|
|
1189
|
+
return value ? {
|
|
1190
|
+
[DrawerPopupDataAttributes.expanded]: ''
|
|
1191
|
+
} : null;
|
|
1192
|
+
},
|
|
1193
|
+
nestedDrawerOpen(value) {
|
|
1194
|
+
return value ? {
|
|
1195
|
+
[DrawerPopupDataAttributes.nestedDrawerOpen]: ''
|
|
1196
|
+
} : null;
|
|
1197
|
+
},
|
|
1198
|
+
nestedDrawerSwiping(value) {
|
|
1199
|
+
return value ? {
|
|
1200
|
+
[DrawerPopupDataAttributes.nestedDrawerSwiping]: ''
|
|
1201
|
+
} : null;
|
|
1202
|
+
},
|
|
1203
|
+
swipeDirection(value) {
|
|
1204
|
+
return value ? {
|
|
1205
|
+
[DrawerPopupDataAttributes.swipeDirection]: value
|
|
1206
|
+
} : null;
|
|
1207
|
+
},
|
|
1208
|
+
swiping(value) {
|
|
1209
|
+
return value ? {
|
|
1210
|
+
[DrawerPopupDataAttributes.swiping]: ''
|
|
1211
|
+
} : null;
|
|
1212
|
+
}
|
|
1213
|
+
};
|
|
1398
1214
|
|
|
1399
1215
|
/**
|
|
1400
|
-
* A
|
|
1401
|
-
* Renders a `<
|
|
1216
|
+
* A container for the drawer contents.
|
|
1217
|
+
* Renders a `<div>` element.
|
|
1402
1218
|
*
|
|
1403
|
-
* Documentation: [Base UI
|
|
1219
|
+
* Documentation: [Base UI Drawer](https://base-ui.com/react/components/drawer)
|
|
1404
1220
|
*/
|
|
1405
|
-
const
|
|
1221
|
+
const DrawerPopup = /*#__PURE__*/React__namespace.forwardRef(function DrawerPopup(componentProps, forwardedRef) {
|
|
1406
1222
|
const {
|
|
1407
|
-
render,
|
|
1408
1223
|
className,
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
payload,
|
|
1413
|
-
handle,
|
|
1224
|
+
finalFocus,
|
|
1225
|
+
initialFocus,
|
|
1226
|
+
render,
|
|
1414
1227
|
...elementProps
|
|
1415
1228
|
} = componentProps;
|
|
1416
|
-
const dialogRootContext = useDialogRootContext(true);
|
|
1417
|
-
const store = handle?.store ?? dialogRootContext?.store;
|
|
1418
|
-
if (!store) {
|
|
1419
|
-
throw new Error(process.env.NODE_ENV !== "production" ? 'Base UI: <Dialog.Trigger> must be used within <Dialog.Root> or provided with a handle.' : useRenderElement.formatErrorMessage(79));
|
|
1420
|
-
}
|
|
1421
|
-
const thisTriggerId = useButton.useBaseUiId(idProp);
|
|
1422
|
-
const floatingContext = store.useState('floatingRootContext');
|
|
1423
|
-
const isOpenedByThisTrigger = store.useState('isOpenedByTrigger', thisTriggerId);
|
|
1424
|
-
const triggerElementRef = React__namespace.useRef(null);
|
|
1425
1229
|
const {
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
} = useTriggerDataForwarding(thisTriggerId, triggerElementRef, store, {
|
|
1429
|
-
payload
|
|
1430
|
-
});
|
|
1230
|
+
store
|
|
1231
|
+
} = useDialogRootContext();
|
|
1431
1232
|
const {
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1233
|
+
swipeDirection,
|
|
1234
|
+
frontmostHeight,
|
|
1235
|
+
hasNestedDrawer,
|
|
1236
|
+
nestedSwiping,
|
|
1237
|
+
nestedSwipeProgressStore,
|
|
1238
|
+
onPopupHeightChange,
|
|
1239
|
+
notifyParentFrontmostHeight,
|
|
1240
|
+
notifyParentHasNestedDrawer
|
|
1241
|
+
} = useDrawerRootContext();
|
|
1242
|
+
const descriptionElementId = store.useState('descriptionElementId');
|
|
1243
|
+
const disablePointerDismissal = store.useState('disablePointerDismissal');
|
|
1244
|
+
const floatingRootContext = store.useState('floatingRootContext');
|
|
1245
|
+
const rootPopupProps = store.useState('popupProps');
|
|
1246
|
+
const modal = store.useState('modal');
|
|
1247
|
+
const mounted = store.useState('mounted');
|
|
1248
|
+
const nested = store.useState('nested');
|
|
1249
|
+
const nestedOpenDialogCount = store.useState('nestedOpenDialogCount');
|
|
1250
|
+
const transitionStatus = store.useState('transitionStatus');
|
|
1251
|
+
const open = store.useState('open');
|
|
1252
|
+
const openMethod = store.useState('openMethod');
|
|
1253
|
+
const titleElementId = store.useState('titleElementId');
|
|
1254
|
+
const role = store.useState('role');
|
|
1255
|
+
const nestedDrawerOpen = nestedOpenDialogCount > 0;
|
|
1256
|
+
const swipe = useDrawerViewportContext();
|
|
1257
|
+
const swiping = swipe?.swiping ?? false;
|
|
1258
|
+
const swipeStrength = swipe?.swipeStrength ?? null;
|
|
1259
|
+
const {
|
|
1260
|
+
snapPoints,
|
|
1261
|
+
activeSnapPoint,
|
|
1262
|
+
activeSnapPointOffset
|
|
1263
|
+
} = useDrawerSnapPoints();
|
|
1264
|
+
useDialogPortalContext();
|
|
1265
|
+
const [popupHeight, setPopupHeight] = React__namespace.useState(0);
|
|
1266
|
+
const popupHeightRef = React__namespace.useRef(0);
|
|
1267
|
+
const measureHeight = useButton.useStableCallback(() => {
|
|
1268
|
+
const popupElement = store.context.popupRef.current;
|
|
1269
|
+
if (!popupElement) {
|
|
1270
|
+
return;
|
|
1271
|
+
}
|
|
1272
|
+
const offsetHeight = popupElement.offsetHeight;
|
|
1273
|
+
|
|
1274
|
+
// Only skip while the element is still actually stretched beyond its last measured height.
|
|
1275
|
+
if (popupHeightRef.current > 0 && frontmostHeight > popupHeightRef.current && offsetHeight > popupHeightRef.current) {
|
|
1276
|
+
return;
|
|
1277
|
+
}
|
|
1278
|
+
const keepHeightWhileNested = popupHeightRef.current > 0 && hasNestedDrawer;
|
|
1279
|
+
if (keepHeightWhileNested) {
|
|
1280
|
+
const oldHeight = popupHeightRef.current;
|
|
1281
|
+
setPopupHeight(oldHeight);
|
|
1282
|
+
onPopupHeightChange(oldHeight);
|
|
1283
|
+
return;
|
|
1284
|
+
}
|
|
1285
|
+
const nextHeight = offsetHeight;
|
|
1286
|
+
if (nextHeight === popupHeightRef.current) {
|
|
1287
|
+
return;
|
|
1288
|
+
}
|
|
1289
|
+
popupHeightRef.current = nextHeight;
|
|
1290
|
+
setPopupHeight(nextHeight);
|
|
1291
|
+
onPopupHeightChange(nextHeight);
|
|
1437
1292
|
});
|
|
1438
|
-
|
|
1439
|
-
|
|
1293
|
+
useButton.useIsoLayoutEffect(() => {
|
|
1294
|
+
if (!mounted) {
|
|
1295
|
+
popupHeightRef.current = 0;
|
|
1296
|
+
setPopupHeight(0);
|
|
1297
|
+
onPopupHeightChange(0);
|
|
1298
|
+
return undefined;
|
|
1299
|
+
}
|
|
1300
|
+
const popupElement = store.context.popupRef.current;
|
|
1301
|
+
if (!popupElement) {
|
|
1302
|
+
return undefined;
|
|
1303
|
+
}
|
|
1304
|
+
removeCSSVariableInheritance$1();
|
|
1305
|
+
measureHeight();
|
|
1306
|
+
if (typeof ResizeObserver !== 'function') {
|
|
1307
|
+
return undefined;
|
|
1308
|
+
}
|
|
1309
|
+
const resizeObserver = new ResizeObserver(measureHeight);
|
|
1310
|
+
resizeObserver.observe(popupElement);
|
|
1311
|
+
return () => {
|
|
1312
|
+
resizeObserver.disconnect();
|
|
1313
|
+
};
|
|
1314
|
+
}, [measureHeight, mounted, nestedDrawerOpen, onPopupHeightChange, store.context.popupRef]);
|
|
1315
|
+
useButton.useIsoLayoutEffect(() => {
|
|
1316
|
+
const popupRef = store.context.popupRef;
|
|
1317
|
+
const syncNestedSwipeProgress = () => {
|
|
1318
|
+
const popupElement = popupRef.current;
|
|
1319
|
+
if (!popupElement) {
|
|
1320
|
+
return;
|
|
1321
|
+
}
|
|
1322
|
+
const progress = nestedSwipeProgressStore.getSnapshot();
|
|
1323
|
+
if (progress > 0) {
|
|
1324
|
+
popupElement.style.setProperty(DrawerBackdropCssVars.swipeProgress, `${progress}`);
|
|
1325
|
+
} else {
|
|
1326
|
+
popupElement.style.setProperty(DrawerBackdropCssVars.swipeProgress, '0');
|
|
1327
|
+
}
|
|
1328
|
+
};
|
|
1329
|
+
syncNestedSwipeProgress();
|
|
1330
|
+
const unsubscribe = nestedSwipeProgressStore.subscribe(syncNestedSwipeProgress);
|
|
1331
|
+
return () => {
|
|
1332
|
+
unsubscribe();
|
|
1333
|
+
const popupElement = popupRef.current;
|
|
1334
|
+
if (popupElement) {
|
|
1335
|
+
popupElement.style.setProperty(DrawerBackdropCssVars.swipeProgress, '0');
|
|
1336
|
+
}
|
|
1337
|
+
};
|
|
1338
|
+
}, [nestedSwipeProgressStore, store.context.popupRef]);
|
|
1339
|
+
React__namespace.useEffect(() => {
|
|
1340
|
+
if (!open) {
|
|
1341
|
+
return undefined;
|
|
1342
|
+
}
|
|
1343
|
+
notifyParentFrontmostHeight?.(frontmostHeight);
|
|
1344
|
+
return () => {
|
|
1345
|
+
notifyParentFrontmostHeight?.(0);
|
|
1346
|
+
};
|
|
1347
|
+
}, [frontmostHeight, open, notifyParentFrontmostHeight]);
|
|
1348
|
+
React__namespace.useEffect(() => {
|
|
1349
|
+
if (!notifyParentHasNestedDrawer) {
|
|
1350
|
+
return undefined;
|
|
1351
|
+
}
|
|
1352
|
+
const present = open || transitionStatus === 'ending';
|
|
1353
|
+
notifyParentHasNestedDrawer(present);
|
|
1354
|
+
return () => {
|
|
1355
|
+
notifyParentHasNestedDrawer(false);
|
|
1356
|
+
};
|
|
1357
|
+
}, [notifyParentHasNestedDrawer, open, transitionStatus]);
|
|
1358
|
+
useButton.useOpenChangeComplete({
|
|
1359
|
+
open,
|
|
1360
|
+
ref: store.context.popupRef,
|
|
1361
|
+
onComplete() {
|
|
1362
|
+
if (open) {
|
|
1363
|
+
store.context.onOpenChangeComplete?.(true);
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1440
1366
|
});
|
|
1441
|
-
const
|
|
1367
|
+
const resolvedInitialFocus = initialFocus === undefined ? store.context.popupRef : initialFocus;
|
|
1442
1368
|
const state = {
|
|
1443
|
-
|
|
1444
|
-
|
|
1369
|
+
open,
|
|
1370
|
+
nested,
|
|
1371
|
+
transitionStatus,
|
|
1372
|
+
expanded: activeSnapPoint === 1,
|
|
1373
|
+
nestedDrawerOpen,
|
|
1374
|
+
nestedDrawerSwiping: nestedSwiping,
|
|
1375
|
+
swipeDirection,
|
|
1376
|
+
swiping
|
|
1445
1377
|
};
|
|
1446
|
-
|
|
1447
|
-
|
|
1378
|
+
let popupHeightCssVarValue;
|
|
1379
|
+
const shouldUseAutoHeight = !hasNestedDrawer && transitionStatus !== 'ending';
|
|
1380
|
+
if (popupHeight && !shouldUseAutoHeight) {
|
|
1381
|
+
popupHeightCssVarValue = `${popupHeight}px`;
|
|
1382
|
+
}
|
|
1383
|
+
const shouldApplySnapPoints = snapPoints && snapPoints.length > 0 && (swipeDirection === 'down' || swipeDirection === 'up');
|
|
1384
|
+
let snapPointOffsetValue = null;
|
|
1385
|
+
if (shouldApplySnapPoints && activeSnapPointOffset !== null) {
|
|
1386
|
+
snapPointOffsetValue = swipeDirection === 'up' ? -activeSnapPointOffset : activeSnapPointOffset;
|
|
1387
|
+
}
|
|
1388
|
+
let dragStyles = swipe ? swipe.getDragStyles() : useRenderElement.EMPTY_OBJECT;
|
|
1389
|
+
if (shouldApplySnapPoints && swipeDirection === 'down') {
|
|
1390
|
+
const baseOffset = activeSnapPointOffset ?? 0;
|
|
1391
|
+
const movementValue = Number.parseFloat(String(dragStyles[DrawerPopupCssVars.swipeMovementY] ?? 0));
|
|
1392
|
+
const nextOffset = Number.isFinite(movementValue) ? baseOffset + movementValue : baseOffset;
|
|
1393
|
+
const shouldDamp = nextOffset < 0;
|
|
1394
|
+
if (swiping && shouldDamp && Number.isFinite(movementValue)) {
|
|
1395
|
+
const overshoot = Math.abs(nextOffset);
|
|
1396
|
+
const dampedOffset = -Math.sqrt(overshoot);
|
|
1397
|
+
const dampedMovement = dampedOffset - baseOffset;
|
|
1398
|
+
dragStyles = {
|
|
1399
|
+
...dragStyles,
|
|
1400
|
+
transform: undefined,
|
|
1401
|
+
[DrawerPopupCssVars.swipeMovementY]: `${dampedMovement}px`
|
|
1402
|
+
};
|
|
1403
|
+
} else {
|
|
1404
|
+
dragStyles = {
|
|
1405
|
+
...dragStyles,
|
|
1406
|
+
transform: undefined
|
|
1407
|
+
};
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
const element = useRenderElement.useRenderElement('div', componentProps, {
|
|
1448
1411
|
state,
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1412
|
+
props: [rootPopupProps, {
|
|
1413
|
+
'aria-labelledby': titleElementId,
|
|
1414
|
+
'aria-describedby': descriptionElementId,
|
|
1415
|
+
role,
|
|
1416
|
+
tabIndex: -1,
|
|
1417
|
+
hidden: !mounted,
|
|
1418
|
+
onKeyDown(event) {
|
|
1419
|
+
if (COMPOSITE_KEYS.has(event.key)) {
|
|
1420
|
+
event.stopPropagation();
|
|
1421
|
+
}
|
|
1422
|
+
},
|
|
1423
|
+
style: {
|
|
1424
|
+
...dragStyles,
|
|
1425
|
+
[DrawerBackdropCssVars.swipeProgress]: '0',
|
|
1426
|
+
[DrawerPopupCssVars.nestedDrawers]: nestedOpenDialogCount,
|
|
1427
|
+
[DrawerPopupCssVars.height]: popupHeightCssVarValue,
|
|
1428
|
+
[DrawerPopupCssVars.snapPointOffset]: typeof snapPointOffsetValue === 'number' ? `${snapPointOffsetValue}px` : '0px',
|
|
1429
|
+
[DrawerPopupCssVars.frontmostHeight]: frontmostHeight ? `${frontmostHeight}px` : undefined,
|
|
1430
|
+
[DrawerPopupCssVars.swipeStrength]: typeof swipeStrength === 'number' && Number.isFinite(swipeStrength) && swipeStrength > 0 ? `${swipeStrength}` : '1'
|
|
1431
|
+
}
|
|
1432
|
+
}, elementProps],
|
|
1433
|
+
ref: [forwardedRef, store.context.popupRef, store.useStateSetter('popupElement')],
|
|
1434
|
+
stateAttributesMapping
|
|
1435
|
+
});
|
|
1436
|
+
return /*#__PURE__*/jsxRuntime.jsx(InternalBackdrop.FloatingFocusManager, {
|
|
1437
|
+
context: floatingRootContext,
|
|
1438
|
+
openInteractionType: openMethod,
|
|
1439
|
+
disabled: !mounted,
|
|
1440
|
+
closeOnFocusOut: !disablePointerDismissal,
|
|
1441
|
+
initialFocus: resolvedInitialFocus,
|
|
1442
|
+
returnFocus: finalFocus,
|
|
1443
|
+
modal: modal !== false,
|
|
1444
|
+
restoreFocus: "popup",
|
|
1445
|
+
children: element
|
|
1455
1446
|
});
|
|
1456
1447
|
});
|
|
1457
|
-
if (process.env.NODE_ENV !== "production")
|
|
1448
|
+
if (process.env.NODE_ENV !== "production") DrawerPopup.displayName = "DrawerPopup";
|
|
1449
|
+
|
|
1450
|
+
/**
|
|
1451
|
+
* A portal element that moves the popup to a different part of the DOM.
|
|
1452
|
+
* By default, the portal element is appended to `<body>`.
|
|
1453
|
+
* Renders a `<div>` element.
|
|
1454
|
+
*
|
|
1455
|
+
* Documentation: [Base UI Drawer](https://base-ui.com/react/components/drawer)
|
|
1456
|
+
*/
|
|
1457
|
+
const DrawerPortal = DialogPortal;
|
|
1458
1458
|
|
|
1459
1459
|
var _DrawerProviderReport, _DrawerProviderReport2;
|
|
1460
1460
|
/**
|
|
@@ -2534,7 +2534,10 @@ function mergeHiddenState(prevState, nextState) {
|
|
|
2534
2534
|
|
|
2535
2535
|
exports.COMPOSITE_KEYS = COMPOSITE_KEYS;
|
|
2536
2536
|
exports.DRAWER_CONTENT_ATTRIBUTE = DRAWER_CONTENT_ATTRIBUTE;
|
|
2537
|
+
exports.DialogPortal = DialogPortal;
|
|
2538
|
+
exports.DialogRoot = DialogRoot;
|
|
2537
2539
|
exports.DialogStore = DialogStore;
|
|
2540
|
+
exports.DialogTrigger = DialogTrigger;
|
|
2538
2541
|
exports.DrawerBackdrop = DrawerBackdrop;
|
|
2539
2542
|
exports.DrawerBackdropCssVars = DrawerBackdropCssVars;
|
|
2540
2543
|
exports.DrawerContent = DrawerContent;
|