# salla-order-options-modal (https://docs.salla.dev/twilight/react/web-components/salla-order-options-modal)



{/* Generated by scripts/sync-web-components.mjs from the components docs.json. Do not edit by hand. */}

Imperative modal that collects a product's order options (the store-level options a shopper must pick
before checkout) and, when an offer grants free products, the options of each free product.
Salla add-to-cart and gifting flows open it for you. A theme calls it only to build a custom checkout flow.
Place one `<salla-order-options-modal>` on the page and call `open()`.

Steps: when free products with options are passed, the modal shows one step per free product, then a
final step for the order options. With only one step there is no step bar. Free products without options
are skipped. `freeProducts` is a list, so there can be several free-product steps.

With `paymentMode: 'apple-pay'` the last step shows an Apple Pay button and the total instead of the
Continue button. Pass `onSubmit` to start the payment session; it is called synchronously on submit.

`open()` resolves when the shopper submits and rejects with `{ reason: 'dismissed' }` when the modal is closed.

## Use it [#use-it]

In HTML or JSX, use the tag `<salla-order-options-modal>` with the **Attribute** names below. In React, the wrapper takes the **Property** names (camelCase).

```tsx
import { SallaOrderOptionsModal } from '@salla.sa/twilight-components-react/order-options-modal';
```

## Example [#example]

```ts
const modal = document.querySelector('salla-order-options-modal');
try {
  const { orderOptions, freeProducts } = await modal.open({
    orderOptions,   // product options array for the store-level step
    freeProducts,   // optional: [{ product, options, offer_name, quantity }]
    basePrice: 120,
  });
  // orderOptions: [{ id, value }]
  // freeProducts: [{ productId, quantity, options: { [optionId]: value } }]
} catch (e) {
  // e.reason === 'dismissed'
}
```

## Methods [#methods]

Call these on the element or a React ref.

### `close() => Promise<void>` [#close--promisevoid]

Closes the modal. If `open()` is still waiting, its promise rejects with `{ reason: 'dismissed' }`.

### `open(payload: { orderOptions: any[]; freeProducts?: any[]; freeProductOptions?: any[]; freeProduct?: any; basePrice?: number; paymentMode?: "default" | "apple-pay"; onSubmit?: (orderOptions: OrderOptionEntry[], total: number, freeProducts: FreeProductSelection[]) => void; }) => Promise<{ orderOptions: OrderOptionEntry[]; freeProductOptions: OrderOptionEntry[]; freeProducts: FreeProductSelection[]; }>` [#openpayload--orderoptions-any-freeproducts-any-freeproductoptions-any-freeproduct-any-baseprice-number-paymentmode-default--apple-pay-onsubmit-orderoptions-orderoptionentry-total-number-freeproducts-freeproductselection--void---promise-orderoptions-orderoptionentry-freeproductoptions-orderoptionentry-freeproducts-freeproductselection-]

Opens the modal and waits for the shopper to finish.

| Parameter | Type                                                                                                                                                                                                                                                                    | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `payload` | `{ orderOptions: any[]; freeProducts?: any[]; freeProductOptions?: any[]; freeProduct?: any; basePrice?: number; paymentMode?: "default" \| "apple-pay"; onSubmit?: (orderOptions: OrderOptionEntry[], total: number, freeProducts: FreeProductSelection[]) => void; }` | What to ask for. `orderOptions` is the array of store-level product options for the final step. `freeProducts` is an optional list of `{ product, options, offer_name, quantity }`, one step each (entries with no options are skipped). `basePrice` is the product price in the store currency, used for the live total (default 0). `paymentMode` is `'default'` (Continue button) or `'apple-pay'` (Apple Pay button on the last step). `onSubmit(orderOptions, total, freeProducts)` is called synchronously on the last submit, before the promise resolves; the total includes all picked surcharges. `freeProduct` and `freeProductOptions` are the old single-gift form; use `freeProducts` instead. |

Returns `Promise<{ orderOptions: OrderOptionEntry[]; freeProductOptions: OrderOptionEntry[]; freeProducts: FreeProductSelection[]; }>`: A Promise that resolves with `{ orderOptions: [{ id, value }], freeProductOptions, freeProducts: [{ productId, quantity, options }] }` after the last step is submitted, and rejects with `{ reason: 'dismissed' }` if the shopper closes the modal first.

## Related [#related]

Renders: [`<salla-modal>`](https://docs.salla.dev/twilight/react/web-components/salla-modal), [`<salla-product-options>`](https://docs.salla.dev/twilight/react/web-components/salla-product-options), [`<salla-button>`](https://docs.salla.dev/twilight/react/web-components/salla-button).

Used inside: [`<salla-gifting>`](https://docs.salla.dev/twilight/react/web-components/salla-gifting), [`<salla-quick-buy>`](https://docs.salla.dev/twilight/react/web-components/salla-quick-buy).
