-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop' into USF-894-adyen-integration
- Loading branch information
Showing
12 changed files
with
869 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
253 changes: 253 additions & 0 deletions
253
src/content/docs/dropins/cart/tutorials/order-summary-lines.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,253 @@ | ||
--- | ||
title: Order Summary Lines | ||
description: Learn how to customize the lines of the Order Summary of the Cart drop-in component. | ||
--- | ||
|
||
import Diagram from '@components/Diagram.astro'; | ||
|
||
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](https://elsie.dev/?path=/docs/components-accordion--overview) from [Elsie](https://elsie.dev/). | ||
|
||
:::note[Note] | ||
The elsie.dev site is currently available to partners only. | ||
::: | ||
|
||
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. | ||
|
||
```typescript | ||
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. | ||
|
||
```typescript | ||
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: | ||
```typescript | ||
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: | ||
|
||
```typescript | ||
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: | ||
```html | ||
<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. | ||
|
||
```typescript | ||
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. | ||
|
||
```typescript | ||
// 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: | ||
<Diagram caption="Cart without any customization"> | ||
![Cart without any customization](@images/dropins/cart/cart-originally.png) | ||
</Diagram> | ||
### Remove Item: Remove total saved | ||
The following example removes the Total saved line: | ||
```typescript | ||
updateLineItems: (lineItems) => { | ||
const index = lineItems.map(item => item.key).indexOf('totalSavedContent'); | ||
lineItems.splice(index, 1); | ||
|
||
return lineItems; | ||
} | ||
``` | ||
<Diagram caption="Cart after removing Total Saved line"> | ||
![Cart after removing Total Saved line](@images/dropins/cart/cart-after-remove-item.png) | ||
</Diagram> | ||
### Reorder items: Move primary action to the beginning | ||
The following example moves the Checkout button to the top: | ||
```typescript | ||
updateLineItems: (lineItems) => { | ||
lineItems.map(lineItem => { | ||
if (lineItem.key === 'primaryActionContent') { | ||
lineItem.sortOrder = 50; | ||
} | ||
return lineItem; | ||
}); | ||
|
||
return lineItems; | ||
}; | ||
``` | ||
<Diagram caption="Cart after moving primary action to the beginning"> | ||
![Cart after moving primary action to the beginning](@images/dropins/cart/cart-after-reorder-items.png) | ||
</Diagram> | ||
### Group items: Group subtotal and tax in an accordion | ||
The following example groups the subtotal and tax in an accordion: | ||
```typescript | ||
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; | ||
} | ||
``` | ||
<Diagram caption="Cart after grouping subtotal and tax in an accordion"> | ||
![Cart after grouping subtotal and tax in an accordion](@images/dropins/cart/cart-after-group-items.png) | ||
</Diagram> | ||
### Add item: Add a new order summary line | ||
The following example adds the FPT line: | ||
```typescript | ||
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; | ||
}; | ||
``` | ||
<Diagram caption="Cart after adding a new order summary line"> | ||
![Cart after adding a new order summary line](@images/dropins/cart/cart-after-add-item.png) | ||
</Diagram> |
Oops, something went wrong.