List Order Block
The ListOrder Component is a fully customizable and accessible order list interface built with React and TypeScript. It provides a complete order listing experience with modern design patterns, clickable order cards, loading states, pagination support, and flexible customization options for order management applications.
π Installationβ
npm install @nodeblocks/frontend-list-order-block
π Usageβ
import {ListOrder} from '@nodeblocks/frontend-list-order-block';
- Basic Usage
- Advanced Usage
function BasicListOrder() { const [orders, setOrders] = useState([ { id: '1', logoUrl: '/img/icon-small.png', title: 'Office Supplies Order', subtitle: 'ABC Company', date: '2024-01-15', status: 'completed', statusLabel: 'Completed', }, { id: '2', logoUrl: '/img/icon-small.png', title: 'Software License', subtitle: 'Tech Corp', date: '2024-01-14', status: 'pending', statusLabel: 'Pending', }, ]); const [hasMore, setHasMore] = useState(true); const [isLoading, setIsLoading] = useState(false); const handleOrderClick = order => { console.log('Order clicked:', order); // Handle order navigation }; const handleLoadMore = () => { setIsLoading(true); // Load more orders logic 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> ); }
function AdvancedOrderList() { const [orders, setOrders] = useState([ { id: '1', logoUrl: '/img/icon-small.png', title: 'π Premium Enterprise Package', subtitle: 'πΌ Global Tech Solutions', date: '2024-01-15', status: 'completed', statusLabel: 'β Delivered', }, { id: '2', logoUrl: '/img/icon-small.png', title: 'π» Software License Bundle', subtitle: 'π Innovation Corp', date: '2024-01-14', status: 'processing', statusLabel: 'β‘ Processing', }, { id: '3', logoUrl: '/img/icon-small.png', title: 'π§ Hardware Maintenance Kit', subtitle: 'π’ Enterprise Systems', date: '2024-01-13', status: 'pending', statusLabel: 'β³ Pending Approval', }, { id: '4', logoUrl: '/img/icon-small.png', title: 'π Analytics Dashboard Pro', subtitle: 'π Data Insights Ltd', date: '2024-01-12', status: 'completed', statusLabel: 'π Successfully Delivered', }, ]); const [hasMore, setHasMore] = useState(true); const [isLoading, setIsLoading] = useState(false); const handleOrderClick = order => { console.log('Premium order selected:', 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: { // Enhanced order list section with modern styling 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)'; }} > {/* Header Section */} <div style={{ display: 'flex', alignItems: 'center', marginBottom: '16px', paddingRight: '60px', }} > <img src={order.logoUrl} alt="Order Logo" 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> {/* Status Badge */} <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> {/* Content Section */} <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', }} > Order Date </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> {/* Action Footer */} <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', }} > View Details β </div> </div> </div> ))} </> ), // Enhanced loading indicator orderLoadingCircle: { ...defaultBlocks.orderLoadingCircle, props: { ...defaultBlocks.orderLoadingCircle.props, style: { display: 'flex', justifyContent: 'center', alignItems: 'center', padding: '20px', }, }, }, // Enhanced load more button 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: 'π Load More Premium Orders', }, }, }, blockOrder: defaultBlockOrder, })} </ListOrder> ); }
π§ Props Referenceβ
Main Component Propsβ
Prop | Type | Default | Description |
---|---|---|---|
orders | Order[] | Required | Array of order objects to display |
hasMore | boolean | Required | Whether there are more orders to load |
onClickOrder | (order: Order) => void | undefined | Callback function triggered when an order is clicked |
onClickLoadMore | () => void | undefined | Callback function triggered when load more button is clicked |
isLoadingList | boolean | undefined | Whether the list is currently loading |
className | string | undefined | Additional CSS class name for styling the container |
children | BlocksOverride | undefined | Function to override default blocks or custom component rendering |
Note: The main component inherits all HTML div
element props.
Sub-Componentsβ
The ListOrder 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.
ListOrder.OrderListSectionβ
Prop | Type | Default | Description |
---|---|---|---|
children | ReactNode | undefined | Custom content to override default order list rendering |
className | string | undefined | Additional CSS class name for styling |
orders | Order[] | From context | Array of orders to display |
onClickOrder | (order: Order) => void | From context | Callback function for order click events |
Note: This component inherits all HTML div
element props.
ListOrder.OrderCardβ
Prop | Type | Default | Description |
---|---|---|---|
order | Order | Required | Order object to display |
className | string | undefined | Additional CSS class name for styling |
onClick | () => void | undefined | Custom click handler for the order card |
children | ReactNode | undefined | Custom content to override default card rendering |
Note: This component inherits all HTML div
element props.
ListOrder.OrderLogoβ
Prop | Type | Default | Description |
---|---|---|---|
src | string | Required | URL of the organization logo |
alt | string | "Organization Logo" | Alternative text for the logo image |
className | string | undefined | Additional CSS class name for styling |
Note: This component inherits all HTML img
element props.
ListOrder.OrderTitleβ
Prop | Type | Default | Description |
---|---|---|---|
children | ReactNode | Required | Title text for the order |
className | string | undefined | Additional CSS class name for styling |
Note: This component inherits all HTML h3
element props.
ListOrder.OrderSubtitleβ
Prop | Type | Default | Description |
---|---|---|---|
children | ReactNode | Required | Subtitle text for the order (typically organization name) |
className | string | undefined | Additional CSS class name for styling |
Note: This component inherits all HTML h4
element props.
ListOrder.OrderDateβ
Prop | Type | Default | Description |
---|---|---|---|
children | ReactNode | Required | Date text for the order |
className | string | undefined | Additional CSS class name for styling |
Note: This component inherits all HTML div
element props.
ListOrder.OrderLoadingCircleβ
Prop | Type | Default | Description |
---|---|---|---|
children | ReactNode | Default loading circle | Custom loading indicator content |
className | string | undefined | Additional CSS class name for styling |
width | string | "100" | Width of the loading circle |
height | string | "100" | Height of the loading circle |
Note: This component inherits all HTML svg
element props.
ListOrder.LoadMoreButtonβ
Prop | Type | Default | Description |
---|---|---|---|
children | ReactNode | "Read More" | Button text content |
className | string | undefined | Additional CSS class name for styling |
hasMore | boolean | From context | Whether more items are available to load |
onClickLoadMore | () => void | From context | Function to load more orders |
onClick | () => void | undefined | Custom click handler for the button |
disabled | boolean | Based on loading state | Whether the button is disabled |
Note: This component inherits all HTML button
element props.
π§ TypeScript Supportβ
Full TypeScript support with comprehensive type definitions:
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
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>
);
};
Built with β€οΈ using React, TypeScript, and modern web standards.