@haus-storefront-react/add-item-to-order
v0.0.50
Published
A headless component for managing adding items to an order with support for pre-operation callbacks, quantity controls, and cart state management. Built with TypeScript, accessibility-first design, and platform-agnostic architecture.
Readme
Add Item to Order Component
A headless component for managing adding items to an order with support for pre-operation callbacks, quantity controls, and cart state management. Built with TypeScript, accessibility-first design, and platform-agnostic architecture.
Installation
npm install @haus-storefront-react/add-item-to-order
# or
yarn add @haus-storefront-react/add-item-to-orderUsage Example
import { AddItemToOrder } from '@haus-storefront-react/add-item-to-order'
// Basic usage
<AddItemToOrder.Root productVariantId="123">
{({ isInCart, isLoading, error }) => (
<>
{!isInCart && (
<AddItemToOrder.Button>
{isLoading ? 'Adding...' : 'Add to cart'}
</AddItemToOrder.Button>
)}
{isInCart && (
<AddItemToOrder.Quantity.Root>
<AddItemToOrder.Quantity.Decrement>-</AddItemToOrder.Quantity.Decrement>
<AddItemToOrder.Quantity.Input />
<AddItemToOrder.Quantity.Increment>+</AddItemToOrder.Quantity.Increment>
</AddItemToOrder.Quantity.Root>
)}
{error && <div>Error: {error.message}</div>}
</>
)}
</AddItemToOrder.Root>
// With preAdd and preAdjust callbacks
<AddItemToOrder.Root
productVariantId="123"
callbacks={{
preAdd: async (productVariantId, quantity) => {
// Custom validation before adding item
if (quantity > 10) {
throw new Error('Cannot add more than 10 items')
}
// Show confirmation dialog
const confirmed = await showConfirmationDialog()
if (!confirmed) {
throw new Error('User cancelled')
}
},
preAdjust: async (orderLineId, quantity) => {
// Custom validation before adjusting quantity
if (quantity > 15) {
throw new Error('Maximum quantity is 15')
}
// Log the adjustment
console.log(`Adjusting order line ${orderLineId} to quantity ${quantity}`)
}
}}
>
{/* Component content */}
</AddItemToOrder.Root>Features
- 🛒 Add items to cart with quantity controls
- ⚡ Pre-operation callbacks for validation and custom logic
- ♿ Accessibility-first, platform-agnostic
- 🔄 Real-time cart state management
- 🎨 Headless, fully customizable
- ⚡ TypeScript support
- 🚫 Error handling with user-friendly messages
API Reference
<AddItemToOrder.Root>
Root component that provides context for all child components.
Props:
productVariantId: string– The ID of the product variant to add to the ordercallbacks?: { preAdd?, preAdjust? }– Optional callbacks for custom logic before operationsorderFilter?: (order: Order) => Order– Optional function to modify the order before cart checks (acts like a modifyData hook)children: (context) => ReactNode– Render prop with component context
Context Value:
productVariantId: string– The product variant IDisInCart: boolean– Whether the item is currently in the cartisLoading: boolean– Whether an operation is in progresserror: Error | null– Any error that occurredaddItemToOrder: (quantity: number) => Promise<Order>– Function to add item to cartorderLineId?: string– The order line ID if item is in cartcallbacks?: object– The callbacks passed to the Root component
Modifying data (modifyData) with orderFilter
Use orderFilter to transform the order before the component derives its state.
The function receives the current order and must return a new order object.
The returned value is used to compute isInCart and orderLineId.
Useful for filtering duplicate productVariant IDs — for example, exclude "gift" lines while letting the regular line be handled by AddItemToOrder.
<AddItemToOrder.Root
productVariantId={variant.id}
orderFilter={(order) => ({
...order,
// Example: exclude gift lines from cart state
lines: order.lines.filter((line) => !line.customFields?.gift),
})}
>
{/* ... */}
</AddItemToOrder.Root><AddItemToOrder.Button>
Button component for adding an item to the order.
Props:
- Accepts all standard button props
asChild?: boolean– Render as a different element
<AddItemToOrder.Quantity.Root>
Quantity controls for adjusting the quantity of an item in the order.
Props:
min?: number– Minimum quantity (default: 1)max?: number– Maximum quantitystep?: number– Step size for quantity changes (default: 1)children: ReactNode– Child components
<AddItemToOrder.Quantity.Decrement>
Decrease quantity button.
<AddItemToOrder.Quantity.Increment>
Increase quantity button.
<AddItemToOrder.Quantity.Input>
Quantity input field.
Callbacks
preAdd Callback
Called before adding an item to the order.
preAdd?: (productVariantId: string, quantity: number) => Promise<void>Parameters:
productVariantId: string– The product variant IDquantity: number– The quantity to add
Usage Examples:
// Validation example
preAdd: async (productVariantId, quantity) => {
if (quantity > 10) {
throw new Error('Cannot add more than 10 items')
}
}
// Confirmation example
preAdd: async (productVariantId, quantity) => {
const confirmed = await showConfirmationDialog()
if (!confirmed) {
throw new Error('User cancelled')
}
}
// API call example
preAdd: async (productVariantId, quantity) => {
await validateInventory(productVariantId, quantity)
}preAdjust Callback
Called before adjusting the quantity of an existing order line.
preAdjust?: (orderLineId: string, quantity: number) => Promise<void>Parameters:
orderLineId: string– The order line IDquantity: number– The new quantity
Usage Examples:
// Validation example
preAdjust: async (orderLineId, quantity) => {
if (quantity > 15) {
throw new Error('Maximum quantity is 15')
}
}
// Logging example
preAdjust: async (orderLineId, quantity) => {
console.log(`Adjusting order line ${orderLineId} to quantity ${quantity}`)
await logQuantityChange(orderLineId, quantity)
}
// Business logic example
preAdjust: async (orderLineId, quantity) => {
if (quantity === 0) {
const confirmed = await confirmRemoval()
if (!confirmed) {
throw new Error('User cancelled removal')
}
}
}Error Handling
When callbacks throw an error, the operation is cancelled and the error is displayed to the user. Common error scenarios:
- Validation errors – Quantity limits, inventory checks
- User cancellation – Confirmation dialogs
- Business logic errors – Custom validation rules
Integration with Other Components
This component is designed to work seamlessly with other components in the ecosystem:
- ProductList – Automatically includes callbacks through
UseAddItemToOrderProps - OrderLines – Uses similar callback patterns for consistency
- Cart components – Real-time state updates
Running unit tests
Run nx test store/components/add-item-to-order to execute the unit tests via Vitest.
