設定ブロック
Settingsコンポーネントは、ReactとTypeScriptで構築された完全にカスタマイズ可能でアクセシブルな設定インターフェースです。モダンなデザインパターン、柔軟なカスタマイズオプション、設定項目を整理するためのクリーンな階層構造を備えた完全な設定メニューを提供します。
🚀 インストール
npm install @nodeblocks/frontend-settings-block@0.1.2
📖 使用法
import {Settings} from '@nodeblocks/frontend-settings-block';
- 基本的な使用法
- 高度な使用法
function BasicSettings() {
const settingsItems = [
{
icon: 'person' as const,
title: 'プロファイル設定',
onClick: () => console.log('プロファイルがクリックされました'),
},
{
icon: 'lock' as const,
title: 'セキュリティ',
onClick: () => console.log('セキュリティがクリックされました'),
},
{
icon: 'notifications' as const,
title: '通知',
onClick: () => console.log('通知がクリックされました'),
},
];
return (
<Settings settingsTitle="アカウント設定" items={settingsItems}>
<Settings.Title>私の設定</Settings.Title>
<Settings.SettingsRows />
</Settings>
);
}
function AdvancedSettings() {
const settingsItems = [
{
icon: 'person' as const,
title: 'プロファイル設定',
onClick: () => console.log('プロファイルがクリックされました'),
},
{
icon: 'lock' as const,
title: 'セキュリティ',
onClick: () => console.log('セキュリティがクリックされました'),
},
{
icon: 'notifications' as const,
title: '通知',
onClick: () => console.log('通知がクリックされました'),
},
];
return (
<Settings settingsTitle="アカウント設定" items={settingsItems}>
{({ defaultBlocks, defaultBlockOrder }) => ({
blocks: {
...defaultBlocks,
// 📋 プロパティオーバーライド付きカスタムタイトル
title: {
...defaultBlocks.title,
props: {
...defaultBlocks.title.props,
className: "custom-settings-title",
style: {
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
WebkitBackgroundClip: 'text',
WebkitTextFillColor: 'transparent',
fontSize: '2rem',
fontWeight: 'bold',
textAlign: 'center',
marginBottom: '30px',
padding: '20px'
},
children: "⚙️ 高度な設定ダッシュボード"
},
},
// 🎛️ 完全なコンポーネントオーバーライド付きリッチ設定行
settingsRows: (
<div style={{
display: 'grid',
gap: '20px',
maxWidth: '600px',
margin: '0 auto'
}}>
{/* アカウントセクション */}
<div style={{
backgroundColor: '#f8f9fa',
borderRadius: '16px',
padding: '20px',
border: '1px solid #e9ecef'
}}>
<h3 style={{
color: '#495057',
fontSize: '1.1rem',
fontWeight: '600',
marginBottom: '15px',
display: 'flex',
alignItems: 'center',
gap: '8px'
}}>
👤 アカウント管理
</h3>
<div style={{ display: 'grid', gap: '12px' }}>
{[
{ icon: '📝', title: 'プロファイル編集', description: '情報を更新', color: '#007bff' },
{ icon: '🔐', title: 'パスワード変更', description: 'アカウントを保護', color: '#28a745' },
{ icon: '📱', title: '二要素認証', description: '追加セキュリティ', color: '#17a2b8' }
].map((item, index) => (
<button
key={index}
style={{
backgroundColor: 'white',
border: `2px solid ${item.color}20`,
borderRadius: '12px',
padding: '16px',
display: 'flex',
alignItems: 'center',
gap: '15px',
cursor: 'pointer',
transition: 'all 0.3s ease',
textAlign: 'left'
}}
onMouseEnter={(e) => {
e.currentTarget.style.backgroundColor = item.color;
e.currentTarget.style.borderColor = item.color;
e.currentTarget.style.color = 'white';
e.currentTarget.style.transform = 'translateX(10px)';
}}
onMouseLeave={(e) => {
e.currentTarget.style.backgroundColor = 'white';
e.currentTarget.style.borderColor = `${item.color}20`;
e.currentTarget.style.color = 'black';
e.currentTarget.style.transform = 'translateX(0)';
}}
>
<div style={{ fontSize: '1.5rem' }}>{item.icon}</div>
<div style={{ flex: 1 }}>
<div style={{ fontWeight: '600', marginBottom: '4px' }}>{item.title}</div>
<div style={{ fontSize: '0.85rem', opacity: 0.8 }}>{item.description}</div>
</div>
<div style={{ fontSize: '1.2rem', opacity: 0.6 }}>→</div>
</button>
))}
</div>
</div>
{/* 設定セクション */}
<div style={{
backgroundColor: '#fff3cd',
borderRadius: '16px',
padding: '20px',
border: '1px solid #ffeaa7'
}}>
<h3 style={{
color: '#856404',
fontSize: '1.1rem',
fontWeight: '600',
marginBottom: '15px',
display: 'flex',
alignItems: 'center',
gap: '8px'
}}>
🎨 設定
</h3>
<div style={{ display: 'grid', gap: '12px' }}>
{[
{ icon: '🔔', title: '通知', description: 'アラート設定を管理', color: '#ffc107' },
{ icon: '🌙', title: 'ダークモード', description: 'テーマ設定を切り替え', color: '#6c757d' },
{ icon: '🌐', title: '言語', description: '言語を選択', color: '#fd7e14' }
].map((item, index) => (
<button
key={index}
style={{
backgroundColor: 'white',
border: `2px solid ${item.color}20`,
borderRadius: '12px',
padding: '16px',
display: 'flex',
alignItems: 'center',
gap: '15px',
cursor: 'pointer',
transition: 'all 0.3s ease',
textAlign: 'left'
}}
onMouseEnter={(e) => {
e.currentTarget.style.backgroundColor = item.color;
e.currentTarget.style.borderColor = item.color;
e.currentTarget.style.color = 'white';
e.currentTarget.style.transform = 'scale(1.02)';
}}
onMouseLeave={(e) => {
e.currentTarget.style.backgroundColor = 'white';
e.currentTarget.style.borderColor = `${item.color}20`;
e.currentTarget.style.color = 'black';
e.currentTarget.style.transform = 'scale(1)';
}}
>
<div style={{ fontSize: '1.5rem' }}>{item.icon}</div>
<div style={{ flex: 1 }}>
<div style={{ fontWeight: '600', marginBottom: '4px' }}>{item.title}</div>
<div style={{ fontSize: '0.85rem', opacity: 0.8 }}>{item.description}</div>
</div>
<div style={{ fontSize: '1.2rem', opacity: 0.6 }}>⚙️</div>
</button>
))}
</div>
</div>
{/* クイックアクション */}
<div style={{
backgroundColor: '#d1ecf1',
borderRadius: '16px',
padding: '20px',
border: '1px solid #bee5eb'
}}>
<h3 style={{
color: '#0c5460',
fontSize: '1.1rem',
fontWeight: '600',
marginBottom: '15px',
display: 'flex',
alignItems: 'center',
gap: '8px'
}}>
⚡ クイックアクション
</h3>
<div style={{ display: 'flex', gap: '12px', flexWrap: 'wrap' }}>
{[
{ icon: '📊', title: '分析', color: '#17a2b8' },
{ icon: '📁', title: 'データエクスポート', color: '#6c757d' },
{ icon: '🗑️', title: 'アカウント削除', color: '#dc3545' }
].map((item, index) => (
<button
key={index}
style={{
backgroundColor: 'white',
border: `2px solid ${item.color}`,
borderRadius: '25px',
padding: '12px 20px',
display: 'flex',
alignItems: 'center',
gap: '8px',
cursor: 'pointer',
transition: 'all 0.3s ease',
fontSize: '0.9rem',
fontWeight: '500'
}}
onMouseEnter={(e) => {
e.currentTarget.style.backgroundColor = item.color;
e.currentTarget.style.color = 'white';
e.currentTarget.style.transform = 'translateY(-2px)';
e.currentTarget.style.boxShadow = `0 4px 15px ${item.color}40`;
}}
onMouseLeave={(e) => {
e.currentTarget.style.backgroundColor = 'white';
e.currentTarget.style.color = 'black';
e.currentTarget.style.transform = 'translateY(0)';
e.currentTarget.style.boxShadow = 'none';
}}
>
<span style={{ fontSize: '1.1rem' }}>{item.icon}</span>
{item.title}
</button>
))}
</div>
</div>
</div>
),
},
blockOrder: defaultBlockOrder,
})}
</Settings>
);
}
🔧 プロパティリファレンス
メインコンポーネントプロパティ
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
settingsTitle | string | 必須 | コンテキストとデフォルトタイトルレンダリングで使用される設定セクションのタイトル |
items | SettingsItem[] | 必須 | 表示する設定項目の配列 |
className | string | undefined | 設定コンテナのスタイリング用の追加CSSクラス名 |
children | BlocksOverride | undefined | デフォルトレンダリングをオーバーライドするカスタムブロックコンポーネント |
注意: このコンポーネントはHTML div要素のすべてのプロパティを継承します。
サブコンポーネント
Settingsコンポーネントは複数のサブコンポーネントを提供します。すべてのサブコンポーネントは、メインコンポーネントのコンテキストからデフォルト値を受け取り、プロパティを通じてこれらの値をオーバーライドできます。
Settings.Title
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | コンテキストのsettingsTitle | タイトルコンテンツ - 提供されない場合はsettingsTitleにフォールバック |
className | string | undefined | タイトルのスタイリング用の追加CSSクラス名 |
注意: このコンポーネントは標準HTML h4要素のすべてのプロパティを継承します。
Settings.SettingsRow
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
icon | IconType | 必須 | 設定行の左側に表示するアイコン |
onClick | () => void | 必須 | 行のクリックインタラクションを処理する関数 |
children | ReactNode | undefined | 設定行テキストとして表示するコンテンツ |
注意: このコンポーネントは標準HTML div要素のすべてのプロパティを継承します。
Settings.SettingsRows
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
items | SettingsItem[] | コンテキストのアイテム | レンダリングする設定項目の配列 - 提供されない場合はコンテキストアイテムにフォールバック |
children | ReactNode | 自動生成された行 | デフォルト設定行レンダリングをオーバーライドするカスタムコンテンツ |
className | string | undefined | 行コンテナのスタイリング用の追加CSSクラス名 |
注意: このコンポーネントは標準HTML div要素のすべてのプロパティを継承します。
🔧 TypeScriptサポート
包括的な型定義による完全なTypeScriptサポート:
import {Settings} from '@nodeblocks/frontend-settings-block';
// 設定項目構造
interface SettingsItem {
icon: ComponentProps<typeof Settings.SettingsRow>['icon'];
title: string;
onClick: () => void;
}
// 追加機能付きカスタム設定
interface CustomSettingsProps {
settingsTitle: string;
items: SettingsItem[];
onSettingClick?: (item: SettingsItem) => void;
}
const MySettingsPanel = () => {
const handleProfileSettings = () => {
console.log('プロファイル設定を開いています');
// プロファイル設定に移動
};
const handleSecuritySettings = () => {
console.log('セキュリティ設定を開いています');
// セキュリティ設定に移動
};
const settingsItems: SettingsItem[] = [
{
icon: 'person',
title: 'プロファイル情報',
onClick: handleProfileSettings
},
{
icon: 'lock',
title: 'プライバシーとセキュリティ',
onClick: handleSecuritySettings
},
{
icon: 'notifications',
title: '通知設定',
onClick: () => console.log('通知')
}
];
return (
<Settings
settingsTitle="アカウント設定"
items={settingsItems}
className="custom-settings-container">
<Settings.Title className="custom-title">
アカウントを管理
</Settings.Title>
<Settings.SettingsRows className="custom-rows" />
</Settings>
);
};
// 個別制御付きカスタム設定行
const CustomSettingsExample = () => {
return (
<Settings
settingsTitle="高度な設定"
items={[]}>
<Settings.Title>カスタム設定</Settings.Title>
<div className="custom-settings-section">
<Settings.SettingsRow
icon="person"
onClick={() => console.log('カスタムプロファイルアクション')}>
プロファイル管理
</Settings.SettingsRow>
<Settings.SettingsRow
icon="notifications"
onClick={() => console.log('カスタム設定アクション')}>
アプリケーション設定
</Settings.SettingsRow>
</div>
</Settings>
);
};
React、TypeScript、モダンWebスタンダードを使用して❤️で構築されました。