🧁
🧁【MUI ✕ Sonner】Toastをスタイリングしてみた
こんにちは!
今回は 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
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