Zag調べてみる
これは2023/7/3の社内勉強会の資料です。
Zagとは
フレームワークに依存せずに、複雑でインタラクティブでアクセシブルなUI Componentを構築できるライブラリで、Chakra UIから出ています。
現時点(2023年7月)ではbeta版です。
Zagの推しポイント
アダプターを使って、React, Vue, SolidなどのJSフレームワークを跨いで使える点や、必要なComponentのみをnpm パッケージからimportできる点などから、今使ってる環境で小さく始めてみるアプローチとかが取りやすな印象を受けました。
また、a11yが考慮されてたり、headlessな見た目だったり、社内でデザインシステムこれから作ってくぜみたいな企業は採用してくのありな気がします。
やってみる
インストール
使いたいComponentと、JSフレームワーク毎に提供されてるアダプターをインストールします。一番シンプルそうなToggleでやってみます。
// toggle componentのインストール
yarn add @zag-js/toggle
// adapterのインストール
yarn add @zag-js/react
example
Toggle
import { useMachine, normalizeProps } from "@zag-js/react"
import * as toggle from "@zag-js/toggle"
export function Toggle() {
const [state, send] = useMachine(toggle.machine({
id: "1"
}))
const api = toggle.connect(state, send, normalizeProps)
return (
<button {...api.buttonProps}>
{api.isPressed ? "On" : "Off"}
</button>
)
}
Dialog
import * as dialog from "@zag-js/dialog"
import { useMachine, normalizeProps, Portal } from "@zag-js/react"
export function Dialog() {
const [state, send] = useMachine(dialog.machine({ id: "1" }))
const api = dialog.connect(state, send, normalizeProps)
return (
<>
<button {...api.triggerProps}>Open Dialog</button>
{api.isOpen && (
<Portal>
<div {...api.backdropProps} />
<div {...api.containerProps}>
<div {...api.contentProps}>
<h2 {...api.titleProps}>Edit profile</h2>
<p {...api.descriptionProps}>
Make changes to your profile here. Click save when you are done.
</p>
<div>
<input placeholder="Enter name..." />
<button>Save</button>
</div>
<button {...api.closeTriggerProps}>Close</button>
</div>
</div>
</Portal>
)}
</>
)
}
利用者側のやることはHTMLを書いて、それぞれの要素に適切なpropsを渡して、スタイルを書くだけになります。
ベータ版ですが、Componentのドキュメントが結構充実していて、
Anatomyのセクションを見ると、DOM構造の図があるので、イメージしやすいかと思います。また、Styling guideのセクションで、ある要素やある状態の時のdata属性も書かれているので、CSSを書く時の参考にできそうです。
実際に試したい方はこちら
ちなみに、今回は既に提供されているComponentを使いましたが、state machineを自作してオリジナルのComponentを作成することも可能そうです!!
まとめ
同様のライブラリでRadix などがあると思いますが、Radixは専用のComponentで見た目を組み立ててくのに対して、Zagの方はComponentの振る舞いをpropsで渡して組み立ていく方式なので、見た目と振る舞いをradix以上に分離できそうな印象を持ちました。また、フレームワークを跨いで使える点もZagの強みだと思うので、複数のJSフレームワーク使ってる場合とかは選択肢の一つとして考えてみるのもありかもしれません。