List Users Block
The ListUsers Component is a fully customizable and accessible users table interface built with React and TypeScript. It provides a complete tabular user listing experience with modern design patterns, sortable columns, tabs, status management, pagination support, loading states, and flexible customization options for advanced user management applications.
🚀 Installation
npm install @nodeblocks/frontend-list-users-block
📖 Usage
import {ListUsers} from '@nodeblocks/frontend-list-users-block';
- Basic Usage
- Advanced Usage
Live Editor
function BasicListUsers() { const [currentTab, setCurrentTab] = useState('active'); const [isLoading, setIsLoading] = useState(false); const userData = [ { id: '1', name: 'John Smith', createdAt: '2024-01-15T10:30:00Z', status: 'active' }, { id: '2', name: 'Sarah Johnson', createdAt: '2024-01-14T09:15:00Z', status: 'inactive' }, { id: '3', name: 'Michael Brown', createdAt: '2024-01-12T14:45:00Z', status: 'active' } ]; const tabs = [ { label: 'Active Users' }, { label: 'Inactive Users' }, { label: 'All Users' } ]; const labels = { emptyStateMessage: 'No users found', headerRow: { name: 'Name', createdAt: 'Created At', status: 'Status' }, cellData: { statusInUse: 'Active', statusNotInUse: 'Inactive' } }; const handleNavigate = (path) => { console.log('Navigate to:', path); }; const getRowHref = (row) => `/users/${row.id}`; return ( <ListUsers listUsersTitle="User Management" labels={labels} isLoading={isLoading} onNavigate={handleNavigate} data={userData} rowHref={getRowHref} tabs={tabs} currentTab={currentTab} onTabChange={setCurrentTab}> <ListUsers.Header> <ListUsers.Title /> </ListUsers.Header> <ListUsers.Content> {isLoading ? ( <ListUsers.Loader /> ) : ( <> <ListUsers.Tabs /> <ListUsers.Table /> </> )} </ListUsers.Content> </ListUsers> ); }
Result
Loading...
Live Editor
function AdvancedListUsers() { const [currentTab, setCurrentTab] = useState('active'); const [isLoading, setIsLoading] = useState(false); const userData = [ { id: '1', name: '田中 太郎', createdAt: '2024-01-15T10:30:00Z', status: 'active', }, { id: '2', name: '佐藤 花子', createdAt: '2024-01-14T09:15:00Z', status: 'inactive', }, { id: '3', name: '山田 次郎', createdAt: '2024-01-12T14:45:00Z', status: 'active', }, { id: '4', name: '鈴木 美咲', createdAt: '2024-01-10T16:20:00Z', status: 'active', }, ]; const tabs = [{label: 'アクティブユーザー'}, {label: '非アクティブユーザー'}, {label: '全ユーザー'}]; const labels = { emptyStateMessage: 'ユーザーが見つかりません', headerRow: { name: 'ユーザー名', createdAt: '作成日時', status: 'ステータス', }, cellData: { statusInUse: 'アクティブ', statusNotInUse: '非アクティブ', }, }; const handleNavigate = path => { console.log('Navigate to:', path); }; const getRowHref = row => `/users/${row.id}`; return ( <ListUsers style={{ background: 'linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%)', borderRadius: '16px', padding: '24px', boxShadow: '0 10px 25px rgba(0, 0, 0, 0.1)', }} listUsersTitle="企業ユーザー管理ダッシュボード" labels={labels} isLoading={isLoading} onNavigate={handleNavigate} data={userData} rowHref={getRowHref} tabs={tabs} currentTab={currentTab} onTabChange={setCurrentTab} > {({defaultBlocks, defaultBlockOrder}) => { return { blocks: { ...defaultBlocks, header: { ...defaultBlocks.header, props: { ...defaultBlocks.header.props, style: { background: 'white', borderRadius: '12px', padding: '24px', marginBottom: '24px', boxShadow: '0 4px 8px rgba(0, 0, 0, 0.1)', }, }, }, content: { ...defaultBlocks.content, props: { ...defaultBlocks.content.props, style: { background: 'white', borderRadius: '12px', padding: '20px', boxShadow: '0 4px 12px rgba(0, 0, 0, 0.05)', border: '1px solid #e2e8f0', }, }, }, tabs: { ...defaultBlocks.tabs, props: { ...defaultBlocks.tabs.props, style: { marginBottom: '20px', borderBottom: '2px solid #e2e8f0', paddingBottom: '12px', }, tabs: tabs.map((tab, index) => ({ ...tab, style: { padding: '12px 24px', borderRadius: '8px', fontWeight: '500', transition: 'all 0.2s ease', background: index === 0 ? 'linear-gradient(135deg, #667eea, #764ba2)' : 'transparent', color: index === 0 ? 'white' : '#64748b', boxShadow: index === 0 ? '0 4px 12px rgba(102, 126, 234, 0.3)' : 'none', }, })), }, }, table: { ...defaultBlocks.table, props: { ...defaultBlocks.table.props, style: { borderRadius: '8px', overflow: 'hidden', border: '1px solid #e2e8f0', }, data: userData.map(user => ({ ...user, style: { padding: '16px', borderBottom: '1px solid #f1f5f9', transition: 'all 0.2s ease', '&:hover': { backgroundColor: '#f8fafc', transform: 'translateY(-1px)', boxShadow: '0 4px 12px rgba(0, 0, 0, 0.1)', }, }, })), headerStyle: { background: 'linear-gradient(135deg, #f8fafc, #f1f5f9)', fontWeight: 'bold', color: '#374151', padding: '16px', borderBottom: '2px solid #e2e8f0', }, }, }, }, blockOrder: defaultBlockOrder, }; }} </ListUsers> ); }
Result
Loading...
🔧 Props Reference
Main Component Props
Prop | Type | Default | Description |
---|---|---|---|
listUsersTitle | ReactNode | Required | Title for the users table section |
labels | UserLabels | Required | Labels object for table headers, status messages, and empty states |
isLoading | boolean | undefined | Whether the table is currently loading |
onNavigate | (to: string) => void | undefined | Callback function for navigation |
data | ListUsersRowData[] | Required | Array of user data objects |
rowHref | (row: ListUsersRowData) => string | undefined | Function to generate row link URLs |
tabs | Tab[] | undefined | Array of tab configuration objects |
currentTab | string | undefined | Currently active tab identifier |
onTabChange | (tab: string) => void | undefined | Callback function when tab is changed |
pagination | PaginationProps | undefined | Pagination configuration object |
className | string | undefined | Additional CSS class name for styling the container |
children | BlocksOverride | undefined | Custom block components to override default rendering |
Sub-Components
The ListUsers 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.
ListUsers.Header
Prop | Type | Default | Description |
---|---|---|---|
children | ReactNode | undefined | Custom content to override default header rendering |
className | string | undefined | Additional CSS class name for styling |
ListUsers.Title
Prop | Type | Default | Description |
---|---|---|---|
children | ReactNode | From context | Custom content to override default title rendering |
className | string | undefined | Additional CSS class name for styling |
size | enum | "3XL" | Typography size for the title |
color | enum | "low-emphasis" | Color theme for the title |
weight | enum | "bold" | Weight of the title |
ListUsers.Content
Prop | Type | Default | Description |
---|---|---|---|
children | ReactNode | undefined | Custom content to override default content rendering |
className | string | undefined | Additional CSS class name for styling |
isLoading | boolean | From context | Loading state from context |
ListUsers.Loader
Prop | Type | Default | Description |
---|---|---|---|
children | ReactNode | Circular progress indicator | Custom loading indicator content |
className | string | undefined | Additional CSS class name for styling |
direction | enum | "row" | Flex direction for action components |
alignItems | enum | From Spacing defaults | Alignment of items in the container |
gapSize | enum | From Spacing defaults | Gap between items in the container |
ListUsers.Tabs
Prop | Type | Default | Description |
---|---|---|---|
tabs | Tab[] | From context | Array of tab configuration objects |
currentTab | string | From context | Currently active tab identifier |
onTabChange | (tab: string) => void | From context | Tab change callback function |
tabWidth | string | "stretch" | Width behavior for tabs |
className | string | undefined | Additional CSS class name for styling |
ListUsers.Table
Prop | Type | Default | Description |
---|---|---|---|
className | string | undefined | Additional CSS class name for styling |
data | ListUsersRowData[] | From context | Array of table data |
emptyState | {icon: enum; message: string} | From context | Configuration for empty state |
isLoading | boolean | From context | Loading state |
onNavigate | (to: string) => void | From context | Navigation callback function |
pagination | PaginationProps | From context | Pagination configuration |
rowHref | (row: ListUsersRowData) => string | From context | Function to generate row link URLs |
labels | UserLabels | From context | Labels for table headers and status messages |
🔧 TypeScript Support
Full TypeScript support with comprehensive type definitions:
import {ListUsers} from '@nodeblocks/frontend-list-users-block';
interface Tab {
isDisabled?: boolean;
key?: string;
label: string;
subtitle?: string;
}
interface ListUsersRowData {
id: string;
createdAt: string;
name: string;
status: string;
}
interface UserLabels {
emptyStateMessage: string;
headerRow: {
createdAt: string;
name: string;
status: string;
};
cellData: {
statusInUse: string;
statusNotInUse: string;
};
}
interface CustomUserTableProps {
users: ListUsersRowData[];
onNavigateToUser: (path: string) => void;
tableTabs: Array<Tab>;
currentActiveTab: string;
onTabSwitch: (tab: string) => void;
isTableLoading: boolean;
paginationConfig?: {
currentPage: number;
totalPages: number;
onPageChange: (page: number) => void;
};
}
const UserTableComponent = ({
users,
onNavigateToUser,
tableTabs,
currentActiveTab,
onTabSwitch,
isTableLoading,
paginationConfig,
}: CustomUserTableProps) => {
const tableLabels: UserLabels = {
emptyStateMessage: 'No users found in the system',
headerRow: {
createdAt: 'Date Created',
name: 'User Name',
status: 'Account Status',
},
cellData: {
statusInUse: 'Active',
statusNotInUse: 'Inactive',
},
};
return (
<ListUsers
listUsersTitle="User Management Dashboard"
labels={tableLabels}
isLoading={isTableLoading}
onNavigate={onNavigateToUser}
data={users}
rowHref={row => `/users/${row.id}`}
tabs={tableTabs}
currentTab={currentActiveTab}
onTabChange={onTabSwitch}
pagination={paginationConfig}>
<ListUsers.Header>
<ListUsers.Title />
</ListUsers.Header>
<ListUsers.Content>
{isTableLoading ? (
<ListUsers.Loader />
) : (
<>
<ListUsers.Tabs />
<ListUsers.Table />
</>
)}
</ListUsers.Content>
</ListUsers>
);
};
Built with ❤️ using React, TypeScript, and modern web standards.