iPhone
loomui/iphoneFreeComponent
A device frame drawn from the real measurements, with a screen you put anything in.
Live preview
live · rendered by the registry
Rendered by loomui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://loomui.design/r/iphone.jsonSource
1import * as React from "react"23import { cn } from "@/lib/utils"45export interface IPhoneProps extends React.ComponentProps<"div"> {6 /** Largest width the device is drawn at, in pixels. It shrinks below this. */7 width?: number8 /** Screenshot to fill the screen with. */9 src?: string10 /** Description of the screenshot. Required whenever `src` is set. */11 alt?: string12 /** Draw the island at the top of the screen. */13 island?: boolean14 /** Draw the buttons down the sides. */15 buttons?: boolean16}1718/** Device points, so every measurement below is a real one. */19const DEVICE_WIDTH = 39320const DEVICE_HEIGHT = 8522122/**23 * Every measurement is a share of the frame's own width, in container units. A24 * percentage radius would go elliptical on a box this tall.25 */26const cq = (points: number) =>27 `${((points / DEVICE_WIDTH) * 100).toFixed(4)}cqw`2829const BUTTONS = [30 { side: "left", top: 150, height: 32 },31 { side: "left", top: 216, height: 62 },32 { side: "left", top: 292, height: 62 },33 { side: "right", top: 240, height: 96 },34] as const3536export function IPhone({37 children,38 src,39 alt = "",40 width = 300,41 island = true,42 buttons = true,43 className,44 style,45 ...props46}: IPhoneProps) {47 return (48 <div49 data-slot="iphone"50 className={cn("relative w-full", className)}51 style={{52 maxWidth: width,53 aspectRatio: `${DEVICE_WIDTH} / ${DEVICE_HEIGHT}`,54 containerType: "inline-size",55 ...style,56 }}57 {...props}58 >59 {buttons60 ? BUTTONS.map((button, index) => (61 <span62 key={index}63 aria-hidden="true"64 className="absolute bg-neutral-500"65 style={{66 ...(button.side === "left"67 ? { left: cq(-2) }68 : { right: cq(-2) }),69 top: cq(button.top),70 width: cq(3),71 height: cq(button.height),72 borderRadius: cq(2),73 }}74 />75 ))76 : null}7778 {/* The rim. A gradient rather than a flat fill, because a solid band the79 same colour all the way round reads as a border, not as metal. */}80 <div81 className="absolute inset-0 bg-linear-to-br from-neutral-600 via-neutral-800 to-neutral-700 shadow-xl"82 style={{ borderRadius: cq(56), padding: cq(9) }}83 >84 <div85 className="relative h-full w-full overflow-hidden bg-neutral-200 dark:bg-neutral-800"86// … truncated
What it pulls in
Other registry items
Files it writes
More from loomui
All 91 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Aurora Backdropaurora-backdrop | loomui | Components | Free | no deps | |
| Bento Gridbento-grid | loomui | Components | Free | no deps | |
| Card Stackcard-stack | loomui | Components | Free | no deps | |
| Compare Slidercompare-slider | loomui | Components | Free | no deps | |
| Confetti Buttonconfetti-button | loomui | Components | Free | no deps | |
| Count Upcount-up | loomui | Components | Free | no deps | |
| Credit Cardcredit-card | loomui | Components | Free | no deps | |
| Drawerdrawer | loomui | Components | Free | 1 dep |
