#按钮
按钮触发当前界面中的操作;需要前往其他地址时,应使用带 href 的链接并应用相同视觉样式。
工作区访问权限2 项待保存更改
审阅者访问权限和部署审批设置已经准备好更新。
安装Terminal
npm install @a3s-lab/ui@0.4.0<section data-save-settings>
<p data-save-status aria-live="polite">可以保存更改。</p>
<button type="button" class="btn" data-save-button>
<span class="grid">
<span class="col-start-1 row-start-1" data-idle-label>保存更改</span>
<span class="invisible col-start-1 row-start-1 inline-flex items-center gap-1.5" data-progress-label aria-hidden="true">
<svg data-icon="inline-start" class="animate-spin" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12a9 9 0 1 1-6.22-8.56" /></svg>
保存中…
</span>
</span>
</button>
</section>
<script type="module">
import { savePermissionChanges } from "./workspace.js";
const region = document.querySelector("[data-save-settings]");
const button = region.querySelector("[data-save-button]");
const status = region.querySelector("[data-save-status]");
const idle = button.querySelector("[data-idle-label]");
const progress = button.querySelector("[data-progress-label]");
let pending = false;
function setPending(nextPending) {
pending = nextPending;
button.disabled = nextPending;
button.toggleAttribute("aria-busy", nextPending);
idle.classList.toggle("invisible", nextPending);
idle.setAttribute("aria-hidden", String(nextPending));
progress.classList.toggle("invisible", !nextPending);
progress.setAttribute("aria-hidden", String(!nextPending));
}
button.addEventListener("click", async () => {
if (pending) return;
setPending(true);
status.textContent = "正在保存权限更改…";
try {
await savePermissionChanges();
status.textContent = "权限更改已保存。";
} catch {
status.textContent = "无法保存更改,请检查连接后重试。";
} finally {
setPending(false);
}
});
</script>import "@a3s-lab/ui/a3s.css";
import "@a3s-lab/ui/all";#用法
导入 Tailwind 与完整 A3S 样式包:
@import "tailwindcss";
@import "@a3s-lab/ui/a3s.css";然后在原生按钮上添加 btn 类。务必显式设置 type="button",避免按钮在表单中意外提交。
<button type="button" class="btn">保存更改</button>需要按组件加载时,依次导入基础样式、按钮结构和 A3S 视觉样式。CDN 与其他接入方式见安装。
@import "@a3s-lab/ui/base.css";
@import "@a3s-lab/ui/components/button.css";
@import "@a3s-lab/ui/styles/a3s.css";#参数
| 参数 | 值 | 用途 |
|---|---|---|
| 根元素 | <button> 或 <a> | 操作使用按钮,页面跳转使用链接 |
class | btn | 必填的组件根类名 |
data-variant | primary、secondary、outline、ghost、link、destructive | 控制操作层级;省略时为主按钮 |
data-size | xs、sm、default、lg、icon-xs、icon-sm、icon、icon-lg | 控制点击目标与视觉密度 |
data-icon | inline-start 或 inline-end | 放在文字按钮的内联图标上,校正间距 |
| 原生状态 | disabled、aria-busy、aria-pressed | 表达不可用、处理中与切换状态 |
按钮没有 JavaScript 控制器或专用框架 Hook。HTML、React 和 Vue 使用相同的原生激活与状态属性;异步操作和防重复提交由应用状态负责。
#状态与变体
同一区域通常只保留一个主按钮。secondary 与 outline 用于次级操作,ghost 用于低强调工具操作,destructive 只用于有明确破坏后果的动作。link 只是按钮的视觉变体,真正的页面导航仍应使用 <a href>。
<div class="flex flex-wrap items-center gap-2">
<button type="button" class="btn">
主操作
</button>
<button type="button" class="btn" data-variant="secondary">
次级操作
</button>
<button type="button" class="btn" data-variant="outline">
弱操作
</button>
<button type="button" class="btn" data-variant="ghost">
工具操作
</button>
<button type="button" class="btn" data-variant="link">
行内操作
</button>
<button type="button" class="btn" data-variant="destructive">
删除
</button>
</div>disabled 阻止交互。异步操作应同时提供可见进度文本和 aria-busy="true";可切换按钮由业务状态更新 aria-pressed,组件不会替应用维护状态。
<div class="flex flex-wrap items-center gap-2">
<button type="button" class="btn" disabled>
不可用
</button>
<button type="button" class="btn" aria-busy="true" disabled>
<svg
data-icon="inline-start"
class="animate-spin"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
>
<path d="M21 12a9 9 0 1 1-6.22-8.56" />
</svg>
保存中…
</button>
<button type="button" class="btn" data-variant="ghost" aria-pressed="true">
已固定
</button>
</div>#尺寸
尺寸应由界面密度决定,不用于表达操作重要性。常规页面使用默认尺寸;紧凑工具栏可使用 sm,大尺寸适合低密度或触控优先界面。仅图标按钮使用对应的 icon-* 尺寸。
<div class="flex flex-wrap items-center gap-2">
<button type="button" class="btn" data-variant="outline" data-size="xs">
特小
</button>
<button type="button" class="btn" data-variant="outline" data-size="sm">
小
</button>
<button type="button" class="btn" data-variant="outline">
默认
</button>
<button type="button" class="btn" data-variant="outline" data-size="lg">
大
</button>
<button
type="button"
class="btn"
data-variant="outline"
data-size="icon-sm"
aria-label="添加"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
>
<path d="M5 12h14M12 5v14" />
</svg>
</button>
<button
type="button"
class="btn"
data-variant="outline"
data-size="icon"
aria-label="设置"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
>
<circle cx="12" cy="12" r="3" />
<path d="M19.4 15a1.7 1.7 0 0 0 .34 1.88l.06.06-2.83 2.83-.06-.06A1.7 1.7 0 0 0 15 19.4a1.7 1.7 0 0 0-1 .6 1.7 1.7 0 0 0-.4 1.1V21h-4v-.09A1.7 1.7 0 0 0 8.6 19.4a1.7 1.7 0 0 0-1.88.34l-.06.06-2.83-2.83.06-.06A1.7 1.7 0 0 0 4.6 15a1.7 1.7 0 0 0-.6-1 1.7 1.7 0 0 0-1.1-.4H3v-4h.09A1.7 1.7 0 0 0 4.6 8.6a1.7 1.7 0 0 0-.34-1.88l-.06-.06 2.83-2.83.06.06A1.7 1.7 0 0 0 9 4.6a1.7 1.7 0 0 0 1-.6 1.7 1.7 0 0 0 .4-1.1V3h4v.09A1.7 1.7 0 0 0 15.4 4.6a1.7 1.7 0 0 0 1.88-.34l.06-.06 2.83 2.83-.06.06A1.7 1.7 0 0 0 19.4 9c.2.37.56.72 1 .9.34.14.7.2 1.1.2h.09v4h-.09a1.7 1.7 0 0 0-1.1.4c-.44.35-.8.7-1 1Z" />
</svg>
</button>
</div>#图标与链接
文字按钮中的图标使用 data-icon 表明位置。仅图标按钮必须通过 aria-label 提供名称。链接按钮保留原生链接语义和浏览器行为。
<div class="flex flex-wrap items-center gap-2">
<button type="button" class="btn" data-variant="outline">
<svg
data-icon="inline-start"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
>
<path d="M12 5v14M5 12h14" />
</svg>
新建项目
</button>
<a class="btn" data-variant="secondary" href="./button-group.html">
查看按钮组
<svg
data-icon="inline-end"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
>
<path d="m9 18 6-6-6-6" />
</svg>
</a>
<button
type="button"
class="btn"
data-variant="ghost"
data-size="icon"
aria-label="更多操作"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="currentColor"
>
<circle cx="5" cy="12" r="1.5" />
<circle cx="12" cy="12" r="1.5" />
<circle cx="19" cy="12" r="1.5" />
</svg>
</button>
</div>#可访问性
- 操作使用
<button>,导航使用带href的<a>;不要用点击事件伪装链接。 - 仅图标按钮必须有可访问名称,通常使用
aria-label。 - 加载状态保留具体的动作文字,同步
disabled与aria-busy="true",并在等待业务操作前立即设置防重复提交保护。 - 切换按钮由应用维护
aria-pressed="true|false";展开浮层的按钮使用aria-expanded与aria-controls。 - 破坏性按钮只表达操作性质。需要二次确认时,使用警报对话框。
- A3S 样式包使用单一外移焦点轮廓,不会叠加 box-shadow 光环;不要在应用样式中移除它。
