🎨 Nodeblocksコンポーネントのテーマ設定
統一されたMUIベースのテーマシステムで、すべてのNodeblocksコンポーネントのルック&フィールをカスタマイズ 🎭
このガイドでは、@nodeblocks/frontend-themeパッケージを使用して、アプリケーション全体で一貫したブランド体験を作成する方法について説明します。
📋 概要
Nodeblocksテーマパッケージは以下を提供します:
- 事前設定されたMUIテーマ – 最適化されたデフォルトを持つ、すぐに使えるMaterial-UIテーマ
- ThemeProviderコンポーネント – アプリ全体への簡単なテーマ適用
- カスタマイズ可能なトークン – パレット、タイポグラフィ、スペーシング、コンポーネントスタイル
- CSS変数サポート – ランタイムテーマ設定のためのモダンなCSSカスタムプロパティ
- グローバルスタイル – 共通UIパターンの一貫したスタイリング
🎯 主なメリット:
ThemeProviderでラップすると、Nodeblocksコンポーネントと一緒に任意のMUIコンポーネント(Button、Tabs、TextField、Cardなど)を使用できます - すべてが同じ一貫したスタイリングを共有します。自由に組み合わせてください!
いつ何を使うか
| シナリオ | アプローチ |
|---|---|
| Nodeblocksコンポーネントをそのまま使用 | <ThemeProvider>でラップするだけ |
| ブランドカラーのみ変更 | ThemeProviderにカスタムパレットを渡す |
| 完全なブランドカスタマイズ | createTheme()でテーマを作成 |
📦 インストール
# テーマパッケージをインストール
npm install @nodeblocks/frontend-theme
# 必要なピア依存関係(まだインストールしていない場合)
npm install @mui/material @emotion/react @emotion/styled
🚀 クイックスタート
基本的な使い方
アプリケーションをThemeProviderでラップして、デフォルトのNodeblocksテーマを適用します:
import React from 'react';
import { ThemeProvider } from '@nodeblocks/frontend-theme';
import { SignIn } from '@nodeblocks/frontend-signin-block';
import { Navbar } from '@nodeblocks/frontend-navbar-block';
function App() {
return (
<ThemeProvider>
<Navbar
leftContent={<span>My App</span>}
centerContent={<nav>Navigation</nav>}
rightContent={<button>Login</button>}
/>
<main>
<SignIn onSubmit={(data) => console.log(data)} />
</main>
</ThemeProvider>
);
}
export default App;
ThemeProviderのプロップ
| プロップ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | - | アプリケーションコンポーネント |
theme | Theme | defaultTheme | カスタムMUIテーマオブジェクト |
enableCssBaseline | boolean | true | CSSリセットとベースラインスタイルを適用 |
injectMuiStylesFirst | boolean | true | MUIスタイルを最初に注入してオーバーライドを容易に |
NodeblocksでMUIコンポーネントを使用
ThemeProvider内では任意のMUIコンポーネントがシームレスに動作します:
import { ThemeProvider } from '@nodeblocks/frontend-theme';
import { ListUsers } from '@nodeblocks/frontend-list-users-block';
import { Button, Tabs, Tab, TextField, Card } from '@mui/material';
function App() {
return (
<ThemeProvider>
{/* MUIコンポーネント - 自動的にスタイル適用 */}
<Card sx={{ p: 2, mb: 2 }}>
<TextField label="ユーザーを検索" size="small" />
<Button variant="contained">検索</Button>
</Card>
<Tabs value={0}>
<Tab label="アクティブ" />
<Tab label="保留中" />
</Tabs>
{/* Nodeblocksコンポーネント - 同じ一貫したスタイリング */}
<ListUsers data={users} />
</ThemeProvider>
);
}
🎨 カラーパレット
テーマにはモダンなアプリケーション向けに設計された包括的なカラーパレットが含まれています。
デフォルトカラー
import { palette } from '@nodeblocks/frontend-theme';
// プライマリカラー
palette.primary.main // #006ead - プライマリブランドカラー
palette.primary.light // #0391d4 - 明るいバリアント
palette.primary.dark // #004e8b - 暗いバリアント
// セカンダリカラー(グレー)
palette.secondary.main // #737d90 - セカンダリアクション
palette.secondary.light // #9ea4b1 - 明るいセカンダリ
palette.secondary.dark // #1d1e20 - 暗いセカンダリ
// セマンティックカラー
palette.error.main // #e54e4b - エラー状態
palette.warning.main // #ed6c02 - 警告状態
palette.success.main // #2e7d32 - 成功状態
palette.info.main // #006ead - 情報状態
// グレースケール
palette.grey[25] // #f8f8f8 - 最も明るいグレー
palette.grey[50] // #f3f3f3
palette.grey[100] // #c9d0da
palette.grey[500] // #737d90 - ミッドグレー
palette.grey[900] // #1d1e20 - 最も暗いグレー
// 背景とサーフェス
palette.background.default // #f3f3f3 - ページ背景
palette.background.paper // #ffffff - カード/ペーパー背景
// テキストカラー
palette.text.primary // #1d1e20 - プライマリテキスト
palette.text.secondary // #737d90 - セカンダリテキスト
palette.text.disabled // #9ea4b1 - 無効テキスト
// サーフェスとディバイダー
palette.surface.accentLightLow // #EBF7FF - 明るいアクセントサーフェス
palette.divider // #e2e4e7 - ボーダー/ディバイダーカラー
カラーのカスタマイズ
import { createTheme } from '@mui/material';
import { ThemeProvider, defaultTheme } from '@nodeblocks/frontend-theme';
// カスタムテーマを作成 - defaultThemeをベースにすると、すべてのNodeblocksデフォルトが保持されます
const customTheme = createTheme(defaultTheme, {
palette: {
primary: {
main: '#8B5CF6', // パープルブランドカラー
light: '#A78BFA',
dark: '#7C3AED',
},
secondary: {
main: '#EC4899', // ピンクアクセント
light: '#F472B6',
dark: '#DB2777',
},
},
});
function App() {
return (
<ThemeProvider theme={customTheme}>
{/* カスタムカラーのアプリ */}
</ThemeProvider>
);
}
💡 重要:
createTheme(defaultTheme, { ... })を使用すると、変更がNodeblocksデフォルトとディープマージされ、タイポグラフィ、スペーシング、コンポーネントスタイルが保持されます。
✍️ タイポグラフィ
テーマには完全なタイポグラフィシステムが含まれています:
デフォルトタイポグラフィスケール
import { typography } from '@nodeblocks/frontend-theme';
// 見出し
typography.h1 // 2.5rem, weight 700
typography.h2 // 2rem, weight 700
typography.h3 // 1.75rem, weight 600
typography.h4 // 1.5rem, weight 600
typography.h5 // 1.25rem, weight 600
typography.h6 // 1.125rem, weight 600
// 本文
typography.body1 // 1rem, weight 400
typography.body2 // 0.875rem, weight 400
// サブタイトル
typography.subtitle1 // 1rem, weight 500
typography.subtitle2 // 0.875rem, weight 500
// その他のバリアント
typography.button // 0.875rem, weight 600
typography.caption // 0.75rem, weight 400
typography.overline // 0.75rem, weight 500, uppercase
デフォルトフォントスタック
テーマは日本語と西洋文字に最適化されたクロスプラットフォームフォントスタックを使用しています:
fontFamily: [
'Hiragino Sans', // macOS 日本語
'ヒラギノ角ゴ ProN W3', // macOS 日本語(代替)
'Hiragino Kaku Gothic ProN',
'Hiragino Kaku Gothic Pro',
'-apple-system', // macOS/iOS システムフォント
'BlinkMacSystemFont', // Chrome on macOS
'Segoe UI', // Windows
'Roboto', // Android/Chrome OS
'Yu Gothic', // Windows 日本語
'Meiryo', // Windows 日本語(レガシー)
'sans-serif',
].join(',')
注: 西洋専用アプリの場合は、
'"Inter", "Helvetica Neue", sans-serif'に置き換えることを検討してください。
タイポグラフィのカスタマイズ
import { createTheme } from '@mui/material';
import { ThemeProvider, defaultTheme } from '@nodeblocks/frontend-theme';
const customTheme = createTheme(defaultTheme, {
typography: {
fontFamily: '"Inter", "Helvetica Neue", sans-serif',
h1: {
fontSize: '3rem',
fontWeight: 800,
},
button: {
fontWeight: 700,
letterSpacing: '0.05em',
},
},
});
function App() {
return (
<ThemeProvider theme={customTheme}>
{/* カスタムタイポグラフィのアプリ */}
</ThemeProvider>
);
}
📐 スペーシングとボーダーラディウス
テーマは一貫したスペーシング、ボーダーラディウス、レスポンシブブレークポイントを提供します。
スペーシングシステム
テーマは8pxベースのスペーシング単位を使用しています:
import { spacing } from '@nodeblocks/frontend-theme';
// spacing = 8(ピクセル単位のベースユニット)
// theme.spacing()での使用
theme.spacing(1) // 8px
theme.spacing(2) // 16px
theme.spacing(3) // 24px
theme.spacing(4) // 32px
ボーダーラディウス
デフォルトテーマは4pxのベースボーダーラディウスを使用しています:
// デフォルトテーマでは:
// shape.borderRadius = 4(ピクセル単位のベースユニット)
// コンポーネントは通常、倍数を使用:
// ボタン、入力: borderRadius * 2 = 8px
// カード: borderRadius * 3 = 12px
ブレークポイント
テーマはカスタムレスポンシブブレークポイントを使用しています:
breakpoints: {
values: {
xs: 0, // 超小型デバイス
sm: 600, // 小型デバイス
md: 900, // 中型デバイス
lg: 1024, // 大型デバイス(カスタム:MUIデフォルトは1200)
xl: 1536, // 超大型デバイス
},
}
注:
lgブレークポイントはMUIのデフォルト1200pxではなく1024pxに設定されています。
スペーシングとシェイプのカスタマイズ
import { createTheme } from '@mui/material';
import { ThemeProvider, defaultTheme } from '@nodeblocks/frontend-theme';
const customTheme = createTheme(defaultTheme, {
spacing: 4, // ベースユニットを4pxに変更(theme.spacing(2) = 8px)
shape: {
borderRadius: 8, // より丸いコーナー(デフォルトは4)
},
});
function App() {
return (
<ThemeProvider theme={customTheme}>
{/* カスタムスペーシングのアプリ */}
</ThemeProvider>
);
}
🧩 コンポーネントオーバーライド
MUIコンポーネントスタイルをオーバーライドして、ブランドのデザインシステムに合わせます。
コンポーネントのカスタマイズ
import { createTheme } from '@mui/material';
import { ThemeProvider, defaultTheme } from '@nodeblocks/frontend-theme';
const customTheme = createTheme(defaultTheme, {
components: {
MuiButton: {
styleOverrides: {
root: {
borderRadius: 20, // ピル型ボタン
textTransform: 'none',
},
},
},
},
});
function App() {
return (
<ThemeProvider theme={customTheme}>
{/* カスタムコンポーネントのアプリ */}
</ThemeProvider>
);
}
🔧 高度な使用法
useThemeフックの使用
コンポーネント内でテーマ値にアクセス:
import { useTheme } from '@nodeblocks/frontend-theme';
function MyComponent() {
const theme = useTheme();
return (
<div style={{
backgroundColor: theme.palette.background.paper,
padding: theme.spacing(2),
borderRadius: theme.shape.borderRadius * 2,
color: theme.palette.text.primary,
}}>
テーマ適用コンテンツ
</div>
);
}
CSS変数の使用
テーマはデフォルトでCSS変数を有効にしています。カスタムCSSで使用:
.my-custom-element {
color: var(--mui-palette-primary-main);
background: var(--mui-palette-background-paper);
padding: calc(var(--mui-spacing) * 2); /* 16px */
}
デフォルトテーマの直接使用
検査や拡張のために事前設定されたテーマオブジェクトにアクセスできます:
import { createTheme } from '@mui/material';
import { defaultTheme } from '@nodeblocks/frontend-theme';
// テーマ値を検査
console.log(defaultTheme.palette.primary.main); // #006ead
console.log(defaultTheme.spacing(2)); // 16
console.log(defaultTheme.shape.borderRadius); // 4
// カスタムテーマのベースとして使用
const extendedTheme = createTheme(defaultTheme, {
palette: {
primary: {
main: '#your-color',
},
},
});
🌙 ダークモード
デフォルトテーマはライトモードのみです。ダークモードサポートを追加するには:
import { createTheme } from '@mui/material';
import { ThemeProvider, defaultTheme } from '@nodeblocks/frontend-theme';
const darkTheme = createTheme(defaultTheme, {
palette: {
mode: 'dark',
background: { default: '#121212', paper: '#1e1e1e' },
text: { primary: '#ffffff', secondary: '#b0b0b0' },
},
});
function App() {
return (
<ThemeProvider theme={darkTheme}>
{/* ダークモードのアプリ */}
</ThemeProvider>
);
}
❓ トラブルシューティング
| 問題 | 解決策 |
|---|---|
| テーマが適用されない | ThemeProviderがルートレベルでアプリ全体をラップしていることを確認 |
| スタイルがオーバーライドされる | ThemeProviderでinjectMuiStylesFirst={true}(デフォルト)を設定 |
| カスタムパレットでTypeScriptエラー | MUIテーマ型を拡張(MUIドキュメント参照) |
| コンポーネントがスタイルなしに見える | @mui/materialピア依存関係がインストールされているか確認 |
🔗 関連リソース
Nodeblocksテーマで美しく一貫したUIを構築 ✨