🧁

🧁【MUI ✕ Sonner】Toastをスタイリングしてみた

2025/04/02に公開

こんにちは!
今回は MUI + Sonner の組み合わせで「オリジナルで可愛いトースト通知」を作ったので、記事にまとめます✍️

✅ 色・影・フォントまで完全にカスタム
✅ MUIのテーマを活かして統一感◎
✅ Success/Errorだけのミニマル設計

🧸使用したライブラリたち

🎯 目標:こんなトーストを作りたい!

✨ 完成コード

  • componentのセットアップ
import { Toaster } from 'sonner';
import { useTheme, styled } from '@mui/material/styles';
import { CheckCircleSolid, WarningCircleSolid } from 'iconoir-react';
import { varAlpha } from '@/theme/core/shadows';

export default function Snackbar() {
  const theme = useTheme();

  return (
    <StyledToaster
      expand
      gap={12}
      offset={16}
      visibleToasts={4}
      position="top-right"
      toastOptions={{
        unstyled: true,
        classNames: {
          error: 'error',
          success: 'success',
          icon: 'icon',
          title: 'title',
          toast: 'toast',
        },
      }}
      icons={{
        success: <CheckCircleSolid />,
        error: <WarningCircleSolid />,
      }}
    />
  );
}
  • sonnerのデフォルトスタイルを無効にしてMUIで完全に制御するようにしています。
unstyled: true
  • toastOptions.classNamesを活用してsonnerの内部構造にスタイルを当てます。
    参考docs1
    参考docs2
  • スタイリング
const StyledToaster = styled(Toaster)(({ theme }) => ({
  width: 300,

  '.toast': {
    gap: 12,
    width: '100%',
    minHeight: 56,
    display: 'flex',
    alignItems: 'center',
    borderRadius: 12,
    padding: '4px',
  },

  '.icon': {
    width: 48,
    height: 48,
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    borderRadius: 'inherit',
    alignSelf: 'flex-start',
    margin: 0,
    svg: {
      width: 24,
      height: 24,
    },
  },

  '.title': {
    fontSize: theme.typography.subtitle2.fontSize,
    fontWeight: theme.typography.subtitle2.fontWeight,
  },

  '& .success .icon': {
    color: theme.palette.success.main,
    backgroundColor: varAlpha(theme.palette.success.main, 0.08),
  },

  '& .error .icon': {
    color: theme.palette.error.main,
    backgroundColor: varAlpha(theme.palette.error.main, 0.08),
  },
}));

まとめ

  • sonner*MUIで簡単に統一感のあるtoastが作れる
  • className と styled() をうまく組み合わせると可愛くなる💫
  • icon だけでなく loader, description, action ボタンも自由にスタイル可能!

トースト通知って地味だけど、世界観づくりには超重要なので、ぜひカスタムしてみてください!

Discussion