For AI agents: the complete documentation index is available at https://a3s-lab.github.io/UI/llms.txt, the full documentation bundle is available at https://a3s-lab.github.io/UI/llms-full.txt, and this page is available as Markdown at https://a3s-lab.github.io/UI/components/device-simulator.md.

设备模拟器

设备模拟器在一个有边界的工作台中切换手机、平板和桌面视口,并为三类设备呈现对应的硬件外壳。浏览器模式使用真实尺寸的 iframe,原生模式则把安全参数交给可信宿主启动 a3s-webview。

实时预览
设备预览
预览尺寸 393 × 852。a3s-webview --url …

手机外壳包含金属边框、传感器区和底部手势区,平板外壳包含窄边框与摄像头;笔记本使用屏幕边框、铰链和底座,桌面显示器则呈现下巴与支架。整套外壳会和设备一起缩放以适配工作区,iframe 内部仍保持所选 CSS viewport 的精确宽高。

模拟器不会伪装 User-Agent、设备像素比、触控能力,也不会向目标页面注入安全区变量,同时不会模拟网络限速或系统浏览器差异。目标页面还必须允许被 iframe 嵌入;受 X-Frame-Options 或 CSP frame-ancestors 限制的页面应改用原生预览。

用法

加载运行时与设备模拟器控制器。完整样式包已包含结构层和 Harness 视觉层。

<section
  class="device-simulator"
  data-device="phone"
  data-orientation="portrait"
>
  <header>
    <select data-device-simulator-select aria-label="Device preset">
      <option
        value="phone"
        data-kind="phone"
        data-orientation="portrait"
        data-width="393"
        data-height="852"
      >
        Phone · 393 × 852
      </option>
      <option
        value="desktop"
        data-kind="desktop"
        data-orientation="landscape"
        data-width="1440"
        data-height="900"
      >
        Desktop · 1440 × 900
      </option>
      <option value="custom">Custom</option>
    </select>
    <input
      type="number"
      min="240"
      max="4000"
      value="393"
      data-device-simulator-width
    />
    <input
      type="number"
      min="180"
      max="3000"
      value="852"
      data-device-simulator-height
    />
    <div
      role="group"
      aria-label="Orientation"
      data-device-simulator-orientation
    >
      <button
        type="button"
        aria-pressed="true"
        data-device-simulator-orientation-value="portrait"
      >
        Portrait
      </button>
      <button
        type="button"
        aria-pressed="false"
        data-device-simulator-orientation-value="landscape"
      >
        Landscape
      </button>
    </div>
    <form data-device-simulator-navigation>
      <input
        type="text"
        inputmode="url"
        value="https://example.com"
        data-device-simulator-url
      />
      <button type="submit">Open</button>
      <button type="button" data-device-simulator-refresh>Refresh</button>
    </form>
  </header>
  <div data-device-simulator-workspace>
    <div data-device-simulator-canvas>
      <div data-device-simulator-frame>
        <iframe
          title="Application preview"
          src="https://example.com"
          data-device-simulator-preview
        ></iframe>
        <span hidden data-device-simulator-screen-status></span>
      </div>
    </div>
  </div>
  <footer>
    <output aria-live="polite" data-device-simulator-status></output>
    <code data-device-simulator-command></code>
    <button type="button" data-device-simulator-copy-command>
      Copy native command
    </button>
    <button type="button" data-device-simulator-native>
      Open native preview
    </button>
  </footer>
</section>
<script type="module">
  import "@a3s-lab/ui/runtime";
  import "@a3s-lab/ui/device-simulator";
</script>

使用完整运行时包时,写法等价于 import "@a3s-lab/ui/all"。

参数

参数可选值默认值用途
预设 data-width240–4000—预设的 CSS viewport 宽度
预设 data-height180–3000—预设的 CSS viewport 高度
预设 data-kindphone、tablet、desktop按宽度推断选择手机、平板或电脑硬件外壳
预设 data-orientationportrait、landscape保持当前方向选择预设时同步其自然方向
根 data-orientationportrait、landscapeportrait当前屏幕方向
根 data-fitactual 或省略自动适配使用 1:1 比例或自动缩小到工作区
根 data-device-title字符串iframe 标题原生窗口标题
--device-simulator-workspace-min-heightCSS 长度38rem工作区最小高度
--device-simulator-workspace-max-heightCSS 长度44rem工作区最大高度

自定义宽高会限制在和 a3s-webview 一致的范围内。修改自定义输入后,控制器会选择值为 custom 的选项并派发尺寸变化事件。

JavaScript API

初始化后,根元素提供以下方法:

方法用途
setDevice(value)选择一个预设;不存在时返回 false
setSize(width, height)切换到自定义尺寸并限制输入范围
setOrientation(value)设置 portrait 或 landscape
navigate(url?)验证并打开 HTTP、HTTPS、file 或相对 URL
refreshPreview()重新加载当前 iframe URL
openNativePreview()派发原生预览请求;无人接管时复制命令

尺寸变化会派发 a3s:device-change,URL 导航会派发 a3s:device-navigate。原生预览使用可取消、可冒泡且可跨 Shadow DOM 的 a3s:device-preview-request 事件,detail 包含 { executable, args, url, width, height, title, command }。

可信宿主应调用 preventDefault() 表示已经接管,并直接使用结构化 args。不要重新解析仅供显示和复制的 command 字符串。

const simulator = document.querySelector(".device-simulator");

simulator.addEventListener("a3s:device-preview-request", async (event) => {
  if (!window.trustedPreviewHost) return;
  event.preventDefault();

  const { executable, args } = event.detail;
  await window.trustedPreviewHost.launch({ executable, args });
});

网页控制器不会直接执行本机程序。没有可信宿主时,“原生预览”只会把等价命令复制到剪贴板。

状态与变体

  • data-state="loading" 在 iframe 导航期间显示加载状态。
  • data-state="ready" 表示尺寸或预览已经同步。
  • data-state="error" 表示 URL 无效或复制失败,并在状态输出中说明恢复方式。
  • 手机、平板、笔记本和桌面显示器使用不同的边框、传感器、底座或支架;iframe 始终使用输入框中的真实 CSS 像素尺寸。
  • file: URL 可交给原生宿主;浏览器是否允许 iframe 打开本地文件由浏览器安全策略决定。

可访问性

为根组件、预设选择器、方向按钮组、URL 输入和 iframe 提供可访问名称。方向按钮使用 aria-pressed,状态输出使用 aria-live="polite"。工作区保持独立滚动,键盘焦点不会被缩放后的 iframe 框体重排。自定义尺寸必须保留数值输入的 min、max 与清楚标签。