設定ブロック
Settingsコンポーネントは、ReactとTypeScriptで構築された完全にカスタマイズ可能でアクセシブルな設定インターフェースです。モダンなデザインパターン、柔軟なカスタマイズオプション、設定項目を整理するためのクリーンな階層構造を備えた完全な設定メニューを提供します。
🚀 インストール
npm install @nodeblocks/frontend-settings-block@0.2.0
📖 使用法
import {Settings} from '@nodeblocks/frontend-settings-block';
- 基本的な使用法
- 高度な使用法
ライブエディター
function SimpleSettings() { const items = [ { icon: AccountCircleIcon, title: 'プロファイル設定', value: '山田太郎', onClick: () => console.log('プロファイルがクリックされました'), }, { icon: NotificationsIcon, title: '通知', value: 'オン', onClick: () => console.log('通知がクリックされました'), }, { icon: LockIcon, title: 'パスワードとセキュリティ', onClick: () => console.log('セキュリティがクリックされました'), }, { icon: LanguageIcon, title: '言語', value: '日本語', onClick: () => console.log('言語がクリックされました'), }, { icon: DarkModeIcon, title: 'テーマ', value: 'ライト', onClick: () => console.log('テーマがクリックされました'), }, ]; return ( <Settings settingsTitle="設定" items={items}> <Settings.Title /> <Settings.SettingsRows /> </Settings> ); }
結果
Loading...
ライブエディター
function AdvancedSettings() { const [selectedItem, setSelectedItem] = useState(null); const items = [ { icon: AccountCircleIcon, title: 'プロファイル', value: '公開プロファイルを管理', onClick: () => setSelectedItem('profile'), }, { icon: SecurityIcon, title: 'セキュリティ', value: 'パスワード、2FA、ログイン履歴', onClick: () => setSelectedItem('security'), }, { icon: NotificationsIcon, title: '通知', value: 'メール、プッシュ、アプリ内アラート', onClick: () => setSelectedItem('notifications'), }, { icon: PaymentIcon, title: '支払い方法', value: '**** 4242', onClick: () => setSelectedItem('payment'), }, { icon: SubscriptionsIcon, title: 'サブスクリプション', value: 'Proプラン', onClick: () => setSelectedItem('subscription'), }, { icon: ReceiptIcon, title: '請求書', onClick: () => setSelectedItem('invoices'), }, { icon: ApiIcon, title: 'APIキー', value: '3つのアクティブキー', onClick: () => setSelectedItem('api'), }, ]; return ( <Settings settingsTitle="アカウント設定" items={items} sx={{ maxWidth: 600, mx: 'auto', p: 3, bgcolor: '#f8fafc', borderRadius: 4, }} > {({defaultBlocks, defaultBlockOrder}) => { const customTitle = ( <div style={{ marginBottom: '24px', paddingBottom: '16px', borderBottom: '1px solid #e2e8f0', }} > <h1 style={{ fontSize: '24px', fontWeight: '700', color: '#1e293b', margin: '0 0 4px 0', }} > アカウント設定 </h1> <p style={{ fontSize: '14px', color: '#64748b', margin: 0, }} > アカウントの設定とセキュリティを管理 </p> {selectedItem && ( <div style={{ marginTop: '12px', padding: '8px 12px', background: '#dbeafe', borderRadius: '8px', fontSize: '13px', color: '#1d4ed8', }} > 選択: {selectedItem} </div> )} </div> ); const customRows = ( <div style={{ display: 'flex', flexDirection: 'column', gap: '8px', }} > {items.map((item, index) => { const IconComponent = item.icon; return ( <button key={index} onClick={item.onClick} style={{ display: 'flex', alignItems: 'center', gap: '16px', padding: '16px 20px', background: selectedItem === item.title.toLowerCase() ? '#eff6ff' : '#ffffff', border: selectedItem === item.title.toLowerCase() ? '1px solid #3b82f6' : '1px solid #e2e8f0', borderRadius: '12px', cursor: 'pointer', textAlign: 'left', width: '100%', transition: 'all 0.2s ease', }} > <div style={{ width: '44px', height: '44px', borderRadius: '12px', background: selectedItem === item.title.toLowerCase() ? 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)' : '#f1f5f9', display: 'flex', alignItems: 'center', justifyContent: 'center', color: selectedItem === item.title.toLowerCase() ? '#ffffff' : '#64748b', }} > <IconComponent /> </div> <div style={{flex: 1}}> <div style={{ fontSize: '15px', fontWeight: '600', color: '#1e293b', marginBottom: '2px', }} > {item.title} </div> {item.value && ( <div style={{ fontSize: '13px', color: '#64748b', }} > {item.value} </div> )} </div> <span style={{color: '#94a3b8', fontSize: '18px'}}>→</span> </button> ); })} </div> ); return { blocks: { ...defaultBlocks, title: customTitle, settingsRows: customRows, }, blockOrder: defaultBlockOrder, }; }} </Settings> ); }
結果
Loading...
🔧 プロパティリファレンス
メインコンポーネントプロパティ
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
settingsTitle | string | 必須 | コンテキストとデフォルトタイトルレンダリングで使用される設定セクションのタイトル |
items | SettingsItem[] | 必須 | 表示する設定項目の配列 |
spacing | number | ResponsiveValue | 1 | 子要素間のスペーシング |
className | string | undefined | 設定コンテナのスタイリング用の追加CSSクラス名 |
sx | SxProps<Theme> | 下記参照 | カスタムスタイリング用のMUIシステムプロパティ |
children | BlocksOverride | undefined | デフォルトレンダリングをオーバーライドするカスタムブロックコンポーネント |
デフォルトsx:
{
bgcolor: 'grey.50',
p: 2
}
注意: このコンポーネントはすべてのMUI Stackプロパティを継承します。
サブコンポーネント
Settingsコンポーネントは複数のサブコンポーネントを提供します。すべてのサブコンポーネントは、メインコンポーネントのコンテキストからデフォルト値を受け取り、プロパティを通じてこれらの値をオーバーライドできます。
Settings.Title
設定セクションのタイトルをレンダリングします。
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | コンテキストのsettingsTitle | タイトルコンテンツ - 提供されない場合はsettingsTitleにフォールバック |
settingsTitle | string | コンテキストから | タイトルテキスト(コンテキストをオーバーライド) |
variant | string | 'h6' | Typographyバリアント |
component | ElementType | 'h4' | ルートノードに使用されるコンポーネント |
sx | SxProps<Theme> | undefined | カスタムスタイリング用のMUIシステムプロパティ |
注意: このコンポーネントはすべてのMUI Typographyプロパティを継承します。
Settings.SettingsRow
個々の設定行アイテムをクリック可能なボタンとしてレンダリングします。
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
icon | SvgIconComponent | 必須 | 左側に表示するMUIアイコンコンポーネント |
label | string | 必須 | 設定行のプライマリテキスト |
value | string | undefined | ラベルの下に表示されるオプションのセカンダリテキスト |
children | ReactNode | デフォルトのラベル/値レンダリング | デフォルトのテキストレンダリングをオーバーライドするカスタムコンテンツ |
onClick | () => void | undefined | クリックハンドラー(ButtonPropsから) |
variant | 'text' | 'outlined' | 'contained' | 'outlined' | ボタンバリアント |
size | 'small' | 'medium' | 'large' | 'large' | ボタンサイズ |
sx | SxProps<Theme> | 下記参照 | カスタムスタイリング用のMUIシステムプロパティ |
デフォルトsx:
{
border: 0,
display: 'flex',
alignItems: 'center',
px: 2,
py: 1.5,
bgcolor: 'background.paper',
borderRadius: 0,
borderTop: '1px solid',
borderColor: theme.palette.divider,
'&:first-of-type': {
borderTopLeftRadius: theme.shape.borderRadius * 2,
borderTopRightRadius: theme.shape.borderRadius * 2,
borderTop: '1px solid transparent'
},
'&:last-of-type': {
borderBottomLeftRadius: theme.shape.borderRadius * 2,
borderBottomRightRadius: theme.shape.borderRadius * 2
},
'&:hover': {
outline: '1px solid',
outlineColor: 'primary.main',
borderColor: 'transparent',
zIndex: 1
}
}
注意: このコンポーネントはすべてのMUI Buttonプロパティを継承します。アイコンはcolor: 'primary.main'でレンダリングされ、右側にChevronRightアイコンが自動的に追加されます。
Settings.SettingsRows
すべての設定行のコンテナをレンダリングします。
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
items | SettingsItem[] | コンテキストから | レンダリングする設定項目の配列 - コンテキストアイテムにフォールバック |
children | ReactNode | 自動生成された行 | デフォルト設定行レンダリングをオーバーライドするカスタムコンテンツ |
sx | SxProps<Theme> | undefined | カスタムスタイリング用のMUIシステムプロパティ |
注意: このコンポーネントはすべてのMUI Stackプロパティを継承します。childrenが提供されない場合、itemsをSettings.SettingsRowコンポーネントにマッピングします。
🎨 設定例
カスタムタイトルスタイリング
<Settings.Title
variant="h5"
sx={{ color: 'primary.main', fontWeight: 700 }}
/>
カスタム設定行スタイリング
<Settings.SettingsRow
icon={Person}
label="プロファイル"
value="山田太郎"
onClick={() => console.log('プロファイルがクリックされました')}
sx={{
bgcolor: 'grey.50',
'&:hover': { bgcolor: 'primary.light' }
}}
/>
カスタム設定行コンテナ
<Settings.SettingsRows
sx={{
boxShadow: 1,
borderRadius: 2,
}}
/>
カスタムスタイリング
import AccountCircleIcon from '@mui/icons-material/AccountCircle';
import LanguageIcon from '@mui/icons-material/Language';
import SecurityIcon from '@mui/icons-material/Security';
function CustomStyledSettings() {
const items = [
{
icon: AccountCircleIcon,
title: '表示名',
value: '山田太郎',
onClick: () => console.log('表示名がクリックされました'),
},
{
icon: LanguageIcon,
title: 'タイムゾーン',
value: 'UTC-5',
onClick: () => console.log('タイムゾーンがクリックされました'),
},
{
icon: SecurityIcon,
title: 'プライバシー',
value: '公開',
onClick: () => console.log('プライバシーがクリックされました'),
},
];
return (
<Settings
settingsTitle="一般設定"
items={items}
sx={{
bgcolor: 'grey.900',
color: 'grey.100',
p: 3,
borderRadius: 2,
}}
>
<Settings.Title
sx={{
color: 'grey.100',
fontWeight: 700,
mb: 2,
}}
/>
<Settings.SettingsRows
sx={{
'& .MuiButton-root': {
bgcolor: 'grey.800',
color: 'grey.100',
borderRadius: 2,
justifyContent: 'flex-start',
p: 2,
mb: 1,
'&:hover': {
bgcolor: 'grey.700',
},
},
'& .MuiTypography-root': {
color: 'grey.100',
},
'& .MuiSvgIcon-root': {
color: 'primary.light',
},
}}
/>
</Settings>
);
}
個別設定行
import AccountCircleIcon from '@mui/icons-material/AccountCircle';
import SecurityIcon from '@mui/icons-material/Security';
import NotificationsIcon from '@mui/icons-material/Notifications';
function SettingsWithIndividualRows() {
const items = [
{
icon: AccountCircleIcon,
title: 'アカウント',
onClick: () => console.log('アカウント'),
},
{
icon: SecurityIcon,
title: 'セキュリティ',
value: '2FA有効',
onClick: () => console.log('セキュリティ'),
},
];
return (
<Settings settingsTitle="クイック設定" items={items} sx={{p: 3}}>
<Settings.Title />
<Settings.SettingsRow icon={AccountCircleIcon} label="アカウント" onClick={() => console.log('アカウント')} />
<Settings.SettingsRow
icon={SecurityIcon}
label="セキュリティ"
value="2FA有効"
onClick={() => console.log('セキュリティ')}
/>
<Settings.SettingsRow
icon={NotificationsIcon}
label="通知"
value="オン"
onClick={() => console.log('通知')}
sx={{
bgcolor: 'primary.light',
color: 'primary.contrastText',
'&:hover': {
bgcolor: 'primary.main',
},
}}
/>
</Settings>
);
}
🔧 TypeScriptサポート
包括的な型定義による完全なTypeScriptサポート:
import {Settings} from '@nodeblocks/frontend-settings-block';
import {SvgIconComponent} from '@mui/icons-material';
import AccountCircleIcon from '@mui/icons-material/AccountCircle';
import LockIcon from '@mui/icons-material/Lock';
import NotificationsIcon from '@mui/icons-material/Notifications';
import DarkModeIcon from '@mui/icons-material/DarkMode';
import LanguageIcon from '@mui/icons-material/Language';
import React from 'react';
interface SettingsItem {
icon: SvgIconComponent;
title: string;
value?: string;
onClick: () => void;
}
function TypedSettings() {
const settingsItems: SettingsItem[] = [
{
icon: AccountCircleIcon,
title: 'プロファイル情報',
value: '個人情報を編集',
onClick: (): void => console.log('プロファイルがクリックされました'),
},
{
icon: LockIcon,
title: 'パスワード',
value: '30日前に変更',
onClick: (): void => console.log('パスワードがクリックされました'),
},
{
icon: NotificationsIcon,
title: '通知',
value: 'すべて有効',
onClick: (): void => console.log('通知がクリックされました'),
},
{
icon: DarkModeIcon,
title: '外観',
value: 'システムデフォルト',
onClick: (): void => console.log('外観がクリックされました'),
},
{
icon: LanguageIcon,
title: '言語',
value: '日本語 (JP)',
onClick: (): void => console.log('言語がクリックされました'),
},
];
return (
<Settings settingsTitle="ユーザー設定" items={settingsItems} spacing={2} sx={{maxWidth: 500}}>
<Settings.Title />
<Settings.SettingsRows />
</Settings>
);
}
📝 注意事項
- メインコンポーネントは
spacing={1}とデフォルトの背景/パディングスタイリングを持つMUIStackを使用します。 Settings.Titleはデフォルトでvariant="h6"とcomponent="h4"を持つMUITypographyを使用します。Settings.SettingsRowはデフォルトでvariant="outlined"とsize="large"を持つMUIButtonを使用します。- 各行にはアイコン(
color: 'primary.main')、ラベル、オプションの値、およびChevronRight矢印が表示されます。 - 行のスタイリングにより、最初/最後のアイテムに角丸を持つシームレスなリストが作成されます。
- ホバー効果には、視覚的なフィードバックのためのプライマリカラーのアウトラインが含まれます。
iconプロパティには、実際のMUISvgIconComponent(@mui/icons-materialからのPerson、Lock、Notificationsなど)が必要です。- コンテキスト値(
settingsTitle、items)はReact Contextを介して共有され、サブコンポーネントレベルでオーバーライドできます。
React、TypeScript、MUIを使用して❤️で構築されました。