0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Chakra UIのV3へメジャーアップデートする際の変更点

Posted at

はじめに

こんにちは、H×Hのセンリツ大好きエンジニアです。(同担OKです😉)

今回は、2024年10月にメジャーアップデートされたChakra UIの変更点が思いの外多かったので、簡単にではありますがまとめました。
(足りない情報があればコメント等で教えていただけますと幸いです🙇)

この記事で取り上げる変更点

使用するパッケージ

V3では @emotion/styledframer-motionパッケージが使用されません。
また、@chakra-ui/next-jsも不要になりました。(asChildpropsの登場により)

そのため、インストールするときは以下のコマンドでインストールします。

npm i @chakra-ui/react @emotion/react

V3ではCLIパッケージも新たに追加され、今まで使用していたコンポーネント(AccordionProgressなど)を使用する際には以下のコマンドから事前に定義されたスニペットとして追加できます。

npx @chakra-ui/cli snippet add

Theme、Recipe

Theme

Themeに関しても、Panda CSSを参考にして作られているため仕様が変わっています。
(Panda CSSを使っているような説明ですが、実際にはPanda CSSはChakra UIで使用されていません)

theme.tsでは今までextendThemeを使用することで独自のスタイリングや、コンポーネント毎のプロパティ調整など行っていましたが、V3からはcreateSystemdefaultConfigを使う必要があります。

theme.ts
import { createSystem, defaultConfig } from "@chakra-ui/react"

export const system = createSystem(defaultConfig, {
  theme: {
    tokens: {
      fonts: {
        heading: { value: `'Figtree', sans-serif` },
        body: { value: `'Figtree', sans-serif` },
      },
    },
  },
})

theme.tsの中で設定できるプロパティの例としては、以下のものがあります。

  • breakpoints: ブレークポイントを定義する
  • keyframes: CSSキーフレームアニメーションを定義する
  • tokens: トークンを定義する
  • semanticTokens: セマンティックトークンを定義する
  • textStyles: タイポグラフィスタイルを定義する
  • layerStyles: レイヤースタイルを定義する
  • animationStyles: アニメーションスタイルを定義する
  • recipes: コンポーネントレシピを定義する
  • slotRecipes: コンポーネントスロットレシピを定義する

この中にあるtokenssemanticTokensは独自のカラーコードやフォントを設定するためのものです。
また、Themeの中で最も変わった部分としては、recipesslotRecipesになるかと思います。

Recipe

Recipeは、ButtonやInputなどのコンポーネントのプロパティをグローバルに定義することが出来るものです。
以前はコンポーネント毎にdefineStyledefineStyleConfigを使用していましたが、Panda CSSライクになったことで廃止になりました。

使用方法としては、defineRecipeを使用して独自のRecipeを作成します。

button.recipe.ts
import { defineRecipe } from "@chakra-ui/react"

export const buttonRecipe = defineRecipe({
  base: {
    display: "flex",
  },
  variants: {
    visual: {
      solid: { bg: "red.200", color: "white" },
      outline: { borderWidth: "1px", borderColor: "red.200" },
    },
    size: {
      sm: { padding: "4", fontSize: "12px" },
      lg: { padding: "8", fontSize: "24px" },
    },
  },
})

これをtheme.ts内で既存のコンポーネントに適用します。

theme.ts
import { buttonRecipe } from "./button.recipe"

export const system = createSystem(defaultConfig, {
  theme: {
    tokens: {
      fonts: {
        heading: { value: `'Figtree', sans-serif` },
        body: { value: `'Figtree', sans-serif` },
      },
    recipes: {
        button: buttonRecipe,
      },
    },
  },
})

ここで注意が必要なのですが、以前のようにvariantを独自で設定した場合CLIでRecipeの型を生成してあげる必要があります。
これをしないと、型エラーが発生してしまいます。

npx @chakra-ui/cli typegen ./theme.ts

ButtonInputなどの単体で動作するコンポーネントに関してはRecipeで定義できますが、Accordionなどの組み合わせることで初めて機能するコンポーネントに関してはSlotRecipeで定義する必要があります。
ちなみに、Accordionは以下のような形になっています。(Ark UIを基に作成されているため)

accoridon.ts
import {
  AccordionItem,
  AccordionItemContent,
  AccordionItemTrigger,
  AccordionRoot,
} from "@/components/ui/accordion"

const Demo = () => {
  return (
    <AccordionRoot collapsible defaultValue={["b"]}>
      {items.map((item, index) => (
        <AccordionItem key={index} value={item.value}>
          <AccordionItemTrigger>{item.title}</AccordionItemTrigger>
          <AccordionItemContent>{item.text}</AccordionItemContent>
        </AccordionItem>
      ))}
    </AccordionRoot>
  )
}

const items = [
  { value: "a", title: "First Item", text: "Some value 1..." },
  { value: "b", title: "Second Item", text: "Some value 2..." },
  { value: "c", title: "Third Item", text: "Some value 3..." },
]

SlotRecipeも基本的にはRecipeと同様に定義することが可能ですが、複数のパーツに分かれているためどこのパーツにプロパティを適用させるか決める必要があります。

以下の画像はArk UIの公式リファレンス内で確認できます。
スクリーンショット 2024-11-30 17.15.34.png

現段階ではChakra UIのリファレンスに上記の画像が掲載されていないため、コンポーネント関連に関してはArk UIのリファレンスを見た方が良いです。

そのため、Accordionを例に挙げる場合はSlotRecipeを以下のようにパーツ毎で記述します。

accordion.recipe.ts
import { defineRecipe } from "@chakra-ui/react"

export const accordionSlotRecipe = defineSlotRecipe({
  slots: ["root", "item", "itemTrigger", "itemBody", "itemContent"],
  base: {
    root: {
      width: "full",
      "--accordion-radius": "radii.l2",
    },
    item: {
      overflowAnchor: "none",
    },
    itemTrigger: {
      display: "flex",
      alignItems: "center",
      width: "full",
      outline: "0",
      gap: "3",
      fontWeight: "medium",
      borderRadius: "var(--accordion-radius)",
      _focusVisible: {
        outline: "2px solid",
        outlineColor: "colorPalette.focusRing",
      },
      _disabled: {
        layerStyle: "disabled",
      },
    },
    itemBody: {
      pt: "var(--accordion-padding-y)",
      pb: "calc(var(--accordion-padding-y) * 2)",
    },
    itemContent: {
      overflow: "hidden",
      borderRadius: "var(--accordion-radius)",
      _open: {
        animationName: "expand-height, fade-in",
        animationDuration: "moderate",
      },
      _closed: {
        animationName: "collapse-height, fade-out",
        animationDuration: "moderate",
      },
    },

    variants: {
      variant: {
        outline: {
          item: {
            borderBottomWidth: "1px",
          },
        },
      },
    },
})

上記のように、Chakra UIが事前に定義しているoutlineのようなvariantにも上書きでプロパティを変更できたりもします。

実際に適用する場合は、AccordionコンポーネントのRootにvariantを設定してあげます。

accordion.ts
import {
  AccordionItem,
  AccordionItemContent,
  AccordionItemTrigger,
  AccordionRoot,
} from "@/components/ui/accordion"

const Demo = () => {
  return (
    <AccordionRoot collapsible defaultValue={["b"]} variant="outline">
      {items.map((item, index) => (
        <AccordionItem key={index} value={item.value}>
          <AccordionItemTrigger>{item.title}</AccordionItemTrigger>
          <AccordionItemContent>{item.text}</AccordionItemContent>
        </AccordionItem>
      ))}
    </AccordionRoot>
  )
}

const items = [
  { value: "a", title: "First Item", text: "Some value 1..." },
  { value: "b", title: "Second Item", text: "Some value 2..." },
  { value: "c", title: "Third Item", text: "Some value 3..." },
]

Components

先ほどの章でも少し取り上げましたが、コンポーネントに関してはArk UIを基に作成したためガラリと変わっています。

基本的にはArk UIのリファレンスを参考にしつつ実装するのが良いと思います。
また、コンポーネントを使用する際は以下のCLIコマンドでスニペットを追加してあげる必要があります。

npx @chakra-ui/cli snippet add

V3ではPaginationなどの新しいコンポーネントが追加された反面、シンプルになった影響で細かい調整などがしにくくなっています。

例えば、V3ではHooksが一部を除き無くなっています。(useBreakpointValue等は現在も使用可能)

そのため、Radioなどで今まで使っていたuseRadiouseRadioGroupを使用されている場合は代替手段としてreact-useusehooks-tsを使用する必要があります。

おわりに

ここまでご覧いただきありがとうございます🙇
見た感じ、Panda CSSとArk UIに触れたことがある方にとってはより親しみやすくなったんじゃないでしょうか。

Chakra UIの今回のメジャーアップデートはかなり破壊的変更が満載ですので、プロダクトに規模によってかなり慎重に検討する必要があるかと思います。
今回は特に変わったところをご紹介したので、他にも気になることがあれば教えていただければと思います🫡

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?