🎉

Next.jsでMaterial UIのColorを変える方法

2024/10/01に公開

事前準備

Next.js のバージョンは 14.2.13 です

npx create-next-app@latest
npm install @mui/material @emotion/react @emotion/styled
npm install @mui/material @mui/styled-engine-sc styled-components
npm install @fontsource/roboto
npm install @mui/icons-material

テーマカラーの定義

thema.tsxを作成して、全体のカラーをデフォルトから変更

thema.tsx
"use client";
import { ThemeProvider, createTheme } from "@mui/material/styles";

// Material UIのカラー変更を全体に適用するコンポーネント
// プロパティとして、children(Reactの子コンポーネント)を受け取る
export function Thema({ children }: { children: React.ReactNode }) {
  const theme = createTheme({
    palette: {
      primary: {
        main: "#8b5cf6",
      },
      success: {
        main: "#22c55e",
        contrastText: "#FFFFFF",
      },
      error: {
        light: "#ff7961",
        main: "#f44336",
        dark: "#ba000d",
        contrastText: "#000",
      },
      background: {
        default: "#FFFFFF",
      },
      secondary: {
        main: "#FFFFFF",
        contrastText: "#FFFFFF",
      },
    },
  });

  return <ThemeProvider theme={theme}>{children}</ThemeProvider>;
}

テーマカラーの適用

layout.tsxで、thema.tsxを import し、childrenを、<Thema>コンポーネントで囲む

layout.tsx
import type { Metadata } from "next";
import localFont from "next/font/local";
import "./globals.css";

// import
import { Thema } from "./thema";

const geistSans = localFont({
  src: "./fonts/GeistVF.woff",
  variable: "--font-geist-sans",
  weight: "100 900",
});
const geistMono = localFont({
  src: "./fonts/GeistMonoVF.woff",
  variable: "--font-geist-mono",
  weight: "100 900",
});

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
        {/* <Thema></Thema>で「children」を囲む */}
        <Thema>{children}</Thema>
      </body>
    </html>
  );
}

カスタムスタイルの定義

style.tsを作成して、カスタムスタイルを定義

style.ts
export const myStyle = {
  "& .MuiInputBase-input": {
    color: "#06b6d4",
  },
  "& label": {
    color: "#06b6d4",
  },
  "& label.Mui-focused": {
    color: "#06b6d4",
  },
  "& .MuiInput-underline:before": {
    borderBottomColor: "#06b6d4",
  },
  "& .MuiInput-underline:hover:not(.Mui-disabled):before": {
    borderBottomColor: "#06b6d4",
  },
  "& .MuiInput-underline:after": {
    borderBottomColor: "#06b6d4",
  },
  "& .MuiInput-underline.Mui-focused:before": {
    borderBottomColor: "#06b6d4",
  },
  "& .MuiOutlinedInput-root": {
    "& fieldset": {
      borderColor: "#06b6d4",
    },
    "&:hover fieldset": {
      borderColor: "#06b6d4",
    },
    "&.Mui-focused fieldset": {
      borderColor: "#06b6d4",
    },
  },
};
State Global class name
active .Mui-active
checked .Mui-checked
completed .Mui-completed
disabled .Mui-disabled
error .Mui-error
expanded .Mui-expanded
focus visible .Mui-focusVisible
focused .Mui-focused
readOnly .Mui-readOnly
required .Mui-required
selected .Mui-selected

カスタムスタイルの適用(カラー変更例)

globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;

ボタンとテキストインプットの例です

page.tsx
import { Button } from "@mui/material";
import { TextField } from "@mui/material";
import { myStyle } from "./style";

export default function Home() {
  return (
    <div className="flex flex-col space-y-4 items-center justify-center h-screen">
      <Button color="primary" variant="contained">
        purple
      </Button>
      <Button color="error" variant="contained">
        error
      </Button>
      <TextField sx={{ ...myStyle, width: "400px" }} variant="standard" label="Input" />
    </div>
  );
}


P.S. 転職活動の際のプログラミングテストで、カラー変更に手間取ったため、まとめました…

参考

https://mui.com/material-ui/customization/how-to-customize/
https://mui.com/material-ui/react-text-field/#customization

GitHubで編集を提案

Discussion