Settings Block
The Settings Component is a fully customizable and accessible settings interface built with React and TypeScript. It provides a complete settings menu with modern design patterns, flexible customization options, and a clean hierarchical structure for organizing settings items.
π Installationβ
npm install @nodeblocks/frontend-settings-block@0.2.0
π Usageβ
import {Settings} from '@nodeblocks/frontend-settings-block';
- Basic Usage
- Advanced Usage
function SimpleSettings() { const items = [ { icon: AccountCircleIcon, title: 'Profile Settings', value: 'John Doe', onClick: () => console.log('Profile clicked'), }, { icon: NotificationsIcon, title: 'Notifications', value: 'On', onClick: () => console.log('Notifications clicked'), }, { icon: LockIcon, title: 'Password & Security', onClick: () => console.log('Security clicked'), }, { icon: LanguageIcon, title: 'Language', value: 'English', onClick: () => console.log('Language clicked'), }, { icon: DarkModeIcon, title: 'Theme', value: 'Light', onClick: () => console.log('Theme clicked'), }, ]; return ( <Settings settingsTitle="Settings" items={items}> <Settings.Title /> <Settings.SettingsRows /> </Settings> ); }
function AdvancedSettings() { const [selectedItem, setSelectedItem] = useState(null); const items = [ { icon: AccountCircleIcon, title: 'Profile', value: 'Manage your public profile', onClick: () => setSelectedItem('profile'), }, { icon: SecurityIcon, title: 'Security', value: 'Password, 2FA, and login activity', onClick: () => setSelectedItem('security'), }, { icon: NotificationsIcon, title: 'Notifications', value: 'Email, push, and in-app alerts', onClick: () => setSelectedItem('notifications'), }, { icon: PaymentIcon, title: 'Payment Methods', value: '**** 4242', onClick: () => setSelectedItem('payment'), }, { icon: SubscriptionsIcon, title: 'Subscription', value: 'Pro Plan', onClick: () => setSelectedItem('subscription'), }, { icon: ReceiptIcon, title: 'Invoices', onClick: () => setSelectedItem('invoices'), }, { icon: ApiIcon, title: 'API Keys', value: '3 active keys', onClick: () => setSelectedItem('api'), }, ]; return ( <Settings settingsTitle="Account Settings" 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', }} > Account Settings </h1> <p style={{ fontSize: '14px', color: '#64748b', margin: 0, }} > Manage your account preferences and security </p> {selectedItem && ( <div style={{ marginTop: '12px', padding: '8px 12px', background: '#dbeafe', borderRadius: '8px', fontSize: '13px', color: '#1d4ed8', }} > Selected: {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> ); }
π§ Props Referenceβ
Main Component Propsβ
| Prop | Type | Default | Description |
|---|---|---|---|
settingsTitle | string | Required | Title for the settings section used in context and default title rendering |
items | SettingsItem[] | Required | Array of settings items to be displayed |
spacing | number | ResponsiveValue | 1 | Spacing between child elements |
className | string | undefined | Additional CSS class name for styling the settings container |
sx | SxProps<Theme> | See below | MUI System prop for custom styling |
children | BlocksOverride | undefined | Custom block components to override default rendering |
Default sx:
{
bgcolor: 'grey.50',
p: 2
}
Note: This component inherits all MUI Stack props.
Sub-Componentsβ
The Settings component provides several sub-components. All sub-components receive their default values from the main component's context and can override these values through props.
Settings.Titleβ
Renders the title for the settings section.
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | settingsTitle from context | Title content - falls back to settingsTitle if not provided |
settingsTitle | string | From context | Title text (overrides context) |
variant | string | 'h6' | Typography variant |
component | ElementType | 'h4' | The component used for the root node |
sx | SxProps<Theme> | undefined | MUI System prop for custom styling |
Note: This component inherits all MUI Typography props.
Settings.SettingsRowβ
Renders an individual settings row item as a clickable button.
| Prop | Type | Default | Description |
|---|---|---|---|
icon | SvgIconComponent | Required | MUI icon component to display on the left |
label | string | Required | Primary text for the settings row |
value | string | undefined | Optional secondary text displayed below the label |
children | ReactNode | Default label/value rendering | Custom content to override default text rendering |
onClick | () => void | undefined | Click handler (from ButtonProps) |
variant | 'text' | 'outlined' | 'contained' | 'outlined' | Button variant |
size | 'small' | 'medium' | 'large' | 'large' | Button size |
sx | SxProps<Theme> | See below | MUI System prop for custom styling |
Default 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
}
}
Note: This component inherits all MUI Button props. The icon is rendered with color: 'primary.main' and a ChevronRight icon is automatically appended on the right.
Settings.SettingsRowsβ
Renders the container for all settings rows.
| Prop | Type | Default | Description |
|---|---|---|---|
items | SettingsItem[] | From context | Array of settings items to render - falls back to context items |
children | ReactNode | Auto-generated rows | Custom content to override default settings rows rendering |
sx | SxProps<Theme> | undefined | MUI System prop for custom styling |
Note: This component inherits all MUI Stack props. When children is not provided, it maps items to Settings.SettingsRow components.
π¨ Configuration examplesβ
Custom Title Stylingβ
<Settings.Title
variant="h5"
sx={{ color: 'primary.main', fontWeight: 700 }}
/>
Custom Settings Row Stylingβ
<Settings.SettingsRow
icon={Person}
label="Profile"
value="John Doe"
onClick={() => console.log('Profile clicked')}
sx={{
bgcolor: 'grey.50',
'&:hover': { bgcolor: 'primary.light' }
}}
/>
Custom Settings Rows Containerβ
<Settings.SettingsRows
sx={{
boxShadow: 1,
borderRadius: 2,
}}
/>
Custom Stylingβ
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: 'Display Name',
value: 'John Doe',
onClick: () => console.log('Display name clicked'),
},
{
icon: LanguageIcon,
title: 'Timezone',
value: 'UTC-5',
onClick: () => console.log('Timezone clicked'),
},
{
icon: SecurityIcon,
title: 'Privacy',
value: 'Public',
onClick: () => console.log('Privacy clicked'),
},
];
return (
<Settings
settingsTitle="General Settings"
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>
);
}
Individual Settings Rowsβ
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: 'Account',
onClick: () => console.log('Account'),
},
{
icon: SecurityIcon,
title: 'Security',
value: '2FA Enabled',
onClick: () => console.log('Security'),
},
];
return (
<Settings settingsTitle="Quick Settings" items={items} sx={{p: 3}}>
<Settings.Title />
<Settings.SettingsRow icon={AccountCircleIcon} label="Account" onClick={() => console.log('Account')} />
<Settings.SettingsRow
icon={SecurityIcon}
label="Security"
value="2FA Enabled"
onClick={() => console.log('Security')}
/>
<Settings.SettingsRow
icon={NotificationsIcon}
label="Notifications"
value="On"
onClick={() => console.log('Notifications')}
sx={{
bgcolor: 'primary.light',
color: 'primary.contrastText',
'&:hover': {
bgcolor: 'primary.main',
},
}}
/>
</Settings>
);
}
π§ TypeScript Supportβ
Full TypeScript support with comprehensive type definitions:
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: 'Profile Information',
value: 'Edit your personal details',
onClick: (): void => console.log('Profile clicked'),
},
{
icon: LockIcon,
title: 'Password',
value: 'Last changed 30 days ago',
onClick: (): void => console.log('Password clicked'),
},
{
icon: NotificationsIcon,
title: 'Notifications',
value: 'All enabled',
onClick: (): void => console.log('Notifications clicked'),
},
{
icon: DarkModeIcon,
title: 'Appearance',
value: 'System default',
onClick: (): void => console.log('Appearance clicked'),
},
{
icon: LanguageIcon,
title: 'Language',
value: 'English (US)',
onClick: (): void => console.log('Language clicked'),
},
];
return (
<Settings settingsTitle="User Preferences" items={settingsItems} spacing={2} sx={{maxWidth: 500}}>
<Settings.Title />
<Settings.SettingsRows />
</Settings>
);
}
π Notesβ
- The main component uses MUI
Stackwithspacing={1}and default background/padding styling. Settings.Titleuses MUITypographywithvariant="h6"andcomponent="h4"by default.Settings.SettingsRowuses MUIButtonwithvariant="outlined"andsize="large"by default.- Each row displays an icon (with
color: 'primary.main'), label, optional value, and aChevronRightarrow. - The row styling creates a seamless list with rounded corners on first/last items.
- Hover effects include a primary color outline for visual feedback.
- The
iconprop requires an actual MUISvgIconComponent(e.g.,Person,Lock,Notificationsfrom@mui/icons-material). - Context values (
settingsTitle,items) are shared via React Context and can be overridden at the sub-component level.
Built with β€οΈ using React, TypeScript, and MUI.