Zag-基于狀態(tài)機(jī)的組件庫
官方介紹:
Zag 是一個(gè)與框架無關(guān)的工具包,用于設(shè)計(jì)系統(tǒng)和 Web 應(yīng)用程序中實(shí)現(xiàn)復(fù)雜、交互式和可訪問的 UI 組件。
可以在 React、Solid 和 Vue 中構(gòu)建可訪問的 UI 組件,無需為邏輯而煩惱。
簡單理解:使用狀態(tài)機(jī)方法實(shí)現(xiàn)常見的組件模式
背景介紹
過去我們經(jīng)歷了太多與我們?nèi)绾螀f(xié)調(diào)事件、管理狀態(tài)和副作用有關(guān)的小問題和錯(cuò)誤。大多數(shù)這些錯(cuò)誤都與useEffect編排useMemo有關(guān)useCallback。
二、Zag的特性
Why Zag?
由狀態(tài)機(jī)提供支持:Zag 建立在狀態(tài)圖中的最新理念之上。不遵循 SCXML 規(guī)范,創(chuàng)建了一個(gè)我們認(rèn)為可以幫助我們快速構(gòu)建更復(fù)雜組件的 API。
一次編寫,隨處使用:組件交互以與框架無關(guān)的方式建模。我們?yōu)?JS 框架提供了適配器,因此可以在 React、Solid 或 Vue 3 中使用它。
關(guān)注可訪問性:Zag 在構(gòu)建時(shí)考慮了可訪問性。處理了與鍵盤交互、焦點(diǎn)管理、詠嘆調(diào)角色和屬性相關(guān)的許多細(xì)節(jié)。
Headless:machine APIs完全沒有樣式,讓用戶可以控制使用自己喜歡的任何樣式解決方案。
增量采用:根據(jù)需要采用機(jī)器。每個(gè)組件機(jī)器都是一個(gè) NPM 包,可以單獨(dú)安裝,以便用戶可以增量使用它們。
三、安裝
Zag 可以在大多數(shù) JS 框架中使用,例如 Vue、React 和 Solid。
@zag-js/vue
@zag-js/react
@zag-js/solid
為自己感興趣的組件安裝機(jī)器
npm i --save @zag-js/{component}
# or
yarn add @zag-js/{component}
2.為自己選擇的框架安裝適配器,命令如下:
# react
npm install @zag-js/react
# or
yarn add @zag-js/react
# vue
npm install @zag-js/vue
# or
yarn add @zag-js/vue
# solid
npm install @zag-js/solid
# or
yarn add @zag-js/solid
四、demo
一、React項(xiàng)目中使用的toggle machine的示例:
import { useMachine, useSetup } from "@zag-js/react"
import * as toggle from "@zag-js/toggle"
export function Toggle() {
const [state, send] = useMachine(toggle.machine)
const ref = useSetup({ send, id: "1" })
const api = toggle.connect(state, send)
return (
<button ref={ref} {...api.buttonProps}>
{api.isPressed ? "開" : "關(guān)"}
</button>
)
}
由于machine hook中使用了 useSnapshot 掛鉤,Zag 在幕后使用 valtio 來提供自動(dòng)渲染優(yōu)化。
二、與 Vue 3 (JSX) 一起使用
Zag 與 Vue 的 JSX 方法無縫協(xié)作。在 Vue 中使用相同的toggle邏輯:
import { computed, defineComponent, h, Fragment } from "vue"
import * as toggle from "@zag-js/toggle"
import { useMachine, useSetup, normalizeProps } from "@zag-js/vue"
export default defineComponent({
name: "Toggle",
setup() {
const [state, send] = useMachine(toggle.machine)
const ref = useSetup({ send, id: "1" })
const apiRef = computed(() => toggle.connect(state, send, normalizeProps))
return () => {
const api = apiRef.value
return (
<button ref={ref} {...api.buttonProps}>
{api.isPressed ? "開" : "關(guān)"}
</button>
)
}
},
})
三、與 Solid.js 一起使用
如何在 Solid 中使用相同的toggle邏輯:
import { createMemo } from "solid-js"
import * as toggle from "@zag-js/toggle"
import { useMachine, useSetup, normalizeProps } from "@zag-js/solid"
export default function Toggle() {
const [state, send] = useMachine(toggle.machine)
const ref = useSetup({ send, id: "1" })
const api = createMemo(() => toggle.connect(state, send, normalizeProps))
return (
<button ref={ref} {...api().buttonProps}>
{api().isPressed ? "開" : "關(guān)"}
</button>
)
}
作者:廣東靚仔
歡迎關(guān)注:前端早茶