ユーザーリストブロック
ListUsersコンポーネントは、ReactとTypeScriptで構築された完全にカスタマイズ可能でアクセシブルなユーザーテーブルインターフェースです。モダンなデザインパターン、ソート可能なカラム、タブ、ステータス管理、ページネーションサポート、ローディング状態、高度なユーザー管理アプリケーション用の柔軟なカスタマイズオプションを備えた完全な表形式ユーザーリスティング体験を提供します。
🚀 インストール
npm install @nodeblocks/frontend-list-users-block@0.1.0
📖 使用方法
import {ListUsers} from '@nodeblocks/frontend-list-users-block';
- 基本的な使用方法
- 高度な使用方法
function BasicListUsers() {
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'
}
];
const tabs = [
{ label: 'アクティブユーザー' },
{ label: '非アクティブユーザー' },
{ label: '全ユーザー' }
];
const labels = {
emptyStateMessage: 'ユーザーが見つかりません',
headerRow: {
name: '名前',
createdAt: '作成日',
status: 'ステータス'
},
cellData: {
statusInUse: 'アクティブ',
statusNotInUse: '非アクティブ'
}
};
const handleNavigate = (path) => {
console.log('ナビゲート先:', path);
};
const getRowHref = (row) => `/users/${row.id}`;
return (
<ListUsers
listUsersTitle="ユーザー管理"
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>
);
}
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('ナビゲート先:', 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>
);
}
🔧 プロパティリファレンス
メインコンポーネントのプロパティ
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
listUsersTitle | ReactNode | 必須 | ユーザーテーブルセクションのタイトル |
labels | UserLabels | 必須 | テーブルヘッダー、ステータスメッセージ、空状態用のラベルオブジェクト |
isLoading | boolean | undefined | テーブルが現在ローディング中かどうか |
onNavigate | (to: string) => void | undefined | ナビゲーション用のコールバック関数 |
data | ListUsersRowData[] | 必須 | ユーザーデータオブジェクトの配列 |
rowHref | (row: ListUsersRowData) => string | undefined | 行リンクURLを生成する関数 |
tabs | Tab[] | undefined | タブ設定オブジェクトの配列 |
currentTab | string | undefined | 現在アクティブなタブ識別子 |
onTabChange | (tab: string) => void | undefined | タブが変更されたときのコールバック関数 |
pagination | PaginationProps | undefined | ページネーション設定オブジェクト |
className | string | undefined | コンテナスタイリング用の追加CSSクラス名 |
children | BlocksOverride | undefined | デフォルトレンダリングをオーバーライドするカスタムブロックコンポーネント |
サブコンポーネント
ListUsersコンポーネントは複数のサブコンポーネントを提供します。すべてのサブコンポーネントは、メインコンポーネントのコンテキストからデフォルト値を受け取り、プロパティを通じてこれらの値をオーバーライドできます。
ListUsers.Header
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | undefined | デフォルトヘッダーレンダリングをオーバーライドするカスタムコンテンツ |
className | string | undefined | スタイリング用の追加CSSクラス名 |
ListUsers.Title
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | コンテキストから | デフォルトタイトルレンダリングをオーバーライドするカスタムコンテンツ |
className | string | undefined | スタイリング用の追加CSSクラス名 |
size | enum | "3XL" | タイトルのタイポグラフィサイズ |
color | enum | "low-emphasis" | タイトルのカラーテーマ |
weight | enum | "bold" | タイトルの太さ |
ListUsers.Content
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | undefined | デフォルトコンテンツレンダリングをオーバーライドするカスタムコンテンツ |
className | string | undefined | スタイリング用の追加CSSクラス名 |
isLoading | boolean | コンテキストから | コンテキストからのローディング状態 |
ListUsers.Loader
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | 円形プログレスインジケーター | カスタムローディングインジケーターコンテンツ |
className | string | undefined | スタイリング用の追加CSSクラス名 |
direction | enum | "row" | アクションコンポーネントのフレックス方向 |
alignItems | enum | Spacingデフォルトから | コンテナ内のアイテムの整列 |
gapSize | enum | Spacingデフォルトから | コンテナ内のアイテム間のギャップ |
ListUsers.Tabs
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
tabs | Tab[] | コンテキストから | タブ設定オブジェクトの配列 |
currentTab | string | コンテキストから | 現在アクティブなタブ識別子 |
onTabChange | (tab: string) => void | コンテキストから | タブ変更コールバック関数 |
tabWidth | string | "stretch" | タブの幅動作 |
className | string | undefined | スタイリング用の追加CSSクラス名 |
ListUsers.Table
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
className | string | undefined | スタイリング用の追加CSSクラス名 |
data | ListUsersRowData[] | コンテキストから | テーブルデータの配列 |
emptyState | {icon: enum; message: string} | コンテキストから | 空状態の設定 |
isLoading | boolean | コンテキストから | ローディング状態 |
onNavigate | (to: string) => void | コンテキストから | ナビゲーションコールバック関数 |
pagination | PaginationProps | コンテキストから | ページネーション設定 |
rowHref | (row: ListUsersRowData) => string | コンテキストから | 行リンクURLを生成する関数 |
labels | UserLabels | コンテキストから | テーブルヘッダーとステータスメッセージ用のラベル |
🔧 TypeScript サポート
包括的な型定義による完全なTypeScriptサポート:
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: 'システムにユーザーが見つかりません',
headerRow: {
createdAt: '作成日',
name: 'ユーザー名',
status: 'アカウント状態',
},
cellData: {
statusInUse: 'アクティブ',
statusNotInUse: '非アクティブ',
},
};
return (
<ListUsers
listUsersTitle="ユーザー管理ダッシュボード"
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>
);
};
React、TypeScript、モダンなウェブ標準を使用して❤️で構築されました。