iPad

A tablet frame drawn from the real measurements, upright or on its side, with a screen you put anything in.

Loading preview

Installation

npx shadcn@latest add @loomui/ipad

Usage

import { IPad } from "@/components/ui/ipad"
<IPad />

On its own it is a blank tablet with a grey screen. Fill it with a screenshot, or with live markup:

<IPad src="/dashboard.png" alt="The dashboard on a tablet" />
<IPad width={520}>
  <Dashboard />
</IPad>

Anything inside is clipped to the screen's radius.

Which way up

<IPad orientation="landscape" width={640} />

portrait is 834 by 1194 points and landscape swaps them. The camera follows the top edge either way. Every other measurement works against whichever side is the width, so the bezel stays the same thickness in both.

One number, and it shrinks

width is a maximum, not a fixed size. The frame fills the space it is given and stops there, so it never pushes a narrow screen sideways.

Everything else (the rim, both corner radii, the camera) is a real device point expressed as a share of the frame's own width, in container units. A percentage border-radius would go elliptical on a box this shape. A scale factor worked out in JavaScript would be wrong the moment the frame had to shrink.

The camera is drawn in the bezel rather than on the screen, which is where it sits and what keeps it clear of anything laid over the display.

The component is not client-side. There is no state and no listener, so it renders on the server and costs nothing on the client.

Props

PropTypeDefaultDescription
widthnumber420Largest width the device is drawn at.
srcstringnoneScreenshot to fill the screen with.
altstring""Description of the screenshot.
orientation"portrait" | "landscape""portrait"Which way up the tablet is held.
camerabooleantrueDraw the camera in the bezel.
classNamestringnoneMerged onto the frame.

Any other <div> prop is forwarded. children fills the screen when there is no src.

Accessibility

The rim and the camera are aria-hidden. They are a picture of a tablet, not content. Give src a real alt describing what is on the screen, or leave it empty when the screenshot is decoration beside copy that already says the same thing.