@biela.dev/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1201 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +408 -0
- package/dist/index.d.ts +408 -0
- package/dist/index.js +1175 -0
- package/dist/index.js.map +1 -0
- package/package.json +50 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
import { RefObject, ReactNode, Component, ErrorInfo, CSSProperties, ReactElement } from 'react';
|
|
2
|
+
import { DeviceMeta, DeviceLayoutContract } from '@biela.dev/devices';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Design token dimension math — conversion utilities.
|
|
7
|
+
* All device dimensions are in logical points (CSS pixels at 1x).
|
|
8
|
+
*/
|
|
9
|
+
/** Convert logical points to physical pixels */
|
|
10
|
+
declare function ptsToPx(pts: number, dpr: number): number;
|
|
11
|
+
/** Convert physical pixels to logical points */
|
|
12
|
+
declare function pxToPts(px: number, dpr: number): number;
|
|
13
|
+
/** Convert points to percentage of a total dimension */
|
|
14
|
+
declare function ptsToPercent(pts: number, total: number): number;
|
|
15
|
+
/** Apply uniform scale factor to any dimension value */
|
|
16
|
+
declare function scaleValue(value: number, scaleFactor: number): number;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Scale Engine Math — mirrors Xcode Simulator "fit to screen" behavior.
|
|
20
|
+
*
|
|
21
|
+
* Rules:
|
|
22
|
+
* 1. Inner content ALWAYS at 1:1 logical point size
|
|
23
|
+
* 2. Scale derived from available container space, never hardcoded
|
|
24
|
+
* 3. SVG frame chrome scales WITH content as one atomic unit
|
|
25
|
+
* 4. Host layout reserves SCALED dimensions
|
|
26
|
+
* 5. Maximum scale always 1.0 — never larger than the real device
|
|
27
|
+
*/
|
|
28
|
+
/** Discrete scale steps matching Xcode Simulator presets */
|
|
29
|
+
declare const SCALE_STEPS: readonly [0.25, 0.33, 0.5, 0.75, 1];
|
|
30
|
+
/**
|
|
31
|
+
* Compute the adaptive scale factor for a device in a given container.
|
|
32
|
+
* Mirrors Xcode "fit to screen" exactly.
|
|
33
|
+
*
|
|
34
|
+
* @param deviceWidth - Logical points width of the device screen
|
|
35
|
+
* @param deviceHeight - Logical points height of the device screen
|
|
36
|
+
* @param containerWidth - Available CSS px width of the host container
|
|
37
|
+
* @param containerHeight - Available CSS px height of the host container
|
|
38
|
+
* @param padding - Breathing room in px (subtracted from each side)
|
|
39
|
+
* @param maxScale - Upper cap — never exceed 1.0 (real device size)
|
|
40
|
+
* @param minScale - Lower floor — prevent invisibly small render
|
|
41
|
+
*/
|
|
42
|
+
declare function computeAdaptiveScale(deviceWidth: number, deviceHeight: number, containerWidth: number, containerHeight: number, padding?: number, maxScale?: number, minScale?: number): number;
|
|
43
|
+
/**
|
|
44
|
+
* Snap a raw scale to the nearest discrete step that does not exceed it.
|
|
45
|
+
* Fixed version: filters steps to only those <= raw, takes max.
|
|
46
|
+
* Falls back to raw if no step qualifies.
|
|
47
|
+
*/
|
|
48
|
+
declare function snapToStep(raw: number): number;
|
|
49
|
+
/**
|
|
50
|
+
* Derive host container size from device dimensions + scale.
|
|
51
|
+
* The host div occupies these dimensions in normal document flow.
|
|
52
|
+
*/
|
|
53
|
+
declare function computeHostSize(deviceWidth: number, deviceHeight: number, scale: number): {
|
|
54
|
+
width: number;
|
|
55
|
+
height: number;
|
|
56
|
+
};
|
|
57
|
+
/** Result returned by the scale computation */
|
|
58
|
+
interface AdaptiveScaleResult {
|
|
59
|
+
/** Computed scale factor e.g. 0.735 */
|
|
60
|
+
scale: number;
|
|
61
|
+
/** Host container width = deviceWidth * scale */
|
|
62
|
+
scaledWidth: number;
|
|
63
|
+
/** Host container height = deviceHeight * scale */
|
|
64
|
+
scaledHeight: number;
|
|
65
|
+
/** Raw logical pts — scaler div width */
|
|
66
|
+
deviceWidth: number;
|
|
67
|
+
/** Raw logical pts — scaler div height */
|
|
68
|
+
deviceHeight: number;
|
|
69
|
+
/** True when scale === maxScale (showing at real size) */
|
|
70
|
+
isAtMaxScale: boolean;
|
|
71
|
+
/** True when scale < maxScale (container is limiting) */
|
|
72
|
+
isConstrained: boolean;
|
|
73
|
+
/** Display string e.g. "73%" */
|
|
74
|
+
scalePercent: string;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Full scale computation returning all derived values.
|
|
78
|
+
*/
|
|
79
|
+
declare function computeFullScale(deviceWidth: number, deviceHeight: number, containerWidth: number, containerHeight: number, options?: {
|
|
80
|
+
padding?: number;
|
|
81
|
+
maxScale?: number;
|
|
82
|
+
minScale?: number;
|
|
83
|
+
snapToSteps?: boolean;
|
|
84
|
+
}): AdaptiveScaleResult;
|
|
85
|
+
|
|
86
|
+
interface ContainerSize {
|
|
87
|
+
width: number;
|
|
88
|
+
height: number;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Observes an element's content box dimensions via ResizeObserver.
|
|
92
|
+
* Foundation of adaptive scaling — same mechanism as Xcode's window resize detection.
|
|
93
|
+
* Uses the actual canvas div, not the window, so it's panel-independent.
|
|
94
|
+
*/
|
|
95
|
+
declare function useContainerSize(ref: RefObject<HTMLElement | null>): ContainerSize;
|
|
96
|
+
|
|
97
|
+
interface UseAdaptiveScaleOptions {
|
|
98
|
+
/** Device metadata (screen dimensions) */
|
|
99
|
+
device: DeviceMeta;
|
|
100
|
+
/** Container width from useContainerSize */
|
|
101
|
+
containerWidth: number;
|
|
102
|
+
/** Container height from useContainerSize */
|
|
103
|
+
containerHeight: number;
|
|
104
|
+
/** Breathing room in px (default: 24) */
|
|
105
|
+
padding?: number;
|
|
106
|
+
/** Upper cap — never exceed 1.0 (default: 1.0) */
|
|
107
|
+
maxScale?: number;
|
|
108
|
+
/** Lower floor (default: 0.1) */
|
|
109
|
+
minScale?: number;
|
|
110
|
+
/** Snap to discrete 25/33/50/75/100% steps (default: false) */
|
|
111
|
+
snapToSteps?: boolean;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Full adaptive scale hook — mirrors Xcode "fit to screen".
|
|
115
|
+
* Recalculates live as container resizes via ResizeObserver.
|
|
116
|
+
*/
|
|
117
|
+
declare function useAdaptiveScale(options: UseAdaptiveScaleOptions): AdaptiveScaleResult;
|
|
118
|
+
|
|
119
|
+
interface UseDeviceContractResult {
|
|
120
|
+
contract: DeviceLayoutContract;
|
|
121
|
+
cssVariables: DeviceLayoutContract["cssVariables"];
|
|
122
|
+
contentZone: DeviceLayoutContract["contentZone"]["portrait"];
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Hook to access the Device Layout Contract for a given device.
|
|
126
|
+
* Returns the contract, CSS variables, and content zone for the current orientation.
|
|
127
|
+
*/
|
|
128
|
+
declare function useDeviceContract(deviceId: string, orientation?: "portrait" | "landscape"): UseDeviceContractResult;
|
|
129
|
+
|
|
130
|
+
interface VolumeState {
|
|
131
|
+
/** Current volume level 0–1 (16 steps, each = 1/16) */
|
|
132
|
+
level: number;
|
|
133
|
+
/** Is audio muted? */
|
|
134
|
+
muted: boolean;
|
|
135
|
+
/** Should the HUD be visible? */
|
|
136
|
+
hudVisible: boolean;
|
|
137
|
+
/** Increase volume by one step */
|
|
138
|
+
volumeUp: () => void;
|
|
139
|
+
/** Decrease volume by one step */
|
|
140
|
+
volumeDown: () => void;
|
|
141
|
+
/** Toggle mute */
|
|
142
|
+
toggleMute: () => void;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Volume control hook — 16-step volume with auto-hiding HUD.
|
|
146
|
+
* Applies volume to all <audio> and <video> elements inside `.bielaframe-content`.
|
|
147
|
+
*/
|
|
148
|
+
declare function useVolumeControl(initialVolume?: number): VolumeState;
|
|
149
|
+
|
|
150
|
+
interface ScreenPowerState {
|
|
151
|
+
/** Is the screen off? */
|
|
152
|
+
isOff: boolean;
|
|
153
|
+
/** Toggle screen on/off */
|
|
154
|
+
toggle: () => void;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Screen power hook — manages on/off state for the power button.
|
|
158
|
+
*/
|
|
159
|
+
declare function useScreenPower(): ScreenPowerState;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Resolve device SVG component by ID.
|
|
163
|
+
* This is a lookup registry — devices register their SVG components here.
|
|
164
|
+
*/
|
|
165
|
+
type DeviceSVGComponent = React.ComponentType<{
|
|
166
|
+
colorScheme?: "light" | "dark";
|
|
167
|
+
style?: React.CSSProperties;
|
|
168
|
+
}>;
|
|
169
|
+
interface FrameInfo {
|
|
170
|
+
bezelTop: number;
|
|
171
|
+
bezelBottom: number;
|
|
172
|
+
bezelLeft: number;
|
|
173
|
+
bezelRight: number;
|
|
174
|
+
totalWidth: number;
|
|
175
|
+
totalHeight: number;
|
|
176
|
+
screenWidth: number;
|
|
177
|
+
screenHeight: number;
|
|
178
|
+
screenRadius: number;
|
|
179
|
+
}
|
|
180
|
+
/** Register a device SVG component for use with DeviceFrame */
|
|
181
|
+
declare function registerDeviceSVG(deviceId: string, component: DeviceSVGComponent, frame: FrameInfo): void;
|
|
182
|
+
/** Optional crop area to rewrite the SVG viewBox (e.g., to exclude side buttons) */
|
|
183
|
+
interface SVGCropArea {
|
|
184
|
+
x: number;
|
|
185
|
+
y: number;
|
|
186
|
+
width: number;
|
|
187
|
+
height: number;
|
|
188
|
+
}
|
|
189
|
+
/** Screen rectangle in SVG native coordinates — used to punch a transparent hole */
|
|
190
|
+
interface SVGScreenRect {
|
|
191
|
+
x: number;
|
|
192
|
+
y: number;
|
|
193
|
+
width: number;
|
|
194
|
+
height: number;
|
|
195
|
+
rx?: number;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Register a custom device SVG from a raw SVG string.
|
|
199
|
+
*
|
|
200
|
+
* Creates a React component that renders the SVG with scoped IDs
|
|
201
|
+
* and registers it in the SVG_REGISTRY.
|
|
202
|
+
*
|
|
203
|
+
* The inner <svg> element is rewritten to use width="100%" height="100%"
|
|
204
|
+
* so it fills the parent container (which is sized by the frame info).
|
|
205
|
+
*
|
|
206
|
+
* If `cropViewBox` is provided, the SVG viewBox is set to that area,
|
|
207
|
+
* cropping out external elements like side buttons.
|
|
208
|
+
*
|
|
209
|
+
* If `screenRect` is provided, a mask is injected to punch a transparent
|
|
210
|
+
* hole where the screen is, so content underneath shows through.
|
|
211
|
+
*/
|
|
212
|
+
declare function registerCustomDeviceSVG(deviceId: string, svgString: string, frame: FrameInfo, cropViewBox?: SVGCropArea, screenRect?: SVGScreenRect): void;
|
|
213
|
+
interface DeviceFrameProps {
|
|
214
|
+
/** Device ID e.g. "iphone-16-pro" */
|
|
215
|
+
device: string;
|
|
216
|
+
/** Orientation */
|
|
217
|
+
orientation?: "portrait" | "landscape";
|
|
218
|
+
/** Scale mode: "fit" auto-scales, "manual" uses manualScale value */
|
|
219
|
+
scaleMode?: "fit" | "manual" | "steps";
|
|
220
|
+
/** Manual scale override (0.1–1.0), only when scaleMode="manual" */
|
|
221
|
+
manualScale?: number;
|
|
222
|
+
/** Show safe zone overlay (dev tool) */
|
|
223
|
+
showSafeAreaOverlay?: boolean;
|
|
224
|
+
/** Show DLC JSON panel */
|
|
225
|
+
showDLCPanel?: boolean;
|
|
226
|
+
/** Show scale bar (default: true) */
|
|
227
|
+
showScaleBar?: boolean;
|
|
228
|
+
/** Frame color scheme */
|
|
229
|
+
colorScheme?: "light" | "dark";
|
|
230
|
+
/** Callback when DLC is ready */
|
|
231
|
+
onContractReady?: (dlc: DeviceLayoutContract) => void;
|
|
232
|
+
/** Callback when scale changes */
|
|
233
|
+
onScaleChange?: (scale: number) => void;
|
|
234
|
+
/** Content rendered inside the device screen at real resolution */
|
|
235
|
+
children?: ReactNode;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* DeviceFrame — the main BielaFrame component.
|
|
239
|
+
*
|
|
240
|
+
* Implements the Two-World Rendering Model:
|
|
241
|
+
* - Inner content renders at 1:1 device resolution (e.g. 402×874px)
|
|
242
|
+
* - Visual presentation scales via CSS transform: scale()
|
|
243
|
+
* - The AI component always thinks it's on a real device
|
|
244
|
+
*
|
|
245
|
+
* DOM structure:
|
|
246
|
+
* bielaframe-sentinel (fills parent, ResizeObserver target)
|
|
247
|
+
* └── bielaframe-host (scaled dimensions in flow)
|
|
248
|
+
* └── bielaframe-scaler (real device dims, transform: scale(N))
|
|
249
|
+
* ├── bielaframe-content (clipped to screen, CSS vars injected)
|
|
250
|
+
* │ └── children (AI-generated component)
|
|
251
|
+
* ├── SVG frame overlay (pointer-events: none)
|
|
252
|
+
* └── SafeAreaOverlay (optional dev tool)
|
|
253
|
+
* └── ScaleBar (outside scaler, in normal flow)
|
|
254
|
+
*/
|
|
255
|
+
declare function DeviceFrame({ device, orientation, scaleMode, manualScale, showSafeAreaOverlay, showScaleBar, colorScheme, onContractReady, onScaleChange, children, }: DeviceFrameProps): react_jsx_runtime.JSX.Element;
|
|
256
|
+
|
|
257
|
+
interface Props {
|
|
258
|
+
children: ReactNode;
|
|
259
|
+
fallback?: ReactNode;
|
|
260
|
+
}
|
|
261
|
+
interface State {
|
|
262
|
+
hasError: boolean;
|
|
263
|
+
error: Error | null;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Error Boundary wrapping the children slot in DeviceFrame.
|
|
267
|
+
* AI-generated components will crash — this catches them gracefully
|
|
268
|
+
* and renders a fallback inside the device screen area.
|
|
269
|
+
*/
|
|
270
|
+
declare class DeviceErrorBoundary extends Component<Props, State> {
|
|
271
|
+
constructor(props: Props);
|
|
272
|
+
static getDerivedStateFromError(error: Error): State;
|
|
273
|
+
componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
|
|
274
|
+
render(): ReactNode;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
interface SafeAreaViewProps {
|
|
278
|
+
/** Which edges to apply safe area padding to (default: all) */
|
|
279
|
+
edges?: Array<"top" | "bottom" | "left" | "right">;
|
|
280
|
+
children: ReactNode;
|
|
281
|
+
style?: CSSProperties;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Convenience wrapper that applies safe area padding via CSS variables.
|
|
285
|
+
* Uses var(--safe-top), var(--safe-bottom), etc. — injected by DeviceFrame.
|
|
286
|
+
*
|
|
287
|
+
* Usage inside a generated app:
|
|
288
|
+
* <SafeAreaView edges={["top", "bottom"]}>
|
|
289
|
+
* {content that never overlaps hardware elements}
|
|
290
|
+
* </SafeAreaView>
|
|
291
|
+
*/
|
|
292
|
+
declare function SafeAreaView({ edges, children, style }: SafeAreaViewProps): react_jsx_runtime.JSX.Element;
|
|
293
|
+
|
|
294
|
+
interface SafeAreaOverlayProps {
|
|
295
|
+
contract: DeviceLayoutContract;
|
|
296
|
+
orientation: "portrait" | "landscape";
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Dev overlay showing safe zones when showSafeAreaOverlay={true}.
|
|
300
|
+
* Does NOT affect layout — position: absolute, pointerEvents: none.
|
|
301
|
+
*
|
|
302
|
+
* Colors:
|
|
303
|
+
* - Red: status bar zone + home indicator zone (restricted)
|
|
304
|
+
* - Orange: hardware overlay (Dynamic Island / punch-hole)
|
|
305
|
+
* - Green: content zone (usable area)
|
|
306
|
+
* - White dimension labels at each edge
|
|
307
|
+
*/
|
|
308
|
+
declare function SafeAreaOverlay({ contract, orientation }: SafeAreaOverlayProps): react_jsx_runtime.JSX.Element;
|
|
309
|
+
|
|
310
|
+
interface ScaleBarProps {
|
|
311
|
+
deviceName: string;
|
|
312
|
+
deviceWidth: number;
|
|
313
|
+
deviceHeight: number;
|
|
314
|
+
scale: number;
|
|
315
|
+
scalePercent: string;
|
|
316
|
+
isAtMaxScale: boolean;
|
|
317
|
+
isConstrained: boolean;
|
|
318
|
+
onScaleChange?: (scale: number) => void;
|
|
319
|
+
onFit?: () => void;
|
|
320
|
+
onRealSize?: () => void;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Persistent footer below device showing scale state:
|
|
324
|
+
* [ iPhone 16 Pro · 402×874pt | ━━━●━━━━━ 66% | Fit ↗ | 1:1 ]
|
|
325
|
+
*
|
|
326
|
+
* Accessibility:
|
|
327
|
+
* - role="slider" with aria-valuenow on scrubber
|
|
328
|
+
* - aria-label on the component
|
|
329
|
+
* - aria-live="polite" on scale announcements
|
|
330
|
+
*/
|
|
331
|
+
declare function ScaleBar({ deviceName, deviceWidth, deviceHeight, scale, scalePercent, isAtMaxScale, isConstrained, onScaleChange, onFit, onRealSize, }: ScaleBarProps): react_jsx_runtime.JSX.Element;
|
|
332
|
+
|
|
333
|
+
interface VolumeHUDProps {
|
|
334
|
+
level: number;
|
|
335
|
+
muted: boolean;
|
|
336
|
+
visible: boolean;
|
|
337
|
+
platform: "ios" | "android";
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Volume HUD overlay — iOS-style vertical pill or Android-style horizontal bar.
|
|
341
|
+
*/
|
|
342
|
+
declare function VolumeHUD({ level, muted, visible, platform }: VolumeHUDProps): react_jsx_runtime.JSX.Element;
|
|
343
|
+
|
|
344
|
+
type ButtonName = "volumeUp" | "volumeDown" | "power" | "actionButton" | "cameraControl";
|
|
345
|
+
interface HardwareButtonsProps {
|
|
346
|
+
/** The container element that holds the SVG frame overlay */
|
|
347
|
+
frameContainerRef: React.RefObject<HTMLDivElement | null>;
|
|
348
|
+
/** Callbacks for button actions */
|
|
349
|
+
onButtonPress?: (button: ButtonName) => void;
|
|
350
|
+
/** Whether interactive buttons are enabled */
|
|
351
|
+
enabled?: boolean;
|
|
352
|
+
/** Current orientation — triggers button position re-discovery */
|
|
353
|
+
orientation?: "portrait" | "landscape";
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* HardwareButtons — creates invisible click-target overlays positioned
|
|
357
|
+
* over the SVG button elements.
|
|
358
|
+
*
|
|
359
|
+
* Because the SVG frame overlay has pointer-events: none (so content
|
|
360
|
+
* underneath remains interactive), we can't attach event listeners directly
|
|
361
|
+
* to SVG elements. Instead, we:
|
|
362
|
+
* 1. Find all [data-button] elements in the SVG
|
|
363
|
+
* 2. Read their bounding rects relative to the scaler container
|
|
364
|
+
* 3. Render transparent absolutely-positioned divs at those positions
|
|
365
|
+
* 4. Handle mouse/touch events on those divs
|
|
366
|
+
* 5. Apply press animation to the original SVG elements
|
|
367
|
+
*/
|
|
368
|
+
declare function HardwareButtons({ frameContainerRef, onButtonPress, enabled, orientation, }: HardwareButtonsProps): ReactElement | null;
|
|
369
|
+
|
|
370
|
+
interface DynamicStatusBarProps {
|
|
371
|
+
contract: DeviceLayoutContract;
|
|
372
|
+
orientation: "portrait" | "landscape";
|
|
373
|
+
colorScheme: "light" | "dark";
|
|
374
|
+
/** Show a live updating clock (default: true) */
|
|
375
|
+
showLiveClock?: boolean;
|
|
376
|
+
/** Fixed time string override (e.g. "9:41") — disables live clock */
|
|
377
|
+
fixedTime?: string;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* DynamicStatusBar — renders ONLY a live clock overlay.
|
|
381
|
+
*
|
|
382
|
+
* The SVG frame already provides all decorative status bar elements
|
|
383
|
+
* (signal bars, wifi, battery). This component only replaces the
|
|
384
|
+
* static time text (e.g. "9:41") with a live-updating clock.
|
|
385
|
+
*
|
|
386
|
+
* It renders a small opaque patch behind the clock text so the
|
|
387
|
+
* SVG's baked-in static time is fully covered, then draws the
|
|
388
|
+
* live time on top.
|
|
389
|
+
*
|
|
390
|
+
* Platform-specific clock positions:
|
|
391
|
+
* - iOS Dynamic Island: left side, paddingLeft ~20
|
|
392
|
+
* - iOS Notch: left side, paddingLeft ~20
|
|
393
|
+
* - iOS SE: centered
|
|
394
|
+
* - Android: left side, paddingLeft ~16
|
|
395
|
+
*/
|
|
396
|
+
declare function DynamicStatusBar({ contract, orientation, colorScheme, showLiveClock, fixedTime, }: DynamicStatusBarProps): react_jsx_runtime.JSX.Element | null;
|
|
397
|
+
|
|
398
|
+
interface StatusBarIndicatorsProps {
|
|
399
|
+
platform: "ios" | "android";
|
|
400
|
+
colorScheme: "light" | "dark";
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Static decorative status bar indicators — signal, wifi, battery.
|
|
404
|
+
* Rendered as small inline SVGs, platform-specific styling.
|
|
405
|
+
*/
|
|
406
|
+
declare function StatusBarIndicators({ platform, colorScheme }: StatusBarIndicatorsProps): react_jsx_runtime.JSX.Element;
|
|
407
|
+
|
|
408
|
+
export { type AdaptiveScaleResult, type ButtonName, DeviceErrorBoundary, DeviceFrame, type DeviceFrameProps, DynamicStatusBar, HardwareButtons, SCALE_STEPS, type SVGCropArea, type SVGScreenRect, SafeAreaOverlay, SafeAreaView, ScaleBar, type ScreenPowerState, StatusBarIndicators, type UseAdaptiveScaleOptions, VolumeHUD, type VolumeState, computeAdaptiveScale, computeFullScale, computeHostSize, ptsToPercent, ptsToPx, pxToPts, registerCustomDeviceSVG, registerDeviceSVG, scaleValue, snapToStep, useAdaptiveScale, useContainerSize, useDeviceContract, useScreenPower, useVolumeControl };
|