ProductFrame
Window or device chrome around a product screenshot or staged UI, optionally set on a tinted stage.
- api.beacon.dev142 ms p95
- app.beacon.dev88 ms p95
- eu-west.beacon.devDegraded · 1.2 s p95
- status.beacon.dev61 ms p95
View code
<ProductFrame
stage="panel"
shadow="tinted"
lights
title="Monitors"
url="app.beacon.dev"
footer="Checked from 12 regions every 30 seconds"
>
<ul>
{monitors.map((monitor) => (
<li>
<span>{monitor.host}</span>
<span>{monitor.detail}</span>
</li>
))}
</ul>
</ProductFrame>Demo landings
Whole pages built only from @sdxc/ui, each for an invented product with its own palette and type. They open in a new tab.
- RooftreeRooftree keeps a household's groceries, chores, calendar and meals on one encrypted list that syncs across iPhone, Android, Mac and Windows./demo/app
- The MeasureA book and video course on web typography for designers and engineers: measure, rhythm, scale and fonts, with CSS for every chapter./demo/book
- KeelKeel meters every event your product emits, prices it on any plan and sends the invoice on the first of the month./demo/saas
Every demo, landings and docs sites alike, is listed in the demo gallery.
Installation
An ordinary dependency: install it, import the theme once, and import the component where it is used.
npm add @sdxc/ui remiximport "@sdxc/ui/theme.css";Usage
import { ProductFrame } from "@sdxc/ui/landing";Wraps children in soft window or device chrome so a landing media slot reads
as a product surface rather than a bare image; stage sets it on a tinted
panel with room around it.
Examples
<ProductFrame stage="panel" shadow="tinted" footer={t("frame.caption")}>{ui}</ProductFrame>Props
Read from the component's own types, so every prop, every default and every allowed value is listed.
| Prop | Type | Required | Description |
|---|---|---|---|
variant | "window" | "device" | No | Outer chrome. Defaults to DEFAULT_VARIANT. |
stage | "none" | "panel" | "backdrop" | No | Panel the frame is staged on, centred at 86% of its width, and at full width under a thin pad below the md container. Host props and mix land on the stage. Defaults to DEFAULT_STAGE. |
backdrop | RemixNode | No | Image or gradient painted behind the frame on stage="backdrop"; a radial brand glow fills the stage when omitted. Always aria-hidden. |
shadow | "stage" | "tinted" | No | Lift under the frame. Defaults to "stage", and to a deep drop shadow on the device variant. |
lights | boolean | "color" | No | Draws three decorative aria-hidden dots in the title bar: neutral ink with true, the red/amber/green set with "color". |
title | RemixNode | No | Optional window title shown in the chrome bar. |
url | RemixNode | No | Optional URL or path shown as a quiet mono field in the chrome bar. |
footer | RemixNode | No | Optional caption row under the body, set as a 12px muted strip. |
designWidth | string | No | Narrowest width the framed UI lays out at, such as "56rem". A narrower body keeps the desktop composition and shows it through fit, so nothing inside reflows or truncates on a phone. |
fit | "crop" | "scale" | No | How a body narrower than designWidth shows it. Defaults to "crop". |
parts | PartsProps | No | Per-part styling for frame, chrome, body and footer. |
children | RemixNode | Yes | Product UI, screenshot, or staged sample inside the frame. |
Also accepts everything in Omit<TagProps<"div">, "title">.
Types
| Name | Values | What it decides |
|---|---|---|
Variant | "window" | "device" | Outer chrome: a desktop window with a title bar, or a phone-proportioned device rim. |
Stage | "none" | "panel" | "backdrop" | What the frame sits on: the band itself, a tinted panel, or a panel with a backdrop image or brand glow behind the frame. |
Shadow | "stage" | "tinted" | Lift under the frame: the neutral stage shadow, or a brand-tinted two-layer lift that suits brand and inverse bands. |
Fit | "crop" | "scale" | How a body narrower than designWidth shows its content: cropped at the end edge under a fade, or scaled down whole. |