devlog

Emotion から Panda CSS に乗り換えるか悩む【雑記】

2023-08-07

雑記です。

趣味のプロジェクトで 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> ) }

課題感としては TailwindTheme 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 も扱えるので、私が求めていたものに近いなあと。。

安定してきたら実際に取り入れてみたいものです。

  • 作成日
    2023-08-07
  • 更新日
    2023-08-08