雑記です。
趣味のプロジェクトで Emotion を使ってます。
Next.js の App Router 移行に伴い Emotion から Panda CSS に乗り換えるか悩みました。考えたことを残しておきます。
動機
App Router は React Server Component(RSC) に対応し、Component の評価をサーバー側でも行えるようになりました。 そんな App Router に移行したいのですが Emotion がオフィシャルでは対応していません。
issue #2928 を参考にすれば動かすことはできますが、Registryの用意を自分たちでする必要があり少々面倒です。 またスタイルは Client Component にしか当てられません。
/** @jsxImportSource @emotion/react */ 'use client' import { css } from '@emotion/react' export default function Page() { return ( <h1 css={css({ color: '#ff6633' })}>Example</h1> ) }
そのため代替策を探してました。
Panda CSS
Panda CSS は Zero Runtime な CSS in JS です。ビルド時にスタイルが吐き出されます。
チュートリアルはこちらです。私は Next.js で入門してみました
import { css } from '../styled-system/css' export default function Page() { return ( <h1 className={css({ color: '#ff6633' })}>Example</h1> ) }
パッと見て思ったことをつらつら書きます。
型補完がきく
CSS in JS だと当たり前ですが、型補完が効きます。そのため開発体験は良いです。
Design Token を扱える
例えば下記のように書くことができます。
import { css } from '../styled-system/css' export default function Page() { return ( <h1 className={css({ fontSize: '2xl', color: 'violet.700' })}>Example</h1> ) }
課題感としては Tailwind や Theme UI に近いでしょうか。
雑に言うと Emotion + デザインシステム なライブラリなんだなと感じました。
Patterns が有用そう
センタリングなどよく使うスタイルがまとめられてます。
import { center } from '../styled-system/patterns' export default function Page() { return ( <div className={center()}>Example</div> ) }
課題感としては polished に近い印象です。
dynamic styling に注意
公式ドキュメントに dynamic styling と言うセクションがありました。
Emotion ではクライアント側で <style>
へ変換されるため、ロジカルなスタイリングを行えるかと思います。
Zero Runtime な CSS in JS ではビルド時にスタイルが吐き出されるため注意が必要、とのことです。
ところが手元で試してみたところ、次のようなコードが動きました。 簡単なロジックは解析できるんですかね。。
'use client' import { css } from '../styled-system/css' import { MouseEventHandler, useState } from 'react' export default function Page() { const [visible, setVisible] = useState(true) const styles = { main: css({ visibility: visible ? 'visible' : 'hidden', }) } const handleToggle: MouseEventHandler<HTMLButtonElement> = (e) => { e.preventDefault() setVisible(!visible) } return ( <> <div className={styles.main}>hey</div> <button onClick={handleToggle}>toggle</button> </> ) }
感想
Panda CSS には他にも機能があります。詳しくはドキュメントをご覧ください。
比較的、開発体験を意識しているように感じられ結構気になってます。 また、ぱっと見た感じ @emotion/react に書き方が似ており、加えて Design Token も扱えるので、私が求めていたものに近いなあと。。
安定してきたら実際に取り入れてみたいものです。