{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "iphone",
  "type": "registry:ui",
  "title": "iPhone",
  "description": "A device frame drawn from the real measurements, with a screen you put anything in.",
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/loomui/iphone.tsx",
      "content": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport interface IPhoneProps extends React.ComponentProps<\"div\"> {\n  /** Largest width the device is drawn at, in pixels. It shrinks below this. */\n  width?: number\n  /** Screenshot to fill the screen with. */\n  src?: string\n  /** Description of the screenshot. Required whenever `src` is set. */\n  alt?: string\n  /** Draw the island at the top of the screen. */\n  island?: boolean\n  /** Draw the buttons down the sides. */\n  buttons?: boolean\n}\n\n/** Device points, so every measurement below is a real one. */\nconst DEVICE_WIDTH = 393\nconst DEVICE_HEIGHT = 852\n\n/**\n * Every measurement is a share of the frame's own width, in container units. A\n * percentage radius would go elliptical on a box this tall.\n */\nconst cq = (points: number) =>\n  `${((points / DEVICE_WIDTH) * 100).toFixed(4)}cqw`\n\nconst BUTTONS = [\n  { side: \"left\", top: 150, height: 32 },\n  { side: \"left\", top: 216, height: 62 },\n  { side: \"left\", top: 292, height: 62 },\n  { side: \"right\", top: 240, height: 96 },\n] as const\n\nexport function IPhone({\n  children,\n  src,\n  alt = \"\",\n  width = 300,\n  island = true,\n  buttons = true,\n  className,\n  style,\n  ...props\n}: IPhoneProps) {\n  return (\n    <div\n      data-slot=\"iphone\"\n      className={cn(\"relative w-full\", className)}\n      style={{\n        maxWidth: width,\n        aspectRatio: `${DEVICE_WIDTH} / ${DEVICE_HEIGHT}`,\n        containerType: \"inline-size\",\n        ...style,\n      }}\n      {...props}\n    >\n      {buttons\n        ? BUTTONS.map((button, index) => (\n            <span\n              key={index}\n              aria-hidden=\"true\"\n              className=\"absolute bg-neutral-500\"\n              style={{\n                ...(button.side === \"left\"\n                  ? { left: cq(-2) }\n                  : { right: cq(-2) }),\n                top: cq(button.top),\n                width: cq(3),\n                height: cq(button.height),\n                borderRadius: cq(2),\n              }}\n            />\n          ))\n        : null}\n\n      {/* The rim. A gradient rather than a flat fill, because a solid band the\n          same colour all the way round reads as a border, not as metal. */}\n      <div\n        className=\"absolute inset-0 bg-linear-to-br from-neutral-600 via-neutral-800 to-neutral-700 shadow-xl\"\n        style={{ borderRadius: cq(56), padding: cq(9) }}\n      >\n        <div\n          className=\"relative h-full w-full overflow-hidden bg-neutral-200 dark:bg-neutral-800\"\n          style={{ borderRadius: cq(48) }}\n        >\n          {src ? (\n            <img src={src} alt={alt} className=\"h-full w-full object-cover\" />\n          ) : (\n            children\n          )}\n\n          {island ? (\n            <span\n              aria-hidden=\"true\"\n              className=\"absolute left-1/2 -translate-x-1/2 bg-black\"\n              style={{\n                top: cq(12),\n                width: cq(120),\n                height: cq(34),\n                borderRadius: cq(17),\n              }}\n            />\n          ) : null}\n        </div>\n      </div>\n    </div>\n  )\n}\n",
      "type": "registry:ui"
    }
  ]
}