Commerce
PluginCart
A catalog the reader picks from, beside a summary of what they picked and what it costs. It searches and filters the catalog, shows how far the selection is from the next volume discount, and renders the price your server sends back.
Example
Pick a few items and watch the summary. The names and prices are sample data, and a small function in the example stands in for the pricing endpoint. The cart lays itself out by the width it has: the summary beside the catalog on a wide screen, and under it on a narrow one, with a bar at the bottom that keeps the count and the total in sight. The example runs in a frame of its own, so it sees the width of this column rather than of the window.
The price comes from your server
The cart never adds up a price. It sends nothing either: when the selection changes it calls onchange, your page asks its server, and the answer goes back in as quote. Set quoting while the request is out and the summary shows a spinner.
A quote whose items or period no longer match the selection is not shown, so a stale total never sits
beside a changed cart.
Each pick is a real checkbox named by fieldName, so inside a form the selection posts
with no JavaScript at all.
Volume discounts
brackets is the discount ladder: how many picks earn which discount. The summary
draws the ladder as a meter and says how many more picks reach the next rung. The kit exports the
same reading as functions for a page that shows it elsewhere: ladderState for where a
count stands, ladderRows for a table of the rungs, billedCount for the
count a bill carries and formatCents for showing money.
Your own summary
A page that prices more than the selection, such as a plan change or a discount code, passes a summary snippet. It replaces everything inside the aside: the title line, the error,
the list, the ladder, the total, notice and actions. The aside keeps its
id, its stickiness and the bar that jumps to it on a narrow screen. The snippet receives the
selected SKUs, the server total and a remove function that takes one SKU out and
reports it through onchange, as unticking its card does. The total is null both while
a price is in flight and before one is asked for, so a page that tells the two apart tracks its
own request. heading names the panel for assistive technology and atop the default summary.
A one-time payment is quoted monthly and charged once. Pass per="once" and the total reads
"$6.00 once" instead of promising a renewal with "/mo".
API
| Prop | Type | Default | Description |
|---|---|---|---|
plugins required | CartPlugin[] | no default | The catalog: every item on sale, with its price in integer cents. |
brackets | DiscountBracket[] | [] | The volume discount ladder. |
selected | Set<string> | no default | The SKUs the reader has picked. Bindable, so the page can price them. |
initial | string[] | [] | Picks carried over from another page's cart. They seed selected. |
held | string[] | [] | SKUs the reader already pays for. Shown as owned, never added twice. |
quote | CartQuote | null | null | The server's price for the selection, or null before one exists. |
quotePeriod | 'monthly' | 'annual' | null | null | The period the quote was priced for. A monthly quote is not shown for a year. |
period | 'monthly' | 'annual' | 'monthly' | The billing period the summary shows. |
per | 'monthly' | 'annual' | 'once' | period | What the total is charged per, when it differs from period. A one-time payment passes 'once', so its total reads "$6.00 once" rather than "$6.00/mo". |
charged | number | null | null | What the order charges, in cents, when the host prices more than the selection, such as a discount code. It stands in for the quote total in the bar and the default summary, and is the total the summary and actions snippets receive. It counts only while quote describes the selection. |
quoting | boolean | false | True while a fresh price is on its way. |
billedSkus | string[] | null | null | The SKUs the bill will carry, when the page knows them better than the cart. |
currency | string | 'USD' | The currency the prices are shown in. |
fieldName | string | 'sku' | The form field each checkbox posts under. |
error | string | null | null | A message at the top of the summary. |
quickPicks | QuickPick[] | [] | Buttons that each replace the selection with a set of SKUs. |
onchange | (skus: string[]) => void | no default | Called with the new selection whenever it changes. |
actions | Snippet<[{ skus: string[]; total: number | null }]> | no default | Your call to action, under the total. |
notice | Snippet | no default | Anything between the total and the actions. |
summary | Snippet<[{ skus: string[]; total: number | null; remove: (sku: string) => void }]> | no default | Your own summary, drawn in place of everything inside the aside. remove takes one selected SKU out and reports it through onchange. |
heading | string | 'Your selection' | The panel's name: the aside's accessible name, also printed atop the default summary. |
stickyTop | string | '1rem' | How far below the top of the window the summary sticks on a wide screen. A page with a sticky header passes its height. |
class | string | no default | Extra classes on the wrapper. |