0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

お題は不問!Qiita Engineer Festa 2023で記事投稿!

MUIv5のcreateThemeを使って独自の変数にカラーコードを持たす

Last updated at Posted at 2023-06-29

はじめに

こんにちは、u-Hoshiです。
普段の業務ではNext.jsやNest.jsを使って開発しています。

何を書いたか

今回はReactのUI Toolsの代表的なmuiでオリジナルのキーワードにカラーコードを当てて呼び出せるようにしました。

これによってmuiのデフォルトで準備されているprimarysecondary以外の単語を割り当てられます。

最終ゴールは今回作成するneutralがcolorでもsx内でも呼び出せるようにします。

page.tsx
<>
  <Button variant="contained" color="neutral">
    neutral
  </Button>

  <Box
    sx={{
      width: 300,
      height: 300,
      backgroundColor: theme.palette.neutral.main,
    }}
  />
</>

なぜ書いたか

元々あるキーワードでもいいのですが、

  • わかりづらい
  • 数が少ない

などの意見が開発中に上がりました。

恐らくこの問題は自分たちだけでは無いと感じたので今回執筆しました。

本題

まずThemeProviderを定義します。MUIのThemeProviderを使用してテーマオブジェクトが子コンポーネント以下で使えるようにします。

neutralという変数にピンクに近い色を持たせます。
今回はmainしか使いませんが、後々の開発の中でアプリケーション全体にdarkモード、lightモードを設定した場合はdark,lightに保持されている値を使うことができます。

src/ThemeProvider.tsx

import { createTheme, ThemeProvider } from "@mui/material";
import * as React from "react";

export const theme = createTheme({
  palette: {
    neutral: {
      main: "#E01E5A",
      dark: "#621B16",
      light: "#FEECEB",
    },
  },
});
export function Example({ children }: { children: React.ReactNode }) {
  return <ThemeProvider theme={theme}>{children}</ThemeProvider>;
}

ThemProviderで全体をラップ

次にMUIのThemeProviderを使用してテーマオブジェクトが子コンポーネント以下に提供します。

Next.js13からstableになったAppRouterを使用する場合はlayout.tsxに記述します。

layout.tsx

"use client";

import { ThemeProvider } from "@mui/material";
import { theme } from "@/ThemeProvider/page";

export default function RootLayout({children}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <ThemeProvider theme={theme}>
        <body>{children}</body>
      </ThemeProvider>
    </html>
  );
}

MUIのテーマにneutralという新しい色のオプションを追加

具体的にはmuiのPalettePaletteOptionsという2つのインターフェースにneutralという新しいカラーオプションを追加します。

ここで設定することでアプリケーション全体でneutralが使えるようになります。

types/createPalette.d.ts
declare module "@mui/material/styles" {
  interface Palette {
    neutral: {
      main: string;
    };
  }
  interface PaletteOptions {
    neutral?: {
      main?: string;
    };
  }
}

MUIのテーマとボタンコンポーネントの型定義を拡張

PaletteOptionsPaletteインターフェースにneutralを追加します。

またボタンコンポーネントのcolorプロパティにneutralを追加し、Buttonコンポーネントのcolorプロパティにneutralを指定することができるようになります。

themeOption.ts
import { PaletteColorOptions } from "@mui/material";

// PaletteOptions,Palette を拡張して、カラーキーワードを追加
declare module "@mui/material/styles/createPalette" {
  interface PaletteOptions {
    neutral: PaletteColorOptions;
  }
  interface Palette {
    neutral: PaletteColor;
  }
}

// Button の color prop に追加
declare module "@mui/material/Button" {
  interface ButtonPropsColorOverrides {
    neutral: true;
  }
}

最後に1番上位コンポーネントのapp直下のpage.tsxneutralを呼び出して使用します。

/app/page.tsx
"use client";
import { theme } from "@/ThemeProvider/page";
import { Box, Button } from "@mui/material";

export default function Home() {
  return (
    <>
      <Button variant="contained" color="neutral">
        neutral
      </Button>

      <Box
        sx={{
          width: 300,
          height: 300,
          backgroundColor: theme.palette.neutral.main,
        }}
      />
    </>
  );
}

これでneutralで指定した色が正しく表示されていれば成功です。

参考文献(なければ不要)

mui公式palette

最後に

最後まで読んでいただきありがとうございます!

0
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?