View Order Block
ViewOrder is a key-value view block built on MUI with a header (title and status badge), optional subheader.
Installationโ
- npm
- yarn
- pnpm
- bun
npm install @nodeblocks/frontend-view-order-block
yarn add @nodeblocks/frontend-view-order-block
pnpm add @nodeblocks/frontend-view-order-block
bun add @nodeblocks/frontend-view-order-block
What You Needโ
| Item | Why it matters |
|---|---|
labels.headerTitle | Main heading in the header |
labels.statusText | Status badge value; when set, the header shows ViewOrder.Status |
data | Order fields as a Record<string, ReactNode> (row keys become labels) or ReactNode[] for value-only rows |
labels.status (optional) | Label above the status badge (default 'Status') |
statusColor (optional) | Background color for the status badge |
ViewOrder does not own order state โ pass labels, data, and optional statusColor from your page. Object data keys become row labels; values can be strings or React nodes (links, images, layouts). Set labels.statusText to show the status badge in the header.
Code Examplesโ
- Quick Start
- Labels
- Compound Components
- Block Override
function Example() { const labels = { headerTitle: 'Order Details', statusText: 'Processing', status: 'Current Status', }; const data = { 'Order ID': '#12345', Customer: 'John Doe', Date: '2024-01-15', Total: '$199.99', }; return ( <ViewOrder labels={labels} statusColor="#e3f2fd" data={data} /> ); }
Customize header copy, status badge, subheader, and row content. Use layout to switch between two-column and stacked rows.
function Example() { const labels = { headerTitle: 'Order #ORD-2024-789', status: 'Fulfillment', statusText: 'Shipped', subheaderTitle: 'Placed January 15, 2024 ยท Premium shipping', }; const data = { 'Order ID': ( <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}> <Typography component="a" href="#orders/ord-2024-789" variant="body2" sx={{ color: 'primary.main', fontWeight: 600, textDecoration: 'none', '&:hover': { textDecoration: 'underline' } }} > #ORD-2024-789 </Typography> <Box component="img" src="https://docs.nodeblocks.dev/img/undraw_docusaurus_react.svg" alt="Order preview" sx={{ maxWidth: '100%', maxHeight: 160, objectFit: 'contain', borderRadius: 1 }} /> </Box> ), Customer: 'Jane Smith', 'Payment method': 'Visa ยทยทยทยท 4242', Total: '$1,299.99', }; return ( <ViewOrder labels={labels} statusColor="#e8f5e9" layout="two-column" data={data} /> ); }
Put headerTitle, status, statusText, and subheaderTitle on the root labels object (or on ViewOrder.Header / ViewOrder.Status in compound layouts). Row labels come from data object keys.
Compose ViewOrder.Header, ViewOrder.Subheader, and ViewOrder.ItemList directly. Pass props on children instead of only on the root.
function Example() { const labels = { headerTitle: 'Order Details', status: 'Current Status', statusText: 'Processing', subheaderTitle: 'Last updated 2 hours ago', }; const data = { 'Order ID': '#12345', Customer: 'John Doe', Date: '2024-01-15', Total: '$199.99', }; return ( <ViewOrder labels={labels} statusColor="#fff3e0" data={data}> <ViewOrder.Header sx={{ px: 2, py: 1.5, bgcolor: 'grey.50', borderRadius: 2, '& .nbb-view-order-status-text': { border: '1px solid', borderColor: 'warning.light' }, }} /> <ViewOrder.Subheader sx={{ px: 2, fontStyle: 'italic' }} /> <ViewOrder.ItemList sx={{ border: '1px solid', borderColor: 'divider', borderRadius: 2, overflow: 'hidden', '& .MuiListItem-root': { bgcolor: 'background.paper' }, }} /> </ViewOrder> ); }
Use function children with defaultBlocks and defaultBlockOrder to inject blocks, replace defaults, and control order.
function Example() { const [noticeVisible, setNoticeVisible] = React.useState(true); const labels = { headerTitle: 'Order Details', status: 'Current Status', statusText: 'Processing', subheaderTitle: 'Warehouse pick in progress', }; const data = { 'Order ID': '#12345', Customer: 'John Doe', Date: '2024-01-15', Total: '$199.99', }; return ( <ViewOrder labels={labels} statusColor="#e3f2fd" data={data}> {({ defaultBlocks, defaultBlockOrder }) => ({ blocks: { ...defaultBlocks, processingNotice: noticeVisible ? ( <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 2, px: 2, py: 1.5, mb: 1, borderRadius: 2, bgcolor: 'info.main', color: 'info.contrastText', }} > <Typography variant="body2" sx={{ fontWeight: 600 }}> Order is being processed </Typography> <Box component="button" type="button" onClick={() => setNoticeVisible(false)} aria-label="Dismiss notification" sx={{ flexShrink: 0, border: '1px solid rgba(255,255,255,0.35)', bgcolor: 'rgba(255,255,255,0.12)', color: 'inherit', borderRadius: '50%', width: 28, height: 28, cursor: 'pointer', fontSize: 16, lineHeight: 1, }} > ร </Box> </Box> ) : null, header: ( <ViewOrder.Header labels={labels} sx={{ px: 2, py: 2, borderRadius: 2, border: '1px solid', borderColor: 'divider', bgcolor: 'background.paper', }} /> ), itemList: ( <ViewOrder.ItemList data={data} sx={{ mt: 2, border: '1px solid', borderColor: 'divider', borderRadius: 2, '& .MuiListItem-root:nth-of-type(even)': { bgcolor: 'grey.50' }, }} /> ), }, blockOrder: [ ...(noticeVisible ? ['processingNotice'] : []), 'header', 'subheader', 'itemList', ], })} </ViewOrder> ); }
When to use block overrides
Default defaultBlockOrder is header, subheader, itemList, item, itemKey, itemValue. The default render uses itemList to map data; the separate item / itemKey / itemValue entries are for granular overrides. This example prepends a dismissible processingNotice, replaces header and itemList with styled variants, and omits unused block keys from blockOrder.
Important Propsโ
Core Propsโ
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
data | Record<string, ReactNode> | ReactNode[] | No | undefined | Row content: object keys become field labels; arrays render value-only rows |
labels | { headerTitle?: string; subheaderTitle?: string; status?: string; statusText?: string } | No | {} | Header title, optional subheader, and status badge copy (statusText enables the badge in the default header) |
Content Propsโ
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
labels.headerTitle | string | No | undefined | Main heading in ViewOrder.Header |
labels.subheaderTitle | string | No | undefined | Secondary line under the header (ViewOrder.Subheader) |
labels.status | string | No | 'Status' | Label above the status badge (ViewOrder.Status) |
labels.statusText | string | No | undefined | Status badge value; shown in the default header when set |
statusColor | string | No | undefined | Status badge background; falls back to theme.palette.grey[50] when unset |
layout | 'one-column' | 'two-column' | No | 'two-column' | Row layout: stacked key/value vs side-by-side columns |
Layout and Composition Propsโ
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | BlocksOverride | ReactNode | No | undefined | Compound JSX children or function override returning blocks and blockOrder |
className | string | No | undefined | Class name on the root stack (nbb-view-order) |
sx | SxProps | No | undefined | MUI system styles for the root stack |
ViewOrder inherits StackProps (except children). Default defaultBlockOrder: header, subheader, itemList, item, itemKey, itemValue.
Sub-component propsโ
Sub-components read from context and accept the same content keys as props to override locally.
| Sub-component | Main Props | Inherits | Built on |
|---|---|---|---|
ViewOrder.Header | labels (headerTitle, status, statusText), children, className, sx | StackProps | Stack + Typography + ViewOrder.Status when statusText is set |
ViewOrder.Status | labels (status, statusText), statusColor, children, className, sx | StackProps | Stack + Box + Typography |
ViewOrder.Subheader | labels (subheaderTitle, headerTitle, headerActionButton), children, className, sx | StackProps | Stack + Typography |
ViewOrder.ItemList | data, children, className, sx | ListProps | List (component="dl") + ViewOrder.Item rows |
ViewOrder.Item | layout, children, className, sx | ListItemProps | ListItem |
ViewOrder.Item.Key | layout, children, className, sx | TypographyProps | Typography (component="dt", variant="subtitle1") |
ViewOrder.Item.Value | layout, children, className, sx | TypographyProps | Typography (component="dd", variant="body2") |
Default UI Blocksโ
| Block | Built on | Notes |
|---|---|---|
ViewOrder (root) | Stack | Column layout with spacing={3} (nbb-view-order) |
header (ViewOrder.Header) | Stack | headerTitle + optional ViewOrder.Status when labels.statusText is set |
subheader (ViewOrder.Subheader) | Stack | Renders when labels.subheaderTitle or custom children is set |
itemList (ViewOrder.ItemList) | List | Maps data object entries or array values to key/value rows |
Default root render order: header โ subheader โ itemList.
TypeScriptโ
import * as React from 'react';
import { ViewOrder } from '@nodeblocks/frontend-view-order-block';
import type { ReactNode } from 'react';
type OrderLabels = {
headerTitle?: string;
subheaderTitle?: string;
status?: string;
statusText?: string;
};
type OrderData = Record<string, ReactNode> | ReactNode[];
export function OrderDetailView() {
const labels: OrderLabels = {
headerTitle: 'Order Details',
status: 'Current Status',
statusText: 'Processing',
};
const data: OrderData = {
'Order ID': '#12345',
Customer: 'John Doe',
Date: '2024-01-15',
Total: '$199.99',
};
return <ViewOrder labels={labels} statusColor="#e3f2fd" data={data} />;
}