🐥

MUIのPaletteにオリジナルのpaletteを追加する

2022/08/17に公開

はじめに

Material UI にオリジナルの Palette を追加したい!!します!!

デフォルト部分のカスタマイズ

Material UI ではテーマを拡張することができます。既存にあるsuccesswarningなどの色を変更することが可能です。

createThemethemeを作成すると上書きすることが可能になります。

index.tsx
import { createTheme } from "@mui/material";

export const theme = createTheme({
  palette: {
    primary: {
      main: "#1760a5",
      light: "skyblue",
    },
  },
});

themeを適用するにはThemeProviderの中で上書きした色を使用することができます。

index.tsx
import { createTheme, Button, ThemeProvider } from "@mui/material";
import React from "react";
import ReactDOM from "react-dom/client";

export const theme = createTheme({
  palette: {
    primary: {
      main: "#1760a5",
      light: "skyblue",
    },
  },
});

const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement,
);

root.render(
  <React.StrictMode>
    <ThemeProvider theme={theme}>
      <Button variant="contained" color="primary">
        Button
      </Button>
    </ThemeProvider>
  </React.StrictMode>,
);

オリジナルのPaletteの追加

今回やりたいこととしては、primaryなどのPaletteを追加することです。
公式ドキュメントでは例として、neutralを追加していたので同じ形で追加していきます。

最初にthemeに含めますが、型定義に存在しないためエラーになります。

index.ts
import { createTheme } from "@mui/material";

export const theme = createTheme({
  palette: {
    primary: {
      main: "#1760a5",
      light: "skyblue",
    },
    neutral: {
      main: "#999",
      contrastText: "#fff",
    },
  },
});

型定義を変更する必要があるので、宣言されているstylesPaletteOptionsを拡張します。

export declare module "@mui/material/styles" {
  interface PaletteOptions {
    neutral: PaletteOptions["seccondary"];
  }
}

公式のドキュメントでは上記でできそうな形になっているのですが、加えて使用する要素(Button)のPropsColorOverridesを拡張する必要があります。公式ドキュメント内のCodeSandboxまで確認すると拡張されてます。

index.ts
export declare module "@mui/material/Button" {
  interface ButtonPropsColorOverrides {
    neutral: true;
  }
}
index.tsx
import { createTheme, Button, ThemeProvider } from "@mui/material";
import React from "react";
import ReactDOM from "react-dom/client";

export const theme = createTheme({
  palette: {
    primary: {
      main: "#1760a5",
      light: "skyblue",
    },
    neutral: {
      main: "#999",
      contrastText: "#fff",
    },
  },
});

declare module "@mui/material/styles" {
  interface PaletteOptions {
    neutral: PaletteOptions["primary"];
  }
}

declare module "@mui/material/Button" {
  interface ButtonPropsColorOverrides {
    neutral: true;
  }
}

const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement,
);

root.render(
  <React.StrictMode>
    <ThemeProvider theme={theme}>
      <Button variant="contained" color="neutral">
        Button
      </Button>
    </ThemeProvider>
  </React.StrictMode>,
);

その他

型部分の拡張を外に出したい場合は、typesなどの自動で読み取られるフォルダ内にcreatePalette.d.tsに書けば読み取られます。

types/createPalette.d.ts
export declare module "@mui/material/styles" {
  interface PaletteOptions {
    neutral: PaletteOptions["seccondary"];
  }
}

export declare module "@mui/material/Button" {
  interface ButtonPropsColorOverrides {
    neutral: true;
  }
}

参考

Palette - Material UI

[Typescript]Material UI テーマのパレットで任意のキーワードを追加する

GitHubで編集を提案

Discussion