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?

MUI 自動的にダークモードとライトモードを切り替える

Last updated at Posted at 2024-12-01

MUIを使ってライトモードとダークモードを切り替える方法の備忘録。

追記

普通にこれで良かった

App.tsx
import Card from '@mui/material/Card'; // なぜかBoxだけサポートされていない
import { ThemeProvider, createTheme } from '@mui/material/styles';

const theme = createTheme({
  // いい感じの色を生成してくれるっぽい
  colorScheme: {
    light: true,
    dark: true,
  },
  // デフォルトのスタイルをオーバーライド
  components: {
    MuiCard: {
      defaultProps: {
        sx: {
          bgcolor: 'white', // 'red'とかだと流石に無理
        },
      },
    },
  },
});

export function App() {
  return (
    <ThemeProvider theme={theme}>
      <Card>
        Hello, World!
      </Card>
    </ThemeProvider>
  );
}

コード

App.tsx
import Box from '@mui/material/Box';
import { ThemeProvider, createTheme } from '@mui/material/styles';

/* Paletteの型宣言ににカスタムの色を追加 */
declare module '@mui/material/styles' {
  interface Palette {
    myBlack: string,
    myGray: string,
  }
  interface PaletteOptions {
    myBlack?: string,
    myGray?: string,
  }
}

const theme = createTheme({
  /* 自動で色を切り替えてくれる */
  colorSchemes: {
    light: {
      palette: {
        /* ライトモードの時のみ採用 */
        myBlack: 'white',
        myGray: '#888888',
      },
    },
    dark: {
      palette: {
        myBlack: 'black',
        myGray: '#DDDDDD',
      },
    },
  },
});

function Content() {
  return (
    <Box
      sx={
        theme => ({
            /* Themeオブジェクトを使って色を指定する */
          color: theme.palette.myBlack,
          bgcolor: theme.palette.myGray,
        })
      }
    >
      <p>Hello, World!</p>
    </Box>
  );
}

export default function App() {
  return (
    <ThemeProvider theme={theme}>
      <Content />
    </ThemeProvider>
  );
}

ポイント

  • colorSchemesを使ってモードに応じた色を自動指定する
  • Themeオブジェクトから色を拾う

課題

  • paletteが簡単に肥大化する(一度しか使わない色でも指定が必要)
  • paletteで色を指定し忘れるとスタイルが消える
  • declare moduleが面倒

余談:Next.js対応

Next.jsで上記のアプローチを取ろうとする際、createTheme()を使ったコンポーネントをlayout.tsxに含めるとエラーが発生する。コンポーネントをapp.tsxApp()で使うようにすると解決する。

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?