Zag
用于可访问JavaScript组件的有限状态机
- 一次编写,随处使用 🦄:组件交互以框架无关的方式建模。我们为React、Solid或Vue等JS框架提供适配器。
- 注重无障碍访问 ♿️:Zag在设计时考虑了无障碍性。我们处理了许多与键盘交互、焦点管理、aria角色和属性相关的细节。
- 无头设计 ✨:机器API完全没有样式,让您可以自由使用任何您喜欢的样式解决方案。
- 由状态机驱动 🌳:Zag基于状态图的最新理念构建。我们不遵循SCXML规范,但我们创建了一个API,我们认为它将帮助我们更快地构建更复杂的组件。
文档
要查看文档,请访问 zagjs.com/
发布
有关更新日志,请查看 CHANGELOG.md
问题
随着设计系统和组件驱动开发的兴起,在多个框架中不断重复实现常见的组件模式(标签页、菜单、模态框等)。
这些实现在本质上似乎非常相似,差异主要在于框架的响应性和效果系统(例如React.js中的useState
、useEffect
)。特定框架的解决方案往往随时间增长而变得复杂,并且经常变得难以理解、调试、改进或测试。
解决方案
Zag是一个使用状态机方法实现常见组件模式的JavaScript API。
安装
npm i --save @zag-js/{component}
# 或
yarn add @zag-js/{component}
{component}
代表任何组件机器,如对话框(@zag-js/dialog
)、工具提示(@zag-js/tooltip
)等。
对于特定框架的解决方案,我们提供简单的包装器来帮助您使用组件状态机。
- ⚛️
@zag-js/react
- 用于在React应用中使用机器的React钩子 - 💚
@zag-js/vue
- 用于在Vue应用中使用机器的Vue组合 - 🎷
@zag-js/solid
- 用于在Solid.js应用中使用机器的Solid.js实用工具
使用
import { normalizeProps, useMachine } from "@zag-js/react"
import * as toggle from "@zag-js/toggle-group"
import { useId } from "react"
export function ToggleGroup() {
const [state, send] = useMachine(toggle.machine({ id: useId() }))
const api = toggle.connect(state, send, normalizeProps)
return (
<div {...api.getRootProps()}>
<button {...api.getItemProps({ value: "bold" })}>B</button>
<button {...api.getItemProps({ value: "italic" })}>I</button>
<button {...api.getItemProps({ value: "underline" })}>U</button>
</div>
)
}
指导原则
- 所有组件机器和测试都按照WAI-ARIA创作实践进行建模
- 根据WAI-ARIA规范为每个组件编写端到端测试。无论使用什么框架,用户都期望组件模式以相同的方式工作!
- 所有机器应该轻量、简单且易于理解。避免使用复杂的机器概念,如生成、嵌套状态等。
有趣的事实
Zag意味着_急剧改变方向_。这清楚地描述了我们使用状态机为UI组件提供动力的方法。
预告
-
当你看到有人使用经典的react、vue或solid来构建Zag中已存在的交互式UI组件时,告诉他们**"使用zag吧!"** ⚡️
-
任何使用Zag的人都将被称为**"zagger"** 💥
-
使用Zag时你会感受到的感觉将被称为**"zagadat!"** 🚀
-
Zag社区将被称为**"zag nation"** 🔥
命令
构建命令
我们的构建使用esbuild和turborepo管理,以在包之间提供快速、并发的构建。
build
: 构建CJS、ESM和DTS文件。这是我们在CI中运行的实际生产构建。
示例
由于zag是框架无关的,我们需要一种方法在框架内测试它。examples/
目录包含我们支持的框架的启动项目。
start-react
: 启动Next.js TypeScript项目start-vue
: 启动Vue 3 TypeScript项目start-solid
: 启动Solid TypeScript项目
端到端测试
我们为我们构建的每个机器设置了端到端测试。我们使用Playwright进行测试,并确保组件在不同框架中以相同的方式工作。
e2e-react
: 启动React项目的E2E测试e2e-vue
: 启动Vue项目的E2E测试e2e-solid
: 启动Solid项目的E2E测试
贡献新机器/功能
generate-machine
: 在packages/
目录中生成一个新的机器包。它为新机器设置所需的文件和结构。generate-util
: 在packages/utilities
目录中生成一个新的实用工具包。
其他命令
test
: 运行所有包的测试lint
: 对所有包进行lint检查
网站
start-website
: 启动网站
灵感来源
- Chakra UI React和Vue中的重复代码 😅
- 关于纯UI的思考 - Guillermo Rauch
- 纯UI控制 - Adam Solve
- Material Components Web 启发了我的第一个原型
- Radix UI 启发了可关闭和存在模式
- XState 启发了状态机的基本实现
- Vue.js和Lit 启发了机器中的新模式(
computed
和watch
) - Sonner 启发了toast机器
贡献
想要贡献?寻找带有Good First Issue标签的问题。
🐛 错误
请为错误、缺失的文档或意外行为提交问题。
💡 功能请求
请提交问题以建议新功能。通过添加👍来对功能请求进行投票。这有助于维护者确定优先处理的内容。
许可证
MIT © Segun Adebayo