component DeviceFrame { outputs { change(payload: { device: string; orientation: string; sourceEvent: Event }) rotate(payload: { device: string; orientation: string; sourceEvent: Event }) } props { size: string = "default" color: string = "primary" title: string = "Device Frame" description: string = "" items: unknown[] = [] variant: string = "default" device: string = "phone" orientation: string = "portrait" src: string = "" srcdoc: string = "" frameTitle: string = "Device preview" showToolbar: boolean = true allow: string = "" class: string = "" } state currentOrientation = orientation functions { client function setDevice(nextDevice, sourceEvent) { output.change({ device: nextDevice, orientation: currentOrientation, sourceEvent: sourceEvent }) } client function rotateFrame(sourceEvent) { currentOrientation = currentOrientation === "portrait" ? "landscape" : "portrait"; output.rotate({ device: device, orientation: currentOrientation, sourceEvent: sourceEvent }); output.change({ device: device, orientation: currentOrientation, sourceEvent: sourceEvent }) } } view {
{#if title}{title}{/if}{#if description}

{description}

{/if}
{#if showToolbar}{/if}
{#if src || srcdoc}{:else}
{/if}
} style { .wire-next--device-frame > header { display: flex; align-items: center; justify-content: space-between; gap: 1rem; } .wire-next__device-actions { display: flex; flex-wrap: wrap; gap: 0.4rem; } .wire-next__device-actions button { min-height: 2.25rem; padding-inline: 0.7rem; border: 1px solid var(--wire-color-border); border-radius: var(--wire-radius-sm); background: var(--wire-color-surface-2); color: inherit; } .wire-next__device-shell { overflow: hidden; width: min(100%, 24rem); min-height: 28rem; margin-inline: auto; border: 0.65rem solid var(--wire-color-text); border-radius: 2rem; background: var(--wire-color-background); transition: width var(--wire-motion-normal) var(--wire-ease-standard); } .wire-next--device-frame[data-device="tablet"] .wire-next__device-shell { width: min(100%, 42rem); } .wire-next--device-frame[data-device="desktop"] .wire-next__device-shell { width: 100%; border-width: 0.4rem; border-radius: var(--wire-radius-md); } .wire-next--device-frame[data-orientation="landscape"] .wire-next__device-shell { width: min(100%, 48rem); min-height: 20rem; } .wire-next__device-shell :is(iframe, .wire-next__device-content) { width: 100%; min-height: inherit; border: 0; } @media (max-width: 640px) { .wire-next--device-frame > header { align-items: stretch; flex-direction: column; } } } }