{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "dialog",
  "title": "UI Dialog",
  "description": "A modal dialog whose opened/closed state is a pure function of the timeline; the backdrop dim and popup zoom are keyframed presets, with a close button and a primary action. Self-contained — pair it with the Button as a trigger (see the example).",
  "dependencies": ["remotion"],
  "registryDependencies": ["@remocn/remocn-ui"],
  "files": [
    {
      "path": "registry/remocn-ui/dialog/index.tsx",
      "content": "\"use client\";\n\nimport { type RemocnTheme, useRemocnTheme } from \"@/lib/remocn-ui\";\n\nexport type DialogState = \"opened\" | \"closed\";\n\nexport interface DialogProps {\n  state?: DialogState;\n  style?: DialogStyle;\n  title?: string;\n  description?: string;\n  actionLabel?: string;\n  cancelLabel?: string;\n  theme?: Partial<RemocnTheme>;\n  className?: string;\n}\n\nconst POPUP_WIDTH = 440;\nconst MAX_OVERLAY_ALPHA = 0.5;\n\nexport interface DialogStyle {\n  overlayOpacity: number;\n  popupOpacity: number;\n  popupScale: number;\n  popupTranslateY: number;\n}\n\nexport interface DialogStyleContext {\n  popoverBg: string;\n  popoverFg: string;\n  mutedFg: string;\n  border: string;\n  radius: number;\n  actionBg: string;\n  actionFg: string;\n  cancelFg: string;\n}\n\nexport function dialogStyleContext(theme: RemocnTheme): DialogStyleContext {\n  return {\n    popoverBg: theme.popover,\n    popoverFg: theme.popoverForeground,\n    mutedFg: theme.mutedForeground,\n    border: theme.border,\n    radius: theme.radius,\n    actionBg: theme.primary,\n    actionFg: theme.primaryForeground,\n    cancelFg: theme.foreground,\n  };\n}\n\nexport function dialogStyle(\n  state: DialogState,\n  _ctx: DialogStyleContext,\n): DialogStyle {\n  switch (state) {\n    case \"opened\":\n      return {\n        overlayOpacity: 1,\n        popupOpacity: 1,\n        popupScale: 1,\n        popupTranslateY: 0,\n      };\n    default:\n      return {\n        overlayOpacity: 0,\n        popupOpacity: 0,\n        popupScale: 0.95,\n        popupTranslateY: 8,\n      };\n  }\n}\n\nexport function Dialog({\n  state = \"closed\",\n  style,\n  title = \"Edit profile\",\n  description = \"Make changes to your profile here. Click save when you're done.\",\n  actionLabel = \"Save changes\",\n  cancelLabel = \"Cancel\",\n  theme: themeOverride,\n  className,\n}: DialogProps) {\n  const theme = useRemocnTheme(themeOverride, \"light\");\n\n  const ctx = dialogStyleContext(theme);\n  const v = style ?? dialogStyle(state, ctx);\n\n  const buttonBase: React.CSSProperties = {\n    height: 40,\n    padding: \"0 20px\",\n    fontSize: 15,\n    fontWeight: 500,\n    letterSpacing: \"-0.01em\",\n    borderRadius: ctx.radius,\n    display: \"inline-flex\",\n    alignItems: \"center\",\n    justifyContent: \"center\",\n    cursor: \"pointer\",\n  };\n\n  return (\n    <div\n      style={{\n        position: \"absolute\",\n        inset: 0,\n        display: \"flex\",\n        alignItems: \"center\",\n        justifyContent: \"center\",\n        fontFamily:\n          \"var(--font-geist-sans), -apple-system, BlinkMacSystemFont, sans-serif\",\n      }}\n    >\n      {}\n      <div\n        style={{\n          position: \"absolute\",\n          inset: 0,\n          background: `rgba(0, 0, 0, ${MAX_OVERLAY_ALPHA * v.overlayOpacity})`,\n        }}\n      />\n      <div\n        className={className}\n        style={{\n          position: \"relative\",\n          width: POPUP_WIDTH,\n          transform: `translateY(${v.popupTranslateY}px) scale(${v.popupScale})`,\n          opacity: v.popupOpacity,\n          background: ctx.popoverBg,\n          color: ctx.popoverFg,\n          border: `1px solid ${ctx.border}`,\n          borderRadius: ctx.radius + 6,\n          padding: 24,\n          display: \"flex\",\n          flexDirection: \"column\",\n          gap: 8,\n          boxShadow: \"0 24px 48px -12px rgba(0,0,0,0.25)\",\n        }}\n      >\n        {}\n        <button\n          type=\"button\"\n          style={{\n            position: \"absolute\",\n            top: 16,\n            right: 16,\n            width: 28,\n            height: 28,\n            display: \"inline-flex\",\n            alignItems: \"center\",\n            justifyContent: \"center\",\n            background: \"transparent\",\n            border: \"none\",\n            borderRadius: ctx.radius,\n            color: ctx.mutedFg,\n            cursor: \"pointer\",\n          }}\n        >\n          <svg width={16} height={16} viewBox=\"0 0 24 24\" fill=\"none\">\n            <path\n              d=\"M18 6 6 18 M6 6 18 18\"\n              stroke={ctx.mutedFg}\n              strokeWidth=\"2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n            />\n          </svg>\n        </button>\n        <div\n          style={{\n            fontSize: 18,\n            fontWeight: 500,\n            letterSpacing: \"-0.01em\",\n            paddingRight: 28,\n          }}\n        >\n          {title}\n        </div>\n        <div style={{ fontSize: 14, lineHeight: 1.5, color: ctx.mutedFg }}>\n          {description}\n        </div>\n        <div\n          style={{\n            display: \"flex\",\n            justifyContent: \"flex-end\",\n            gap: 8,\n            marginTop: 16,\n          }}\n        >\n          {}\n          <button\n            type=\"button\"\n            style={{\n              ...buttonBase,\n              background: \"transparent\",\n              color: ctx.cancelFg,\n              border: `1px solid ${ctx.border}`,\n            }}\n          >\n            {cancelLabel}\n          </button>\n          {}\n          <button\n            type=\"button\"\n            style={{\n              ...buttonBase,\n              background: ctx.actionBg,\n              color: ctx.actionFg,\n              border: \"1px solid transparent\",\n            }}\n          >\n            {actionLabel}\n          </button>\n        </div>\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/remocn/dialog.tsx"
    },
    {
      "path": "registry/remocn-ui/dialog/use-dialog-transition.ts",
      "content": "\"use client\";\n\nimport {\n  type DialogState,\n  type DialogStyle,\n  dialogStyle,\n  dialogStyleContext,\n} from \"@/components/remocn/dialog\";\nimport {\n  easings,\n  type RemocnTheme,\n  type Step,\n  useRemocnTheme,\n  useStateTransition,\n} from \"@/lib/remocn-ui\";\n\nexport const DEFAULT_DURATION = 12;\n\nexport function tweenDialogStyle(\n  a: DialogStyle,\n  b: DialogStyle,\n  t: number,\n): DialogStyle {\n  return {\n    overlayOpacity:\n      a.overlayOpacity + (b.overlayOpacity - a.overlayOpacity) * t,\n    popupOpacity: a.popupOpacity + (b.popupOpacity - a.popupOpacity) * t,\n    popupScale: a.popupScale + (b.popupScale - a.popupScale) * t,\n    popupTranslateY:\n      a.popupTranslateY + (b.popupTranslateY - a.popupTranslateY) * t,\n  };\n}\n\nexport interface DialogTransitionOptions {\n  theme?: Partial<RemocnTheme>;\n  mode?: \"light\" | \"dark\";\n  speed?: number;\n  defaultDuration?: number;\n}\n\nexport function useDialogTransition(\n  steps: Step<DialogState>[],\n  opts: DialogTransitionOptions = {},\n): DialogStyle {\n  const {\n    theme: themeOverride,\n    mode,\n    speed = 1,\n    defaultDuration = DEFAULT_DURATION,\n  } = opts;\n  const theme = useRemocnTheme(themeOverride, mode);\n  const ctx = dialogStyleContext(theme);\n  const { from, to, progress } = useStateTransition(\n    steps,\n    \"closed\",\n    speed,\n    defaultDuration,\n  );\n  const t = easings.out(progress);\n  return tweenDialogStyle(dialogStyle(from, ctx), dialogStyle(to, ctx), t);\n}\n",
      "type": "registry:component",
      "target": "components/remocn/use-dialog-transition.ts"
    }
  ],
  "type": "registry:component"
}
