@kreativa/device-preview
v0.1.0
Published
App-agnostic device frame + catalog for rendering web previews of mobile UI at real device window sizes and safe-area insets.
Maintainers
Readme
@kreativa/device-preview
App-agnostic device frame + catalog for rendering web previews of mobile UI
at real device window sizes and safe-area insets. Render any React tree (e.g. a
react-native-web screen) inside a device bezel that lays out at the device's
true logical size, then scales for display — so the preview never lies about
layout.
It deliberately knows nothing about your app, theme system, or React Native: you
map your theme to a background colour + statusBarStyle and wrap the children
in whatever providers they need.
Install
npm install @kreativa/device-previewreact is a peer dependency (>=18). The package renders DOM, so it's for web /
react-native-web previews.
Usage
import {
DeviceFrame,
IPHONE_17_PRO,
displayWidthFor,
} from '@kreativa/device-preview';
function Preview() {
return (
<DeviceFrame
device={IPHONE_17_PRO}
statusBarStyle="light" // light glyphs on a dark UI
background="#120a18"
displayWidth={402} // CSS px; height follows the aspect ratio
>
<YourScreen />
</DeviceFrame>
);
}Feed the device's real safe-area insets into your layout (e.g. inject
react-native-safe-area-context's SafeAreaInsetsContext/SafeAreaFrameContext
from device.safeArea / device.logicalWidth × device.logicalHeight) so screens
get the correct insets at every scale.
Exports
| Export | What it is |
|--------|------------|
| DeviceFrame | The presentational bezel (status bar, Dynamic Island, home indicator). |
| DEVICES, IPHONE_17_PRO, getDevice(id), DEFAULT_DEVICE_ID | The device catalog. |
| DevicePicker | A bare, host-styled <select> over the catalog (auto-locks with one device). |
| ScalePicker | A <select> over the scale modes. |
| displayWidthFor(device, mode, ctx), SCALE_MODES | Compute the rendered width for a scale mode. |
| Types | DeviceProfile, DeviceInsets, DynamicIsland, StatusBarStyle, ScaleMode, ScaleContext. |
Scale modes
Mirrors the iOS Simulator's window-scale menu (the modes a browser can reproduce faithfully). Layout is always computed at the device's logical size — only the on-screen zoom changes:
point— 1 device point ↔ 1 CSS px (the design-true default).pixel— 1 device pixel ↔ 1 physical monitor pixel (usesdevicePixelRatio).fit— scale to fit the available preview area.
const width = displayWidthFor(IPHONE_17_PRO, 'pixel', {
devicePixelRatio: window.devicePixelRatio,
});The Simulator's "Physical Size" is intentionally omitted — a browser can't read the monitor's true PPI, so it can't render life-size accurately.
License
MIT
