Skip to main content

Order

Order management components for displaying and managing customer orders in e-commerce applications.

Purpose

This library provides components for displaying and managing customer orders, including order details, order history, and order status tracking. It's designed as a headless component that provides all the order logic while allowing complete UI customization. Use this library when you need to display order confirmation details, order history, or allow customers to view their past orders.

Features

  • Order details display with loading and error states
  • Order line item management via integrated OrderLines components
  • Order totals and pricing calculations
  • Shipping lines display with method names and prices
  • Shipping and billing address display
  • Order summary with subtotal, shipping, and total calculations
  • Generic field component for displaying any order property

Installation

npm install @haus-storefront-react/order

Note: This is not a public package. Contact the Haus Tech Team for access.

API Reference

Order.Root

Root component that fetches order data and provides context for all child components. Must be used as the wrapper for all other Order components.

Props

PropTypeRequiredDefaultDescription
orderCodestringYes-The order code to fetch order details
childrenChildrenProps<OrderContextValue>No-Render prop function that receives order data and loading states

Order.Field

Generic component for displaying any order property. Must be used within Order.Root.

Props

PropTypeRequiredDefaultDescription
fieldkeyof OrderTypeYes-The order field to display (e.g., 'code', 'state', 'totalQuantity')
formatter(value: OrderType[keyof OrderType]) => stringNo-Optional function to format the value
childrenReact.ReactNode | ((props: { value, formattedValue }) => React.ReactNode)No-Optional render prop or content
asChildbooleanNofalseRender as a child element instead of a div

Order.Items

Container component for displaying order items. Must be used within Order.Root.

Order.Items.Root

Container that provides order lines context. Uses the order code from Order.Root context automatically. Provides order lines via render prop.

Props

PropTypeRequiredDefaultDescription
childrenReact.ReactNode | ((props: { orderLines: OrderLine[] | undefined }) => React.ReactNode)No-Render prop that receives order lines array

Order.Items.Item

Individual order item component. Must be used within Order.Items.Root.

Props

PropTypeRequiredDefaultDescription
orderLineOrderLineYes-The order line data to display
asChildbooleanNofalseRender as a child element instead of default element

Order.Items.Image

Product image display component. Must be used within Order.Items.Item. Inherits from OrderLines.Image component, from @haus-storefront-react/order-lines.

Order.Items.Price

Price display component for order lines. Must be used within Order.Items.Item. Inherits from OrderLines.Price component, from @haus-storefront-react/order-lines.

Order.ShippingLines

Container component for shipping lines. Must be used within Order.Root. Provides shipping lines array to children via render prop.

Props

PropTypeRequiredDefaultDescription
childrenReact.ReactNode | ((props: { shippingLines }) => React.ReactNode)No-Render prop that receives shipping lines array
asChildbooleanNofalseRender as a child element instead of a div

Order.ShippingLine

Individual shipping line component. Must be used within Order.ShippingLines. Provides shipping method name, price, price with tax, and currency code to children via render prop.

PropTypeRequiredDefaultDescription
shippingLineShippingLineYes-The shipping line data to display
childrenReact.ReactNode | ((props: { name, price, priceWithTax, currencyCode }) => React.ReactNode)No-Render prop that receives shipping data
asChildbooleanNofalseRender as a child element instead of a div

Order.Summary

Summary component for displaying order totals. Must be used within Order.Root. Provides order summary data to children via render prop.

Props

PropTypeRequiredDefaultDescription
childrenReact.ReactNode | ((props: OrderSummaryData) => React.ReactNode)No-Render prop that receives order summary data
asChildbooleanNofalseRender as a child element instead of a div

Render Prop Data

PropertyTypeDescription
totalPricenumberOrder total price (without tax)
totalWithTaxnumberOrder total price (with tax)
subTotalnumberOrder subtotal (without tax)
subTotalWithTaxnumberOrder subtotal (with tax)
shippingnumberShipping cost (without tax)
shippingWithTaxnumberShipping cost (with tax)
taxSummaryOrderTaxSummary[]Array of tax summary entries
currencyCodeCurrencyCodeCurrency code for the order

Order.Addresses

Container component for displaying shipping and billing addresses. Must be used within Order.Root.

Order.Addresses.Root

Container for address components.

Props

PropTypeRequiredDefaultDescription
asChildbooleanNofalseRender as a child element instead of a div
childrenReact.ReactNodeNo-Child components

Order.Addresses.Shipping

Component that provides shipping address to children via render prop. Must be used within Order.Addresses.Root.

Props

PropTypeRequiredDefaultDescription
childrenReact.ReactNode | ((address: OrderAddress | null) => React.ReactNode)No-Render prop that receives shipping address or null
asChildbooleanNofalseRender as a child element instead of a div

Order.Addresses.Billing

Component that provides billing address to children via render prop. Must be used within Order.Addresses.Root.

Props

PropTypeRequiredDefaultDescription
childrenReact.ReactNode | ((address: OrderAddress | undefined | null) => React.ReactNode)No-Render prop that receives billing address, undefined, or null
asChildbooleanNofalseRender as a child element instead of a div

useOrderContext

Internal hook for accessing Order context. Used internally by Order components. Not typically needed by consumers, but exported for advanced use cases.

Parameters

ParameterTypeRequiredDescription
componentNamestringYesComponent name for error messaging
scopeScopeNoOptional scope for context isolation

Returns

OrderContextValue - Order context value with order data and loading states

createOrderScope

Creates a new scope for Order context. Used for advanced use cases when multiple Order instances need to be nested.

Returns

Scope - A new scope identifier for Order context

Basic Usage

Simple Order Display

import { Order } from '@haus-storefront-react/order'
import { Price } from '@haus-storefront-react/common-ui'

function OrderConfirmation({ orderCode }) {
return (
<Order.Root orderCode={orderCode}>
{({ order, isLoading, error, isError, isSuccess }) => (
<div>
{isLoading && <div>Loading...</div>}
{isError && error && <div>Error: {error.message}</div>}

{isSuccess && order && (
<div>
<h2>Thank you for your order!</h2>
<p>Order #{order.code}</p>
<p>
Placed on {new Date(order.orderPlacedAt).toLocaleDateString()}
</p>
<p>Status: {order.state}</p>

<Order.Items.Root>
{({ orderLines }) =>
orderLines?.map((line) => (
<Order.Items.Item key={line.id} orderLine={line}>
<Order.Items.Image />
<Order.Items.Price />
<span>{line.quantity} x</span>
</Order.Items.Item>
))
}
</Order.Items.Root>

<Order.Summary>
{({ totalPrice, currencyCode }) => (
<div>
<p>
Total: {totalPrice} {currencyCode}
</p>
</div>
)}
</Order.Summary>
</div>
)}
</div>
)}
</Order.Root>
)
}

Basic Hook Usage

The Order component uses hooks internally via useOrderProps. For direct order fetching, use hooks from @haus-storefront-react/hooks:

import { useOrderByCode } from '@haus-storefront-react/hooks'

function MyComponent({ orderCode }) {
const { data: order, isLoading, error } = useOrderByCode(orderCode)

if (isLoading) return <div>Loading...</div>
if (error) return <div>Error: {error.message}</div>
if (!order) return <div>Order not found</div>

return (
<div>
<h1>Order #{order.code}</h1>
<p>Status: {order.state}</p>
</div>
)
}

Advanced Usage

Using Order.Field for Custom Display

import { Order } from '@haus-storefront-react/order'

function OrderWithCustomFields({ orderCode }) {
return (
<Order.Root orderCode={orderCode}>
{({ order, isLoading, isSuccess }) => {
if (!isSuccess || !order) return null

return (
<div>
<Order.Field field='code'>
{({ value, formattedValue }) => (
<h1>Order #{formattedValue}</h1>
)}
</Order.Field>

<Order.Field
field='orderPlacedAt'
formatter={(value) => new Date(value).toLocaleDateString()}
>
{({ formattedValue }) => <p>Placed on {formattedValue}</p>}
</Order.Field>

<Order.Field field='state'>
{({ value }) => (
<span className={`status status-${value?.toLowerCase()}`}>
{value}
</span>
)}
</Order.Field>

<Order.Field field='totalQuantity'>
{({ value }) => <p>Total items: {value}</p>}
</Order.Field>
</div>
)
}}
</Order.Root>
)
}

Order History List

import { Order } from '@haus-storefront-react/order'
import { useActiveCustomerOrders } from '@haus-storefront-react/hooks'
import { Price } from '@haus-storefront-react/common-ui'

function OrderHistory() {
const {
data: orders,
isLoading,
error,
} = useActiveCustomerOrders({
take: 20,
})

if (isLoading) return <div>Loading orders...</div>
if (error) return <div>Error: {error.message}</div>
if (!orders?.items.length) return <div>No orders found</div>

return (
<div className='order-history'>
<h1>Order History</h1>

{orders.items.map((order) => (
<Order.Root key={order.id} orderCode={order.code}>
{({ order: orderData, isLoading: orderLoading, isSuccess }) => (
<div className='order-history-item'>
{orderLoading && <div>Loading order details...</div>}

{isSuccess && orderData && (
<>
<div className='order-header'>
<h3>Order #{orderData.code}</h3>
<span className='order-date'>
{new Date(orderData.orderPlacedAt).toLocaleDateString()}
</span>
</div>

<div className='order-summary'>
<div className='order-items-count'>
{orderData.totalQuantity} items
</div>

<div className='order-total'>
<Price.Root
price={orderData.total}
priceWithTax={orderData.totalWithTax}
currencyCode={orderData.currencyCode}
>
<Price.Amount withCurrency />
</Price.Root>
</div>

<div className='order-status'>
<span
className={`status-badge status-${orderData.state.toLowerCase()}`}
>
{orderData.state}
</span>
</div>
</div>

<div className='order-actions'>
<a href={`/orders/${orderData.code}`}>View Details</a>
</div>
</>
)}
</div>
)}
</Order.Root>
))}
</div>
)
}

Conditional Rendering Patterns

import { Order } from '@haus-storefront-react/order'
import { Price } from '@haus-storefront-react/common-ui'

function ConditionalOrderDisplay({ orderCode }) {
return (
<Order.Root orderCode={orderCode}>
{({ order, isLoading, isError, isSuccess }) => {
if (isLoading) {
return (
<div className='order-loading'>
<div className='spinner' />
<p>Loading order details...</p>
</div>
)
}

if (isError || !isSuccess) {
return (
<div className='order-error'>
<p>Unable to load order details.</p>
<button onClick={() => window.location.reload()}>
Try Again
</button>
</div>
)
}

if (!order) {
return (
<div className='order-not-found'>
<p>Order not found.</p>
</div>
)
}

return (
<div className='order-display'>
<div className='order-header'>
<h1>Order #{order.code}</h1>
<Order.Field field='state'>
{({ value }) => (
<span className={`badge badge-${value?.toLowerCase()}`}>
{value}
</span>
)}
</Order.Field>
</div>

<Order.Items.Root>
{({ orderLines }) =>
orderLines && orderLines.length > 0 ? (
orderLines.map((line) => (
<Order.Items.Item key={line.id} orderLine={line}>
<Order.Items.Image />
<div className='item-info'>
<h3>{line.productVariant.product.name}</h3>
<p>Quantity: {line.quantity}</p>
</div>
<Order.Items.Price />
</Order.Items.Item>
))
) : (
<p>No items in this order</p>
)
}
</Order.Items.Root>

{order.shippingLines && order.shippingLines.length > 0 ? (
<Order.ShippingLines>
{({ shippingLines }) => (
<div className='shipping-section'>
<h2>Shipping</h2>
{shippingLines.map((shippingLine) => (
<Order.ShippingLine
key={shippingLine.id || shippingLine.shippingMethod.id}
shippingLine={shippingLine}
>
{({ name, price, priceWithTax, currencyCode }) => (
<div className='shipping-line'>
<span>{name}</span>
<Price.Root
price={price}
priceWithTax={priceWithTax}
currencyCode={currencyCode}
>
<Price.Amount withCurrency />
</Price.Root>
</div>
)}
</Order.ShippingLine>
))}
</div>
)}
</Order.ShippingLines>
) : (
<p>No shipping information available</p>
)}

<Order.Summary>
{({ totalPrice, totalWithTax, currencyCode }) => (
<div className='order-total'>
<h2>Total</h2>
<Price.Root
price={totalPrice}
priceWithTax={totalWithTax}
currencyCode={currencyCode}
>
<Price.Amount withCurrency />
</Price.Root>
</div>
)}
</Order.Summary>
</div>
)
}}
</Order.Root>
)
}

Made with ❤️ by Haus Tech Team