{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "dialog", "type": "registry:ui", "title": "Dialog", "description": "A customizable dialog component", "dependencies": [ "clsx", "tailwind-merge", "@base-ui/react", "lucide-react" ], "registryDependencies": [ "classes" ], "files": [ { "path": "src/registry/pure-ui/ui/dialog/index.tsx", "content": "\"use client\";\r\n\r\nimport { createContext, useContext, useMemo } from \"react\";\r\nimport { Dialog as DialogPrimitive } from \"@base-ui/react/dialog\";\r\nimport { XIcon } from \"lucide-react\";\r\n\r\nimport { cn } from \"@/lib/classes\";\r\n\r\nconst cssAnimationPresets = {\r\n none: \"transition-none\",\r\n scale: [\r\n `[transition-property:scale,opacity,translate] [will-change:scale,opacity,translate]`,\r\n `data-starting-style:opacity-0 data-ending-style:opacity-0 max-sm:opacity-[calc(1-min(var(--nested-dialogs),1))] max-sm:data-starting-style:translate-y-4 max-sm:data-ending-style:translate-y-4 max-sm:data-starting-style:scale-98 max-sm:data-ending-style:scale-98 max-sm:origin-bottom`,\r\n `sm:-translate-y-[calc(2rem*var(--nested-dialogs))] sm:scale-[calc(1-0.1*var(--nested-dialogs))] sm:data-starting-style:scale-98 sm:data-ending-style:scale-98 sm:data-nested:data-ending-style:translate-y-8 sm:data-nested:data-starting-style:translate-y-8`,\r\n ],\r\n fade: [\r\n `[transition-property:opacity,translate,scale] [will-change:opacity,translate,scale]`,\r\n `data-starting-style:opacity-0 data-ending-style:opacity-0 max-sm:opacity-[calc(1-min(var(--nested-dialogs),1))] max-sm:data-starting-style:translate-y-4 max-sm:data-ending-style:translate-y-4`,\r\n `sm:-translate-y-[calc(2rem*var(--nested-dialogs))] sm:scale-[calc(1-0.1*var(--nested-dialogs))]`,\r\n ],\r\n topFlip: [\r\n `[transition-property:opacity,filter,transform,translate,scale] [will-change:opacity,filter,transform,translate,scale]`,\r\n `data-starting-style:opacity-0 data-ending-style:opacity-0 data-starting-style:blur-[4px] data-ending-style:blur-[4px] data-starting-style:transform-[perspective(1000px)_rotateX(50deg)_scale(0.8)] data-ending-style:transform-[perspective(1000px)_rotateX(50deg)_scale(0.8)]`,\r\n `sm:translate-y-[calc(3.5rem*var(--nested-dialogs))] sm:scale-[calc(1-0.1*var(--nested-dialogs))]`,\r\n ],\r\n bottomFlip: [\r\n `[transition-property:opacity,filter,transform,translate,scale] [will-change:opacity,filter,transform,translate,scale]`,\r\n `data-starting-style:opacity-0 data-ending-style:opacity-0 data-starting-style:blur-[4px] data-ending-style:blur-[4px] data-starting-style:transform-[perspective(1000px)_rotateX(-50deg)_scale(0.8)] data-ending-style:transform-[perspective(1000px)_rotateX(-50deg)_scale(0.8)]`,\r\n `sm:-translate-y-[calc(2rem*var(--nested-dialogs))] sm:scale-[calc(1-0.1*var(--nested-dialogs))]`,\r\n ],\r\n rightFlip: [\r\n `[transition-property:opacity,filter,transform,translate,scale] [will-change:opacity,filter,transform,translate,scale]`,\r\n `data-starting-style:opacity-0 data-ending-style:opacity-0 data-starting-style:blur-[4px] data-ending-style:blur-[4px] data-starting-style:transform-[perspective(1000px)_rotateY(50deg)_scale(0.8)] data-ending-style:transform-[perspective(1000px)_rotateY(50deg)_scale(0.8)]`,\r\n `sm:-translate-x-[calc(2.5rem*var(--nested-dialogs))] sm:scale-[calc(1-0.1*var(--nested-dialogs))]`,\r\n ],\r\n leftFlip: [\r\n `[transition-property:opacity,filter,transform,translate,scale] [will-change:opacity,filter,transform,translate,scale]`,\r\n `data-starting-style:opacity-0 data-ending-style:opacity-0 data-starting-style:blur-[4px] data-ending-style:blur-[4px] data-starting-style:transform-[perspective(1000px)_rotateY(-50deg)_scale(0.8)] data-ending-style:transform-[perspective(1000px)_rotateY(-50deg)_scale(0.8)]`,\r\n `sm:translate-x-[calc(2.5rem*var(--nested-dialogs))] sm:scale-[calc(1-0.1*var(--nested-dialogs))]`,\r\n ],\r\n topSlide: [\r\n `[transition-property:opacity,transform,translate,scale] [will-change:opacity,transform,translate,scale]`,\r\n `data-starting-style:opacity-0 data-ending-style:opacity-0 data-starting-style:translate-y-[-20px] data-ending-style:translate-y-[-20px] max-sm:data-starting-style:-translate-y-4 max-sm:data-ending-style:-translate-y-4`,\r\n `sm:translate-y-[calc(3.5rem*var(--nested-dialogs))] sm:scale-[calc(1-0.1*var(--nested-dialogs))]`,\r\n ],\r\n bottomSlide: [\r\n `[transition-property:opacity,transform,translate,scale] [will-change:opacity,transform,translate,scale]`,\r\n `data-starting-style:opacity-0 data-ending-style:opacity-0 data-starting-style:translate-y-[20px] data-ending-style:translate-y-[20px] max-sm:data-starting-style:translate-y-4 max-sm:data-ending-style:translate-y-4`,\r\n `sm:-translate-y-[calc(2rem*var(--nested-dialogs))] sm:scale-[calc(1-0.1*var(--nested-dialogs))]`,\r\n ],\r\n leftSlide: [\r\n `[transition-property:opacity,transform,translate,scale] [will-change:opacity,transform,translate,scale]`,\r\n `data-starting-style:opacity-0 data-ending-style:opacity-0 data-starting-style:translate-x-[-20px] data-ending-style:translate-x-[-20px] max-sm:data-starting-style:-translate-x-4 max-sm:data-ending-style:-translate-x-4`,\r\n `sm:translate-x-[calc(2.5rem*var(--nested-dialogs))] sm:scale-[calc(1-0.1*var(--nested-dialogs))]`,\r\n ],\r\n rightSlide: [\r\n `[transition-property:opacity,transform,translate,scale] [will-change:opacity,transform,translate,scale]`,\r\n `data-starting-style:opacity-0 data-ending-style:opacity-0 data-starting-style:translate-x-[20px] data-ending-style:translate-x-[20px] max-sm:data-starting-style:translate-x-4 max-sm:data-ending-style:translate-x-4`,\r\n `sm:-translate-x-[calc(2.5rem*var(--nested-dialogs))] sm:scale-[calc(1-0.1*var(--nested-dialogs))]`,\r\n ],\r\n wipe: [\r\n `[transition-property:clip-path,translate,scale] [will-change:clip-path,translate,scale] [clip-path:inset(0_0_0_0_round_12px)] [-webkit-clip-path:inset(0_0_0_0_round_12px)]`,\r\n `data-starting-style:[clip-path:inset(0_0_100%_0_round_12px)] data-ending-style:[clip-path:inset(0_0_100%_0_round_12px)]`,\r\n `sm:-translate-y-[calc(2rem*var(--nested-dialogs))] sm:scale-[calc(1-0.1*var(--nested-dialogs))]`,\r\n ],\r\n};\r\n\r\nconst cssTransitionPresets = {\r\n inExpo: `duration-[0.35s] ease-[cubic-bezier(0.95,0.05,0.795,0.035)]`,\r\n outExpo: `duration-[0.35s] ease-[cubic-bezier(0.19,1,0.22,1)]`,\r\n inOutExpo: `duration-[0.35s] ease-[cubic-bezier(1,0,0,1)]`,\r\n anticipate: `duration-[0.35s] ease-[cubic-bezier(1,-0.4,0.35,0.95)]`,\r\n quickOut: `duration-[0.35s] ease-out`,\r\n overshootOut: `duration-[0.35s] ease-[cubic-bezier(0.175,0.885,0.32,1.275)]`,\r\n swiftOut: `duration-[0.35s] ease-[cubic-bezier(0.175,0.885,0.32,1.1)]`,\r\n snappyOut: `duration-[0.35s] ease-[cubic-bezier(0.19,1,0.22,1)]`,\r\n in: `duration-[0.35s] ease-[cubic-bezier(0.42,0,1,1)]`,\r\n out: `duration-[0.35s] ease-[cubic-bezier(0,0,0.58,1)]`,\r\n inOut: `duration-[0.25s] ease-[cubic-bezier(0.42,0,0.58,1)]`,\r\n outIn: `duration-[0.35s] ease-[cubic-bezier(0.1,0.7,0.9,0.5)]`,\r\n inQuad: `duration-[0.35s] ease-[cubic-bezier(0.55,0.085,0.68,0.53)]`,\r\n outQuad: `duration-[0.25s] ease-[cubic-bezier(0.25,0.46,0.45,0.94)]`,\r\n inOutQuad: `duration-[0.32s] ease-[cubic-bezier(0.455,0.03,0.515,0.955)]`,\r\n inCubic: `duration-[0.35s] ease-[cubic-bezier(0.55,0.055,0.675,0.19)]`,\r\n outCubic: `duration-[0.35s] ease-[cubic-bezier(0.215,0.61,0.355,1)]`,\r\n inOutCubic: `duration-[0.35s] ease-[cubic-bezier(0.645,0.045,0.355,1)]`,\r\n inQuart: `duration-[0.35s] ease-[cubic-bezier(0.895,0.03,0.685,0.22)]`,\r\n outQuart: `duration-[0.35s] ease-[cubic-bezier(0.165,0.84,0.44,1)]`,\r\n inOutQuart: `duration-[0.35s] ease-[cubic-bezier(0.77,0,0.175,1)]`,\r\n inQuint: `duration-[0.35s] ease-[cubic-bezier(0.755,0.05,0.855,0.06)]`,\r\n outQuint: `duration-[0.35s] ease-[cubic-bezier(0.23,1,0.32,1)]`,\r\n inOutQuint: `duration-[0.35s] ease-[cubic-bezier(0.86,0,0.07,1)]`,\r\n inCirc: `duration-[0.35s] ease-[cubic-bezier(0.6,0.04,0.98,0.335)]`,\r\n outCirc: `duration-[0.35s] ease-[cubic-bezier(0.075,0.82,0.165,1)]`,\r\n inOutCirc: `duration-[0.35s] ease-[cubic-bezier(0.785,0.135,0.15,0.86)]`,\r\n inOutBase: `duration-[0.35s] ease-[cubic-bezier(0.25,0.1,0.25,1)]`,\r\n};\r\n\r\ntype CSSAnimationPresets = keyof typeof cssAnimationPresets;\r\ntype CSSTransitionPresets = keyof typeof cssTransitionPresets;\r\n\r\ninterface DialogContextType {\r\n modal: DialogProps[\"modal\"];\r\n}\r\n\r\nconst DialogContext = createContext(undefined);\r\n\r\nfunction useDialog() {\r\n const context = useContext(DialogContext);\r\n if (!context) {\r\n throw new Error(\"useDialog must be used within a DialogProvider\");\r\n }\r\n return context;\r\n}\r\n\r\ninterface DialogProps\r\n extends DialogPrimitive.Root.Props {}\r\n\r\nfunction Dialog({\r\n modal = true,\r\n ...props\r\n}: DialogProps) {\r\n return (\r\n \r\n \r\n \r\n );\r\n}\r\n\r\ninterface DialogTriggerProps extends DialogPrimitive.Trigger.Props {}\r\n\r\nfunction DialogTrigger({ ...props }: DialogTriggerProps) {\r\n return ;\r\n}\r\n\r\ninterface DialogViewportProps extends DialogPrimitive.Viewport.Props {}\r\n\r\nfunction DialogViewport({ ...props }: DialogViewportProps) {\r\n return ;\r\n}\r\n\r\ninterface DialogPortalProps extends DialogPrimitive.Portal.Props {}\r\n\r\nfunction DialogPortal(props: DialogPortalProps) {\r\n return ;\r\n}\r\n\r\ninterface DialogBackdropProps extends DialogPrimitive.Backdrop.Props {}\r\n\r\nfunction DialogBackdrop({ className, ...props }: DialogBackdropProps) {\r\n return (\r\n \r\n }\r\n {...props}\r\n />\r\n );\r\n}\r\n\r\ninterface DialogPopupProps extends DialogPrimitive.Popup.Props {\r\n animationPreset?: CSSAnimationPresets;\r\n transitionPreset?: CSSTransitionPresets;\r\n reduceMotion?: boolean;\r\n showCloseButton?: boolean;\r\n}\r\n\r\nfunction DialogPopup({\r\n className,\r\n animationPreset = \"scale\",\r\n transitionPreset = \"outCubic\",\r\n children,\r\n reduceMotion = false,\r\n showCloseButton = true,\r\n ...rest\r\n}: DialogPopupProps) {\r\n const { modal } = useDialog();\r\n\r\n const cssAnimationConfig = useMemo(() => {\r\n if (reduceMotion) return \"none\";\r\n\r\n if (animationPreset) {\r\n return cssAnimationPresets[animationPreset];\r\n }\r\n\r\n return cssAnimationPresets.scale;\r\n }, [animationPreset, reduceMotion]);\r\n\r\n const cssTransitionConfig = useMemo(() => {\r\n if (reduceMotion) return \"none\";\r\n\r\n if (transitionPreset) {\r\n return cssTransitionPresets[transitionPreset];\r\n }\r\n\r\n return cssTransitionPresets.snappyOut;\r\n }, [transitionPreset, reduceMotion]);\r\n\r\n return (\r\n \r\n {modal && }\r\n
\r\n
\r\n \r\n {children}\r\n {showCloseButton && (\r\n \r\n \r\n Close\r\n \r\n )}\r\n
\r\n }\r\n {...rest}\r\n />\r\n
\r\n \r\n
\r\n );\r\n}\r\n\r\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n \r\n );\r\n}\r\n\r\nfunction DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\r\n return (\r\n \r\n );\r\n}\r\n\r\nfunction DialogTitle({ className, ...props }: DialogPrimitive.Title.Props) {\r\n return (\r\n \r\n );\r\n}\r\n\r\nfunction DialogDescription({\r\n className,\r\n ...props\r\n}: DialogPrimitive.Description.Props) {\r\n return (\r\n \r\n );\r\n}\r\n\r\ninterface DialogCloseProps extends DialogPrimitive.Close.Props {}\r\n\r\nfunction DialogClose(props: DialogCloseProps) {\r\n return ;\r\n}\r\n\r\nexport {\r\n Dialog,\r\n DialogClose,\r\n DialogPopup,\r\n DialogDescription,\r\n DialogFooter,\r\n DialogHeader,\r\n DialogBackdrop,\r\n DialogViewport,\r\n DialogPortal,\r\n DialogTitle,\r\n DialogTrigger,\r\n};\r\n", "type": "registry:ui", "target": "components/ui/dialog.tsx" } ] }