Order Summary Lines
The Cart dropin allows you to customize the lines of the Order Summary to meet your requirements.
You might want to group and sort the order summary lines into sections using the native Accordion component from Elsie.
You can specify the line items shown in the accordion and decide the order in which they are displayed. You can also customize the title and content of these order summary lines.
Customize the lines of the Order Summary to meet your needs
This customization is possible thanks to the attribute updateLineItems from the OrderSummary container. This attribute allows you to modify the order summary lines before they are rendered.
export const OrderSummary: Container<OrderSummaryProps, CartModel | null> = ({ ... updateLineItems = (lineItems) => lineItems, ...});It doesn’t matter if you want to customize the existing order summary lines, add new ones, or skip some of them.
The OrderSummary container passes the updateLineItems to the OrderSummary component, which performs the appropriate actions.
updateLineItems is an optional function that receives the line items as an argument and returns the updated line items. In both cases, lineItems are an array of OrderSummaryLineItem object.
export interface OrderSummaryLineItem { key: string; title?: string; className?: string; sortOrder: number; content: | string | JSXInternal.Element | VNode<HTMLAttributes<HTMLDivElement>> | OrderSummaryLineItem[] | undefined;}There are default order summary lines in the OrderSummary component. If no customization is needed, and therefore nothing is passed using the updateLineItems attribute, the default order summary lines will be rendered.
Let’s imagine that lineItems contains the following lines:
const lineItems: Array<OrderSummaryLineItem> = [ { key: 'subTotalContent', sortOrder: 100, content: subTotalContent, }, { key: 'discountsContent', sortOrder: 300, content: discountsContent, }, { key: 'taxContent', sortOrder: 400, content: taxContent, }, ];In the example above, the OrderSummary component renders the sub-total, discounts, and tax lines, in that order.
The value of the sortOrder attribute determines the order in which the lines are rendered.
The larger the sortOrder value, the lower the line will be rendered in the order summary.
The content attribute can be a string, a JSX element, or an array of OrderSummaryLineItem objects (whenever is not undefined).
For instance, you could choose to render a JSX element in a form of a OrderSummaryLine container.
This OrderSummaryLine container it is defined as follows:
export interface OrderSummaryLineProps extends HTMLAttributes<HTMLDivElement> { label: string; price: VNode<HTMLAttributes<HTMLSpanElement>>; classSuffixes?: Array<string>; labelClassSuffix?: string; testId?: string; children?: any;}See an example of how to use the OrderSummaryLine container below, where only the mandatory props are passed:
<OrderSummaryLine label={translations.subtotalLabel} price={subTotal.price} classSuffixes={['subTotal']} > {children} </OrderSummaryLine> );Note that the OrderSummaryLine container behaves like a wrapper for the OrderSummaryLine component.
The component ultimately decides how to render the line item based on the children attribute.
export interface OrderSummaryLineComponentProps extends HTMLAttributes<HTMLDivElement> { label: string; price: VNode<HTMLAttributes<HTMLSpanElement>>; classSuffixes?: Array<string>; labelClassSuffix?: string; testId?: string; children?: any;}Where to perform the customizations
To customize the order summary lines, you need to render the Cart component passing the OrderSummary component as a slot.
When rendering the OrderSummary component, you can pass the updateLineItems attribute to customize the order summary lines as needed.
// Cart provider.render(Cart, { slots: { OrderSummary: (ctx) => { const orderSummary = document.createElement('div');
provider.render(OrderSummary, { updateLineItems: (lineItems) => { // Customize the order summary lines here return lineItems; } } } } });Examples
For the examples shown below, assume that this is how Order Summary looks originally:

Remove Item: Remove total saved
The following example removes the Total saved line:
updateLineItems: (lineItems) => { const index = lineItems.map(item => item.key).indexOf('totalSavedContent'); lineItems.splice(index, 1);
return lineItems;}
Reorder items: Move primary action to the beginning
The following example moves the Checkout button to the top:
updateLineItems: (lineItems) => { lineItems.map(lineItem => { if (lineItem.key === 'primaryActionContent') { lineItem.sortOrder = 50; } return lineItem; });
return lineItems;};
Group items: Group subtotal and tax in an accordion
The following example groups the subtotal and tax in an accordion:
updateLineItems: (lineItems) => { const totalsIndex = lineItems.map(item => item.key).indexOf('taxContent'); const taxContent = lineItems.splice(totalsIndex, 1)[0]; const subtotalIndex = lineItems.map(item => item.key).indexOf('subTotalContent'); const subTotalContent = lineItems.splice(subtotalIndex, 1)[0]; lineItems.push({ key: 'subtotalTaxGrouped', sortOrder: 50, title: 'Subtotal and Tax', content: [ taxContent, subTotalContent, ], });
return lineItems;}
Add item: Add a new order summary line
The following example adds the FPT line:
updateLineItems: (lineItems) => { const totalFpt = ctx.data.items.reduce((allItemsFpt, item) => { const itemFpt = item.fixedProductTaxes.reduce((accumulator, fpt) => { accumulator.labels.push(fpt.label); accumulator.total += fpt.amount.value; return accumulator; }, { labels: [], total: 0 }); allItemsFpt.labels = [...allItemsFpt.labels, ...itemFpt.labels]; allItemsFpt.total += itemFpt.total; return allItemsFpt; }, { labels: [], total: 0 });
lineItems.push({ key: 'fpt', sortOrder: 350, title: 'Fixed Product Tax', content: OrderSummaryLine({label: "FPT(" + totalFpt.labels.join(',') + ')', price: Price({amount: totalFpt.total}), classSuffix: 'fpt'}) })
return lineItems;};