Skip to main content

List Order Table Block

The ListOrderTable Component is a fully customizable and accessible order table interface built with React and TypeScript. It provides a complete tabular order listing experience with modern design patterns, sortable columns, action dropdowns, tabs, pagination support, loading states, and flexible customization options for advanced order management applications.


πŸš€ Installation​

npm install @nodeblocks/frontend-list-order-table-block@0.1.0

πŸ“– Usage​

import {ListOrderTable} from '@nodeblocks/frontend-list-order-table-block';
Live Editor
function BasicListOrderTable() {
  const [currentTab, setCurrentTab] = useState('pending');
  const [isLoading] = useState(false);

  const orderData = [
    {
      id: '1',
      createdAt: '2024-01-15T10:30:00Z',
      orderName: 'ORD-001',
      title: 'Office Supplies Order',
      status: 'pending',
    },
    {
      id: '2',
      createdAt: '2024-01-14T14:20:00Z',
      orderName: 'ORD-002',
      title: 'Software License',
      status: 'accepted',
    },
  ];

  const tabs = [{label: 'Pending Orders'}, {label: 'Accepted Orders'}, {label: 'Canceled Orders'}];

  const labels = {
    emptyStateMessage: 'No orders found',
    actions: {
      headerAction: 'Create Order',
    },
    headerRow: {
      createdAt: 'Created',
      title: 'Order Title',
      orderName: 'Order ID',
    },
    rowActions: {
      accepted: 'Accept Order',
      canceled: 'Cancel Order',
      processing: 'Mark Processing',
    },
  };

  const handleOrderAccepted = (orderId, title) => {
    console.log('Order accepted:', orderId, title);
  };

  const handleOrderRejected = (orderId, title) => {
    console.log('Order rejected:', orderId, title);
  };

  const handleOrderProcessing = (orderId, title) => {
    console.log('Order processing:', orderId, title);
  };

  const handleNavigate = (path) => {
    console.log('Navigate to:', path);
  };

  const getRowHref = (row) => `#${row.id}`;
  const getUpdateRowHref = (row) => `#${row.id}/edit`;

  return (
    <ListOrderTable
      listOrderTableTitle="Order Management"
      labels={labels}
      isLoading={isLoading}
      onNavigate={handleNavigate}
      onOrderAccepted={handleOrderAccepted}
      onOrderRejected={handleOrderRejected}
      onOrderProcessing={handleOrderProcessing}
      data={orderData}
      rowHref={getRowHref}
      updateRowHref={getUpdateRowHref}
      tabs={tabs}
      currentTab={currentTab}
      onTabChange={setCurrentTab}
      createHref="#new"
      style={{
        backgroundColor: 'white',
        padding: '8px',
      }}
    >
      <ListOrderTable.Header style={{display: 'flex', justifyContent: 'space-between'}}>
        <ListOrderTable.Title />
        <ListOrderTable.Action />
      </ListOrderTable.Header>
      <ListOrderTable.Content>
        {isLoading ? (
          <ListOrderTable.Loader />
        ) : (
          <>
            <ListOrderTable.Tabs />
            <ListOrderTable.Table />
          </>
        )}
      </ListOrderTable.Content>
    </ListOrderTable>
  );
}
Result
Loading...

πŸ”§ Props Reference​

Main Component Props​

PropTypeDefaultDescription
listOrderTableTitleReactNodeRequiredTitle for the order table section
labelsTableLabelsRequiredLabels object for table headers, actions, and messages
isLoadingbooleanundefinedWhether the table is currently loading
onNavigate(to: string) => voidRequiredCallback function for navigation
onOrderAccepted(id: string, title?: string) => voidRequiredCallback function when order is accepted
onOrderRejected(id: string, title?: string) => voidRequiredCallback function when order is rejected
onOrderProcessing(id: string, title?: string) => voidRequiredCallback function when order is marked as processing
dataListOrderTableRowData[]RequiredArray of order data objects
rowHref(row: ListOrderTableRowData) => stringRequiredFunction to generate row link URLs
updateRowHref(row: ListOrderTableRowData) => stringRequiredFunction to generate update row link URLs
tabsTabData[]RequiredArray of tab configuration objects
currentTabstringundefinedCurrently active tab identifier
onTabChange(tab: string) => voidundefinedCallback function when tab is changed
createHrefstringRequiredURL for creating new orders
pagination{currentPage: number; onPageChange: (page: number) => void; totalPages: number}undefinedPagination configuration object
classNamestringundefinedAdditional CSS class name for styling the container
childrenBlocksOverrideundefinedFunction to override default blocks or custom component rendering

Note: The main component inherits MUI Stack props.

Sub-Components​

The ListOrderTable 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.

ListOrderTable.Title​

PropTypeDefaultDescription
childrenReactNodeFrom contextTitle content - overrides listOrderTableTitle from context
listOrderTableTitleReactNodeFrom contextTitle text when children not provided
variantTypographyProps['variant']"h4"MUI Typography variant
componentElementType"h1"HTML element to render
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits all MUI Typography props.

ListOrderTable.Action​

PropTypeDefaultDescription
childrenReactNodeundefinedCustom content to override default action rendering
createHrefstringFrom contextURL for the create action button
labelsTableLabelsFrom contextLabels for action text
onNavigate(to: string) => voidFrom contextNavigation callback for the create button
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI Stack props (except direction which is fixed to "row").

ListOrderTable.Header​

PropTypeDefaultDescription
childrenReactNodeundefinedCustom content to override default header rendering
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI Stack props. Default layout is direction="row" with justifyContent: 'space-between' and alignItems: 'center'.

ListOrderTable.Loader​

PropTypeDefaultDescription
childrenReactNodeCircularProgressCustom loading indicator content
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI Stack props. Default alignment is alignItems: 'center'.

ListOrderTable.Content​

PropTypeDefaultDescription
childrenReactNodeundefinedCustom content to override default content rendering
isLoadingbooleanFrom contextLoading state from context
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI Box props. When not using custom children and not loading, it renders Tabs and Table in a Stack with spacing={3}.

ListOrderTable.Tabs​

PropTypeDefaultDescription
tabsTabData[]From contextArray of tab configuration objects
currentTabstringFrom contextCurrently active tab label
onTabChange(tab: string) => voidFrom contextTab change callback function
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI Tabs props (except value, onChange, and variant which are managed internally). Uses variant="fullWidth" by default.

ListOrderTable.Table​

PropTypeDefaultDescription
labelsTableLabelsFrom contextLabels object for table headers, actions, and messages
dataListOrderTableRowData[]From contextArray of table data
rowHref(row: ListOrderTableRowData) => stringFrom contextFunction to generate row link URLs
onNavigate(to: string) => voidFrom contextNavigation callback for row clicks
onOrderAcceptedDropdownItemActionFrom contextCallback when order is accepted
onOrderRejectedDropdownItemActionFrom contextCallback when order is rejected
onOrderProcessingDropdownItemActionFrom contextCallback when order is marked as processing
paginationPaginationPropsFrom contextPagination configuration object
spacingnumber3Stack spacing between elements
classNamestringundefinedAdditional CSS class name for styling

Note: This component inherits MUI Stack props.


🎨 Configuration examples​

Custom Header Styling​

<ListOrderTable.Header 
sx={{
bgcolor: 'primary.light',
borderRadius: 2,
p: 2
}}
/>

Custom Title Styling​

<ListOrderTable.Title 
variant="h3"
component="h2"
sx={{ color: 'primary.main', fontWeight: 700 }}
/>

Custom Action Button​

<ListOrderTable.Action>
<Button variant="outlined" startIcon={<Add />}>
Custom Create Button
</Button>
</ListOrderTable.Action>

Custom Table Styling​

<ListOrderTable.Table 
sx={{
'& .MuiTableCell-root': {
borderBottom: '2px solid',
borderColor: 'divider'
}
}}
/>

Using Block Override Pattern​

<ListOrderTable {...props}>
{({defaultBlocks, defaultBlockOrder}) => ({
blocks: {
header: {
...defaultBlocks.header,
props: {
...defaultBlocks.header.props,
sx: {background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)'},
},
},
},
blockOrder: defaultBlockOrder,
})}
</ListOrderTable>

πŸ”§ TypeScript Support​

Full TypeScript support with comprehensive type definitions:

import {ListOrderTable} from '@nodeblocks/frontend-list-order-table-block';
import {Stack} from '@mui/material';
import {ComponentProps, ReactNode} from 'react';

// Tab data interface
interface TabData {
key?: string;
label: string;
isDisabled?: boolean;
subtitle?: string;
}

// Main component interface
interface ListOrderTableProps<Tabs extends TabData[]> extends Omit<ComponentProps<typeof Stack>, 'children'> {
listOrderTableTitle: ReactNode;
labels: TableLabels;
isLoading?: boolean;
onNavigate: (to: string) => void;
onOrderAccepted: DropdownItemAction;
onOrderRejected: DropdownItemAction;
onOrderProcessing: DropdownItemAction;
data: ListOrderTableRowData[];
rowHref: (row: ListOrderTableRowData) => string;
updateRowHref: (row: ListOrderTableRowData) => string;
tabs: Tabs;
currentTab?: Tabs[number]['label'];
onTabChange?: (tab: Tabs[number]['label']) => void;
createHref: string;
pagination?: PaginationProps;
children?: BlocksOverride;
}

// Row data interface
export interface ListOrderTableRowData {
createdAt: string;
id: string;
orderName: string;
title: string;
status: string;
}

// Action callback type
export type DropdownItemAction = (
order: ListOrderTableRowData['id'],
title?: ListOrderTableRowData['title'],
) => void;

// Pagination props interface
export interface PaginationProps {
className?: string;
currentPage: number;
onPageChange: (page: number) => void;
totalPages: number;
}

// Labels interface
interface TableLabels {
emptyStateMessage: string;
actions?: {
headerAction: string;
};
headerRow: {
createdAt: string;
title: string;
orderName: string;
};
rowActions: {
canceled: string;
processing: string;
accepted: string;
};
}

// Usage example with full typing
function TypedListOrderTableExample() {
const [currentTab, setCurrentTab] = useState('pending');
const [isLoading] = useState(false);

const orders: ListOrderTableRowData[] = [
{
createdAt: '2024-01-15T10:30:00Z',
id: '1',
orderName: 'ORD-001',
title: 'Order Title',
status: 'pending',
},
];

const tableTabs: TabData[] = [
{label: 'Pending', key: 'pending'},
{label: 'Accepted', key: 'accepted'},
{label: 'Rejected', key: 'rejected'},
];

const tableLabels: TableLabels = {
emptyStateMessage: 'No orders available',
actions: {headerAction: 'New Order'},
headerRow: {
createdAt: 'Date Created',
title: 'Order Title',
orderName: 'Order Number',
},
rowActions: {
accepted: 'Accept',
canceled: 'Reject',
processing: 'Process',
},
};

const onAcceptOrder: DropdownItemAction = (id, title) => {
console.log('Accept order:', id, title);
};

const onRejectOrder: DropdownItemAction = (id, title) => {
console.log('Reject order:', id, title);
};

const onProcessOrder: DropdownItemAction = (id, title) => {
console.log('Process order:', id, title);
};

return (
<ListOrderTable
listOrderTableTitle="Orders Dashboard"
labels={tableLabels}
isLoading={isLoading}
onNavigate={path => console.log('Navigate:', path)}
onOrderAccepted={onAcceptOrder}
onOrderRejected={onRejectOrder}
onOrderProcessing={onProcessOrder}
data={orders}
rowHref={row => `/orders/${row.id}`}
updateRowHref={row => `/orders/${row.id}/edit`}
tabs={tableTabs}
currentTab={currentTab}
onTabChange={setCurrentTab}
createHref="#orders/create"
>
<ListOrderTable.Header />
<ListOrderTable.Content />
<ListOrderTable.Table />
</ListOrderTable>
);
}

πŸ“ Notes​

  • The root component uses MUI's Stack with default spacing={3} and sx={{ p: 3 }} padding
  • Dates are formatted using the luxon library with format yyyy/M/d HH:mm
  • Row titles have a tooltip showing full datetime on hover
  • The table uses MUI Table, TableContainer, TableHead, TableBody, and TableRow components
  • Row actions are displayed in a dropdown menu using MUI Menu and MenuItem components with icons
  • The Tabs component returns null if no tabs are provided or tabs array is empty
  • Empty state displays a Person icon with the emptyStateMessage from labels
  • Pagination uses MUI Pagination component with variant="outlined" and shape="rounded"
  • Table rows are clickable when rowHref returns a valid URL (cursor changes to pointer)
  • All sub-components inherit MUI component props and support the sx prop for styling
  • Block override pattern allows customizing, replacing, or reordering default blocks

Built with ❀️ using React, TypeScript, and MUI.