注文リストブロック
ListOrderコンポーネントは、ReactとTypeScriptで構築された完全にカスタマイズ可能でアクセシブルな注文リストインターフェースです。モダンなデザインパターン、クリック可能な注文カード、ローディング状態、ページネーションサポート、および注文管理アプリケーション向けの柔軟なカスタマイズオプションを備えた完全な注文リスト体験を提供します。
🚀 インストール
npm install @nodeblocks/frontend-list-order-block@0.1.1
📖 使用法
import {ListOrder} from '@nodeblocks/frontend-list-order-block';
- 基本的な使用法
- 高度な使用法
ライブエディター
function SimpleListOrder() { const orders = [ { id: '1', logoUrl: 'https://placehold.co/600x400', title: '注文 #ORD-001', subtitle: '3項目 - 電子機器', date: '2024-01-15', status: 'delivered', statusLabel: '配送済み', }, { id: '2', logoUrl: 'https://placehold.co/600x400', title: '注文 #ORD-002', subtitle: '1項目 - 衣類', date: '2024-01-14', status: 'processing', statusLabel: '処理中', }, { id: '3', logoUrl: 'https://placehold.co/600x400', title: '注文 #ORD-003', subtitle: '5項目 - ホーム・ガーデン', date: '2024-01-13', status: 'shipped', statusLabel: '発送済み', }, ]; return ( <ListOrder orders={orders} hasMore={false} onClickOrder={order => console.log('注文がクリックされました:', order.id)}> <ListOrder.OrderListSection /> </ListOrder> ); }
結果
Loading...
ライブエディター
import {useState} from 'react'; function AdvancedListOrder() { const [hasMore, setHasMore] = useState(true); const [isLoading, setIsLoading] = useState(false); const orders = [ { id: '1', logoUrl: 'https://placehold.co/600x400', title: 'プレミアムサブスクリプション', subtitle: '年間プラン - $249.99', date: '2024-01-20', status: 'delivered', statusLabel: '配送済み', }, { id: '2', logoUrl: 'https://placehold.co/600x400', title: 'ソフトウェアライセンス', subtitle: 'エンタープライズ版 - $149.50', date: '2024-01-19', status: 'processing', statusLabel: '処理中', }, { id: '3', logoUrl: 'https://placehold.co/600x400', title: 'ハードウェアキット', subtitle: '開発者パック - $89.00', date: '2024-01-18', status: 'shipped', statusLabel: '発送済み', }, { id: '4', logoUrl: 'https://placehold.co/600x400', title: 'コンサルティングセッション', subtitle: '2時間 - $399.99', date: '2024-01-17', status: 'pending', statusLabel: '保留中', }, { id: '5', logoUrl: 'https://placehold.co/600x400', title: 'トレーニングコース', subtitle: 'オンラインアクセス - $75.00', date: '2024-01-16', status: 'cancelled', statusLabel: 'キャンセル済み', }, ]; const getStatusColor = (status) => { const colors = { delivered: {bg: '#dcfce7', text: '#166534'}, processing: {bg: '#dbeafe', text: '#1e40af'}, shipped: {bg: '#fef3c7', text: '#92400e'}, pending: {bg: '#f3f4f6', text: '#374151'}, cancelled: {bg: '#fee2e2', text: '#991b1b'}, }; return colors[status] || {bg: '#f3f4f6', text: '#374151'}; }; const handleLoadMore = () => { setIsLoading(true); setTimeout(() => { setIsLoading(false); setHasMore(false); }, 1500); }; const handleOrderClick = (order) => { console.log('注文を表示:', order.id, order.title); }; return ( <ListOrder orders={orders} hasMore={hasMore} onClickOrder={handleOrderClick} onClickLoadMore={handleLoadMore} isLoadingList={isLoading} className="custom-list-order" > {({defaultBlocks, defaultBlockOrder}) => { const header = ( <div style={{ padding: '24px', borderBottom: '1px solid #e2e8f0', marginBottom: '16px', }} > <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', }} > <div> <div style={{ fontSize: '24px', fontWeight: '700', color: '#1e293b', marginBottom: '4px', }} > 注文履歴 </div> <p style={{fontSize: '14px', color: '#64748b', margin: 0}}>注文を管理および追跡</p> </div> <div style={{ padding: '8px 16px', borderRadius: '8px', background: '#f1f5f9', fontSize: '14px', color: '#64748b', }} > {orders.length}件の注文 </div> </div> </div> ); const customOrderList = ( <div style={{display: 'flex', flexDirection: 'column', gap: '12px', padding: '0 24px'}}> {orders.map(order => { const statusColors = getStatusColor(order.status); return ( <div key={order.id} onClick={() => handleOrderClick(order)} style={{ padding: '20px', borderRadius: '12px', border: '1px solid #e2e8f0', cursor: 'pointer', transition: 'all 0.2s ease', display: 'flex', alignItems: 'center', gap: '16px', }} > <img src={order.logoUrl} alt={order.title} style={{ width: '56px', height: '56px', borderRadius: '12px', objectFit: 'cover', }} /> <div style={{flex: 1}}> <div style={{ display: 'flex', alignItems: 'center', gap: '12px', marginBottom: '4px', }} > <span style={{ fontSize: '16px', fontWeight: '600', color: '#1e293b', }} > {order.title} </span> <span style={{ padding: '4px 12px', borderRadius: '20px', background: statusColors.bg, color: statusColors.text, fontSize: '12px', fontWeight: '600', }} > {order.statusLabel} </span> </div> <div style={{fontSize: '14px', color: '#64748b'}}>{order.subtitle}</div> </div> <div style={{textAlign: 'right'}}> <div style={{fontSize: '13px', color: '#94a3b8'}}>{order.date}</div> </div> </div> ); })} </div> ); const customLoadMore = hasMore ? ( <div style={{textAlign: 'center', padding: '24px'}}> <button onClick={handleLoadMore} disabled={isLoading} style={{ padding: '12px 32px', borderRadius: '10px', border: '1px solid #e2e8f0', background: '#ffffff', color: '#475569', fontSize: '14px', fontWeight: '500', cursor: isLoading ? 'not-allowed' : 'pointer', opacity: isLoading ? 0.6 : 1, }} > {isLoading ? '読み込み中...' : 'さらに注文を読み込む'} </button> </div> ) : null; return { blocks: { ...defaultBlocks, header, orderListSection: customOrderList, loadMoreButton: customLoadMore, }, blockOrder: ['header', ...defaultBlockOrder], }; }} </ListOrder> ); }
結果
Loading...
🔧 プロパティリファレンス
メインコンポーネントのプロパティ
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
orders | Order[] | 必須 | 表示する注文オブジェクトの配列 |
hasMore | boolean | 必須 | 読み込む注文がまだあるかどうか |
onClickOrder | (order: Order) => void | undefined | 注文がクリックされたときにトリガーされるコールバック関数 |
onClickLoadMore | () => void | undefined | 「もっと読み込む」ボタンがクリックされたときにトリガーされるコールバック関数 |
isLoadingList | boolean | undefined | リストが現在読み込み中かどうか |
className | string | undefined | コンテナスタイリング用の追加CSSクラス名 |
children | BlocksOverride | undefined | デフォルトブロックをオーバーライドまたはカスタムコンポーネントレンダリングするための関数 |
注意: メインコンポーネントはすべてのHTML div 要素プロパティを継承します。
サブコンポーネント
ListOrderコンポーネントは複数のサブコンポーネントを提供します。すべてのサブコンポーネントは、メインコンポーネントのコンテキストからデフォルト値を受け取り、プロパティを通じてこれらの値をオーバーライドできます。
ListOrder.OrderListSection
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | undefined | デフォルト注文リストレンダリングをオーバーライドするカスタムコンテンツ |
className | string | undefined | スタイリング用の追加CSSクラス名 |
orders | Order[] | コンテキストから | 表示する注文の配列 |
onClickOrder | (order: Order) => void | コンテキストから | 注文クリックイベントのコールバック関数 |
注意: このコンポーネントはすべてのHTML div 要素プロパティを継承します。
ListOrder.OrderCard
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
order | Order | 必須 | 表示する注文オブジェクト |
className | string | undefined | スタイリング用の追加CSSクラス名 |
onClick | () => void | undefined | 注文カードのカスタムクリックハンドラー |
children | ReactNode | undefined | デフォルトカードレンダリングをオーバーライドするカスタムコンテンツ |
注意: このコンポーネントはすべてのHTML div 要素プロパティを継承します。
ListOrder.OrderLogo
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
src | string | 必須 | 組織ロゴのURL |
alt | string | "Organization Logo" | ロゴ画像の代替テキスト |
className | string | undefined | スタイリング用の追加CSSクラス名 |
注意: このコンポーネントはすべてのHTML img 要素プロパティを継承します。
ListOrder.OrderTitle
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | 必須 | 注文のタイトルテキスト |
className | string | undefined | スタイリング用の追加CSSクラス名 |
注意: このコンポーネントはすべてのHTML h3 要素プロパティを継承します。
ListOrder.OrderSubtitle
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | 必須 | 注文のサブタイトルテキスト(通常は組織名) |
className | string | undefined | スタイリング用の追加CSSクラス名 |
注意: このコンポーネントはすべてのHTML h4 要素プロパティを継承します。
ListOrder.OrderDate
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | 必須 | 注文の日付テキスト |
className | string | undefined | スタイリング用の追加CSSクラス名 |
注意: このコンポーネントはすべてのHTML div 要素プロパティを継承します。
ListOrder.OrderLoadingCircle
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | デフォルトローディングサークル | カスタムローディングインジケーターコンテンツ |
className | string | undefined | スタイリング用の追加CSSクラス名 |
width | string | "100" | ローディングサークルの幅 |
height | string | "100" | ローディングサークルの高さ |
注意: このコンポーネントはすべてのHTML svg 要素プロパティを継承します。
ListOrder.LoadMoreButton
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
children | ReactNode | "Read More" | ボタンテキストコンテンツ |
className | string | undefined | スタイリング用の追加CSSクラス名 |
hasMore | boolean | コンテキストから | 読み込み可能なアイテムがまだあるかどうか |
onClickLoadMore | () => void | コンテキストから | 注文をさらに読み込む関数 |
onClick | () => void | undefined | ボタンのカスタムクリックハンドラー |
disabled | boolean | ローディング状態に基づく | ボタンが無効かどうか |
注意: このコンポーネントはすべてのHTML button 要素プロパティを継承します。
🔧 TypeScript サポート
包括的な型定義による完全なTypeScriptサポート:
import {ListOrder} from '@nodeblocks/frontend-list-order-block';
import {ComponentProps} from 'react';
// Order data interface
export type Order = {
id: string;
logoUrl: string;
title: string;
subtitle: string;
date: string;
status: string;
statusLabel: string;
};
// Main component interface
interface ListOrderProps extends Omit<ComponentProps<'div'>, 'children'> {
orders: Order[];
hasMore: boolean;
onClickOrder?: (order: Order) => void;
onClickLoadMore?: () => void;
isLoadingList?: boolean;
className?: string;
}
// Usage example with full typing
function TypedListOrder() {
const orderData: Order[] = [
{
id: 'order-1',
logoUrl: 'https://placehold.co/600x400',
title: 'プレミアムパッケージ',
subtitle: '年間サブスクリプション - 5ユーザー',
date: '2024-01-20',
status: 'delivered',
statusLabel: '配送済み',
},
{
id: 'order-2',
logoUrl: 'https://placehold.co/600x400',
title: 'スタンダードパッケージ',
subtitle: '月間サブスクリプション - 2ユーザー',
date: '2024-01-19',
status: 'processing',
statusLabel: '配送中',
},
];
const handleOrderClick = (order: Order): void => {
console.log('選択された注文:', order.id, order.title);
};
const handleLoadMore = (): void => {
console.log('さらに注文を読み込み中...');
};
return (
<ListOrder
orders={orderData}
hasMore={true}
onClickOrder={handleOrderClick}
onClickLoadMore={handleLoadMore}
isLoadingList={false}
style={{
maxWidth: '800px',
margin: '0 auto',
padding: '24px',
border: '1px solid #e5e7eb',
borderRadius: '16px',
}}
>
<ListOrder.OrderListSection />
<ListOrder.LoadMoreButton />
</ListOrder>
);
}
React、TypeScript、モダンなウェブ標準を使用して❤️で構築されました。