Skip to main content

List Users Block

The ListUsers Component is a fully customizable and accessible users table interface built with React, TypeScript, and MUI. 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@0.2.0

πŸ“– Usage​

import {ListUsers} from '@nodeblocks/frontend-list-users-block';
Live Editor
function SimpleListUsers() {
  const users = [
    {
      id: '1',
      name: 'John Doe',
      status: 'in_use',
      createdAt: '2023-01-15',
    },
    {
      id: '2',
      name: 'Jane Smith',
      status: 'in_use',
      createdAt: '2023-02-20',
    },
    {
      id: '3',
      name: 'Bob Johnson',
      status: 'not_in_use',
      createdAt: '2023-03-10',
    },
  ];

  const pagination = {
    currentPage: 1,
    totalPages: 1,
    onPageChange: newPage => console.log('Page:', newPage),
  };

  const labels = {
    emptyStateMessage: 'No users found',
    headerRow: {
      createdAt: 'Created',
      name: 'Name',
      status: 'Status',
    },
    cellData: {
      statusInUse: 'Active',
      statusNotInUse: 'Inactive',
    },
  };

  return (
    <ListUsers
      listUsersTitle="Team Members"
      data={users}
      isLoading={false}
      pagination={pagination}
      onNavigate={href => console.log('Navigate:', href)}
      rowHref={row => `/users/${row.id}`}
      labels={labels}
    >
      <ListUsers.Header />
      <ListUsers.Table />
    </ListUsers>
  );
}
Result
Loading...

πŸ”§ Props Reference​

Main Component Props​

PropTypeDefaultDescription
listUsersTitleReactNodeRequiredTitle for the users table section
labelsLabelsConfigRequiredLabels object for table headers, status messages, and empty states
dataUserData[]RequiredArray of user data objects
isLoadingbooleanundefinedWhether the table is currently loading
onNavigate(to: string) => voidundefinedCallback function for navigation
rowHref(row: UserData) => stringundefinedFunction to generate row link URLs
tabsTabConfig[]undefinedArray of tab configuration objects
currentTabstringundefinedCurrently active tab label
onTabChange(tab: string) => voidundefinedCallback function when tab is changed
paginationPaginationConfigundefinedPagination configuration object
classNamestringundefinedAdditional CSS class name for styling the container
childrenBlocksOverrideundefinedCustom block components to override default rendering
sxSxPropsundefinedMUI sx prop for custom styling
spacingnumber3Spacing between child elements

Note: This component extends MUI StackProps, inheriting all Stack component props.

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.Title​

PropTypeDefaultDescription
listUsersTitleReactNodeFrom contextTitle content to display
childrenReactNodeFrom contextCustom content to override default title rendering
classNamestringundefinedAdditional CSS class name for styling
variantstring"h4"MUI Typography variant
componentstring"h1"HTML element to render

Note: This component extends MUI TypographyProps.

ListUsers.Header​

PropTypeDefaultDescription
childrenReactNodeundefinedCustom content to override default header rendering
classNamestringundefinedAdditional CSS class name for styling

Note: This component extends MUI BoxProps.

ListUsers.Content​

PropTypeDefaultDescription
isLoadingbooleanFrom contextLoading state from context
childrenReactNodeundefinedCustom content to override default content rendering
classNamestringundefinedAdditional CSS class name for styling

Note: This component extends MUI BoxProps.

ListUsers.Loader​

PropTypeDefaultDescription
childrenReactNode<CircularProgress />Custom loading indicator content
classNamestringundefinedAdditional CSS class name for styling
sxSxPropsundefinedMUI sx prop for custom styling

Note: This component extends MUI StackProps with default alignItems: 'center'.

ListUsers.Tabs​

PropTypeDefaultDescription
tabsTabConfig[]From contextArray of tab configuration objects
currentTabstringFrom contextCurrently active tab label
onTabChange(tab: string) => voidFrom contextTab change callback function
classNamestringundefinedAdditional CSS class name for styling

Note: This component extends MUI TabsProps (excluding value, onChange, variant). Uses variant="fullWidth" internally.

ListUsers.Table​

PropTypeDefaultDescription
dataUserData[]From contextArray of table data
labelsLabelsConfigFrom contextLabels for table headers and status messages
rowHref(row: UserData) => stringFrom contextFunction to generate row link URLs
onNavigate(to: string) => voidFrom contextNavigation callback function
paginationPaginationConfigFrom contextPagination configuration
classNamestringundefinedAdditional CSS class name for styling
spacingnumber3Spacing between elements

Note: This component extends MUI StackProps.


🎨 Configuration examples​

Custom Title Styling​

<ListUsers.Title
variant="h3"
sx={{
color: 'primary.main',
fontWeight: 'bold',
textTransform: 'uppercase',
}}
>
Custom User Title
</ListUsers.Title>

Pagination Setup​

<ListUsers
listUsersTitle="Paginated Users"
labels={labels}
data={userData}
pagination={{
currentPage: 1,
totalPages: 10,
onPageChange: (page) => console.log('Page:', page),
}}
/>

Custom Empty State Message​

const labels = {
emptyStateMessage: 'No users match your search criteria',
headerRow: {
name: 'Full Name',
createdAt: 'Registration Date',
status: 'Account Status',
},
cellData: {
statusInUse: 'Active',
statusNotInUse: 'Inactive',
},
};

Block Override Pattern​

<ListUsers listUsersTitle="Users" labels={labels} data={userData}>
{({defaultBlocks, defaultBlockOrder}) => ({
blocks: {
...defaultBlocks,
header: (
<ListUsers.Header
sx={{
p: 3,
borderBottom: '1px solid #e2e8f0',
'& .nbb-list-users-title': {
fontSize: 24,
fontWeight: 700,
color: '#1e293b',
},
}}
/>
),
tabs: (
<ListUsers.Tabs
sx={{
px: 3,
borderBottom: '1px solid #e2e8f0',
'& .MuiTab-root': {
textTransform: 'none',
fontWeight: 500,
color: '#64748b',
'&.Mui-selected': {
color: '#6366f1',
fontWeight: 600,
},
},
}}
/>
),
table: (
<ListUsers.Table
sx={{
'& .MuiTableHead-root': {
bgcolor: '#f8fafc',
},
}}
/>
),
},
blockOrder: defaultBlockOrder,
})}
</ListUsers>

Custom Styling​

<ListUsers
listUsersTitle="Users"
data={users}
isLoading={false}
pagination={pagination}
onNavigate={console.log}
rowHref={row => `/users/${row.id}`}
labels={labels}
sx={{
bgcolor: 'grey.900',
color: 'grey.100',
borderRadius: 2,
}}
>
<ListUsers.Header
sx={{
p: 2,
borderBottom: '1px solid',
borderColor: 'grey.700',
'& .MuiTypography-root': {
color: 'grey.100',
},
}}
/>
<ListUsers.Table
sx={{
'& .MuiTableCell-root': {
color: 'grey.300',
borderColor: 'grey.700',
},
'& .MuiTableHead-root .MuiTableCell-root': {
color: 'grey.400',
bgcolor: 'grey.800',
},
}}
/>
</ListUsers>

Tabs with Subtitles​

const tabs = [
{ label: 'Active', subtitle: '(24)' },
{ label: 'Inactive', subtitle: '(8)' },
{ label: 'Pending', subtitle: '(3)', isDisabled: true },
];

<ListUsers tabs={tabs} currentTab="Active" onTabChange={setTab} /* ... */ />

πŸ”§ TypeScript Support​

Full TypeScript support with comprehensive type definitions:

import {ListUsers} from '@nodeblocks/frontend-list-users-block';
import {useState} from 'react';

interface UserData {
id: string;
name: string;
status: string;
createdAt: string;
}

interface PaginationConfig {
currentPage: number;
totalPages: number;
onPageChange: (page: number) => void;
}

interface TabConfig {
key?: string;
label: string;
isDisabled?: boolean;
subtitle?: string;
}

interface LabelsConfig {
emptyStateMessage: string;
headerRow: {
createdAt: string;
name: string;
status: string;
};
cellData: {
statusInUse: string;
statusNotInUse: string;
};
}

function TypedListUsers() {
const userData: UserData[] = [
{
id: 'u1',
name: 'John Smith',
status: 'in_use',
createdAt: '2023-01-15',
},
{
id: 'u2',
name: 'Jane Doe',
status: 'in_use',
createdAt: '2023-02-20',
},
{
id: 'u3',
name: 'Mike Wilson',
status: 'not_in_use',
createdAt: '2023-03-10',
},
];

const paginationConfig: PaginationConfig = {
currentPage: 1,
totalPages: 1,
onPageChange: newPage => console.log('Page changed:', newPage),
};

const tabConfig: TabConfig[] = [
{key: 'all', label: 'All Users'},
{key: 'active', label: 'Active'},
{key: 'inactive', label: 'Inactive'},
];

const labelsConfig: LabelsConfig = {
emptyStateMessage: 'No team members found',
headerRow: {
createdAt: 'Joined',
name: 'Full Name',
status: 'Status',
},
cellData: {
statusInUse: 'Active',
statusNotInUse: 'Inactive',
},
};

const handleNavigate = (href: string): void => {
console.log('Navigating to:', href);
};

return (
<ListUsers
listUsersTitle="Team Management"
data={userData}
isLoading={false}
pagination={paginationConfig}
onNavigate={handleNavigate}
rowHref={(row: UserData) => `/users/${row.id}`}
tabs={tabConfig}
currentTab="All Users"
onTabChange={tab => console.log('Tab changed:', tab)}
labels={labelsConfig}
spacing={2}
sx={{
maxWidth: 1000,
mx: 'auto',
border: '1px solid #e5e7eb',
borderRadius: 2,
}}
>
<ListUsers.Header />
<ListUsers.Tabs />
<ListUsers.Table />
</ListUsers>
);
}

πŸ“ Notes​

  • The component uses MUI's Stack component as its base, providing flexible layout options
  • Default spacing is 3 (24px) and default padding is p: 3 (24px)
  • All sub-components automatically receive context values from the main component
  • Date formatting uses luxon library with format yyyy/M/d for display
  • Full datetime is shown on hover via title attribute
  • The Tabs component uses MUI's variant="fullWidth" internally
  • Empty state displays a person icon with the emptyStateMessage from labels
  • Row hover effects are only applied when rowHref is provided
  • Clicking a row triggers onNavigate with the href returned by rowHref
  • Default blocks are: title, header, content, tabs, table
  • CSS classes follow BEM-style naming: nbb-list-users-container, nbb-list-users-title, etc.
  • The Loader component renders MUI CircularProgress by default

Built with ❀️ using React, TypeScript, and MUI.