@biela.dev/core 1.5.0 → 1.6.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.d.cts CHANGED
@@ -158,6 +158,27 @@ interface ScreenPowerState {
158
158
  */
159
159
  declare function useScreenPower(): ScreenPowerState;
160
160
 
161
+ interface UseOrientationResult {
162
+ /** Current orientation */
163
+ orientation: "portrait" | "landscape";
164
+ /** Convenience boolean */
165
+ isLandscape: boolean;
166
+ /** Toggle between portrait and landscape */
167
+ toggle: () => void;
168
+ /** Set orientation directly */
169
+ setOrientation: (o: "portrait" | "landscape") => void;
170
+ }
171
+ /**
172
+ * Hook for managing device orientation state with a toggle function.
173
+ *
174
+ * ```tsx
175
+ * const { orientation, toggle } = useOrientation();
176
+ * <button onClick={toggle}>Rotate</button>
177
+ * <DeviceFrame deviceId="iphone-17-pro" orientation={orientation} />
178
+ * ```
179
+ */
180
+ declare function useOrientation(initial?: "portrait" | "landscape"): UseOrientationResult;
181
+
161
182
  /**
162
183
  * Resolve device SVG component by ID.
163
184
  * This is a lookup registry — devices register their SVG components here.
@@ -212,7 +233,9 @@ interface SVGScreenRect {
212
233
  declare function registerCustomDeviceSVG(deviceId: string, svgString: string, frame: FrameInfo, cropViewBox?: SVGCropArea, screenRect?: SVGScreenRect): void;
213
234
  interface DeviceFrameProps {
214
235
  /** Device ID e.g. "iphone-16-pro" */
215
- device: string;
236
+ device?: string;
237
+ /** Alias for device — accepts either prop name */
238
+ deviceId?: string;
216
239
  /** Orientation */
217
240
  orientation?: "portrait" | "landscape";
218
241
  /** Scale mode: "fit" auto-scales, "manual" uses manualScale value */
@@ -252,7 +275,45 @@ interface DeviceFrameProps {
252
275
  * └── SafeAreaOverlay (optional dev tool)
253
276
  * └── ScaleBar (outside scaler, in normal flow)
254
277
  */
255
- declare function DeviceFrame({ device, orientation, scaleMode, manualScale, showSafeAreaOverlay, showScaleBar, colorScheme, onContractReady, onScaleChange, children, }: DeviceFrameProps): react_jsx_runtime.JSX.Element;
278
+ declare function DeviceFrame({ device: deviceProp, deviceId, orientation, scaleMode, manualScale, showSafeAreaOverlay, showScaleBar, colorScheme, onContractReady, onScaleChange, children, }: DeviceFrameProps): react_jsx_runtime.JSX.Element;
279
+
280
+ interface DeviceCompareProps {
281
+ /** First device ID */
282
+ deviceA: string;
283
+ /** Second device ID */
284
+ deviceB: string;
285
+ /** Orientation for both devices */
286
+ orientation?: "portrait" | "landscape";
287
+ /** Frame color scheme */
288
+ colorScheme?: "light" | "dark";
289
+ /** Show safe area overlays */
290
+ showSafeAreaOverlay?: boolean;
291
+ /** Show scale bars */
292
+ showScaleBar?: boolean;
293
+ /** Layout direction — "auto" picks row for portrait, column for landscape */
294
+ layout?: "horizontal" | "vertical" | "auto";
295
+ /** Gap between the two frames in px (default: 24) */
296
+ gap?: number;
297
+ /** Content rendered inside BOTH device frames */
298
+ children?: ReactNode;
299
+ /** Content for device A only (overrides children for A) */
300
+ childrenA?: ReactNode;
301
+ /** Content for device B only (overrides children for B) */
302
+ childrenB?: ReactNode;
303
+ /** Callback when device A contract is ready */
304
+ onContractReadyA?: (dlc: DeviceLayoutContract) => void;
305
+ /** Callback when device B contract is ready */
306
+ onContractReadyB?: (dlc: DeviceLayoutContract) => void;
307
+ }
308
+ /**
309
+ * DeviceCompare — renders two device frames side-by-side for comparison.
310
+ *
311
+ * Layout defaults to "auto": horizontal (row) in portrait, vertical (column) in landscape.
312
+ * Each frame auto-scales independently to fit its half of the container.
313
+ *
314
+ * Must be placed inside a container with explicit width and height.
315
+ */
316
+ declare function DeviceCompare({ deviceA, deviceB, orientation, colorScheme, showSafeAreaOverlay, showScaleBar, layout, gap, children, childrenA, childrenB, onContractReadyA, onContractReadyB, }: DeviceCompareProps): react_jsx_runtime.JSX.Element;
256
317
 
257
318
  interface Props {
258
319
  children: ReactNode;
@@ -405,4 +466,46 @@ interface StatusBarIndicatorsProps {
405
466
  */
406
467
  declare function StatusBarIndicators({ platform, colorScheme }: StatusBarIndicatorsProps): react_jsx_runtime.JSX.Element;
407
468
 
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 };
469
+ interface SVGOverrideEntry {
470
+ deviceId: string;
471
+ svgString: string;
472
+ bezelTop: number;
473
+ bezelBottom: number;
474
+ bezelLeft: number;
475
+ bezelRight: number;
476
+ screenRect?: SVGScreenRect;
477
+ updatedAt: string;
478
+ }
479
+ /**
480
+ * Persistent storage for custom SVG overrides.
481
+ *
482
+ * When a user uploads a custom SVG frame for a device, it's stored in
483
+ * localStorage and automatically applied on subsequent imports.
484
+ *
485
+ * SSR-safe: falls back to no-op storage when localStorage is unavailable.
486
+ */
487
+ declare class CustomSVGStore {
488
+ private storage;
489
+ constructor(storage?: Storage | null);
490
+ /** Load all stored overrides */
491
+ getAll(): Record<string, SVGOverrideEntry>;
492
+ /** Save an override and register it in the SVG registry */
493
+ save(entry: SVGOverrideEntry): void;
494
+ /** Remove an override (revert to built-in) */
495
+ remove(deviceId: string): void;
496
+ /** Check if a device has a custom override */
497
+ has(deviceId: string): boolean;
498
+ /** Get a single override by device ID */
499
+ get(deviceId: string): SVGOverrideEntry | undefined;
500
+ /**
501
+ * Apply all stored overrides to the SVG registry.
502
+ * Called during auto-registration to restore user customizations.
503
+ */
504
+ applyAll(): void;
505
+ private applyEntry;
506
+ private persist;
507
+ }
508
+ /** Get the default CustomSVGStore instance (singleton, uses localStorage) */
509
+ declare function getCustomSVGStore(): CustomSVGStore;
510
+
511
+ export { type AdaptiveScaleResult, type ButtonName, CustomSVGStore, DeviceCompare, type DeviceCompareProps, DeviceErrorBoundary, DeviceFrame, type DeviceFrameProps, DynamicStatusBar, HardwareButtons, SCALE_STEPS, type SVGCropArea, type SVGOverrideEntry, type SVGScreenRect, SafeAreaOverlay, SafeAreaView, ScaleBar, type ScreenPowerState, StatusBarIndicators, type UseAdaptiveScaleOptions, type UseOrientationResult, VolumeHUD, type VolumeState, computeAdaptiveScale, computeFullScale, computeHostSize, getCustomSVGStore, ptsToPercent, ptsToPx, pxToPts, registerCustomDeviceSVG, registerDeviceSVG, scaleValue, snapToStep, useAdaptiveScale, useContainerSize, useDeviceContract, useOrientation, useScreenPower, useVolumeControl };
package/dist/index.d.ts CHANGED
@@ -158,6 +158,27 @@ interface ScreenPowerState {
158
158
  */
159
159
  declare function useScreenPower(): ScreenPowerState;
160
160
 
161
+ interface UseOrientationResult {
162
+ /** Current orientation */
163
+ orientation: "portrait" | "landscape";
164
+ /** Convenience boolean */
165
+ isLandscape: boolean;
166
+ /** Toggle between portrait and landscape */
167
+ toggle: () => void;
168
+ /** Set orientation directly */
169
+ setOrientation: (o: "portrait" | "landscape") => void;
170
+ }
171
+ /**
172
+ * Hook for managing device orientation state with a toggle function.
173
+ *
174
+ * ```tsx
175
+ * const { orientation, toggle } = useOrientation();
176
+ * <button onClick={toggle}>Rotate</button>
177
+ * <DeviceFrame deviceId="iphone-17-pro" orientation={orientation} />
178
+ * ```
179
+ */
180
+ declare function useOrientation(initial?: "portrait" | "landscape"): UseOrientationResult;
181
+
161
182
  /**
162
183
  * Resolve device SVG component by ID.
163
184
  * This is a lookup registry — devices register their SVG components here.
@@ -212,7 +233,9 @@ interface SVGScreenRect {
212
233
  declare function registerCustomDeviceSVG(deviceId: string, svgString: string, frame: FrameInfo, cropViewBox?: SVGCropArea, screenRect?: SVGScreenRect): void;
213
234
  interface DeviceFrameProps {
214
235
  /** Device ID e.g. "iphone-16-pro" */
215
- device: string;
236
+ device?: string;
237
+ /** Alias for device — accepts either prop name */
238
+ deviceId?: string;
216
239
  /** Orientation */
217
240
  orientation?: "portrait" | "landscape";
218
241
  /** Scale mode: "fit" auto-scales, "manual" uses manualScale value */
@@ -252,7 +275,45 @@ interface DeviceFrameProps {
252
275
  * └── SafeAreaOverlay (optional dev tool)
253
276
  * └── ScaleBar (outside scaler, in normal flow)
254
277
  */
255
- declare function DeviceFrame({ device, orientation, scaleMode, manualScale, showSafeAreaOverlay, showScaleBar, colorScheme, onContractReady, onScaleChange, children, }: DeviceFrameProps): react_jsx_runtime.JSX.Element;
278
+ declare function DeviceFrame({ device: deviceProp, deviceId, orientation, scaleMode, manualScale, showSafeAreaOverlay, showScaleBar, colorScheme, onContractReady, onScaleChange, children, }: DeviceFrameProps): react_jsx_runtime.JSX.Element;
279
+
280
+ interface DeviceCompareProps {
281
+ /** First device ID */
282
+ deviceA: string;
283
+ /** Second device ID */
284
+ deviceB: string;
285
+ /** Orientation for both devices */
286
+ orientation?: "portrait" | "landscape";
287
+ /** Frame color scheme */
288
+ colorScheme?: "light" | "dark";
289
+ /** Show safe area overlays */
290
+ showSafeAreaOverlay?: boolean;
291
+ /** Show scale bars */
292
+ showScaleBar?: boolean;
293
+ /** Layout direction — "auto" picks row for portrait, column for landscape */
294
+ layout?: "horizontal" | "vertical" | "auto";
295
+ /** Gap between the two frames in px (default: 24) */
296
+ gap?: number;
297
+ /** Content rendered inside BOTH device frames */
298
+ children?: ReactNode;
299
+ /** Content for device A only (overrides children for A) */
300
+ childrenA?: ReactNode;
301
+ /** Content for device B only (overrides children for B) */
302
+ childrenB?: ReactNode;
303
+ /** Callback when device A contract is ready */
304
+ onContractReadyA?: (dlc: DeviceLayoutContract) => void;
305
+ /** Callback when device B contract is ready */
306
+ onContractReadyB?: (dlc: DeviceLayoutContract) => void;
307
+ }
308
+ /**
309
+ * DeviceCompare — renders two device frames side-by-side for comparison.
310
+ *
311
+ * Layout defaults to "auto": horizontal (row) in portrait, vertical (column) in landscape.
312
+ * Each frame auto-scales independently to fit its half of the container.
313
+ *
314
+ * Must be placed inside a container with explicit width and height.
315
+ */
316
+ declare function DeviceCompare({ deviceA, deviceB, orientation, colorScheme, showSafeAreaOverlay, showScaleBar, layout, gap, children, childrenA, childrenB, onContractReadyA, onContractReadyB, }: DeviceCompareProps): react_jsx_runtime.JSX.Element;
256
317
 
257
318
  interface Props {
258
319
  children: ReactNode;
@@ -405,4 +466,46 @@ interface StatusBarIndicatorsProps {
405
466
  */
406
467
  declare function StatusBarIndicators({ platform, colorScheme }: StatusBarIndicatorsProps): react_jsx_runtime.JSX.Element;
407
468
 
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 };
469
+ interface SVGOverrideEntry {
470
+ deviceId: string;
471
+ svgString: string;
472
+ bezelTop: number;
473
+ bezelBottom: number;
474
+ bezelLeft: number;
475
+ bezelRight: number;
476
+ screenRect?: SVGScreenRect;
477
+ updatedAt: string;
478
+ }
479
+ /**
480
+ * Persistent storage for custom SVG overrides.
481
+ *
482
+ * When a user uploads a custom SVG frame for a device, it's stored in
483
+ * localStorage and automatically applied on subsequent imports.
484
+ *
485
+ * SSR-safe: falls back to no-op storage when localStorage is unavailable.
486
+ */
487
+ declare class CustomSVGStore {
488
+ private storage;
489
+ constructor(storage?: Storage | null);
490
+ /** Load all stored overrides */
491
+ getAll(): Record<string, SVGOverrideEntry>;
492
+ /** Save an override and register it in the SVG registry */
493
+ save(entry: SVGOverrideEntry): void;
494
+ /** Remove an override (revert to built-in) */
495
+ remove(deviceId: string): void;
496
+ /** Check if a device has a custom override */
497
+ has(deviceId: string): boolean;
498
+ /** Get a single override by device ID */
499
+ get(deviceId: string): SVGOverrideEntry | undefined;
500
+ /**
501
+ * Apply all stored overrides to the SVG registry.
502
+ * Called during auto-registration to restore user customizations.
503
+ */
504
+ applyAll(): void;
505
+ private applyEntry;
506
+ private persist;
507
+ }
508
+ /** Get the default CustomSVGStore instance (singleton, uses localStorage) */
509
+ declare function getCustomSVGStore(): CustomSVGStore;
510
+
511
+ export { type AdaptiveScaleResult, type ButtonName, CustomSVGStore, DeviceCompare, type DeviceCompareProps, DeviceErrorBoundary, DeviceFrame, type DeviceFrameProps, DynamicStatusBar, HardwareButtons, SCALE_STEPS, type SVGCropArea, type SVGOverrideEntry, type SVGScreenRect, SafeAreaOverlay, SafeAreaView, ScaleBar, type ScreenPowerState, StatusBarIndicators, type UseAdaptiveScaleOptions, type UseOrientationResult, VolumeHUD, type VolumeState, computeAdaptiveScale, computeFullScale, computeHostSize, getCustomSVGStore, ptsToPercent, ptsToPx, pxToPts, registerCustomDeviceSVG, registerDeviceSVG, scaleValue, snapToStep, useAdaptiveScale, useContainerSize, useDeviceContract, useOrientation, useScreenPower, useVolumeControl };