{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "desktop-window",
  "description": "Wraps content in static macOS, Windows 11, or Ubuntu window chrome.",
  "dependencies": [
    "class-variance-authority"
  ],
  "registryDependencies": [
    "@ondo-ui/utils"
  ],
  "files": [
    {
      "path": "components/ui/desktop-window.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cva } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype DesktopWindowOs = \"macos\" | \"windows\" | \"ubuntu\"\n\nconst DesktopWindowContext = React.createContext<{ os: DesktopWindowOs }>({\n  os: \"macos\",\n})\n\nfunction useDesktopWindowOs() {\n  return React.useContext(DesktopWindowContext).os\n}\n\nconst desktopWindowVariants = cva(\n  \"flex flex-col overflow-hidden border border-black/10 shadow-2xl dark:border-white/10\",\n  {\n    variants: {\n      os: {\n        macos: \"rounded-[0.625rem]\",\n        windows: \"rounded-lg\",\n        ubuntu: \"rounded-xl\",\n      },\n    },\n    defaultVariants: {\n      os: \"macos\",\n    },\n  }\n)\n\nconst desktopWindowTitlebarVariants = cva(\n  \"group/titlebar relative flex shrink-0 items-center select-none\",\n  {\n    variants: {\n      os: {\n        macos:\n          \"h-7 border-b border-black/10 bg-[oklch(0.943_0_0)] px-5 dark:border-white/10 dark:bg-[oklch(0.294_0.004_286.2)]\",\n        windows:\n          \"h-8 bg-[oklch(0.964_0_0)] ps-3 pe-0 dark:bg-[oklch(0.244_0_0)]\",\n        ubuntu:\n          \"h-12 border-b border-black/10 bg-[oklch(0.94_0_0)] px-3 dark:border-white/10 dark:bg-[oklch(0.309_0_0)]\",\n      },\n    },\n    defaultVariants: {\n      os: \"macos\",\n    },\n  }\n)\n\n// macOS and Ubuntu center the title on the window, so it is taken out of flow.\n// The inset -- not padding -- reserves room for the controls, because `truncate`\n// clips at the title's own padding box: padding would leave the text free to\n// render straight over the buttons, while an inset moves the clip edge itself.\n//\n// The inset is the titlebar's horizontal padding PLUS the controls' width. An\n// absolutely positioned box resolves against its ancestor's padding box, and a\n// padding box *includes* that padding rather than excluding it, so the titlebar's\n// own `px-*` has to be added here or the title starts on top of the controls.\n//\n//   macOS   px-5 (20px) + three 12px lights + two 8px gaps  = 72px = inset-x-18\n//   Ubuntu  px-3 (12px) + three 24px buttons + two 6px gaps = 96px = inset-x-24\nconst desktopWindowTitleVariants = cva(\"truncate\", {\n  variants: {\n    os: {\n      macos:\n        \"pointer-events-none absolute inset-x-18 text-center text-[0.8125rem]/[1] font-semibold text-black/70 dark:text-white/80\",\n      windows:\n        \"min-w-0 pe-2 text-[0.75rem]/[1] font-normal text-black/80 dark:text-white/90\",\n      ubuntu:\n        \"pointer-events-none absolute inset-x-24 text-center text-[0.875rem]/[1] font-bold text-black/80 dark:text-white/90\",\n    },\n  },\n  defaultVariants: {\n    os: \"macos\",\n  },\n})\n\nconst desktopWindowControlsVariants = cva(\"flex shrink-0 items-center\", {\n  variants: {\n    os: {\n      macos: \"z-10 gap-2\",\n      windows: \"order-last ms-auto\",\n      ubuntu: \"z-10 order-last ms-auto gap-1.5\",\n    },\n  },\n  defaultVariants: {\n    os: \"macos\",\n  },\n})\n\ninterface DesktopWindowProps extends React.ComponentProps<\"div\"> {\n  os?: DesktopWindowOs\n}\n\nfunction DesktopWindow({ os = \"macos\", className, ...props }: DesktopWindowProps) {\n  const context = React.useMemo(() => ({ os }), [os])\n\n  return (\n    <DesktopWindowContext.Provider value={context}>\n      <div\n        data-slot=\"desktop-window\"\n        data-os={os}\n        className={cn(desktopWindowVariants({ os }), className)}\n        {...props}\n      />\n    </DesktopWindowContext.Provider>\n  )\n}\n\ntype DesktopWindowTitlebarProps = React.ComponentProps<\"div\">\n\nfunction DesktopWindowTitlebar({ className, ...props }: DesktopWindowTitlebarProps) {\n  const os = useDesktopWindowOs()\n\n  return (\n    <div\n      data-slot=\"desktop-window-titlebar\"\n      data-os={os}\n      className={cn(desktopWindowTitlebarVariants({ os }), className)}\n      {...props}\n    />\n  )\n}\n\ntype DesktopWindowTitleProps = React.ComponentProps<\"div\">\n\nfunction DesktopWindowTitle({ className, ...props }: DesktopWindowTitleProps) {\n  const os = useDesktopWindowOs()\n\n  return (\n    <div\n      data-slot=\"desktop-window-title\"\n      data-os={os}\n      className={cn(desktopWindowTitleVariants({ os }), className)}\n      {...props}\n    />\n  )\n}\n\ntype DesktopWindowContentProps = React.ComponentProps<\"div\">\n\nfunction DesktopWindowContent({ className, ...props }: DesktopWindowContentProps) {\n  const os = useDesktopWindowOs()\n\n  return (\n    <div\n      data-slot=\"desktop-window-content\"\n      data-os={os}\n      className={cn(\"min-w-0 flex-1 bg-background\", className)}\n      {...props}\n    />\n  )\n}\n\nconst MACOS_LIGHTS = {\n  close: { label: \"Close\", color: \"bg-[oklch(0.694_0.196_26.4)]\" },\n  minimize: { label: \"Minimize\", color: \"bg-[oklch(0.835_0.161_80.9)]\" },\n  zoom: { label: \"Zoom\", color: \"bg-[oklch(0.728_0.217_144.7)]\" },\n} as const\n\n// Windows 11 and Ubuntu draw the same three shapes; only the button around\n// them differs, so the glyph is shared rather than copied per platform.\ntype CaptionAction = \"minimize\" | \"maximize\" | \"close\"\n\nconst WINDOWS_CAPTIONS = {\n  minimize: {\n    label: \"Minimize\",\n    interactive:\n      \"hover:bg-black/[0.06] focus-visible:inset-ring-2 focus-visible:inset-ring-ring/70 dark:hover:bg-white/[0.08]\",\n  },\n  maximize: {\n    label: \"Maximize\",\n    interactive:\n      \"hover:bg-black/[0.06] focus-visible:inset-ring-2 focus-visible:inset-ring-ring/70 dark:hover:bg-white/[0.08]\",\n  },\n  close: {\n    label: \"Close\",\n    interactive:\n      \"hover:bg-[oklch(0.536_0.191_30.1)] hover:text-white focus-visible:inset-ring-2 focus-visible:inset-ring-ring/70\",\n  },\n} as const\n\nfunction DesktopWindowControl({\n  label,\n  onClick,\n  className,\n  interactive,\n  children,\n}: {\n  label: string\n  onClick?: () => void\n  className: string\n  interactive: string\n  children: React.ReactNode\n}) {\n  // Decorative by default: a mockup should not put three no-op stops in the\n  // tab order, and a hover wash on something unclickable is a lie.\n  if (!onClick) {\n    return (\n      <span aria-hidden=\"true\" className={className}>\n        {children}\n      </span>\n    )\n  }\n\n  return (\n    <button\n      type=\"button\"\n      aria-label={label}\n      onClick={onClick}\n      className={cn(\n        className,\n        interactive,\n        \"outline-none [&:focus-visible_svg]:opacity-100\"\n      )}\n    >\n      {children}\n    </button>\n  )\n}\n\nfunction MacosGlyph({ action }: { action: keyof typeof MACOS_LIGHTS }) {\n  return (\n    <svg\n      viewBox=\"0 0 10 10\"\n      aria-hidden=\"true\"\n      fill=\"none\"\n      stroke=\"currentColor\"\n      strokeWidth={1.4}\n      strokeLinecap=\"round\"\n      className=\"size-2 text-black/55 opacity-0 transition-opacity group-hover/titlebar:opacity-100\"\n    >\n      {action === \"close\" ? <path d=\"M2.6 2.6 7.4 7.4M7.4 2.6 2.6 7.4\" /> : null}\n      {action === \"minimize\" ? <path d=\"M2.4 5h5.2\" /> : null}\n      {action === \"zoom\" ? (\n        <path\n          d=\"M2.4 2.4h3.1L2.4 5.5zM7.6 7.6H4.5l3.1-3.1z\"\n          fill=\"currentColor\"\n          stroke=\"none\"\n        />\n      ) : null}\n    </svg>\n  )\n}\n\nfunction MacosLight({\n  action,\n  onClick,\n}: {\n  action: keyof typeof MACOS_LIGHTS\n  onClick?: () => void\n}) {\n  const { label, color } = MACOS_LIGHTS[action]\n\n  return (\n    <DesktopWindowControl\n      label={label}\n      onClick={onClick}\n      className={cn(\n        \"grid size-3 place-items-center rounded-full inset-ring-[0.5px] inset-ring-black/15\",\n        color\n      )}\n      interactive=\"focus-visible:ring-2 focus-visible:ring-ring/70\"\n    >\n      <MacosGlyph action={action} />\n    </DesktopWindowControl>\n  )\n}\n\nfunction CaptionGlyph({ action }: { action: CaptionAction }) {\n  return (\n    <svg\n      viewBox=\"0 0 10 10\"\n      aria-hidden=\"true\"\n      fill=\"none\"\n      stroke=\"currentColor\"\n      strokeWidth={1}\n      className=\"size-[0.625rem]\"\n    >\n      {action === \"minimize\" ? <path d=\"M1 5h8\" /> : null}\n      {action === \"maximize\" ? (\n        <rect x=\"1.5\" y=\"1.5\" width=\"7\" height=\"7\" rx=\"1\" />\n      ) : null}\n      {action === \"close\" ? <path d=\"M1.6 1.6 8.4 8.4M8.4 1.6 1.6 8.4\" /> : null}\n    </svg>\n  )\n}\n\nfunction WindowsCaption({\n  action,\n  onClick,\n}: {\n  action: CaptionAction\n  onClick?: () => void\n}) {\n  const { label, interactive } = WINDOWS_CAPTIONS[action]\n\n  return (\n    <DesktopWindowControl\n      label={label}\n      onClick={onClick}\n      className=\"grid h-8 w-[2.875rem] place-items-center text-black/80 transition-colors dark:text-white/90\"\n      interactive={interactive}\n    >\n      <CaptionGlyph action={action} />\n    </DesktopWindowControl>\n  )\n}\n\nconst UBUNTU_CAPTIONS = {\n  minimize: { label: \"Minimize\" },\n  maximize: { label: \"Maximize\" },\n  close: { label: \"Close\" },\n} as const\n\nfunction UbuntuCaption({\n  action,\n  onClick,\n}: {\n  action: CaptionAction\n  onClick?: () => void\n}) {\n  const { label } = UBUNTU_CAPTIONS[action]\n\n  return (\n    <DesktopWindowControl\n      label={label}\n      onClick={onClick}\n      // Yaru gives every button the same gray circle -- unlike Windows 11,\n      // close is not red.\n      className=\"grid size-6 place-items-center rounded-full bg-black/10 text-black/80 transition-colors dark:bg-white/10 dark:text-white/90\"\n      interactive=\"hover:bg-black/15 focus-visible:ring-2 focus-visible:ring-ring/70 dark:hover:bg-white/15\"\n    >\n      <CaptionGlyph action={action} />\n    </DesktopWindowControl>\n  )\n}\n\ninterface DesktopWindowControlsProps extends React.ComponentProps<\"div\"> {\n  onClose?: () => void\n  onMinimize?: () => void\n  onMaximize?: () => void\n}\n\nfunction DesktopWindowControls({\n  onClose,\n  onMinimize,\n  onMaximize,\n  className,\n  ...props\n}: DesktopWindowControlsProps) {\n  const os = useDesktopWindowOs()\n\n  return (\n    <div\n      data-slot=\"desktop-window-controls\"\n      data-os={os}\n      className={cn(desktopWindowControlsVariants({ os }), className)}\n      {...props}\n    >\n      {os === \"macos\" ? (\n        <>\n          <MacosLight action=\"close\" onClick={onClose} />\n          <MacosLight action=\"minimize\" onClick={onMinimize} />\n          <MacosLight action=\"zoom\" onClick={onMaximize} />\n        </>\n      ) : os === \"windows\" ? (\n        <>\n          <WindowsCaption action=\"minimize\" onClick={onMinimize} />\n          <WindowsCaption action=\"maximize\" onClick={onMaximize} />\n          <WindowsCaption action=\"close\" onClick={onClose} />\n        </>\n      ) : (\n        <>\n          <UbuntuCaption action=\"minimize\" onClick={onMinimize} />\n          <UbuntuCaption action=\"maximize\" onClick={onMaximize} />\n          <UbuntuCaption action=\"close\" onClick={onClose} />\n        </>\n      )}\n    </div>\n  )\n}\n\nexport {\n  DesktopWindow,\n  DesktopWindowContent,\n  DesktopWindowControls,\n  DesktopWindowTitle,\n  DesktopWindowTitlebar,\n  type DesktopWindowContentProps,\n  type DesktopWindowControlsProps,\n  type DesktopWindowOs,\n  type DesktopWindowProps,\n  type DesktopWindowTitleProps,\n  type DesktopWindowTitlebarProps,\n}\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}