"use client"; // src/dialog.tsx import * as React from "react"; import { composeEventHandlers } from "@radix-ui/primitive"; import { useComposedRefs } from "@radix-ui/react-compose-refs"; import { createContextScope } from "@radix-ui/react-context"; import { useId } from "@radix-ui/react-id"; import { useControllableState } from "@radix-ui/react-use-controllable-state"; import { DismissableLayer, useDismissableLayerSurface } from "@radix-ui/react-dismissable-layer"; import { FocusScope } from "@radix-ui/react-focus-scope"; import { Portal as PortalPrimitive } from "@radix-ui/react-portal"; import { Presence } from "@radix-ui/react-presence"; import { Primitive } from "@radix-ui/react-primitive"; import { useFocusGuards } from "@radix-ui/react-focus-guards"; import { RemoveScroll } from "react-remove-scroll"; import { hideOthers } from "aria-hidden"; import { createSlot } from "@radix-ui/react-slot"; import { Fragment, jsx } from "react/jsx-runtime"; var DIALOG_NAME = "Dialog"; var [createDialogContext, createDialogScope] = createContextScope(DIALOG_NAME); var [DialogProvider, useDialogContext] = createDialogContext(DIALOG_NAME); var Dialog = (props) => { const { __scopeDialog, children, open: openProp, defaultOpen, onOpenChange, modal = true } = props; const triggerRef = React.useRef(null); const contentRef = React.useRef(null); const [open, setOpen] = useControllableState({ prop: openProp, defaultProp: defaultOpen ?? false, onChange: onOpenChange, caller: DIALOG_NAME }); return /* @__PURE__ */ jsx( DialogProvider, { scope: __scopeDialog, triggerRef, contentRef, contentId: useId(), titleId: useId(), descriptionId: useId(), open, onOpenChange: setOpen, onOpenToggle: React.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]), modal, children } ); }; Dialog.displayName = DIALOG_NAME; var TRIGGER_NAME = "DialogTrigger"; var DialogTrigger = React.forwardRef( (props, forwardedRef) => { const { __scopeDialog, ...triggerProps } = props; const context = useDialogContext(TRIGGER_NAME, __scopeDialog); const composedTriggerRef = useComposedRefs(forwardedRef, context.triggerRef); return /* @__PURE__ */ jsx( Primitive.button, { type: "button", "aria-haspopup": "dialog", "aria-expanded": context.open, "aria-controls": context.open ? context.contentId : void 0, "data-state": getState(context.open), ...triggerProps, ref: composedTriggerRef, onClick: composeEventHandlers(props.onClick, context.onOpenToggle) } ); } ); DialogTrigger.displayName = TRIGGER_NAME; var PORTAL_NAME = "DialogPortal"; var [PortalProvider, usePortalContext] = createDialogContext(PORTAL_NAME, { forceMount: void 0 }); var DialogPortal = (props) => { const { __scopeDialog, forceMount, children, container } = props; const context = useDialogContext(PORTAL_NAME, __scopeDialog); return /* @__PURE__ */ jsx(PortalProvider, { scope: __scopeDialog, forceMount, children: React.Children.map(children, (child) => /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(PortalPrimitive, { asChild: true, container, children: child }) })) }); }; DialogPortal.displayName = PORTAL_NAME; var OVERLAY_NAME = "DialogOverlay"; var DialogOverlay = React.forwardRef( (props, forwardedRef) => { const portalContext = usePortalContext(OVERLAY_NAME, props.__scopeDialog); const { forceMount = portalContext.forceMount, ...overlayProps } = props; const context = useDialogContext(OVERLAY_NAME, props.__scopeDialog); return context.modal ? /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(DialogOverlayImpl, { ...overlayProps, ref: forwardedRef }) }) : null; } ); DialogOverlay.displayName = OVERLAY_NAME; var Slot = createSlot("DialogOverlay.RemoveScroll"); var DialogOverlayImpl = React.forwardRef( (props, forwardedRef) => { const { __scopeDialog, ...overlayProps } = props; const context = useDialogContext(OVERLAY_NAME, __scopeDialog); const registerDismissableSurface = useDismissableLayerSurface(); const composedRefs = useComposedRefs(forwardedRef, registerDismissableSurface); return ( // Make sure `Content` is scrollable even when it doesn't live inside `RemoveScroll` // ie. when `Overlay` and `Content` are siblings /* @__PURE__ */ jsx(RemoveScroll, { as: Slot, allowPinchZoom: true, shards: [context.contentRef], children: /* @__PURE__ */ jsx( Primitive.div, { "data-state": getState(context.open), ...overlayProps, ref: composedRefs, style: { pointerEvents: "auto", ...overlayProps.style } } ) }) ); } ); var CONTENT_NAME = "DialogContent"; var DialogContent = React.forwardRef( (props, forwardedRef) => { const portalContext = usePortalContext(CONTENT_NAME, props.__scopeDialog); const { forceMount = portalContext.forceMount, ...contentProps } = props; const context = useDialogContext(CONTENT_NAME, props.__scopeDialog); return /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: context.modal ? /* @__PURE__ */ jsx(DialogContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx(DialogContentNonModal, { ...contentProps, ref: forwardedRef }) }); } ); DialogContent.displayName = CONTENT_NAME; var DialogContentModal = React.forwardRef( (props, forwardedRef) => { const context = useDialogContext(CONTENT_NAME, props.__scopeDialog); const contentRef = React.useRef(null); const composedRefs = useComposedRefs(forwardedRef, context.contentRef, contentRef); React.useEffect(() => { const content = contentRef.current; if (content) return hideOthers(content); }, []); return /* @__PURE__ */ jsx( DialogContentImpl, { ...props, ref: composedRefs, trapFocus: context.open, disableOutsidePointerEvents: context.open, onCloseAutoFocus: composeEventHandlers(props.onCloseAutoFocus, (event) => { event.preventDefault(); context.triggerRef.current?.focus(); }), onPointerDownOutside: composeEventHandlers(props.onPointerDownOutside, (event) => { const originalEvent = event.detail.originalEvent; const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true; const isRightClick = originalEvent.button === 2 || ctrlLeftClick; if (isRightClick) event.preventDefault(); }), onFocusOutside: composeEventHandlers( props.onFocusOutside, (event) => event.preventDefault() ) } ); } ); var DialogContentNonModal = React.forwardRef( (props, forwardedRef) => { const context = useDialogContext(CONTENT_NAME, props.__scopeDialog); const hasInteractedOutsideRef = React.useRef(false); const hasPointerDownOutsideRef = React.useRef(false); return /* @__PURE__ */ jsx( DialogContentImpl, { ...props, ref: forwardedRef, trapFocus: false, disableOutsidePointerEvents: false, onCloseAutoFocus: (event) => { props.onCloseAutoFocus?.(event); if (!event.defaultPrevented) { if (!hasInteractedOutsideRef.current) context.triggerRef.current?.focus(); event.preventDefault(); } hasInteractedOutsideRef.current = false; hasPointerDownOutsideRef.current = false; }, onInteractOutside: (event) => { props.onInteractOutside?.(event); if (!event.defaultPrevented) { hasInteractedOutsideRef.current = true; if (event.detail.originalEvent.type === "pointerdown") { hasPointerDownOutsideRef.current = true; } } const target = event.target; const targetIsTrigger = context.triggerRef.current?.contains(target); if (targetIsTrigger) event.preventDefault(); if (event.detail.originalEvent.type === "focusin" && hasPointerDownOutsideRef.current) { event.preventDefault(); } } } ); } ); var DialogContentImpl = React.forwardRef( (props, forwardedRef) => { const { __scopeDialog, trapFocus, onOpenAutoFocus, onCloseAutoFocus, ...contentProps } = props; const context = useDialogContext(CONTENT_NAME, __scopeDialog); useFocusGuards(); return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx( FocusScope, { asChild: true, loop: true, trapped: trapFocus, onMountAutoFocus: onOpenAutoFocus, onUnmountAutoFocus: onCloseAutoFocus, children: /* @__PURE__ */ jsx( DismissableLayer, { role: "dialog", id: context.contentId, "aria-describedby": context.descriptionId, "aria-labelledby": context.titleId, "data-state": getState(context.open), ...contentProps, ref: forwardedRef, deferPointerDownOutside: true, onDismiss: () => context.onOpenChange(false) } ) } ) }); } ); var TITLE_NAME = "DialogTitle"; var DialogTitle = React.forwardRef( (props, forwardedRef) => { const { __scopeDialog, ...titleProps } = props; const context = useDialogContext(TITLE_NAME, __scopeDialog); return /* @__PURE__ */ jsx(Primitive.h2, { id: context.titleId, ...titleProps, ref: forwardedRef }); } ); DialogTitle.displayName = TITLE_NAME; var DESCRIPTION_NAME = "DialogDescription"; var DialogDescription = React.forwardRef( (props, forwardedRef) => { const { __scopeDialog, ...descriptionProps } = props; const context = useDialogContext(DESCRIPTION_NAME, __scopeDialog); return /* @__PURE__ */ jsx(Primitive.p, { id: context.descriptionId, ...descriptionProps, ref: forwardedRef }); } ); DialogDescription.displayName = DESCRIPTION_NAME; var CLOSE_NAME = "DialogClose"; var DialogClose = React.forwardRef( (props, forwardedRef) => { const { __scopeDialog, ...closeProps } = props; const context = useDialogContext(CLOSE_NAME, __scopeDialog); return /* @__PURE__ */ jsx( Primitive.button, { type: "button", ...closeProps, ref: forwardedRef, onClick: composeEventHandlers(props.onClick, () => context.onOpenChange(false)) } ); } ); DialogClose.displayName = CLOSE_NAME; var WarningProvider = (props) => { return props.children; }; function getState(open) { return open ? "open" : "closed"; } export { DialogClose as Close, DialogContent as Content, DialogDescription as Description, Dialog, DialogClose, DialogContent, DialogDescription, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DialogOverlay as Overlay, DialogPortal as Portal, Dialog as Root, DialogTitle as Title, DialogTrigger as Trigger, WarningProvider, createDialogScope }; //# sourceMappingURL=index.mjs.map