Developer · 界面 SDK
v1.3.1

界面 SDK

所有 Nexus 应用共用的一套界面,外观与 shadcn/ui 一致、取值与 AIDC Console 同源。纯 HTML 应用引一个样式表就有全部组件;需要脚本的部分(主题、Toast、确认框、标签页、加载动效)在 aidc.js 的 ui 里。

<link rel="stylesheet" href="/developer/sdk/v1/ui.css" />
<script type="module">
  import { ui } from "/developer/sdk/v1/aidc.js";
  ui.toast("已保存", { variant: "success" });
</script>

页面

顶栏

appbar

应用最上面一条:标识、应用名、右侧操作。吸顶、半透明毛玻璃。

瑕疵检测
测试版
<header class="aidc-appbar">
  <span class="aidc-logo"><svg class="aidc-mark" viewBox="0 0 40 40" fill="currentColor" aria-hidden="true"><g transform="translate(20 20) skewX(-18)"><rect x="-9.6" y="-15" width="6.6" height="30"/><rect x="3" y="-15" width="6.6" height="30"/></g></svg><span>AIDC</span></span>
  <span class="aidc-appbar__title">瑕疵检测</span>
  <div class="aidc-appbar__actions">
    <span class="aidc-badge aidc-badge--signal">测试版</span>
    <button type="button" class="aidc-btn aidc-btn--ghost aidc-btn--sm">反馈</button>
  </div>
</header>
.aidc-appbar.aidc-appbar__title.aidc-appbar__actions

版面

layout

页面容器(最大宽度 + 留白)、竖排 / 横排间距、次要文字。不用 Tailwind 也能排版。

今日产线

数据每 30 秒同步一次。

<main class="aidc-page aidc-page--narrow">
  <div class="aidc-stack">
    <h1>今日产线</h1>
    <p class="aidc-muted">数据每 30 秒同步一次。</p>
    <div class="aidc-row">
      <button type="button" class="aidc-btn">开始检测</button>
      <button type="button" class="aidc-btn aidc-btn--outline">导出</button>
    </div>
  </div>
</main>
.aidc-page.aidc-page--narrow.aidc-stack.aidc-row.aidc-muted

操作

按钮

button

主按钮是实心黑(signal 主题下是信号橙);次要、描边、幽灵、危险、链接五种变体,三种尺寸与图标按钮。

查看说明
<div class="aidc-row">
  <button type="button" class="aidc-btn">发布</button>
  <button type="button" class="aidc-btn aidc-btn--secondary">保存草稿</button>
  <button type="button" class="aidc-btn aidc-btn--outline">预览</button>
  <button type="button" class="aidc-btn aidc-btn--ghost">取消</button>
  <button type="button" class="aidc-btn aidc-btn--destructive">删除</button>
  <a class="aidc-btn aidc-btn--link" href="#">查看说明</a>
</div>
<div class="aidc-row">
  <button type="button" class="aidc-btn aidc-btn--sm">小</button>
  <button type="button" class="aidc-btn">默认</button>
  <button type="button" class="aidc-btn aidc-btn--lg">大</button>
  <button type="button" class="aidc-btn aidc-btn--outline aidc-btn--icon" aria-label="刷新"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12a9 9 0 1 1-3-6.7L21 8"/><path d="M21 3v5h-5"/></svg></button>
  <button type="button" class="aidc-btn" disabled><span class="aidc-loader" data-variant="dial" role="status" aria-label="Loading"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></span>提交中</button>
</div>
.aidc-btn.aidc-btn--secondary.aidc-btn--outline.aidc-btn--ghost.aidc-btn--destructive.aidc-btn--link.aidc-btn--sm.aidc-btn--lg.aidc-btn--icon.aidc-btn--block

标签页

tabs

同一块区域里切换几组内容。标记写好后调 ui.tabs(容器) 接管点击与方向键。

3 张工单进行中。
<div class="aidc-tabs" id="orderTabs">
  <div class="aidc-tabs__list" role="tablist" aria-label="订单">
    <button type="button" class="aidc-tabs__trigger" role="tab" id="tab-open" aria-controls="panel-open" aria-selected="true">进行中</button>
    <button type="button" class="aidc-tabs__trigger" role="tab" id="tab-done" aria-controls="panel-done" aria-selected="false">已完成</button>
  </div>
  <div class="aidc-tabs__panel" role="tabpanel" id="panel-open" aria-labelledby="tab-open">3 张工单进行中。</div>
  <div class="aidc-tabs__panel" role="tabpanel" id="panel-done" aria-labelledby="tab-done" hidden>本周完成 18 张。</div>
</div>
ui.tabs("#orderTabs", { onChange: (panelId) => console.log(panelId) });
.aidc-tabs.aidc-tabs__list.aidc-tabs__trigger.aidc-tabs__panel

对话框

dialog

原生 <dialog>。确认与输入用 ui.confirm / ui.prompt(代替 window.confirm / prompt),复杂内容自己写标记后 showModal()。

发布到 Nexus

发布后全公司成员都能打开这个版本。

<div class="aidc-row">
  <button type="button" class="aidc-btn aidc-btn--destructive" data-demo="confirm">删除工单</button>
  <button type="button" class="aidc-btn aidc-btn--outline" data-demo="prompt">标记问题</button>
  <button type="button" class="aidc-btn aidc-btn--outline" data-demo="custom-dialog">自定义对话框</button>
</div>
<dialog class="aidc-dialog" id="custom">
  <form method="dialog" class="aidc-stack">
    <div class="aidc-dialog__header">
      <h2 class="aidc-dialog__title">发布到 Nexus</h2>
      <p class="aidc-dialog__description">发布后全公司成员都能打开这个版本。</p>
    </div>
    <div class="aidc-dialog__footer">
      <button type="submit" value="cancel" class="aidc-btn aidc-btn--outline">取消</button>
      <button type="submit" value="confirm" class="aidc-btn">发布</button>
    </div>
  </form>
</dialog>
if (await ui.confirm({ title: "删除这张工单?", description: "删除后不能恢复。", confirmText: "删除", destructive: true })) { /* … */ }
const reason = await ui.prompt({ title: "标记问题", label: "问题描述", placeholder: "例如:布面污渍", required: true });
document.querySelector("#custom").showModal();
.aidc-dialog.aidc-dialog__header.aidc-dialog__title.aidc-dialog__description.aidc-dialog__footer

表单

输入框

input

单行输入;手机上字号 16px(iOS 不会自动放大)。出错时加 aria-invalid="true"。

<input class="aidc-input" type="text" placeholder="批次号,例如 B-2026-0926" />
<input class="aidc-input" type="email" placeholder="错误示例" aria-invalid="true" value="not-an-email" />
<input class="aidc-input" type="file" />
.aidc-input

多行输入

textarea

多行文本,可纵向拉伸。

<textarea class="aidc-textarea" rows="3" placeholder="写下这次检查的备注…"></textarea>
.aidc-textarea

下拉选择

select

原生 <select>,弹出层由系统负责(手机上是系统选择器)。

<select class="aidc-select">
  <option>一号产线</option>
  <option>二号产线</option>
  <option>三号产线</option>
</select>
.aidc-select

复选框

checkbox

原生 <input type="checkbox">,外观与 shadcn 一致。

<label class="aidc-label"><input type="checkbox" class="aidc-checkbox" checked /> 发布后通知全员</label>
.aidc-checkbox

单选框

radio

原生 <input type="radio">。

<div class="aidc-stack" style="gap: 0.75rem">
  <label class="aidc-label"><input type="radio" class="aidc-radio" name="shift" checked /> 白班</label>
  <label class="aidc-label"><input type="radio" class="aidc-radio" name="shift" /> 夜班</label>
</div>
.aidc-radio

开关

switch

原生复选框加 role="switch":开 / 关一项设置。

<label class="aidc-label"><input type="checkbox" role="switch" class="aidc-switch" checked /> 实时同步</label>
.aidc-switch

标签

label

表单项的文字标签;包住复选框 / 单选框 / 开关时自动横排对齐。

<label class="aidc-label" for="qty">数量</label>
.aidc-label

表单项

field

标签 + 控件 + 说明 / 错误提示的一组。

印在料盒侧面,以 B- 开头。

批次号不能为空。

<div class="aidc-field">
  <label class="aidc-label" for="batch">批次号</label>
  <input class="aidc-input" id="batch" aria-invalid="true" aria-describedby="batch-error" />
  <p class="aidc-field__description">印在料盒侧面,以 B- 开头。</p>
  <p class="aidc-field__error" id="batch-error">批次号不能为空。</p>
</div>
.aidc-field.aidc-field__description.aidc-field__error

展示

卡片

card

一组相关内容的容器:标题、说明、右上角操作、正文、底部操作。

今日良率

一号产线 · 截至 14:30

+1.2%
98.4%
<div class="aidc-card" style="max-width: 24rem">
  <div class="aidc-card__header">
    <h3 class="aidc-card__title">今日良率</h3>
    <p class="aidc-card__description">一号产线 · 截至 14:30</p>
    <span class="aidc-card__action aidc-badge aidc-badge--success">+1.2%</span>
  </div>
  <div class="aidc-card__content"><strong style="font-size: 2rem">98.4%</strong></div>
  <div class="aidc-card__footer">
    <button type="button" class="aidc-btn aidc-btn--outline aidc-btn--sm">明细</button>
  </div>
</div>
.aidc-card.aidc-card__header.aidc-card__title.aidc-card__description.aidc-card__action.aidc-card__content.aidc-card__footer

徽章

badge

状态与标签。信号橙只用于需要注意的状态。

已发布 草稿 v1.2.0 合格 待复核 不合格
<div class="aidc-row">
  <span class="aidc-badge">已发布</span>
  <span class="aidc-badge aidc-badge--secondary">草稿</span>
  <span class="aidc-badge aidc-badge--outline">v1.2.0</span>
  <span class="aidc-badge aidc-badge--success">合格</span>
  <span class="aidc-badge aidc-badge--signal">待复核</span>
  <span class="aidc-badge aidc-badge--destructive">不合格</span>
</div>
.aidc-badge.aidc-badge--secondary.aidc-badge--outline.aidc-badge--destructive.aidc-badge--signal.aidc-badge--success

表格

table

数据表:外面包一层 .aidc-table-wrap 就能横向滚动;数字列加 .aidc-num 右对齐、等宽数字。

工单产线状态数量
WO-1041一号完成1,200
WO-1042二号待复核860
WO-1043三号排产2,400
合计4,460
<div class="aidc-table-wrap">
  <table class="aidc-table">
    <thead><tr><th>工单</th><th>产线</th><th>状态</th><th class="aidc-num">数量</th></tr></thead>
    <tbody>
      <tr><td>WO-1041</td><td>一号</td><td><span class="aidc-badge aidc-badge--success">完成</span></td><td class="aidc-num">1,200</td></tr>
      <tr><td>WO-1042</td><td>二号</td><td><span class="aidc-badge aidc-badge--signal">待复核</span></td><td class="aidc-num">860</td></tr>
      <tr><td>WO-1043</td><td>三号</td><td><span class="aidc-badge aidc-badge--secondary">排产</span></td><td class="aidc-num">2,400</td></tr>
    </tbody>
    <tfoot><tr><td colspan="3">合计</td><td class="aidc-num">4,460</td></tr></tfoot>
  </table>
</div>
.aidc-table-wrap.aidc-table.aidc-table--wrap.aidc-num

头像

avatar

圆形头像;没有图片时放姓氏或缩写。

郭李AI
<div class="aidc-row"><span class="aidc-avatar">郭</span><span class="aidc-avatar">李</span><span class="aidc-avatar">AI</span></div>
.aidc-avatar

按键

kbd

快捷键提示。

按 ⌘ K 搜索
<span class="aidc-muted">按 <kbd class="aidc-kbd">⌘</kbd> <kbd class="aidc-kbd">K</kbd> 搜索</span>
.aidc-kbd

分隔线

separator

横向用 <hr>;在横排里用竖向变体。

上半部分
产线班次
<div class="aidc-stack">
  <span>上半部分</span>
  <hr class="aidc-separator" />
  <div class="aidc-row" style="height: 1.25rem">
    <span>产线</span><span class="aidc-separator aidc-separator--vertical"></span><span>班次</span>
  </div>
</div>
.aidc-separator.aidc-separator--vertical

空状态

empty

没有数据时告诉用户为什么、下一步做什么。

还没有工单

ERP 同步过来的工单会出现在这里。

<div class="aidc-empty">
  <div class="aidc-empty__media"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 7h18M3 12h18M3 17h18"/></svg></div>
  <h3 class="aidc-empty__title">还没有工单</h3>
  <p class="aidc-empty__description">ERP 同步过来的工单会出现在这里。</p>
  <button type="button" class="aidc-btn aidc-btn--outline aidc-btn--sm">立即同步</button>
</div>
.aidc-empty.aidc-empty__media.aidc-empty__title.aidc-empty__description

反馈

提示条

alert

页面里的常驻提示;出错用 destructive。

数据源在线
ERP 发布端 2 分钟前心跳正常。
<div class="aidc-alert" role="status">
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4M12 8h.01"/></svg>
  <div class="aidc-alert__title">数据源在线</div>
  <div class="aidc-alert__description">ERP 发布端 2 分钟前心跳正常。</div>
</div>
<div class="aidc-alert aidc-alert--destructive" role="alert">
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 8v4M12 16h.01"/></svg>
  <div class="aidc-alert__title">连不上数据源</div>
  <div class="aidc-alert__description">发布端已 10 分钟没有心跳,页面上的数据可能不是最新的。</div>
</div>
.aidc-alert.aidc-alert__title.aidc-alert__description.aidc-alert--destructive

Toast

toast

操作结果的轻提示,几秒后自动消失(悬停暂停)。只用 ui.toast(),不用手写标记。

<div class="aidc-row">
  <button type="button" class="aidc-btn aidc-btn--outline" data-demo="toast">已保存</button>
  <button type="button" class="aidc-btn aidc-btn--outline" data-demo="toast-error">保存失败</button>
  <button type="button" class="aidc-btn aidc-btn--outline" data-demo="toast-action">带撤销</button>
</div>
ui.toast("已保存", { variant: "success" });
ui.toast("保存失败", { variant: "error", description: "网络断开,稍后重试。" });
ui.toast("已删除 1 条记录", { action: { label: "撤销", onClick: undo } });
.aidc-toaster.aidc-toast.aidc-toast__body.aidc-toast__title.aidc-toast__description.aidc-toast__action

加载动效

loader

八种等待态都以品牌斜杆 // 为母题(dial 刻度轮、cadence 节拍、sequence 递进、sweep 掠光、march 行进、pulse 韵律、breathe 呼吸、track 轨道),按场景选、同一界面不混用;大小跟字号,颜色跟 --signal。

<div class="aidc-row" style="gap: 1.5rem; font-size: 1.5rem">
  <span class="aidc-loader" data-variant="dial" role="status" aria-label="Loading"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></span>
  <span class="aidc-loader" data-variant="cadence" role="status" aria-label="Loading"><i></i><i></i></span>
  <span class="aidc-loader" data-variant="sequence" role="status" aria-label="Loading"><i></i><i></i></span>
  <span class="aidc-loader" data-variant="sweep" role="status" aria-label="Loading"><i></i><i></i></span>
  <span class="aidc-loader" data-variant="march" role="status" aria-label="Loading"><span data-slot="train"><i></i><i></i><i></i><i></i><i></i></span></span>
  <span class="aidc-loader" data-variant="pulse" role="status" aria-label="Loading"><i></i><i></i></span>
  <span class="aidc-loader" data-variant="breathe" role="status" aria-label="Loading"><i></i><i></i></span>
  <span style="font-size: 1rem"><span class="aidc-loader" data-variant="track" role="status" aria-label="Loading"><span data-slot="lane"><span data-slot="runner"><i></i><i></i></span></span></span></span>
</div>
button.prepend(ui.loader("dial"));              // 刻度轮
panel.append(ui.loader("cadence", { label: "加载订单" }));
.aidc-loader

骨架屏

skeleton

内容加载前的占位形状。

<div class="aidc-row" style="gap: 0.75rem">
  <div class="aidc-skeleton" style="width: 2.5rem; height: 2.5rem; border-radius: 9999px"></div>
  <div class="aidc-stack" style="gap: 0.5rem">
    <div class="aidc-skeleton" style="width: 12rem; height: 1rem"></div>
    <div class="aidc-skeleton" style="width: 8rem; height: 1rem"></div>
  </div>
</div>
.aidc-skeleton

进度条

progress

原生 <progress>:有明确进度的等待。

62%
<progress class="aidc-progress" value="62" max="100">62%</progress>
.aidc-progress