Tailwind CSSでcolor属性を取得

profile image

Tailwind CSSで設定したcolorタイプを取得してみましょう!

この記事は DeepL によって翻訳されました。誤訳があれば教えてください!

アイコンコンポーネントを作る時、propsで色に関する属性を取得してclassNameに追加したかった。

アイコンはSVGで構成されており、fillとstrokeの値を直接指定するのではなく、classNameにTailwind CSSのオートコンプリートを利用して色を指定したかった。

例えば、次のようなコードを書きたいと思いました。

typescript
interface IconProps { fill: string
  fill: string
  stroke: string
}
const Icon = ({fill, stroke}: IconProps) => { {
  <svg className={`${fill} ${stroke}`} /> }
}

tailwindのオートコンプリートの力を借りるためにはfillと strokeのタイプにstringの代わりに他のタイプを入れる必要があります。 つまり、tailwindに設定されているcolor classesの名前を取得する必要があります。

タイプを抽出する

まず、tailwindの基本的なcolor情報を取得します。

typescript
import defaultColors from "tailwindcss/colors"
export type DefaultColors = keyof typeof defaultColors

const color: DefaultColors = 'blue'

Image.png

しかし、カラーキーだけが自動補完されるだけで、その後ろの属性は提供されません。(blueはできますが、blue-500などの自動補完はされません)

次のステップとして、tailwindのconfig全体を取得してみましょう。

typescript
import resolveConfig from "tailwindcss/resolveConfig"
import tailwindConfig from "web/tailwind.config.ts"; // tailwind 設定ファイル

const fullConfig = resolveConfig(tailwindConfig);

すると、fullConfigでは次のような情報を取得することができます。

Image.png

上記の情報を組み合わせてColorShadeという新しいタイプを作成してみましょう。

typescript
type ColorShade<T extends DefaultColors> = keyof ColorConfig[T] extends
  | string
  | number
  ? keyof ColorConfig[T
  : never

const shade: ColorShade<'blue'> = '500'

Image.png

これで色の後ろの属性も取得できるようになりました。

これらを組み合わせて、色と明るさを組み合わせた名前を抽出することができるようになりました。

typescript
type TailwindColorClass = { {...
  [P in DefaultColors]:ColorShade<P> extends never ? P`${P}-${ColorShade<P>}`
}[DefaultColors];

Image.png

適用

次は、私が欲しかった機能であるfillにはfillに入れるclassName、strokeにはstrokeだけ入れるclassNameを作りましょう。

typescript
interface IconProps {
  fill`fill-${TailwindColorClass}`
  stroke`storke-${TailwindColorClass}`
}

Image.png

カスタムカラー適用

上のコードの問題点はtailwindの基本的な色だけ取ってきて、ユーザーが定義した色は取れないです。

カスタムカラーの分離

まず、カスタムで適用したcolorsを一つの変数で分離してみましょう。

typescript
const color = { .
  ...formalColors
  ...keyColors
  ...accentColors
  ...grayColor
  ...theme.colors
}

そして上で使ってたDefaultColorsの代わりに下記のタイプを作りましょう。

typescript
type CustomColors = typeof color
type DefaultColors = typeof defaultColors
export type Colors = CustomColors & DefaultColors

最終コード

tailwin.config.ts

typescript
type CustomColors = typeof color
export type DefaultColors = typeof defaultColors
export type Colors = CustomColors & DefaultColors

Component.tsx

typescript
const fullConfig = resolveConfig(tailwindConfig);
const colorTheme = fullConfig.theme.colors as Colors
type ColorConfig = typeof colorTheme
type ColorKeys = keyof Colors

type ColorShade<T extends ColorKeys> = keyof ColorConfig[T] extends
  | string
  | number
  keyof ColorConfig[T] ?
  : never


type TailwindColorClass = { {...
  [P in ColorKeys]:ColorShade<P> never extends ? P`${P}-${ColorShade<P>}`
}[ColorKeys];



interface IconProps {
  塗りつぶしを行います`fill-${TailwindColorClass}`
  ストローク`storke-${TailwindColorClass}`
}
❤️ 0
🔥 0
😎 0
⭐️ 0
🆒 0