注文リストブロック
ListOrderコンポーネントは、ReactとTypeScriptで構築された完全にカスタマイズ可能でアクセシブルな注文リストインターフェースです。モダンなデザインパターン、クリック可能な注文カード、ローディング状態、ページネーションサポート、および注文管理アプリケーション向けの柔軟なカスタマイズオプションを備えた完全な注文リスト体験を提供します。
🚀 インストール
npm install @nodeblocks/frontend-list-order-block
📖 使用方法
import {ListOrder} from '@nodeblocks/frontend-list-order-block';
- 基本的な使用方法
- 高度な使用方法
ライブエディター
function BasicListOrder() { const [orders, setOrders] = useState([ { id: '1', logoUrl: '/img/icon-small.png', title: 'オフィス用品注文', subtitle: 'ABC会社', date: '2024-01-15', status: 'completed', statusLabel: '完了', }, { id: '2', logoUrl: '/img/icon-small.png', title: 'ソフトウェアライセンス', subtitle: 'テック株式会社', date: '2024-01-14', status: 'pending', statusLabel: '保留中', }, ]); const [hasMore, setHasMore] = useState(true); const [isLoading, setIsLoading] = useState(false); const handleOrderClick = order => { console.log('注文がクリックされました:', order); // 注文ナビゲーション処理 }; const handleLoadMore = () => { setIsLoading(true); // 追加注文読み込みロジック setTimeout(() => { setIsLoading(false); setOrders([...orders, ...orders]); setHasMore(false); }, 1000); }; return ( <ListOrder orders={orders} hasMore={hasMore} onClickOrder={handleOrderClick} onClickLoadMore={handleLoadMore} isLoadingList={isLoading}> <ListOrder.OrderListSection /> <ListOrder.OrderLoadingCircle /> <ListOrder.LoadMoreButton /> </ListOrder> ); }
結果
Loading...
ライブエディター
function AdvancedOrderList() { const [orders, setOrders] = useState([ { id: '1', logoUrl: '/img/icon-small.png', title: '🛒 プレミアムエンタープライズパッケージ', subtitle: '💼 グローバル・テック・ソリューションズ', date: '2024-01-15', status: 'completed', statusLabel: '✅ 配送済み', }, { id: '2', logoUrl: '/img/icon-small.png', title: '💻 ソフトウェアライセンスバンドル', subtitle: '🚀 イノベーション株式会社', date: '2024-01-14', status: 'processing', statusLabel: '⚡ 処理中', }, { id: '3', logoUrl: '/img/icon-small.png', title: '🔧 ハードウェアメンテナンスキット', subtitle: '🏢 エンタープライズシステムズ', date: '2024-01-13', status: 'pending', statusLabel: '⏳ 承認待ち', }, { id: '4', logoUrl: '/img/icon-small.png', title: '📊 アナリティクスダッシュボードPro', subtitle: '📈 データインサイト株式会社', date: '2024-01-12', status: 'completed', statusLabel: '🎉 配送完了', }, ]); const [hasMore, setHasMore] = useState(true); const [isLoading, setIsLoading] = useState(false); const handleOrderClick = order => { console.log('プレミアム注文が選択されました:', order.title); }; const handleLoadMore = () => { setIsLoading(true); setTimeout(() => { setIsLoading(false); setOrders([...orders, ...orders.map(order => ({...order, id: order.id + '_new'}))]); setHasMore(false); }, 1000); }; return ( <ListOrder orders={orders} hasMore={hasMore} onClickOrder={handleOrderClick} onClickLoadMore={handleLoadMore} isLoadingList={isLoading} > {({defaultBlocks, defaultBlockOrder}) => ({ blocks: { // モダンスタイリングで強化された注文リストセクション orderListSection: ( <> {orders.map(order => ( <div key={order.id} onClick={() => handleOrderClick(order)} style={{ width: '100%', background: 'rgba(255, 255, 255, 0.95)', borderRadius: '16px', padding: '24px', cursor: 'pointer', boxShadow: '0 8px 25px rgba(0,0,0,0.08)', border: '1px solid rgba(255,255,255,0.2)', backdropFilter: 'blur(10px)', transition: 'all 0.3s ease', position: 'relative', overflow: 'hidden', }} onMouseEnter={e => { e.target.style.transform = 'translateY(-5px)'; e.target.style.boxShadow = '0 15px 40px rgba(0,0,0,0.12)'; }} onMouseLeave={e => { e.target.style.transform = 'translateY(0)'; e.target.style.boxShadow = '0 8px 25px rgba(0,0,0,0.08)'; }} > {/* ヘッダーセクション */} <div style={{ display: 'flex', alignItems: 'center', marginBottom: '16px', paddingRight: '60px', }} > <img src={order.logoUrl} alt="注文ロゴ" style={{ width: '48px', height: '48px', borderRadius: '12px', marginRight: '16px', objectFit: 'cover', border: '2px solid rgba(105, 124, 213, 0.2)', }} /> <div style={{flex: 1}}> <h3 style={{ margin: '0 0 4px 0', fontSize: '18px', fontWeight: 'bold', color: '#2c3e50', lineHeight: '1.3', }} > {order.title} </h3> <p style={{ margin: 0, fontSize: '14px', color: '#7f8c8d', fontWeight: '500', }} > {order.subtitle} </p> </div> </div> {/* ステータスバッジ */} <div style={{ marginTop: '16px', marginBottom: '16px', background: order.status === 'completed' ? 'linear-gradient(135deg, #4CAF50, #45a049)' : order.status === 'processing' ? 'linear-gradient(135deg, #FF9800, #F57C00)' : 'linear-gradient(135deg, #2196F3, #1976D2)', color: 'white', padding: '6px 12px', borderRadius: '20px', fontSize: '12px', fontWeight: 'bold', boxShadow: '0 4px 12px rgba(0,0,0,0.15)', }} > {order.statusLabel} </div> {/* コンテンツセクション */} <div style={{ background: 'rgba(105, 124, 213, 0.05)', borderRadius: '12px', padding: '16px', marginBottom: '16px', }} > <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', }} > <div> <span style={{ fontSize: '12px', color: '#95a5a6', textTransform: 'uppercase', fontWeight: 'bold', letterSpacing: '0.5px', }} > 注文日 </span> <div style={{ fontSize: '16px', fontWeight: 'bold', color: '#34495e', marginTop: '4px', }} > {order.date} </div> </div> <div style={{ width: '40px', height: '40px', background: 'linear-gradient(135deg, rgb(105, 124, 213), rgb(85, 104, 193))', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white', fontSize: '18px', }} > {order.status === 'completed' ? '✅' : order.status === 'processing' ? '⚡' : '⏳'} </div> </div> </div> {/* アクションフッター */} <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', paddingTop: '8px', borderTop: '1px solid rgba(0,0,0,0.05)', }} > <span style={{ fontSize: '12px', color: '#95a5a6', fontWeight: '500', }} > ID: {order.id} </span> <div style={{ color: 'rgb(105, 124, 213)', fontSize: '14px', fontWeight: 'bold', display: 'flex', alignItems: 'center', gap: '4px', }} > 詳細を表示 → </div> </div> </div> ))} </> ), // 強化されたローディングインジケーター orderLoadingCircle: { ...defaultBlocks.orderLoadingCircle, props: { ...defaultBlocks.orderLoadingCircle.props, style: { display: 'flex', justifyContent: 'center', alignItems: 'center', padding: '20px', }, }, }, // 強化された「もっと読み込む」ボタン loadMoreButton: { ...defaultBlocks.loadMoreButton, props: { ...defaultBlocks.loadMoreButton.props, style: { background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)', color: 'white', border: 'none', borderRadius: '50px', padding: '16px 32px', fontSize: '16px', fontWeight: 'bold', cursor: 'pointer', boxShadow: '0 8px 16px rgba(102, 126, 234, 0.3)', margin: '0 auto', display: 'block', transform: 'scale(1)', transition: 'all 0.2s ease', }, children: '🔄 プレミアム注文をさらに読み込む', }, }, }, blockOrder: 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';
// 注文データインターフェース
export type Order = {
id: string;
logoUrl: string;
title: string;
subtitle: string;
date: string;
status: string;
statusLabel: string;
};
// メインコンポーネントインターフェース
interface ListOrderProps extends Omit<ComponentProps<'div'>, 'children'> {
orders: Order[];
hasMore: boolean;
onClickOrder?: (order: Order) => void;
onClickLoadMore?: () => void;
isLoadingList?: boolean;
className?: string;
}
// 完全な型付けを使用した使用例
interface CustomOrderListProps {
orderData: Order[];
onOrderSelect: (order: Order) => void;
loadMoreOrders: () => void;
hasMoreData: boolean;
isLoading: boolean;
}
const OrderListComponent = ({
orderData,
onOrderSelect,
loadMoreOrders,
hasMoreData,
isLoading,
}: CustomOrderListProps) => {
return (
<ListOrder
orders={orderData}
hasMore={hasMoreData}
onClickOrder={onOrderSelect}
onClickLoadMore={loadMoreOrders}
isLoadingList={isLoading}>
<ListOrder.OrderListSection />
<ListOrder.OrderLoadingCircle />
<ListOrder.LoadMoreButton />
</ListOrder>
);
};
React、TypeScript、モダンなウェブ標準を使用して❤️で構築されました。