2023年09月10日
Panda CSSでPrimaryカラーにデフォルトのパレットの色を設定する
Panda CSSでPrimaryカラーにデフォルトのパレットの色を設定するコードの作成例です。
環境
- @pandacss/dev: ^0.13.1
目標
PandaCSSデフォルトのテーマに組み込まれているColorsトークンの値をPrimaryカラーに設定し、primary.${shade}
という色合い(Shade
)を持つトークンとして利用できるようにすること。
import { css } from "../styled-system/css";
const style = css({ color: "primary.600" });
方法
import type { PropertyTypes } from "../styled-system/types/prop-type";
const shades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950];
function definePalette(props: Record<string, PropertyTypes["colorPalette"]>) {
return Object.entries(props).reduce<{
[key: string]: {
[key: string]: { value: string };
};
}>(
(accum, [key, color]) => ({
...accum,
[key]: shades.reduce<{
[key: string]: { value: string };
}>(
(previousValue, curr) => ({
...previousValue,
[curr]: { value: `{colors.${color}.${curr}}` },
}),
{},
),
}),
{},
);
}
export default defineConfig({
theme: {
extend: {
semanticTokens: {
colors: {
...definePalette({ primary: "sky", secondary: "orange" }),
},
},
},
},
});
留意点
この方法ではpanda.config
はデフォルトのテーマを拡張(extend)することを前提としています。
解説
panda.config
にsemanticTokens
を設定する- ヘルパーとなる
definePalette
関数を作成する
(補) デザイントークンとは
デザイントークンはUIフレームワークで使用されている短縮記法です。デザイントークンを用いることで統一感のあるデザインが可能になります。Panda CSSのデフォルトのテーマにはColors, Spacing, Border Radiusなど豊富なトークンが組み込まれていています。
以下の例では、<p>
要素にPanda CSSの文字サイズmd
、文字色red.600
を設定するReactのコードです。
import { css } from "../styled-system/css";
const App = () => {
return <p className={css({ fontSize: "md", color: "red.600" })}>Hoge</p>;
};
上記のコードは以下のDOMに変換されます。
<p class="fs_md text_red\.600">hoge</p>
上記のDOMは以下のようなCSS変数とクラスの組み合わせによってスタイリングされます。
:where(:root, :host) {
--font-sizes-md: 1rem;
--colors-red-600: #dc2626;
}
.fs_md {
font-size: var(--font-sizes-md);
}
.text_red\.600 {
color: var(--colors-red-600);
}
1. panda.config
にsemanticTokens
を設定する
panda.config
で新たなトークンを設定する場合、値を直接指定するtokens
と、既存のトークンの値を使用して新たなトークンを設定するsemanticTokens
の2種類があります。
import { defineConfig } from "@pandacss/dev";
export default defineConfig({
theme: {
extend: {
tokens: {
colors: {
success: { value: "#6f6" },
},
},
semanticTokens: {
colors: {
danger: { value: "{colors.red.700}" },
},
},
},
},
});
上記の例ではtokens
でsuccessカラーを設定し、semanticTokens
でdangerカラーを設定しています。tokens
では色をカラーコードで指定したのに対して、semanticTokens
ではデフォルトのテーマに組み込まれているトークンの値を選択することができます。
ちなみにPanda CSSのデフォルトのパレットはTailwind CSSのパレットがベースになっているようです。Panda CSSと開発者が同じChakra UIのパレットとは同じトークン名であっても色が異なります。
Customizing Colors - Tailwind CSS
PrimaryカラーにデフォルトColorsのSkyを指定するには以下のようにsemanticTokens
を設定することで実現可能です。
export default defineConfig({
theme: {
extend: {
semanticTokens: {
colors: {
primary: {
50: { value: "{colors.sky.50}" },
100: { value: "{colors.sky.100}" },
200: { value: "{colors.sky.200}" },
/* 略 */
950: { value: "{colors.sky.950}" },
},
},
},
},
},
});
しかし上記のように、デフォルトのColorsと同様50から950までの11種類の色合い(Shade
)を一つ一つ手作業で設定するのは非常に面倒です。この例だとPrimaryカラーを変更するのも面倒です。さらにPrimaryカラーだけではなく、Secondaryカラーなど複数のパレットを設定する場合、コードは更に冗長になります。
そこでsemanticTokens
にを出力するdefinePalette
関数を作成します。
2. definePalette
関数を作成する
import type { PropertyTypes } from "../styled-system/types/prop-type";
const shades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950];
function definePalette(props: Record<string, PropertyTypes["colorPalette"]>) {
return Object.entries(props).reduce<{
[key: string]: {
[key: string]: { value: string };
};
}>(
(accum, [key, color]) => ({
...accum,
[key]: shades.reduce<{
[key: string]: { value: string };
}>(
(previousValue, curr) => ({
...previousValue,
[curr]: { value: `{colors.${color}.${curr}}` },
}),
{},
),
}),
{},
);
}
この関数の使い方は以下の通りです。semanticTokens.colors
にスプレッド構文でdefinePalette
を記述します。
export default defineConfig({
theme: {
extend: {
semanticTokens: {
colors: {
...definePalette({ primary: "sky", secondary: "orange" }),
},
},
},
},
});
これで色合いを持つPrimaryカラー、Secondaryカラーを利用することができます。
import { css } from "../styled-system/css";
const style = css({
color: { base: "primary.700", _dark: "primary.100" },
bg: { base: "secondary.50", _dark: "secondary: 950" },
});
リンク
Cumbia Algarrobera / Son Rompe Pera (2020)
Panda CSS
Panda CSSは型安全を保ちながらスタイルを記述することができるCSS-in-JSのパッケージです。
https://panda-css.com/