一个交互组件(如开关组、折叠面板)往往要在 React、Vue、Solid 多个框架里重复实现一遍行为逻辑,而真正难的是键盘操作和焦点管理。每换一个框架就重写一次,既浪费又容易出无障碍 bug。
Zag 用有限状态机(XState 思路)描述组件行为,再把『适配器』接到不同框架上。你写标记和样式,Zag 保证键盘导航、焦点与 ARIA 行为在各框架间一致。
项目基本信息
| 信息项 | 详情 |
|---|---|
| 项目名称 | zag |
| GitHub地址 | https://github.com/chakra-ui/zag |
| 项目描述 | Build your design system in React, Solid, Vue, Svelte or Vanilla. Powered by finite state machines |
| 作者 | chakra-ui |
| 开源协议 | MIT License |
| 开源状态 | 公开 |
| Languages | TypeScript |
| 支持平台 | Windows / macOS / Linux |
| 最后更新 | 2026-10-26 |
一、项目介绍
zag(Build your design system in React, Solid, Vue, Svelte or Vanilla. Powered by finite state machines),框架无关的 Headless 组件状态机库。它把相关能力封装成开箱即用的形态,让开发者无需从零搭建即可直接落地,下文从优势、场景到安装使用逐一展开。
二、核心优势
- 框架无关,同一套状态机驱动 React/Vue/Solid/Svelte
- 行为由状态机描述,复杂交互可预测、可测试
- 内置键盘导航、焦点管理、ARIA,符合无障碍规范
- 完全 headless,标记与样式由你掌控
三、适用场景
- 在多个前端框架间共享同一套组件行为
- 搭建需要高可访问性的设计系统
- 希望交互逻辑可单测、可维护的团队
四、安装教程
以 React 的开关组为例,安装对应组件机与框架适配器:
npm install @zag-js/toggle-group @zag-js/react常见报错:module not found @zag-js/react。记得同时安装你所用框架的适配器(如 Vue 用 @zag-js/vue,Svelte 用 @zag-js/svelte),只装核心机是不够的。
五、使用示例
把状态机连接到你的标记:
import { normalizeProps, useMachine } from "@zag-js/react";
import * as toggle from "@zag-js/toggle-group";
import { useId } from "react";
export function ToggleGroup() {
const service = useMachine(toggle.machine, { id: useId() });
const api = toggle.connect(service, normalizeProps);
return (
<div {...api.getRootProps()}>
<button {...api.getItemProps({ value: "bold" })}>B</button>
<button {...api.getItemProps({ value: "italic" })}>I</button>
</div>
);
}输入:声明机器与若干按钮项。
输出:Zag 接管方向键切换、焦点环与 ARIA 属性,按钮组行为在各框架表现一致。
六、常见问题
问:Zag 和 Radix 有什么区别?
答:Radix 主要服务 React,Zag 则把行为抽象成框架无关的状态机,可跨框架复用同一份逻辑。
问:必须用 XState 吗?
答:不需要,Zag 内部封装了自己的状态机实现,你只需调用 connect 接入。
七、总结
Zag 用状态机把『组件行为』从框架里解耦出来,是做跨框架设计系统的利器,尤其适合对一致性与无障碍要求高的场景。
评论 0
还没有评论,来说两句吧。