ComponentsRounded-[3rem] outer + p-[6px] frame + bg-fg. Inner screen rounded-[2.6rem] bg-black. Tasti come thin div absolute.
MockDeviceiOS
Esempio01
iphone-mock.tsx 001Default · v2 · dynamic island002App preview · with contentComponenti
36 brand-locked
Animated Beam
Magic Card
Dock
003Variant v1 · notch tsxsrc/components/iphone-mock.tsx
import type { ReactNode } from "react";
import { cn } from "@/lib/utils";
export type IphoneMockProps = {
imageSrc?: string;
videoSrc?: string;
children?: ReactNode;
width?: number;
height?: number;
/** v1 = notch, v2 = dynamic island. Default v2. */
variant?: "v1" | "v2";
className?: string;
};
/**
* <IphoneMock/> — iPhone 15 Pro–style frame with dynamic island (v2) or
* notch (v1), volume/action/power side buttons. Inner screen is
* `bg-black`; chrome uses `bg-fg` so it inverts cleanly with the theme.
*/
export function IphoneMock({
imageSrc,
videoSrc,
children,
width = 433,
height = 882,
variant = "v2",
className,
}: IphoneMockProps) {
return (
<div
className={cn("relative", className)}
style={{ aspectRatio: `${width} / ${height}` }}
>
<div className="absolute inset-0 rounded-[3rem] bg-fg p-[6px] shadow-md">
<div className="absolute -left-[3px] top-[18%] h-12 w-[3px] rounded-l-md bg-fg-muted" />
<div className="absolute -left-[3px] top-[28%] h-20 w-[3px] rounded-l-md bg-fg-muted" />
<div className="absolute -left-[3px] top-[38%] h-20 w-[3px] rounded-l-md bg-fg-muted" />
<div className="absolute -right-[3px] top-[28%] h-28 w-[3px] rounded-r-md bg-fg-muted" />
<div className="relative h-full w-full overflow-hidden rounded-[2.6rem] bg-black">
{variant === "v2" ? (
<div className="absolute left-1/2 top-2 z-20 h-[26px] w-[100px] -translate-x-1/2 rounded-full bg-black" />
) : (
<div className="absolute left-1/2 top-0 z-20 h-6 w-40 -translate-x-1/2 rounded-b-2xl bg-black" />
)}
{videoSrc ? (
<video
src={videoSrc}
autoPlay
muted
loop
playsInline
className="h-full w-full object-cover"
/>
) : imageSrc ? (
// eslint-disable-next-line @next/next/no-img-element
<img
src={imageSrc}
alt=""
className="h-full w-full object-cover"
/>
) : (
children
)}
</div>
</div>
</div>
);
}
Note — Variant v1 = notch top, v2 = dynamic island. Il frame bg-fg si inverte automaticamente in dark mode (frame chiaro su sfondo nero).
Prompt LLM02
Incolla in Claude o ChatGPT per generare la tua variante. Include il contesto del brand, i token e i vincoli del progetto.
Sei un senior frontend engineer. Stai lavorando su un sito Next.js 16 + React 19 + Tailwind v4 in italiano, look chanhdai-inspired: colonna stretta 672px, Geist Sans + Geist Mono, hairline 1px, divisori a stripe diagonale, palette zinc.
Token CSS disponibili: --bg, --bg-alt, --fg, --fg-muted, --fg-soft, --border, --border-strong, --accent. Usa SEMPRE queste variabili tramite le utility tailwind generate (bg-bg, text-fg-muted, border-border, ecc.). Helper "cn" da "@/lib/utils". Niente librerie UI extra: solo lucide-react e tailwind-merge.
Genera un componente <IphoneMock>.
Props:
- imageSrc?, videoSrc?, children?: ReactNode.
- width?: number (default 433), height?: number (default 882).
- variant?: "v1" | "v2" (default "v2").
- className?.
Implementazione:
- Server component. Wrapper relative aspect-ratio width/height.
- Frame absolute inset-0 rounded-[3rem] bg-fg p-[6px] shadow-md.
- 4 tasti laterali absolute -left-[3px] e -right-[3px]: volume up/down, action, power.
- Inner screen relative h-full overflow-hidden rounded-[2.6rem] bg-black.
- Dynamic island (v2): absolute left-1/2 top-2 h-[26px] w-[100px] -translate-x-1/2 rounded-full bg-black z-20.
- Notch (v1): absolute left-1/2 top-0 h-6 w-40 -translate-x-1/2 rounded-b-2xl bg-black z-20.
- Content: video | img | children.
Output: file completo src/components/iphone-mock.tsx.
Uso tipico03
<IphoneMock variant="v2" imageSrc="/screen.png" />
Dipendenze04
Ti è servito? Dimmelo, oppure proponi il prossimo componente.