@mmtitanl/tablets-core 0.1.1
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 +1242 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +330 -0
- package/dist/index.d.ts +330 -0
- package/dist/index.js +1249 -0
- package/dist/index.js.map +1 -0
- package/package.json +38 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/math/scale.ts","../src/hooks/use-container-size.ts","../src/hooks/use-adaptive-scale.ts","../src/hooks/use-device-contract.ts","../src/hooks/use-orientation.ts","../src/hooks/use-volume-control.ts","../src/hooks/use-screen-power.ts","../src/hooks/use-device-frame.ts","../src/messages.ts","../src/hooks/use-fold-state.ts","../src/registration.tsx","../src/components/DeviceFrame.tsx","../src/components/DeviceErrorBoundary.tsx","../src/components/SafeAreaOverlay.tsx","../src/components/ScaleBar.tsx","../src/components/DynamicStatusBar.tsx","../src/components/DeviceCompare.tsx","../src/components/SafeAreaView.tsx","../src/components/VolumeHUD.tsx","../src/components/HardwareButtons.tsx","../src/components/StatusBarIndicators.tsx","../src/storage/custom-svg-store.ts"],"sourcesContent":["export function ptsToPx(pts: number, dpr: number): number {\n return pts * dpr;\n}\nexport function pxToPts(px: number, dpr: number): number {\n return px / dpr;\n}\nexport function ptsToPercent(pts: number, total: number): number {\n return (pts / total) * 100;\n}\nexport function scaleValue(value: number, scaleFactor: number): number {\n return value * scaleFactor;\n}\n\nexport const SCALE_STEPS = [0.25, 0.33, 0.5, 0.75, 1] as const;\n\nexport function computeAdaptiveScale(\n deviceWidth: number,\n deviceHeight: number,\n containerWidth: number,\n containerHeight: number,\n padding = 24,\n maxScale = 1,\n minScale = 0.1\n): number {\n const availW = Math.max(0, containerWidth - padding * 2);\n const availH = Math.max(0, containerHeight - padding * 2);\n if (availW <= 0 || availH <= 0) return minScale;\n const sx = availW / deviceWidth;\n const sy = availH / deviceHeight;\n const raw = Math.min(sx, sy, maxScale);\n return Math.max(raw, minScale);\n}\n\nexport function snapToStep(raw: number): number {\n const allowed = SCALE_STEPS.filter((s) => s <= raw);\n if (allowed.length === 0) return raw;\n return Math.max(...allowed);\n}\n\nexport function computeHostSize(deviceWidth: number, deviceHeight: number, scale: number) {\n return { width: deviceWidth * scale, height: deviceHeight * scale };\n}\n\nexport interface AdaptiveScaleResult {\n scale: number;\n scaledWidth: number;\n scaledHeight: number;\n deviceWidth: number;\n deviceHeight: number;\n isAtMaxScale: boolean;\n isConstrained: boolean;\n scalePercent: string;\n}\n\nexport function computeFullScale(\n deviceWidth: number,\n deviceHeight: number,\n containerWidth: number,\n containerHeight: number,\n options: { padding?: number; maxScale?: number; minScale?: number; snapToSteps?: boolean } = {}\n): AdaptiveScaleResult {\n const { padding = 24, maxScale = 1, minScale = 0.1, snapToSteps = false } = options;\n const raw = computeAdaptiveScale(deviceWidth, deviceHeight, containerWidth, containerHeight, padding, maxScale, minScale);\n const scale = snapToSteps ? snapToStep(raw) : raw;\n const { width: scaledWidth, height: scaledHeight } = computeHostSize(deviceWidth, deviceHeight, scale);\n return {\n scale,\n scaledWidth,\n scaledHeight,\n deviceWidth,\n deviceHeight,\n isAtMaxScale: scale >= maxScale - 0.0001,\n isConstrained: scale < maxScale - 0.0001,\n scalePercent: `${Math.round(scale * 100)}%`,\n };\n}\n","import { useEffect, useState, type RefObject } from \"react\";\n\nexport interface ContainerSize {\n width: number;\n height: number;\n}\n\nfunction clampToViewport(w: number, h: number): ContainerSize {\n if (typeof window === \"undefined\") return { width: w, height: h };\n const vw = window.visualViewport?.width ?? window.innerWidth;\n const vh = window.visualViewport?.height ?? window.innerHeight;\n return { width: Math.min(w, vw), height: Math.min(h, vh) };\n}\n\nfunction viewportFallback(): ContainerSize {\n if (typeof window === \"undefined\") return { width: 800, height: 600 };\n return {\n width: window.visualViewport?.width ?? window.innerWidth,\n height: window.visualViewport?.height ?? window.innerHeight,\n };\n}\n\nexport function useContainerSize(ref: RefObject<HTMLElement | null>): ContainerSize {\n const [size, setSize] = useState<ContainerSize>(() => viewportFallback());\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n\n let rafId: number | null = null;\n\n const measure = () => {\n if (rafId !== null) cancelAnimationFrame(rafId);\n rafId = requestAnimationFrame(() => {\n rafId = null;\n const rect = el.getBoundingClientRect();\n const raw = rect.height > 0 ? { width: rect.width, height: rect.height } : viewportFallback();\n setSize(clampToViewport(raw.width, raw.height));\n });\n };\n\n measure();\n const ro = new ResizeObserver(measure);\n ro.observe(el);\n return () => {\n ro.disconnect();\n if (rafId !== null) cancelAnimationFrame(rafId);\n };\n }, [ref]);\n\n return size;\n}\n","import { useMemo } from \"react\";\nimport type { DeviceMeta } from \"@mmtitanl/tablets\";\nimport { computeFullScale, type AdaptiveScaleResult } from \"../math/scale.js\";\n\nexport interface UseAdaptiveScaleOptions {\n device: DeviceMeta;\n containerWidth: number;\n containerHeight: number;\n padding?: number;\n maxScale?: number;\n minScale?: number;\n snapToSteps?: boolean;\n orientation?: \"portrait\" | \"landscape\";\n}\n\nexport function useAdaptiveScale(options: UseAdaptiveScaleOptions): AdaptiveScaleResult {\n const {\n device,\n containerWidth,\n containerHeight,\n padding = 24,\n maxScale = 1,\n minScale = 0.1,\n snapToSteps = false,\n orientation = \"portrait\",\n } = options;\n\n return useMemo(() => {\n const dw = orientation === \"portrait\" ? device.screen.width : device.screen.height;\n const dh = orientation === \"portrait\" ? device.screen.height : device.screen.width;\n return computeFullScale(dw, dh, containerWidth, containerHeight, { padding, maxScale, minScale, snapToSteps });\n }, [\n device.screen.width,\n device.screen.height,\n containerWidth,\n containerHeight,\n padding,\n maxScale,\n minScale,\n snapToSteps,\n orientation,\n ]);\n}\n","import { useMemo } from \"react\";\nimport { getDeviceContract, type DeviceLayoutContract } from \"@mmtitanl/tablets\";\n\nexport interface UseDeviceContractResult {\n contract: DeviceLayoutContract;\n cssVariables: DeviceLayoutContract[\"cssVariables\"];\n contentZone: DeviceLayoutContract[\"contentZone\"][\"portrait\"];\n}\n\nexport function useDeviceContract(\n deviceId: string,\n orientation: \"portrait\" | \"landscape\" = \"portrait\"\n): UseDeviceContractResult {\n return useMemo(() => {\n const contract = getDeviceContract(deviceId, orientation);\n return {\n contract,\n cssVariables: contract.cssVariables,\n contentZone: orientation === \"portrait\" ? contract.contentZone.portrait : contract.contentZone.landscape,\n };\n }, [deviceId, orientation]);\n}\n","import { useCallback, useState } from \"react\";\n\nexport interface UseOrientationResult {\n orientation: \"portrait\" | \"landscape\";\n isLandscape: boolean;\n toggle: () => void;\n setOrientation: (o: \"portrait\" | \"landscape\") => void;\n}\n\n/**\n * Hook for managing tablet orientation state with a toggle function.\n *\n * ```tsx\n * const { orientation, toggle } = useOrientation();\n * <button onClick={toggle}>Rotate</button>\n * <DeviceFrame deviceId=\"ipad-pro-13\" orientation={orientation} />\n * ```\n */\nexport function useOrientation(initial: \"portrait\" | \"landscape\" = \"portrait\"): UseOrientationResult {\n const [orientation, setOrientation] = useState<\"portrait\" | \"landscape\">(initial);\n const toggle = useCallback(() => {\n setOrientation((o) => (o === \"portrait\" ? \"landscape\" : \"portrait\"));\n }, []);\n return { orientation, isLandscape: orientation === \"landscape\", toggle, setOrientation };\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\n\nconst STEPS = 16;\n\nexport interface VolumeState {\n level: number;\n muted: boolean;\n hudVisible: boolean;\n volumeUp: () => void;\n volumeDown: () => void;\n toggleMute: () => void;\n}\n\nfunction applyToMedia(level: number, muted: boolean) {\n if (typeof document === \"undefined\") return;\n const nodes = document.querySelectorAll<HTMLMediaElement>(\".bielaframe-content audio, .bielaframe-content video\");\n nodes.forEach((el) => {\n el.volume = Math.max(0, Math.min(1, level));\n el.muted = muted;\n });\n}\n\nexport function useVolumeControl(initialVolume = 0.5): VolumeState {\n const [level, setLevel] = useState(initialVolume);\n const [muted, setMuted] = useState(false);\n const [hudVisible, setHudVisible] = useState(false);\n const timer = useRef<number | null>(null);\n\n const flashHUD = useCallback(() => {\n setHudVisible(true);\n if (timer.current) window.clearTimeout(timer.current);\n timer.current = window.setTimeout(() => setHudVisible(false), 1500);\n }, []);\n\n const volumeUp = useCallback(() => {\n setLevel((l) => Math.min(1, l + 1 / STEPS));\n flashHUD();\n }, [flashHUD]);\n const volumeDown = useCallback(() => {\n setLevel((l) => Math.max(0, l - 1 / STEPS));\n flashHUD();\n }, [flashHUD]);\n const toggleMute = useCallback(() => {\n setMuted((m) => !m);\n flashHUD();\n }, [flashHUD]);\n\n useEffect(() => {\n applyToMedia(level, muted);\n }, [level, muted]);\n\n return { level, muted, hudVisible, volumeUp, volumeDown, toggleMute };\n}\n","import { useCallback, useState } from \"react\";\n\nexport interface ScreenPowerState {\n isOff: boolean;\n toggle: () => void;\n}\n\nexport function useScreenPower(): ScreenPowerState {\n const [isOff, setIsOff] = useState(false);\n const toggle = useCallback(() => setIsOff((v) => !v), []);\n return { isOff, toggle };\n}\n","import { useCallback, useEffect, useState } from \"react\";\nimport { isBielaMessage, type BielaDeviceInfoMessage } from \"../messages.js\";\n\nexport interface DeviceFrameInsets {\n top: number;\n bottom: number;\n left: number;\n right: number;\n}\n\nexport interface DeviceFrameInfo {\n insets: DeviceFrameInsets;\n vars: Record<string, string>;\n platform: \"ios\" | \"android\" | null;\n deviceId: string | null;\n orientation: \"portrait\" | \"landscape\" | null;\n isReady: boolean;\n reportColorScheme: (scheme: \"light\" | \"dark\") => void;\n}\n\nfunction parsePx(value: string | undefined): number {\n if (!value) return 0;\n const n = parseFloat(value);\n return Number.isFinite(n) ? n : 0;\n}\n\nexport function useDeviceFrame(): DeviceFrameInfo {\n const [vars, setVars] = useState<Record<string, string>>({});\n const [platform, setPlatform] = useState<\"ios\" | \"android\" | null>(null);\n const [deviceId, setDeviceId] = useState<string | null>(null);\n const [orientation, setOrientation] = useState<\"portrait\" | \"landscape\" | null>(null);\n const [isReady, setIsReady] = useState(false);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const handler = (event: MessageEvent) => {\n if (!isBielaMessage(event.data)) return;\n if (event.data.type === \"biela:deviceInfo\") {\n const msg = event.data as BielaDeviceInfoMessage;\n setVars(msg.payload.vars);\n setPlatform(msg.payload.platform);\n setDeviceId(msg.payload.deviceId);\n setOrientation(msg.payload.orientation);\n setIsReady(true);\n }\n };\n window.addEventListener(\"message\", handler);\n window.parent?.postMessage({ type: \"biela:requestDeviceInfo\" }, \"*\");\n return () => window.removeEventListener(\"message\", handler);\n }, []);\n\n const reportColorScheme = useCallback((scheme: \"light\" | \"dark\") => {\n if (typeof window === \"undefined\") return;\n window.parent?.postMessage({ type: \"biela:colorScheme\", payload: { scheme } }, \"*\");\n }, []);\n\n const insets: DeviceFrameInsets = {\n top: parsePx(vars[\"--safe-top\"]),\n bottom: parsePx(vars[\"--safe-bottom\"]),\n left: parsePx(vars[\"--safe-left\"]),\n right: parsePx(vars[\"--safe-right\"]),\n };\n\n return { insets, vars, platform, deviceId, orientation, isReady, reportColorScheme };\n}\n","export const BIELA_PREFIX = \"biela:\" as const;\n\nexport interface BielaDeviceInfoMessage {\n type: \"biela:deviceInfo\";\n payload: {\n vars: Record<string, string>;\n platform: \"ios\" | \"android\";\n deviceId: string;\n orientation: \"portrait\" | \"landscape\";\n };\n}\nexport interface BielaRequestMessage {\n type: \"biela:requestDeviceInfo\";\n}\nexport interface BielaColorSchemeMessage {\n type: \"biela:colorScheme\";\n payload: { scheme: \"light\" | \"dark\" };\n}\n\nexport function isBielaMessage(data: unknown): data is { type: string } {\n return (\n typeof data === \"object\" &&\n data !== null &&\n \"type\" in data &&\n typeof (data as { type: unknown }).type === \"string\" &&\n (data as { type: string }).type.startsWith(BIELA_PREFIX)\n );\n}\n","import { useState, useCallback } from \"react\";\n\nexport type FoldState = \"folded\" | \"open\";\n\nexport interface UseFoldStateResult {\n foldState: FoldState;\n isOpen: boolean;\n deviceId: string;\n toggle: () => void;\n setFoldState: (state: FoldState) => void;\n}\n\n/**\n * Manages fold state for foldable tablet devices.\n * Convention: the open variant uses `${baseDeviceId}-open`.\n */\nexport function useFoldState(\n baseDeviceId: string,\n initial: FoldState = \"folded\"\n): UseFoldStateResult {\n const [foldState, setFoldStateRaw] = useState<FoldState>(initial);\n\n const toggle = useCallback(() => {\n setFoldStateRaw((s) => (s === \"folded\" ? \"open\" : \"folded\"));\n }, []);\n\n const setFoldState = useCallback((state: FoldState) => {\n setFoldStateRaw(state);\n }, []);\n\n const isOpen = foldState === \"open\";\n const deviceId = isOpen ? `${baseDeviceId}-open` : baseDeviceId;\n\n return { foldState, isOpen, deviceId, toggle, setFoldState };\n}\n","import type { ComponentType, CSSProperties } from \"react\";\nimport { scopeSVGIds, type SVGScreenRect } from \"@mmtitanl/tablets\";\n\nexport type DeviceSVGComponent = ComponentType<{\n colorScheme?: \"light\" | \"dark\";\n style?: CSSProperties;\n}>;\n\nexport interface FrameInfo {\n bezelTop: number;\n bezelBottom: number;\n bezelLeft: number;\n bezelRight: number;\n totalWidth: number;\n totalHeight: number;\n screenWidth: number;\n screenHeight: number;\n screenRadius: number;\n /** Optional per-edge overrides. Fall back to screenRadius when unset. */\n screenRadiusTop?: number;\n screenRadiusBottom?: number;\n}\n\nexport interface SVGCropArea {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface LandscapeSVGRegistration {\n svgString: string;\n frame: FrameInfo;\n cropViewBox?: SVGCropArea;\n screenRect?: SVGScreenRect;\n}\n\nexport interface LandscapeBuiltinRegistration {\n component: DeviceSVGComponent;\n frame: FrameInfo;\n screenRect?: SVGScreenRect;\n}\n\ninterface RegistryEntry {\n component: DeviceSVGComponent;\n frame: FrameInfo;\n screenRect?: SVGScreenRect;\n landscapeComponent?: DeviceSVGComponent;\n landscapeFrame?: FrameInfo;\n landscapeScreenRect?: SVGScreenRect;\n}\n\nconst SVG_REGISTRY = new Map<string, RegistryEntry>();\n\nexport function registerDeviceSVG(\n deviceId: string,\n component: DeviceSVGComponent,\n frame: FrameInfo,\n screenRect?: SVGScreenRect,\n landscape?: LandscapeBuiltinRegistration\n): void {\n SVG_REGISTRY.set(deviceId, {\n component,\n frame,\n screenRect,\n landscapeComponent: landscape?.component,\n landscapeFrame: landscape?.frame,\n landscapeScreenRect: landscape?.screenRect,\n });\n}\n\nexport function getDeviceSVG(deviceId: string): RegistryEntry | undefined {\n return SVG_REGISTRY.get(deviceId);\n}\n\nfunction buildCustomComponent(\n deviceId: string,\n svgString: string,\n cropViewBox: SVGCropArea | undefined,\n screenRect: SVGScreenRect | undefined,\n suffix: string\n): DeviceSVGComponent {\n const scopeKey = suffix ? `${deviceId}${suffix}` : deviceId;\n let svg = scopeSVGIds(svgString, scopeKey);\n if (cropViewBox) {\n svg = svg.replace(\n /<svg\\b([^>]*)>/i,\n (_m, attrs: string) => {\n const stripped = attrs\n .replace(/\\sviewBox\\s*=\\s*[\"'][^\"']*[\"']/i, \"\")\n .replace(/\\swidth\\s*=\\s*[\"'][^\"']*[\"']/i, \"\")\n .replace(/\\sheight\\s*=\\s*[\"'][^\"']*[\"']/i, \"\");\n return `<svg${stripped} viewBox=\"${cropViewBox.x} ${cropViewBox.y} ${cropViewBox.width} ${cropViewBox.height}\" width=\"100%\" height=\"100%\">`;\n }\n );\n } else {\n svg = svg.replace(\n /<svg\\b([^>]*)>/i,\n (_m, attrs: string) => {\n const stripped = attrs.replace(/\\swidth\\s*=\\s*[\"'][^\"']*[\"']/i, \"\").replace(/\\sheight\\s*=\\s*[\"'][^\"']*[\"']/i, \"\");\n return `<svg${stripped} width=\"100%\" height=\"100%\">`;\n }\n );\n }\n\n // No mask needed — the iframe (bielaframe-content) is rendered ON TOP of\n // the SVG in DeviceFrame, clipped to the screen rect via clip-path.\n // The SVG just provides bezel/body decoration underneath.\n void screenRect;\n\n const Component: DeviceSVGComponent = ({ style }) => (\n <span\n style={{ display: \"block\", width: \"100%\", height: \"100%\", ...style }}\n dangerouslySetInnerHTML={{ __html: svg }}\n />\n );\n Component.displayName = `CustomDeviceSVG(${scopeKey})`;\n return Component;\n}\n\nexport function registerCustomDeviceSVG(\n deviceId: string,\n svgString: string,\n frame: FrameInfo,\n cropViewBox?: SVGCropArea,\n screenRect?: SVGScreenRect,\n landscape?: LandscapeSVGRegistration\n): void {\n const portraitComponent = buildCustomComponent(deviceId, svgString, cropViewBox, screenRect, \"\");\n const landscapeComponent = landscape\n ? buildCustomComponent(deviceId, landscape.svgString, landscape.cropViewBox, landscape.screenRect, \"-landscape\")\n : undefined;\n\n SVG_REGISTRY.set(deviceId, {\n component: portraitComponent,\n frame,\n screenRect,\n landscapeComponent,\n landscapeFrame: landscape?.frame,\n landscapeScreenRect: landscape?.screenRect,\n });\n}\n","import { useEffect, useMemo, useRef, useState, type ReactNode, type RefObject } from \"react\";\nimport {\n getDeviceContract,\n getDeviceMetadata,\n type DeviceLayoutContract,\n} from \"@mmtitanl/tablets\";\nimport { computeFullScale, type AdaptiveScaleResult } from \"../math/scale.js\";\nimport { useContainerSize } from \"../hooks/use-container-size.js\";\nimport { DeviceErrorBoundary } from \"./DeviceErrorBoundary.js\";\nimport { SafeAreaOverlay } from \"./SafeAreaOverlay.js\";\nimport { ScaleBar } from \"./ScaleBar.js\";\nimport { DynamicStatusBar } from \"./DynamicStatusBar.js\";\nimport { getDeviceSVG, type DeviceSVGComponent } from \"../registration.js\";\nimport {\n // Tablets\n IPadPro13SVG, IPAD_PRO_13_FRAME, IPAD_PRO_13_SCREEN_RECT,\n IPadPro11SVG, IPAD_PRO_11_FRAME, IPAD_PRO_11_SCREEN_RECT,\n IPadAir13SVG, IPAD_AIR_13_FRAME, IPAD_AIR_13_SCREEN_RECT,\n IPadAir11SVG, IPAD_AIR_11_FRAME, IPAD_AIR_11_SCREEN_RECT,\n IPadMini7SVG, IPAD_MINI_7_FRAME, IPAD_MINI_7_SCREEN_RECT,\n GalaxyTabS10SVG, GALAXY_TAB_S10_FRAME, GALAXY_TAB_S10_SCREEN_RECT,\n GalaxyTabS10UltraSVG, GALAXY_TAB_S10_ULTRA_FRAME, GALAXY_TAB_S10_ULTRA_SCREEN_RECT,\n GalaxyTabS10FeSVG, GALAXY_TAB_S10_FE_FRAME, GALAXY_TAB_S10_FE_SCREEN_RECT,\n // Phones — iOS\n IPhone17ProMaxSVG, IPHONE_17_PRO_MAX_FRAME, IPHONE_17_PRO_MAX_SCREEN_RECT,\n IPhone17ProSVG, IPHONE_17_PRO_FRAME, IPHONE_17_PRO_SCREEN_RECT,\n IPhoneAirSVG, IPHONE_AIR_FRAME, IPHONE_AIR_SCREEN_RECT,\n IPhone16SVG, IPHONE_16_FRAME, IPHONE_16_SCREEN_RECT,\n IPhone16eSVG, IPHONE_16E_FRAME, IPHONE_16E_SCREEN_RECT,\n IPhoneSE3SVG, IPHONE_SE_3_FRAME, IPHONE_SE_3_SCREEN_RECT,\n // Phones — Android\n GalaxyS25SVG, GALAXY_S25_FRAME, GALAXY_S25_SCREEN_RECT,\n GalaxyS25EdgeSVG, GALAXY_S25_EDGE_FRAME,\n GalaxyS25UltraSVG, GALAXY_S25_ULTRA_FRAME, GALAXY_S25_ULTRA_SCREEN_RECT,\n Pixel9ProSVG, PIXEL_9_PRO_FRAME, PIXEL_9_PRO_SCREEN_RECT,\n Pixel9ProXLSVG, PIXEL_9_PRO_XL_FRAME, PIXEL_9_PRO_XL_SCREEN_RECT,\n // Foldables\n GalaxyZFold7SVG, GALAXY_Z_FOLD_7_FRAME, GALAXY_Z_FOLD_7_SCREEN_RECT,\n GalaxyZFold7OpenSVG, GALAXY_Z_FOLD_7_OPEN_FRAME, GALAXY_Z_FOLD_7_OPEN_SCREEN_RECT,\n} from \"@mmtitanl/tablets\";\nimport { registerDeviceSVG } from \"../registration.js\";\n\nlet didAutoRegister = false;\nfunction ensureBuiltinsRegistered() {\n if (didAutoRegister) return;\n // Tablets\n registerDeviceSVG(\"ipad-pro-13\", IPadPro13SVG as DeviceSVGComponent, IPAD_PRO_13_FRAME, IPAD_PRO_13_SCREEN_RECT);\n registerDeviceSVG(\"ipad-pro-11\", IPadPro11SVG as DeviceSVGComponent, IPAD_PRO_11_FRAME, IPAD_PRO_11_SCREEN_RECT);\n registerDeviceSVG(\"ipad-air-13\", IPadAir13SVG as DeviceSVGComponent, IPAD_AIR_13_FRAME, IPAD_AIR_13_SCREEN_RECT);\n registerDeviceSVG(\"ipad-air-11\", IPadAir11SVG as DeviceSVGComponent, IPAD_AIR_11_FRAME, IPAD_AIR_11_SCREEN_RECT);\n registerDeviceSVG(\"ipad-mini-7\", IPadMini7SVG as DeviceSVGComponent, IPAD_MINI_7_FRAME, IPAD_MINI_7_SCREEN_RECT);\n registerDeviceSVG(\"galaxy-tab-s10\", GalaxyTabS10SVG as DeviceSVGComponent, GALAXY_TAB_S10_FRAME, GALAXY_TAB_S10_SCREEN_RECT);\n registerDeviceSVG(\"galaxy-tab-s10-ultra\", GalaxyTabS10UltraSVG as DeviceSVGComponent, GALAXY_TAB_S10_ULTRA_FRAME, GALAXY_TAB_S10_ULTRA_SCREEN_RECT);\n registerDeviceSVG(\"galaxy-tab-s10-fe\", GalaxyTabS10FeSVG as DeviceSVGComponent, GALAXY_TAB_S10_FE_FRAME, GALAXY_TAB_S10_FE_SCREEN_RECT);\n // Phones — iOS\n registerDeviceSVG(\"iphone-17-pro-max\", IPhone17ProMaxSVG as DeviceSVGComponent, IPHONE_17_PRO_MAX_FRAME, IPHONE_17_PRO_MAX_SCREEN_RECT);\n registerDeviceSVG(\"iphone-17-pro\", IPhone17ProSVG as DeviceSVGComponent, IPHONE_17_PRO_FRAME, IPHONE_17_PRO_SCREEN_RECT);\n registerDeviceSVG(\"iphone-air\", IPhoneAirSVG as DeviceSVGComponent, IPHONE_AIR_FRAME, IPHONE_AIR_SCREEN_RECT);\n registerDeviceSVG(\"iphone-16\", IPhone16SVG as DeviceSVGComponent, IPHONE_16_FRAME, IPHONE_16_SCREEN_RECT);\n registerDeviceSVG(\"iphone-16e\", IPhone16eSVG as DeviceSVGComponent, IPHONE_16E_FRAME, IPHONE_16E_SCREEN_RECT);\n registerDeviceSVG(\"iphone-se-3\", IPhoneSE3SVG as DeviceSVGComponent, IPHONE_SE_3_FRAME, IPHONE_SE_3_SCREEN_RECT);\n // Phones — Android\n registerDeviceSVG(\"galaxy-s25\", GalaxyS25SVG as DeviceSVGComponent, GALAXY_S25_FRAME, GALAXY_S25_SCREEN_RECT);\n registerDeviceSVG(\"galaxy-s25-edge\", GalaxyS25EdgeSVG as DeviceSVGComponent, GALAXY_S25_EDGE_FRAME);\n registerDeviceSVG(\"galaxy-s25-ultra\", GalaxyS25UltraSVG as DeviceSVGComponent, GALAXY_S25_ULTRA_FRAME, GALAXY_S25_ULTRA_SCREEN_RECT);\n registerDeviceSVG(\"pixel-9-pro\", Pixel9ProSVG as DeviceSVGComponent, PIXEL_9_PRO_FRAME, PIXEL_9_PRO_SCREEN_RECT);\n registerDeviceSVG(\"pixel-9-pro-xl\", Pixel9ProXLSVG as DeviceSVGComponent, PIXEL_9_PRO_XL_FRAME, PIXEL_9_PRO_XL_SCREEN_RECT);\n // Foldables\n registerDeviceSVG(\"galaxy-z-fold-7\", GalaxyZFold7SVG as DeviceSVGComponent, GALAXY_Z_FOLD_7_FRAME, GALAXY_Z_FOLD_7_SCREEN_RECT);\n registerDeviceSVG(\"galaxy-z-fold-7-open\", GalaxyZFold7OpenSVG as DeviceSVGComponent, GALAXY_Z_FOLD_7_OPEN_FRAME, GALAXY_Z_FOLD_7_OPEN_SCREEN_RECT);\n didAutoRegister = true;\n}\n\nexport interface DeviceFrameProps {\n device?: string;\n deviceId?: string;\n orientation?: \"portrait\" | \"landscape\";\n scaleMode?: \"fit\" | \"manual\" | \"steps\";\n manualScale?: number;\n showSafeAreaOverlay?: boolean;\n showDLCPanel?: boolean;\n showScaleBar?: boolean;\n showStatusBar?: boolean;\n colorScheme?: \"light\" | \"dark\";\n iframeRef?: RefObject<HTMLIFrameElement | null>;\n onColorSchemeChange?: (scheme: \"light\" | \"dark\") => void;\n onContractReady?: (dlc: DeviceLayoutContract) => void;\n onScaleChange?: (scale: number) => void;\n children?: ReactNode;\n}\n\nfunction sendDeviceInfo(\n iframe: HTMLIFrameElement | null,\n contract: DeviceLayoutContract,\n orientation: \"portrait\" | \"landscape\"\n) {\n if (!iframe?.contentWindow) return;\n iframe.contentWindow.postMessage(\n {\n type: \"biela:deviceInfo\",\n payload: {\n vars: contract.cssVariables,\n platform: contract.device.platform,\n deviceId: contract.device.id,\n orientation,\n },\n },\n \"*\"\n );\n}\n\nexport function DeviceFrame({\n device,\n deviceId,\n orientation = \"portrait\",\n scaleMode = \"fit\",\n manualScale = 1,\n showSafeAreaOverlay = false,\n showScaleBar = true,\n showStatusBar = true,\n colorScheme = \"light\",\n iframeRef,\n onColorSchemeChange,\n onContractReady,\n onScaleChange,\n children,\n}: DeviceFrameProps) {\n ensureBuiltinsRegistered();\n\n const resolvedId = device ?? deviceId;\n if (!resolvedId) throw new Error(\"DeviceFrame requires `device` or `deviceId`\");\n\n const meta = getDeviceMetadata(resolvedId);\n const contract = useMemo(() => getDeviceContract(resolvedId, orientation), [resolvedId, orientation]);\n\n const portW = meta.screen.width;\n const portH = meta.screen.height;\n const rotateFrame = orientation === \"landscape\";\n // Content dimensions swap for landscape.\n const dw = rotateFrame ? portH : portW;\n const dh = rotateFrame ? portW : portH;\n\n const sentinelRef = useRef<HTMLDivElement>(null);\n const frameContainerRef = useRef<HTMLDivElement>(null);\n const containerSize = useContainerSize(sentinelRef);\n\n const svgEntryEarly = getDeviceSVG(resolvedId);\n const portraitFrameEarly = svgEntryEarly?.frame;\n const landscapeFrameEarly = svgEntryEarly?.landscapeFrame;\n const hasLandscapeSVGEarly = !!svgEntryEarly?.landscapeComponent && !!landscapeFrameEarly;\n // Active frame total dims drive the host box.\n // - With 2-SVG: pick the matching frame for the current orientation.\n // - With 1-SVG (rotated): swap portrait dims when landscape.\n const fitW = portraitFrameEarly\n ? (rotateFrame\n ? (hasLandscapeSVGEarly ? landscapeFrameEarly!.totalWidth : portraitFrameEarly.totalHeight)\n : portraitFrameEarly.totalWidth)\n : (rotateFrame ? portH : portW);\n const fitH = portraitFrameEarly\n ? (rotateFrame\n ? (hasLandscapeSVGEarly ? landscapeFrameEarly!.totalHeight : portraitFrameEarly.totalWidth)\n : portraitFrameEarly.totalHeight)\n : (rotateFrame ? portW : portH);\n\n const fitResult: AdaptiveScaleResult = useMemo(\n () =>\n computeFullScale(fitW, fitH, containerSize.width, containerSize.height, {\n snapToSteps: scaleMode === \"steps\",\n }),\n [fitW, fitH, containerSize.width, containerSize.height, scaleMode]\n );\n\n const [overrideScale, setOverrideScale] = useState<number | null>(null);\n\n useEffect(() => {\n setOverrideScale(null);\n }, [orientation]);\n\n const scale =\n scaleMode === \"manual\" ? manualScale : overrideScale ?? fitResult.scale;\n const hostWidth = fitW * scale;\n const hostHeight = fitH * scale;\n const isAtMaxScale = scale >= 0.9999;\n\n useEffect(() => {\n onContractReady?.(contract);\n }, [contract, onContractReady]);\n\n useEffect(() => {\n onScaleChange?.(scale);\n }, [scale, onScaleChange]);\n\n useEffect(() => {\n if (!iframeRef?.current) return;\n sendDeviceInfo(iframeRef.current, contract, orientation);\n const onLoad = () => sendDeviceInfo(iframeRef.current, contract, orientation);\n iframeRef.current.addEventListener(\"load\", onLoad);\n return () => iframeRef.current?.removeEventListener(\"load\", onLoad);\n }, [iframeRef, contract, orientation]);\n\n useEffect(() => {\n if (!iframeRef) return;\n const handler = (event: MessageEvent) => {\n const data = event.data as { type?: string; payload?: { scheme?: \"light\" | \"dark\" } } | null;\n if (!data || typeof data !== \"object\") return;\n if (data.type === \"biela:requestDeviceInfo\") {\n sendDeviceInfo(iframeRef.current, contract, orientation);\n } else if (data.type === \"biela:colorScheme\" && data.payload?.scheme) {\n onColorSchemeChange?.(data.payload.scheme);\n }\n };\n window.addEventListener(\"message\", handler);\n return () => window.removeEventListener(\"message\", handler);\n }, [iframeRef, contract, orientation, onColorSchemeChange]);\n\n const svgEntry = getDeviceSVG(resolvedId);\n const SVGComponent: DeviceSVGComponent | null = svgEntry?.component ?? null;\n const portraitFrame = svgEntry?.frame;\n const LandscapeSVGComponent: DeviceSVGComponent | null = svgEntry?.landscapeComponent ?? null;\n const landscapeFrame = svgEntry?.landscapeFrame;\n const hasLandscapeSVG = !!LandscapeSVGComponent && !!landscapeFrame;\n\n const cssVarsStyle = contract.cssVariables as unknown as React.CSSProperties;\n\n // For 2-SVG devices, use a stable container sized to the maximum of portrait and\n // landscape frame dims. scalerW/scalerH never change between orientations — no layout\n // jump, no rotation tricks. The host clips to the correct visible rectangle via\n // overflow:hidden. For single-SVG devices the rotation fallback is unchanged.\n const activeFrame = hasLandscapeSVG && rotateFrame ? landscapeFrame! : portraitFrame;\n const scalerW = hasLandscapeSVG\n ? Math.max(portraitFrame?.totalWidth ?? dw, landscapeFrame?.totalWidth ?? dh)\n : (activeFrame?.totalWidth ?? (rotateFrame ? portW : dw));\n const scalerH = hasLandscapeSVG\n ? Math.max(portraitFrame?.totalHeight ?? dh, landscapeFrame?.totalHeight ?? dw)\n : (activeFrame?.totalHeight ?? (rotateFrame ? portH : dh));\n const contentBezelLeft = activeFrame?.bezelLeft ?? 0;\n const contentBezelTop = activeFrame?.bezelTop ?? 0;\n const contentScreenW = activeFrame?.screenWidth ?? dw;\n const contentScreenH = activeFrame?.screenHeight ?? dh;\n const baseRadius = activeFrame?.screenRadius ?? meta.screen.cornerRadius ?? 0;\n const radiusTop = activeFrame?.screenRadiusTop ?? baseRadius;\n const radiusBottom = activeFrame?.screenRadiusBottom ?? baseRadius;\n\n const useRotationFallback = rotateFrame && !hasLandscapeSVG;\n const scalerTransform = useRotationFallback\n ? `scale(${scale}) translate(0px, ${scalerW}px) rotate(-90deg)`\n : `scale(${scale})`;\n\n return (\n <div\n ref={sentinelRef}\n className=\"bielaframe-sentinel\"\n style={{ width: \"100%\", height: \"100%\", display: \"flex\", flexDirection: \"column\", alignItems: \"center\", justifyContent: \"center\", overflow: \"hidden\" }}\n >\n <div\n className=\"bielaframe-host\"\n style={{\n width: hostWidth,\n height: hostHeight,\n position: \"relative\",\n flexShrink: 0,\n overflow: \"hidden\",\n transition: \"width 400ms cubic-bezier(0.4, 0, 0.2, 1), height 400ms cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n >\n <div\n className=\"bielaframe-scaler\"\n ref={frameContainerRef}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: scalerW,\n height: scalerH,\n transform: scalerTransform,\n transformOrigin: \"top left\",\n willChange: \"transform\",\n transition: \"transform 400ms cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n >\n {SVGComponent && portraitFrame && (\n <div\n aria-hidden\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: portraitFrame.totalWidth,\n height: portraitFrame.totalHeight,\n pointerEvents: \"none\",\n zIndex: 1,\n opacity: hasLandscapeSVG && rotateFrame ? 0 : 1,\n transition: \"opacity 400ms cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n >\n <SVGComponent\n colorScheme={colorScheme}\n style={{ position: \"absolute\", top: 0, left: 0, width: \"100%\", height: \"100%\", pointerEvents: \"none\" }}\n />\n </div>\n )}\n\n {hasLandscapeSVG && LandscapeSVGComponent && landscapeFrame && (\n <div\n aria-hidden\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: landscapeFrame.totalWidth,\n height: landscapeFrame.totalHeight,\n pointerEvents: \"none\",\n zIndex: 1,\n opacity: rotateFrame ? 1 : 0,\n transition: \"opacity 400ms cubic-bezier(0.4, 0, 0.2, 1)\",\n }}\n >\n <LandscapeSVGComponent\n colorScheme={colorScheme}\n style={{ position: \"absolute\", top: 0, left: 0, width: \"100%\", height: \"100%\", pointerEvents: \"none\" }}\n />\n </div>\n )}\n\n <div\n className=\"bielaframe-content\"\n style={{\n position: \"absolute\",\n left: contentBezelLeft,\n top: contentBezelTop,\n width: contentScreenW,\n height: contentScreenH,\n // `border-radius + overflow:hidden` clips the <iframe> child\n // in every browser. clip-path is kept as belt-and-braces — some\n // engines apply it to the iframe, some don't. Per-edge radii\n // (top vs bottom) let devices with asymmetric corners — e.g.\n // flat-bottom — clip correctly.\n borderRadius: `${radiusTop}px ${radiusTop}px ${radiusBottom}px ${radiusBottom}px`,\n clipPath: `inset(0 round ${radiusTop}px ${radiusTop}px ${radiusBottom}px ${radiusBottom}px)`,\n overflow: \"hidden\",\n isolation: \"isolate\",\n backfaceVisibility: \"hidden\",\n transform: \"translateZ(0)\",\n background: colorScheme === \"dark\" ? \"#000\" : \"#fff\",\n zIndex: 5,\n ...cssVarsStyle,\n }}\n >\n <DeviceErrorBoundary>{children}</DeviceErrorBoundary>\n {showStatusBar && (\n <DynamicStatusBar contract={contract} orientation={orientation} colorScheme={colorScheme} />\n )}\n {showSafeAreaOverlay && <SafeAreaOverlay contract={contract} orientation={orientation} />}\n </div>\n </div>\n </div>\n\n {showScaleBar && (\n <ScaleBar\n deviceName={meta.name}\n deviceWidth={dw}\n deviceHeight={dh}\n scale={scale}\n scalePercent={`${Math.round(scale * 100)}%`}\n isAtMaxScale={isAtMaxScale}\n isConstrained={!isAtMaxScale}\n onScaleChange={(s) => setOverrideScale(s)}\n onFit={() => setOverrideScale(null)}\n onRealSize={() => setOverrideScale(1)}\n />\n )}\n </div>\n );\n}\n","import { Component, type ErrorInfo, type ReactNode } from \"react\";\n\ninterface Props {\n children: ReactNode;\n fallback?: ReactNode;\n}\n\ninterface State {\n hasError: boolean;\n error: Error | null;\n}\n\nexport class DeviceErrorBoundary extends Component<Props, State> {\n constructor(props: Props) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: Error): State {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo): void {\n console.error(\"[BielaFrame] device content crashed\", error, errorInfo);\n }\n\n render(): ReactNode {\n if (this.state.hasError) {\n return (\n this.props.fallback ?? (\n <div\n style={{\n padding: 20,\n fontFamily: \"system-ui\",\n color: \"#ff453a\",\n background: \"#1c1c1e\",\n height: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n textAlign: \"center\",\n }}\n >\n <div>\n <div style={{ fontSize: 14, fontWeight: 600, marginBottom: 8 }}>Component crashed</div>\n <div style={{ fontSize: 12, opacity: 0.8 }}>{this.state.error?.message}</div>\n </div>\n </div>\n )\n );\n }\n return this.props.children;\n }\n}\n","import type { DeviceLayoutContract } from \"@mmtitanl/tablets\";\n\nexport interface SafeAreaOverlayProps {\n contract: DeviceLayoutContract;\n orientation: \"portrait\" | \"landscape\";\n}\n\nexport function SafeAreaOverlay({ contract, orientation }: SafeAreaOverlayProps) {\n const safe = orientation === \"portrait\" ? contract.safeArea.portrait : contract.safeArea.landscape;\n const w = orientation === \"portrait\" ? contract.screen.width : contract.screen.height;\n const h = orientation === \"portrait\" ? contract.screen.height : contract.screen.width;\n const baseStyle = { position: \"absolute\" as const, pointerEvents: \"none\" as const };\n return (\n <>\n <div style={{ ...baseStyle, top: 0, left: 0, right: 0, height: safe.top, background: \"rgba(255,69,58,0.25)\" }} />\n <div\n style={{ ...baseStyle, bottom: 0, left: 0, right: 0, height: safe.bottom, background: \"rgba(255,69,58,0.25)\" }}\n />\n <div style={{ ...baseStyle, top: 0, left: 0, bottom: 0, width: safe.left, background: \"rgba(255,69,58,0.25)\" }} />\n <div\n style={{ ...baseStyle, top: 0, right: 0, bottom: 0, width: safe.right, background: \"rgba(255,69,58,0.25)\" }}\n />\n <div\n style={{\n ...baseStyle,\n top: safe.top,\n bottom: safe.bottom,\n left: safe.left,\n right: safe.right,\n outline: \"1px dashed rgba(48,209,88,0.6)\",\n }}\n />\n <div\n style={{\n ...baseStyle,\n top: 4,\n left: 8,\n color: \"white\",\n background: \"rgba(0,0,0,0.6)\",\n padding: \"2px 6px\",\n fontSize: 10,\n fontFamily: \"ui-monospace, monospace\",\n borderRadius: 4,\n }}\n >\n {w}×{h} · safe {safe.top}/{safe.bottom}/{safe.left}/{safe.right}\n </div>\n </>\n );\n}\n","import { SCALE_STEPS } from \"../math/scale.js\";\n\nexport interface ScaleBarProps {\n deviceName: string;\n deviceWidth: number;\n deviceHeight: number;\n scale: number;\n scalePercent: string;\n isAtMaxScale: boolean;\n isConstrained: boolean;\n onScaleChange?: (scale: number) => void;\n onFit?: () => void;\n onRealSize?: () => void;\n}\n\nexport function ScaleBar({\n deviceName,\n deviceWidth,\n deviceHeight,\n scale,\n scalePercent,\n isAtMaxScale,\n onScaleChange,\n onFit,\n onRealSize,\n}: ScaleBarProps) {\n return (\n <div\n role=\"region\"\n aria-label=\"Device scale controls\"\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n padding: \"8px 12px\",\n background: \"rgba(28,28,30,0.92)\",\n color: \"white\",\n borderRadius: 8,\n fontFamily: \"ui-monospace, monospace\",\n fontSize: 12,\n marginTop: 8,\n }}\n >\n <span>{deviceName}</span>\n <span style={{ opacity: 0.6 }}>·</span>\n <span>\n {deviceWidth}×{deviceHeight}pt\n </span>\n <input\n type=\"range\"\n min={0.1}\n max={2}\n step={0.01}\n value={scale}\n aria-label=\"Scale\"\n aria-valuenow={scale}\n role=\"slider\"\n onChange={(e) => onScaleChange?.(parseFloat(e.target.value))}\n style={{ flex: 1 }}\n />\n <span aria-live=\"polite\" style={{ width: 40, textAlign: \"right\" }}>\n {scalePercent}\n </span>\n <button onClick={onFit} type=\"button\" style={btn}>\n Fit\n </button>\n <button onClick={onRealSize} type=\"button\" style={{ ...btn, opacity: isAtMaxScale ? 0.5 : 1 }}>\n 1:1\n </button>\n </div>\n );\n}\n\nconst btn = {\n background: \"transparent\",\n color: \"white\",\n border: \"1px solid rgba(255,255,255,0.25)\",\n padding: \"2px 8px\",\n borderRadius: 4,\n cursor: \"pointer\",\n fontSize: 11,\n};\n","import { useEffect, useState, type CSSProperties } from \"react\";\nimport type { DeviceLayoutContract } from \"@mmtitanl/tablets\";\n\nexport interface DynamicStatusBarProps {\n contract: DeviceLayoutContract;\n orientation: \"portrait\" | \"landscape\";\n colorScheme: \"light\" | \"dark\";\n showLiveClock?: boolean;\n fixedTime?: string;\n}\n\nfunction formatNow(): string {\n const now = new Date();\n return `${now.getHours()}:${now.getMinutes().toString().padStart(2, \"0\")}`;\n}\n\nexport function DynamicStatusBar({\n contract,\n orientation,\n colorScheme,\n showLiveClock = true,\n fixedTime,\n}: DynamicStatusBarProps) {\n const [now, setNow] = useState(formatNow);\n\n useEffect(() => {\n if (!showLiveClock || fixedTime) return;\n const id = window.setInterval(() => setNow(formatNow()), 30_000);\n return () => window.clearInterval(id);\n }, [showLiveClock, fixedTime]);\n\n // iOS in landscape hides the status bar entirely.\n if (orientation === \"landscape\" && contract.device.platform === \"ios\") return null;\n\n const time = fixedTime ?? (showLiveClock ? now : \"9:41\");\n const platform = contract.device.platform;\n const statusBarStyle = contract.statusBar.style;\n const height = contract.statusBar.height;\n const textColor = colorScheme === \"dark\" ? \"#fff\" : \"#000\";\n const bgColor = colorScheme === \"dark\" ? \"#000\" : \"#fff\";\n const fontFamily = platform === \"ios\"\n ? \"-apple-system, 'SF Pro Text', 'Helvetica Neue', sans-serif\"\n : \"'Roboto', 'Google Sans', sans-serif\";\n const baseFontSize = platform === \"ios\" ? 15 : 12;\n const clockStyle: CSSProperties = {\n color: textColor,\n fontFamily,\n fontSize: baseFontSize,\n fontWeight: platform === \"ios\" ? 600 : 400,\n letterSpacing: platform === \"ios\" ? 0.3 : 0,\n lineHeight: `${height}px`,\n whiteSpace: \"nowrap\",\n };\n // Patch only the area around the clock — leave the rest of the bar alone so\n // the iframe app's own mock status bar (signal / wifi / battery) shows\n // through on the sides.\n const patchStyle: CSSProperties = {\n position: \"absolute\",\n top: 0,\n height,\n display: \"flex\",\n alignItems: \"center\",\n background: bgColor,\n pointerEvents: \"none\",\n };\n\n // iOS classic / fullwidth — centered narrow patch around the clock.\n if (platform === \"ios\" && statusBarStyle !== \"dynamic-island\" && statusBarStyle !== \"notch\") {\n return (\n <div\n aria-hidden\n style={{ ...patchStyle, left: \"50%\", transform: \"translateX(-50%)\", paddingLeft: 6, paddingRight: 6 }}\n >\n <span style={{ ...clockStyle, fontWeight: 500, fontSize: baseFontSize - 1 }}>{time}</span>\n </div>\n );\n }\n\n // iOS with Dynamic Island / notch — left-aligned with iOS spacing.\n if (platform === \"ios\") {\n return (\n <div aria-hidden style={{ ...patchStyle, left: 0, paddingLeft: 20, paddingRight: 8 }}>\n <span style={clockStyle}>{time}</span>\n </div>\n );\n }\n\n // Android — left-aligned.\n return (\n <div aria-hidden style={{ ...patchStyle, left: 0, paddingLeft: 16, paddingRight: 8 }}>\n <span style={clockStyle}>{time}</span>\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport type { DeviceLayoutContract } from \"@mmtitanl/tablets\";\nimport { DeviceFrame } from \"./DeviceFrame.js\";\n\nexport interface DeviceCompareProps {\n deviceA: string;\n deviceB: string;\n orientation?: \"portrait\" | \"landscape\";\n colorScheme?: \"light\" | \"dark\";\n showSafeAreaOverlay?: boolean;\n showScaleBar?: boolean;\n layout?: \"horizontal\" | \"vertical\" | \"auto\";\n gap?: number;\n children?: ReactNode;\n childrenA?: ReactNode;\n childrenB?: ReactNode;\n onContractReadyA?: (dlc: DeviceLayoutContract) => void;\n onContractReadyB?: (dlc: DeviceLayoutContract) => void;\n}\n\nexport function DeviceCompare({\n deviceA,\n deviceB,\n orientation = \"portrait\",\n colorScheme = \"light\",\n showSafeAreaOverlay,\n showScaleBar,\n layout = \"auto\",\n gap = 24,\n children,\n childrenA,\n childrenB,\n onContractReadyA,\n onContractReadyB,\n}: DeviceCompareProps) {\n const direction = layout === \"auto\" ? (orientation === \"portrait\" ? \"row\" : \"column\") : layout === \"horizontal\" ? \"row\" : \"column\";\n return (\n <div style={{ display: \"flex\", flexDirection: direction, gap, width: \"100%\", height: \"100%\" }}>\n <div style={{ flex: 1 }}>\n <DeviceFrame\n deviceId={deviceA}\n orientation={orientation}\n colorScheme={colorScheme}\n showSafeAreaOverlay={showSafeAreaOverlay}\n showScaleBar={showScaleBar}\n onContractReady={onContractReadyA}\n >\n {childrenA ?? children}\n </DeviceFrame>\n </div>\n <div style={{ flex: 1 }}>\n <DeviceFrame\n deviceId={deviceB}\n orientation={orientation}\n colorScheme={colorScheme}\n showSafeAreaOverlay={showSafeAreaOverlay}\n showScaleBar={showScaleBar}\n onContractReady={onContractReadyB}\n >\n {childrenB ?? children}\n </DeviceFrame>\n </div>\n </div>\n );\n}\n","import type { CSSProperties, ReactNode } from \"react\";\n\nexport interface SafeAreaViewProps {\n edges?: Array<\"top\" | \"bottom\" | \"left\" | \"right\">;\n children: ReactNode;\n style?: CSSProperties;\n}\n\nexport function SafeAreaView({ edges = [\"top\", \"bottom\", \"left\", \"right\"], children, style }: SafeAreaViewProps) {\n const padding: CSSProperties = {\n paddingTop: edges.includes(\"top\") ? \"var(--safe-top, 0px)\" : undefined,\n paddingBottom: edges.includes(\"bottom\") ? \"var(--safe-bottom, 0px)\" : undefined,\n paddingLeft: edges.includes(\"left\") ? \"var(--safe-left, 0px)\" : undefined,\n paddingRight: edges.includes(\"right\") ? \"var(--safe-right, 0px)\" : undefined,\n };\n return <div style={{ ...padding, ...style }}>{children}</div>;\n}\n","export interface VolumeHUDProps {\n level: number;\n muted: boolean;\n visible: boolean;\n platform: \"ios\" | \"android\";\n}\n\nexport function VolumeHUD({ level, muted, visible, platform }: VolumeHUDProps) {\n if (!visible) return null;\n const isIOS = platform === \"ios\";\n const pct = Math.round((muted ? 0 : level) * 100);\n return (\n <div\n role=\"status\"\n aria-label={`Volume ${pct}%`}\n style={{\n position: \"absolute\",\n ...(isIOS\n ? { top: \"12%\", left: \"50%\", transform: \"translateX(-50%)\", width: 6, height: 220, borderRadius: 3 }\n : { top: 16, left: \"50%\", transform: \"translateX(-50%)\", width: 240, height: 6, borderRadius: 3 }),\n background: \"rgba(255,255,255,0.2)\",\n overflow: \"hidden\",\n pointerEvents: \"none\",\n }}\n >\n <div\n style={{\n background: muted ? \"#8e8e93\" : \"white\",\n ...(isIOS ? { width: \"100%\", height: `${pct}%`, marginTop: `${100 - pct}%` } : { width: `${pct}%`, height: \"100%\" }),\n }}\n />\n </div>\n );\n}\n","import { useEffect, useState, type ReactElement, type RefObject } from \"react\";\n\nexport type ButtonName = \"volumeUp\" | \"volumeDown\" | \"power\" | \"actionButton\" | \"cameraControl\";\n\ninterface ButtonRect {\n name: ButtonName;\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\nexport interface HardwareButtonsProps {\n frameContainerRef: RefObject<HTMLDivElement | null>;\n onButtonPress?: (button: ButtonName) => void;\n enabled?: boolean;\n orientation?: \"portrait\" | \"landscape\";\n}\n\nexport function HardwareButtons({\n frameContainerRef,\n onButtonPress,\n enabled = true,\n orientation = \"portrait\",\n}: HardwareButtonsProps): ReactElement | null {\n const [rects, setRects] = useState<ButtonRect[]>([]);\n\n useEffect(() => {\n if (!enabled) return;\n const container = frameContainerRef.current;\n if (!container) return;\n const found: ButtonRect[] = [];\n const nodes = container.querySelectorAll<SVGElement>(\"[data-button]\");\n const containerRect = container.getBoundingClientRect();\n nodes.forEach((node) => {\n const name = node.getAttribute(\"data-button\") as ButtonName | null;\n if (!name) return;\n const r = node.getBoundingClientRect();\n found.push({\n name,\n left: r.left - containerRect.left,\n top: r.top - containerRect.top,\n width: r.width,\n height: r.height,\n });\n });\n setRects(found);\n }, [frameContainerRef, enabled, orientation]);\n\n if (!enabled || rects.length === 0) return null;\n\n return (\n <>\n {rects.map((r) => (\n <div\n key={r.name}\n role=\"button\"\n aria-label={r.name}\n onMouseDown={() => onButtonPress?.(r.name)}\n onTouchStart={() => onButtonPress?.(r.name)}\n style={{\n position: \"absolute\",\n left: r.left,\n top: r.top,\n width: r.width,\n height: r.height,\n cursor: \"pointer\",\n zIndex: 20,\n }}\n />\n ))}\n </>\n );\n}\n","export interface StatusBarIndicatorsProps {\n platform: \"ios\" | \"android\";\n colorScheme: \"light\" | \"dark\";\n}\n\nexport function StatusBarIndicators({ platform, colorScheme }: StatusBarIndicatorsProps) {\n const fill = colorScheme === \"dark\" ? \"white\" : \"black\";\n if (platform === \"ios\") {\n return (\n <div style={{ display: \"inline-flex\", alignItems: \"center\", gap: 6 }}>\n <svg width=\"18\" height=\"10\" viewBox=\"0 0 18 10\">\n <rect x=\"0\" y=\"6\" width=\"3\" height=\"4\" fill={fill} rx=\"1\" />\n <rect x=\"5\" y=\"4\" width=\"3\" height=\"6\" fill={fill} rx=\"1\" />\n <rect x=\"10\" y=\"2\" width=\"3\" height=\"8\" fill={fill} rx=\"1\" />\n <rect x=\"15\" y=\"0\" width=\"3\" height=\"10\" fill={fill} rx=\"1\" />\n </svg>\n <svg width=\"14\" height=\"10\" viewBox=\"0 0 14 10\">\n <path d=\"M7 9.5l3-3a4 4 0 0 0-6 0z\" fill={fill} />\n </svg>\n <svg width=\"26\" height=\"12\" viewBox=\"0 0 26 12\">\n <rect x=\"1\" y=\"1\" width=\"22\" height=\"10\" rx=\"2.5\" fill=\"none\" stroke={fill} strokeWidth=\"1\" />\n <rect x=\"24\" y=\"4\" width=\"1.5\" height=\"4\" rx=\"0.5\" fill={fill} />\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"6\" rx=\"1.5\" fill={fill} />\n </svg>\n </div>\n );\n }\n return (\n <div style={{ display: \"inline-flex\", alignItems: \"center\", gap: 6 }}>\n <svg width=\"14\" height=\"10\" viewBox=\"0 0 14 10\">\n <path d=\"M0 9 L14 9 L14 1 Z\" fill={fill} />\n </svg>\n <svg width=\"20\" height=\"10\" viewBox=\"0 0 20 10\">\n <rect x=\"1\" y=\"1\" width=\"16\" height=\"8\" rx=\"1.5\" fill=\"none\" stroke={fill} strokeWidth=\"1\" />\n <rect x=\"18\" y=\"3\" width=\"1.5\" height=\"4\" rx=\"0.5\" fill={fill} />\n <rect x=\"3\" y=\"3\" width=\"12\" height=\"4\" fill={fill} />\n </svg>\n </div>\n );\n}\n","import type { SVGScreenRect } from \"@mmtitanl/tablets\";\nimport { registerCustomDeviceSVG } from \"../registration.js\";\n\nexport interface SVGOverrideEntry {\n deviceId: string;\n name?: string;\n platform?: \"ios\" | \"android\";\n formFactor?: \"tablet\" | \"phone\" | \"foldable\";\n /** Reported logical-pt screen size (independent of SVG viewBox scale). */\n logicalScreenWidth?: number;\n logicalScreenHeight?: number;\n svgString: string;\n bezelTop: number;\n bezelBottom: number;\n bezelLeft: number;\n bezelRight: number;\n screenRect?: SVGScreenRect;\n // Optional landscape variant (separate SVG rendered when device is rotated)\n svgStringLandscape?: string;\n bezelTopLandscape?: number;\n bezelBottomLandscape?: number;\n bezelLeftLandscape?: number;\n bezelRightLandscape?: number;\n screenRectLandscape?: SVGScreenRect;\n updatedAt: string;\n}\n\nconst STORAGE_KEY = \"bielaframe-custom-tablet-svgs\";\n\nexport class CustomSVGStore {\n private storage: Storage | null;\n constructor(storage?: Storage | null) {\n this.storage = storage ?? (typeof localStorage !== \"undefined\" ? localStorage : null);\n }\n\n getAll(): Record<string, SVGOverrideEntry> {\n if (!this.storage) return {};\n try {\n const raw = this.storage.getItem(STORAGE_KEY);\n return raw ? (JSON.parse(raw) as Record<string, SVGOverrideEntry>) : {};\n } catch {\n return {};\n }\n }\n\n save(entry: SVGOverrideEntry): void {\n const all = this.getAll();\n all[entry.deviceId] = entry;\n this.persist(all);\n this.applyEntry(entry);\n }\n\n remove(deviceId: string): void {\n const all = this.getAll();\n delete all[deviceId];\n this.persist(all);\n }\n\n has(deviceId: string): boolean {\n return !!this.getAll()[deviceId];\n }\n\n get(deviceId: string): SVGOverrideEntry | undefined {\n return this.getAll()[deviceId];\n }\n\n applyAll(): void {\n const all = this.getAll();\n Object.values(all).forEach((entry) => this.applyEntry(entry));\n }\n\n private applyEntry(entry: SVGOverrideEntry): void {\n const rawW = entry.screenRect?.width ?? 0;\n const rawH = entry.screenRect?.height ?? 0;\n // Bezels + screenRect are persisted in SVG-viewBox units. If the entry\n // declared a logical screen size (the actual pt size the device reports),\n // uniformly scale everything so the iframe viewport reports logical dims\n // — otherwise the iframe gets a viewport of raw SVG units (huge) and the\n // app renders desktop-style. Uniform scale preserves bezel proportions;\n // the screen height ends up dictated by the SVG screen-rect aspect.\n // Legacy entries (no logicalScreenWidth) get inferred defaults per form\n // factor so they don't render at raw SVG pixel size.\n const FORM_FACTOR_LOGICAL_W: Record<NonNullable<SVGOverrideEntry[\"formFactor\"]>, number> = {\n tablet: 834,\n phone: 390,\n foldable: 374,\n };\n const logicalW =\n entry.logicalScreenWidth ??\n (entry.formFactor ? FORM_FACTOR_LOGICAL_W[entry.formFactor] : rawW);\n const scale = rawW > 0 ? logicalW / rawW : 1;\n\n const sr = entry.screenRect\n ? {\n x: entry.screenRect.x * scale,\n y: entry.screenRect.y * scale,\n width: rawW * scale,\n height: rawH * scale,\n rx: (entry.screenRect.rx ?? 0) * scale,\n rxTop: entry.screenRect.rxTop !== undefined\n ? entry.screenRect.rxTop * scale\n : undefined,\n rxBottom: entry.screenRect.rxBottom !== undefined\n ? entry.screenRect.rxBottom * scale\n : undefined,\n }\n : undefined;\n const portraitBezelTop = entry.bezelTop * scale;\n const portraitBezelBottom = entry.bezelBottom * scale;\n const portraitBezelLeft = entry.bezelLeft * scale;\n const portraitBezelRight = entry.bezelRight * scale;\n const portraitScreenW = sr?.width ?? logicalW;\n const portraitScreenH = sr?.height ?? (entry.logicalScreenHeight ?? rawH);\n\n let landscape: Parameters<typeof registerCustomDeviceSVG>[5];\n if (entry.svgStringLandscape && entry.screenRectLandscape) {\n const lRawW = entry.screenRectLandscape.width;\n const lRawH = entry.screenRectLandscape.height;\n // Landscape's logical width matches portrait's logical height.\n const lScale = lRawW > 0 ? (entry.logicalScreenHeight ?? lRawW) / lRawW : 1;\n const lsr = {\n x: entry.screenRectLandscape.x * lScale,\n y: entry.screenRectLandscape.y * lScale,\n width: lRawW * lScale,\n height: lRawH * lScale,\n rx: (entry.screenRectLandscape.rx ?? 0) * lScale,\n rxTop: entry.screenRectLandscape.rxTop !== undefined\n ? entry.screenRectLandscape.rxTop * lScale\n : undefined,\n rxBottom: entry.screenRectLandscape.rxBottom !== undefined\n ? entry.screenRectLandscape.rxBottom * lScale\n : undefined,\n };\n const lBezelTop = (entry.bezelTopLandscape ?? 0) * lScale;\n const lBezelBottom = (entry.bezelBottomLandscape ?? 0) * lScale;\n const lBezelLeft = (entry.bezelLeftLandscape ?? 0) * lScale;\n const lBezelRight = (entry.bezelRightLandscape ?? 0) * lScale;\n landscape = {\n svgString: entry.svgStringLandscape,\n frame: {\n bezelTop: lBezelTop,\n bezelBottom: lBezelBottom,\n bezelLeft: lBezelLeft,\n bezelRight: lBezelRight,\n totalWidth: lsr.width + lBezelLeft + lBezelRight,\n totalHeight: lsr.height + lBezelTop + lBezelBottom,\n screenWidth: lsr.width,\n screenHeight: lsr.height,\n screenRadius: lsr.rx,\n screenRadiusTop: lsr.rxTop,\n screenRadiusBottom: lsr.rxBottom,\n },\n screenRect: lsr,\n };\n }\n\n registerCustomDeviceSVG(\n entry.deviceId,\n entry.svgString,\n {\n bezelTop: portraitBezelTop,\n bezelBottom: portraitBezelBottom,\n bezelLeft: portraitBezelLeft,\n bezelRight: portraitBezelRight,\n totalWidth: portraitScreenW + portraitBezelLeft + portraitBezelRight,\n totalHeight: portraitScreenH + portraitBezelTop + portraitBezelBottom,\n screenWidth: portraitScreenW,\n screenHeight: portraitScreenH,\n screenRadius: sr?.rx ?? 0,\n screenRadiusTop: sr?.rxTop,\n screenRadiusBottom: sr?.rxBottom,\n },\n undefined,\n sr,\n landscape\n );\n }\n\n private persist(all: Record<string, SVGOverrideEntry>): void {\n if (!this.storage) return;\n try {\n this.storage.setItem(STORAGE_KEY, JSON.stringify(all));\n } catch {\n // ignore\n }\n }\n}\n\nlet singleton: CustomSVGStore | null = null;\nexport function getCustomSVGStore(): CustomSVGStore {\n if (!singleton) singleton = new CustomSVGStore();\n return singleton;\n}\n"],"mappings":"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","names":["useMemo","useState","useCallback","useEffect","useState","useCallback","useState","useCallback","useEffect","useState","useState","useEffect","useCallback","useState","useCallback","Component","useEffect","useMemo","useRef","useState","getDeviceContract","jsx","jsx","jsxs","jsx","jsxs","useEffect","useState","jsx","jsx","jsxs","useMemo","getDeviceContract","useRef","useState","useEffect","jsx","jsxs","jsx","jsx","useEffect","useState","Fragment","jsx","jsx","jsxs"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mmtitanl/tablets-core",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Core React components and hooks for tablet device frames — adaptive scaling and orientation",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.cjs",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"require": {
|
|
17
|
+
"types": "./dist/index.d.cts",
|
|
18
|
+
"default": "./dist/index.cjs"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": ["dist"],
|
|
23
|
+
"sideEffects": ["./dist/registration.*", "./src/registration.*"],
|
|
24
|
+
"keywords": ["tablet", "device-frame", "react", "responsive", "orientation"],
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"react": ">=18.0.0",
|
|
27
|
+
"react-dom": ">=18.0.0"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@mmtitanl/tablets": "0.1.1"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsup",
|
|
34
|
+
"dev": "tsup --watch",
|
|
35
|
+
"typecheck": "tsc --noEmit",
|
|
36
|
+
"clean": "rm -rf dist"
|
|
37
|
+
}
|
|
38
|
+
}
|