メインコンテンツまでスキップ

招待リストブロック

ListInvitesコンポーネントは、React、TypeScript、MUIで構築された完全にカスタマイズ可能でアクセシブルな招待管理インターフェースです。モダンなデザインパターン、アクションドロップダウン、ページネーションサポート、ローディング状態、および高度な招待管理アプリケーション向けの柔軟なカスタマイズオプションを備えた完全な表形式招待リスト体験を提供します。


🚀 インストール

npm install @nodeblocks/frontend-list-invites-block@0.2.1

📖 使用法

import {ListInvites} from '@nodeblocks/frontend-list-invites-block';
ライブエディター
function SimpleListInvites() {
  const inviteData = [
    {
      id: '1',
      name: '田中太郎',
      email: 'tanaka.taro@example.com',
      status: 'Pending',
    },
    {
      id: '2',
      name: '佐藤花子',
      email: 'sato.hanako@example.com',
      status: 'Accepted',
    },
    {
      id: '3',
      name: '鈴木次郎',
      email: 'suzuki.jiro@example.com',
      status: 'Expired',
    },
  ];

  const labels = {
    emptyStateMessage: '招待が見つかりません',
    actions: {
      inviteUser: 'ユーザーを招待',
    },
    headerRow: {
      name: '名前',
      email: 'メールアドレス',
      status: 'ステータス',
    },
    rowActions: {
      reject: '拒否',
    },
    unsetDateMessage: '設定されていません',
  };

  return (
    <ListInvites
      data={inviteData}
      labels={labels}
      listInvitesTitle="チーム招待"
      onNavigate={to => console.log('ナビゲート先:', to)}
      onClickAction={() => console.log('招待アクションがクリックされました')}
      onItemReject={id => console.log('招待を拒否:', id)}
      rowHref={row => `/invites/${row.id}`}
    >
      <ListInvites.Header />
      <ListInvites.Content />
    </ListInvites>
  );
}
結果
Loading...

🔧 プロパティリファレンス

メインコンポーネントのプロパティ

プロパティデフォルト説明
listInvitesTitleReactNode必須招待セクションのタイトル
labelsTableLabels必須テーブルヘッダー、アクション、メッセージのラベルオブジェクト
isLoadingbooleanundefinedテーブルが現在読み込み中かどうか
onNavigate(to: string) => void必須ナビゲーション用のコールバック関数
onClickAction() => void必須メインアクションボタンのコールバック関数
onItemReject(inviteId: string) => void必須招待が拒否されたときのコールバック関数
dataListInvitesRowData[]必須招待データオブジェクトの配列
rowHref(row: ListInvitesRowData) => string必須行リンクURLを生成する関数
shouldShowDropdownMenu(row: ListInvitesRowData) => booleanundefined行ごとにドロップダウンメニューを条件付きで表示する関数
paginationPaginationPropsundefinedページネーション設定
classNamestringundefinedコンテナスタイリング用の追加CSSクラス名
childrenBlocksOverrideundefinedデフォルトブロックをオーバーライドする関数

注意: メインコンポーネントはMUI Stack プロパティを継承します。ルートコンテナはデフォルトで spacing={3}sx={{ p: 3 }} を使用します。

サブコンポーネント

ListInvitesコンポーネントは複数のサブコンポーネントを提供します。すべてのサブコンポーネントは、メインコンポーネントのコンテキストからデフォルト値を受け取り、プロパティを通じてこれらの値をオーバーライドできます。

ListInvites.Header

タイトルとアクションボタンを含むヘッダーのコンテナです。

プロパティデフォルト説明
childrenReactNodeundefinedデフォルトヘッダーレンダリングをオーバーライドするカスタムコンテンツ
classNamestringundefinedスタイリング用の追加CSSクラス名

注意: このコンポーネントはMUI Box プロパティを継承します。direction="row"justifyContent: 'space-between' のStackを含みます。

ListInvites.Title

招待セクションのタイトルを表示します。

プロパティデフォルト説明
childrenReactNodeコンテキストからタイトルをオーバーライドするカスタムコンテンツ
listInvitesTitleReactNodeコンテキストからchildrenが提供されていない場合のタイトルテキスト
variantTypographyProps['variant']"h4"MUI Typographyバリアント
componentElementType"h1"レンダリングするHTML要素
classNamestringundefinedスタイリング用の追加CSSクラス名

注意: このコンポーネントはMUI Typography プロパティを継承します。

ListInvites.Action

アクションボタンのコンテナです。

プロパティデフォルト説明
childrenReactNodeundefinedデフォルトアクションレンダリングをオーバーライドするカスタムコンテンツ
onClickAction() => voidコンテキストからアクションボタンのコールバック
labelsTableLabelsコンテキストからアクションテキスト用のラベル
classNamestringundefinedスタイリング用の追加CSSクラス名

注意: このコンポーネントはMUI Stack プロパティを継承します(direction"row" に固定)。デフォルトの整列は alignItems: 'center' です。

ListInvites.Content

メインコンテンツエリア(ローダーまたはテーブル)のコンテナです。

プロパティデフォルト説明
childrenReactNodeundefinedデフォルトレンダリングをオーバーライドするカスタムコンテンツ
isLoadingbooleanコンテキストからコンテキストからのローディング状態
classNamestringundefinedスタイリング用の追加CSSクラス名

注意: このコンポーネントはMUI Box プロパティを継承します。読み込み中は Loader を、それ以外は Table をレンダリングします。

ListInvites.Loader

ローディングインジケーターを表示します。

プロパティデフォルト説明
childrenReactNodeCircularProgressカスタムローディングインジケーターコンテンツ
classNamestringundefinedスタイリング用の追加CSSクラス名

注意: このコンポーネントはMUI Stack プロパティを継承します。デフォルトの整列は alignItems: 'center' です。

ListInvites.Table

招待データをテーブル形式で表示します。

プロパティデフォルト説明
labelsTableLabelsコンテキストからテーブルヘッダーとアクション用のラベル
dataListInvitesRowData[]コンテキストから招待データの配列
rowHref(row: ListInvitesRowData) => stringコンテキストから行リンクを生成する関数
onNavigate(to: string) => voidコンテキストから行クリック時のナビゲーションコールバック
onItemReject(id: string) => voidコンテキストから招待を拒否するときのコールバック
shouldShowDropdownMenu(row: ListInvitesRowData) => booleanコンテキストからドロップダウンを条件付きで表示する関数
paginationPaginationPropsコンテキストからページネーション設定
spacingnumber3要素間のStackスペーシング
classNamestringundefinedスタイリング用の追加CSSクラス名

注意: このコンポーネントはMUI Stack プロパティを継承します。


🎨 Configuration examples

Custom Styled Example

<ListInvites
data={inviteData}
labels={labels}
listInvitesTitle="招待"
onNavigate={console.log}
onClickAction={() => console.log('アクションがクリックされました')}
onItemReject={console.log}
rowHref={row => `/invite/${row.id}`}
sx={{
bgcolor: 'grey.900',
color: 'grey.100',
p: 3,
borderRadius: 2,
}}
>
<ListInvites.Header
sx={{
'& .MuiTypography-root': {
color: 'grey.100',
},
}}
/>
<ListInvites.Content
sx={{
'& .MuiTableCell-root': {
color: 'grey.100',
borderColor: 'grey.700',
},
}}
/>
</ListInvites>

Using Block Override Pattern

<ListInvites {...props}>
{({defaultBlocks, defaultBlockOrder}) => {
const customHeader = (
<div style={{padding: '24px', borderBottom: '1px solid #e2e8f0'}}>
<div style={{display: 'flex', justifyContent: 'space-between', alignItems: 'center'}}>
<div>
<div style={{fontSize: '24px', fontWeight: '700', color: '#1e293b'}}>
チーム招待
</div>
<p style={{fontSize: '14px', color: '#64748b', margin: 0}}>
保留中および過去のチーム招待を管理
</p>
</div>
<button
onClick={handleInviteAction}
style={{
padding: '12px 24px',
borderRadius: '10px',
background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)',
color: '#ffffff',
border: 'none',
cursor: 'pointer',
}}
>
<span>+</span> メンバーを招待
</button>
</div>
</div>
);

return {
blocks: {
...defaultBlocks,
header: customHeader,
},
blockOrder: defaultBlockOrder,
};
}}
</ListInvites>

🔧 TypeScript サポート

包括的な型定義による完全なTypeScriptサポート:

import {ListInvites} from '@nodeblocks/frontend-list-invites-block';
import { StackProps } from '@mui/material';
import { ReactNode } from 'react';

// 行データインターフェース
interface ListInvitesRowData {
id: string;
name: string;
email: string;
status: string;
}

// ページネーションプロパティインターフェース
interface PaginationProps {
className?: string;
currentPage: number;
onPageChange: (page: number) => void;
totalPages: number;
}

// ラベルインターフェース
interface TableLabels {
emptyStateMessage: string;
actions: {
inviteUser: string;
};
headerRow: {
name: string;
email: string;
status: string;
};
rowActions: {
reject: string;
};
unsetDateMessage: string;
}

// メインコンポーネントプロパティインターフェース
interface ListInvitesProps extends Omit<StackProps, 'children'> {
listInvitesTitle: ReactNode;
labels: TableLabels;
isLoading?: boolean;
onNavigate: (to: string) => void;
onClickAction: () => void;
onItemReject: (inviteId: string) => void;
data: ListInvitesRowData[];
rowHref: (row: ListInvitesRowData) => string;
shouldShowDropdownMenu?: (row: ListInvitesRowData) => boolean;
pagination?: PaginationProps;
children?: BlocksOverride;
}

// Usage example with full typing
function TypedListInvites() {
const [page, setPage] = useState(1);

const inviteData: ListInvitesRowData[] = [
{
id: 'inv-1',
name: '開発者1',
email: 'developer@company.com',
status: 'Pending',
},
{
id: 'inv-2',
name: 'デザイナー2',
email: 'designer@company.com',
status: 'Accepted',
},
];

const labels: TableLabels = {
emptyStateMessage: 'チーム招待が見つかりません',
actions: {
inviteUser: 'チームメンバーを招待',
},
headerRow: {
name: '氏名',
email: 'メールアドレス',
status: '招待ステータス',
},
rowActions: {
reject: '招待を拒否',
},
unsetDateMessage: '日付が設定されていません',
};

const handleNavigate = (to: string): void => {
console.log('ナビゲート先:', to);
};

const handleInviteAction = (): void => {
console.log('招待ダイアログを開く');
};

const handleReject = (id: string): void => {
console.log('招待を拒否:', id);
};

const pagination: PaginationProps = {
currentPage: page,
totalPages: 5,
onPageChange: newPage => setPage(newPage),
};

return (
<ListInvites
data={inviteData}
labels={labels}
listInvitesTitle="チーム招待"
onNavigate={handleNavigate}
onClickAction={handleInviteAction}
onItemReject={handleReject}
rowHref={row => `/invitations/${row.id}`}
pagination={pagination}
isLoading={false}
sx={{
maxWidth: 800,
mx: 'auto',
p: 3,
border: '1px solid #e5e7eb',
borderRadius: 2,
}}
>
<ListInvites.Header />
<ListInvites.Table />
</ListInvites>
);
}

📝 注意事項

  • ルートコンポーネントはデフォルトで spacing={3}sx={{ p: 3 }} のパディングを持つMUIの Stack を使用します
  • MUI TableTableContainerTableHeadTableBodyTableRow コンポーネントを使用します
  • 行アクションは block アイコンを持つMUI MenuMenuItem を使用してドロップダウンメニューで表示されます
  • 空状態はラベルの emptyStateMessage と共に person アイコン(Material Symbols)を表示します
  • ページネーションは variant="outlined"shape="rounded" を持つMUI Pagination コンポーネントを使用します
  • rowHref が有効なURLを返す場合、テーブル行はクリック可能です(カーソルがポインターに変わります)
  • shouldShowDropdownMenu プロパティにより、行ごとにアクションメニューの条件付き表示が可能です
  • デフォルトのアクションボタンは variant="contained"people_outline アイコンを持つMUI Button を使用します
  • ListInvites.Title はデフォルトで variant="h4"component="h1" を持つMUI Typographyを使用します
  • すべてのサブコンポーネントはそれぞれのMUIコンポーネントプロパティを継承し、スタイリング用の sx プロパティをサポートします
  • ブロックオーバーライドパターンにより、デフォルトブロックのカスタマイズ、置換、並べ替えが可能です

React、TypeScript、MUIを使用して❤️で構築されました。