Skip to main content

List Order Block

ListOrder is an order list built on MUI Stack + cards, with optional chips, status banner, load-more behavior, and composition via compound children or block overrides.

Installation

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

What You Need

ItemWhy it matters
ordersRows to render (id, logoUrl, title, subtitle, date, optional chips, disabled, status)
hasMoreUsed by LoadMoreButton to decide whether it renders
onClickOrder (optional)Row click handler used by default OrderCard / OrderListSection
onClickLoadMore (optional)Load-more handler consumed by LoadMoreButton
isLoadingList (optional)Toggles OrderLoadingCircle and disables LoadMoreButton
Controlled list state

ListOrder does not own list state. Keep orders, hasMore, and loading state in your app, then pass them to the block. The common pattern is: slice/fetch next page in onClickLoadMore, append rows, and update hasMore.

Code Examples

Live Editor
function Example() {
  const allOrders = Array.from({length: 12}, (_, i) => ({
    id: String(i + 1),
    logoUrl: 'https://unsplash.it/16',
    title: `Order #${i + 1}`,
    subtitle: `Organization ${i + 1}`,
    date: new Date(2024, 0, i + 1).toLocaleDateString(),
    chips: i % 3 === 0 ? [{label: 'Pending'}] : [{label: 'Approved'}],
  }));

  const [displayedOrders, setDisplayedOrders] = React.useState(allOrders.slice(0, 5));
  const [hasMore, setHasMore] = React.useState(true);
  const [lastAction, setLastAction] = React.useState('Clicking an order will show inline feedback here.');

  const handleLoadMore = () => {
    const next = allOrders.slice(0, displayedOrders.length + 5);
    setDisplayedOrders(next);
    setHasMore(next.length < allOrders.length);
  };

  return (
    <>
      <ListOrder
        orders={displayedOrders}
        hasMore={hasMore}
        onClickOrder={(order) => setLastAction(`Clicked: ${order.title}`)}
        onClickLoadMore={handleLoadMore}
        sx={{bgcolor: 'background.default'}}
      >
        <ListOrder.OrderListSection />
        <ListOrder.OrderLoadingCircle />
        <ListOrder.LoadMoreButton />
      </ListOrder>
      <div style={{marginTop: 12, color: '#475569', fontSize: 13}}>{lastAction}</div>
    </>
  );
}
Result
Loading...

Important Props

Core Props

PropTypeRequiredDefaultDescription
ordersOrder[]Yes-Order rows
hasMorebooleanYes-Context value used by LoadMoreButton to render/hide itself
onClickOrder(order: Order) => voidNoundefinedCalled when a row is clicked
onClickLoadMore() => voidNoundefinedHandler for load-more action
isLoadingListbooleanNoundefinedShows OrderLoadingCircle; disables LoadMoreButton

Order shape:

PropTypeRequiredDefaultDescription
idstringYes-Unique row id
logoUrlstringYes-Organization logo URL
titlestringYes-Primary text
subtitlestringYes-Secondary text
datestringYes-Date text
chips({ label: string } & ChipProps)[]NoundefinedOptional chips above date
disabledbooleanNoundefinedApplies disabled card style (bgcolor: grey.75)
statusstringNoundefinedOptional status banner text (sm+ only)

Content Props

ComponentPropTypeRequiredDefaultDescription
OrderListSectionordersOrder[]NoRoot ordersRows used in default list mapping
OrderListSectiononClickOrder(order: Order) => voidNoRoot handlerRow click fallback when children are omitted
OrderListSectionchildrenReactNodeNoMaps orders to OrderCardCustom list content
OrderCardorderOrderYes-Row data for one card
OrderCardonClickCardProps['onClick']NoRoot onClickOrder(order)Click handler override
OrderCardchildrenReactNodeNoBuilt card content from orderCustom card body
OrderLoadingCircleisLoadingListbooleanNoRoot isLoadingListRenders spinner only when true
LoadMoreButtonhasMorebooleanNoRoot hasMoreRenders only when true
LoadMoreButtononClickButtonProps['onClick']NoRoot onClickLoadMoreClick handler override
LoadMoreButtonisLoadingListbooleanNoRoot isLoadingListDisables button when loading
LoadMoreButtonchildrenReactNodeNoRead MoreButton label/content
OrderLogosrcstringNofrom order.logoUrlLogo image source
OrderLogoaltstringNoundefinedImage alt text
OrderTitlechildrenReactNodeNofrom order.titleTitle content
OrderSubtitlechildrenReactNodeNofrom order.subtitleSubtitle content
OrderDatechildrenReactNodeNofrom order.dateDate content
OrderStatusBannerchildrenReactNodeNofrom order.statusStatus content

OrderListSection, OrderCard, OrderLoadingCircle, LoadMoreButton, OrderLogo, OrderTitle, OrderSubtitle, OrderDate, and OrderStatusBanner are ListOrder.OrderListSection, etc.

Layout and Composition Props

PropTypeRequiredDefaultDescription
childrenBlocksOverride | ReactNodeNoundefinedCompound JSX children or function override returning blocks and blockOrder
classNamestringNoundefinedRoot class (nbb-list-order is applied by default)
sxSxPropsNoundefinedMUI system styles for root list

ListOrder inherits StackProps (except children), with root defaults spacing={2} and p: 2. defaultBlockOrder is orderListSection, orderLoadingCircle, loadMoreButton, orderCard, orderLogo, orderSubtitle, orderDate, orderStatusBanner.

Default UI Blocks

BlockBuilt onNotes
ListOrder (root)StackRoot list container
ListOrder.OrderListSectionStackDefault order list section
ListOrder.OrderCardCard + CardActionArea + CardContentCard row built from order
ListOrder.OrderLogoBox (component="img")Circular logo image
ListOrder.OrderTitleTypographyTitle (variant="h6")
ListOrder.OrderSubtitleTypographySubtitle (variant="body1")
ListOrder.OrderDateBoxDate text with secondary color
ListOrder.OrderStatusBannerBox + TypographyStatus banner (sm+)
ListOrder.OrderLoadingCircleCircularProgressLoading spinner
ListOrder.LoadMoreButtonButtonFull-width action, default text Read More
chips inside default OrderCardChipUses order.chips entries (label required)

TypeScript

import { ListOrder, type Order } from '@nodeblocks/frontend-list-order-block';

const orders: Order[] = [
{
id: '1',
logoUrl: 'https://unsplash.it/16',
title: 'Order #1',
subtitle: 'Organization 1',
date: 'January 1, 2024',
chips: [{label: 'Pending'}],
status: 'Processing',
},
];

<ListOrder
orders={orders}
hasMore={false}
onClickOrder={() => {}}
/>;