UNPKG

ivt

Version:

Ivt Components Library

324 lines (319 loc) 13.3 kB
import * as React from 'react'; import { P as Primitive, c as composeEventHandlers } from './index-Dsw02Eup.mjs'; import { c as createContextScope, a as createContext2, u as useComposedRefs } from './index-D4jPaBZ2.mjs'; import { u as useId } from './index-gX0V59dZ.mjs'; import { u as useControllableState } from './index-1toTCGyr.mjs'; import { D as DismissableLayer } from './index-4NpeUekv.mjs'; import { h as hideOthers, R as ReactRemoveScroll, u as useFocusGuards, F as FocusScope } from './index-z4Hk6sF4.mjs'; import { P as Portal$1 } from './index-BksCjWh6.mjs'; import { P as Presence } from './index-DfeRLazC.mjs'; import { createSlot } from '@radix-ui/react-slot'; import { jsx, jsxs, Fragment } 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.contentId, "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(Portal$1, { 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); return(// Make sure `Content` is scrollable even when it doesn't live inside `RemoveScroll` // ie. when `Overlay` and `Content` are siblings /* @__PURE__ */ jsx(ReactRemoveScroll, { as: Slot, allowPinchZoom: true, shards: [ context.contentRef ], children: /* @__PURE__ */ jsx(Primitive.div, { "data-state": getState(context.open), ...overlayProps, ref: forwardedRef, 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: true, 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); const contentRef = React.useRef(null); const composedRefs = useComposedRefs(forwardedRef, contentRef); useFocusGuards(); return /* @__PURE__ */ jsxs(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: composedRefs, onDismiss: ()=>context.onOpenChange(false) }) }), /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx(TitleWarning, { titleId: context.titleId }), /* @__PURE__ */ jsx(DescriptionWarning, { contentRef, descriptionId: context.descriptionId }) ] }) ] }); }); 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; function getState(open) { return open ? "open" : "closed"; } var TITLE_WARNING_NAME = "DialogTitleWarning"; var [WarningProvider, useWarningContext] = createContext2(TITLE_WARNING_NAME, { contentName: CONTENT_NAME, titleName: TITLE_NAME, docsSlug: "dialog" }); var TitleWarning = ({ titleId })=>{ const titleWarningContext = useWarningContext(TITLE_WARNING_NAME); const MESSAGE = `\`${titleWarningContext.contentName}\` requires a \`${titleWarningContext.titleName}\` for the component to be accessible for screen reader users. If you want to hide the \`${titleWarningContext.titleName}\`, you can wrap it with our VisuallyHidden component. For more information, see https://radix-ui.com/primitives/docs/components/${titleWarningContext.docsSlug}`; React.useEffect(()=>{ if (titleId) { const hasTitle = document.getElementById(titleId); if (!hasTitle) console.error(MESSAGE); } }, [ MESSAGE, titleId ]); return null; }; var DESCRIPTION_WARNING_NAME = "DialogDescriptionWarning"; var DescriptionWarning = ({ contentRef, descriptionId })=>{ const descriptionWarningContext = useWarningContext(DESCRIPTION_WARNING_NAME); const MESSAGE = `Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${descriptionWarningContext.contentName}}.`; React.useEffect(()=>{ const describedById = contentRef.current?.getAttribute("aria-describedby"); if (descriptionId && describedById) { const hasDescription = document.getElementById(descriptionId); if (!hasDescription) console.warn(MESSAGE); } }, [ MESSAGE, contentRef, descriptionId ]); return null; }; var Root = Dialog; var Trigger = DialogTrigger; var Portal = DialogPortal; var Overlay = DialogOverlay; var Content = DialogContent; var Title = DialogTitle; var Description = DialogDescription; var Close = DialogClose; export { Close as C, Description as D, Overlay as O, Portal as P, Root as R, Title as T, WarningProvider as W, Content as a, Trigger as b, createDialogScope as c }; //# sourceMappingURL=index-CaYwp6E6.mjs.map