@nok-integration/storefront-react 0.16.5 → 0.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -24,15 +24,15 @@ declare type AddCartItemRequest = z.infer<typeof AddCartItemRequest>;
24
24
 
25
25
  /** The `error` member — a machine `code`, a human `message`, and optional `details`. */
26
26
  declare const ApiErrorBody: z.ZodObject<{
27
- code: z.ZodEnum<["invalid_request", "unauthorized", "out_of_stock", "cart_locked", "sku_not_found", "category_not_found", "amount_mismatch", "duplicate_order", "order_not_found", "order_not_cancellable", "cart_not_found", "forbidden", "invalid_transition", "rate_limited", "server_error"]>;
27
+ code: z.ZodEnum<["invalid_request", "unauthorized", "out_of_stock", "cart_locked", "sku_not_found", "category_not_found", "amount_mismatch", "duplicate_order", "order_not_found", "order_not_cancellable", "cart_not_found", "support_ticket_not_found", "forbidden", "invalid_transition", "rate_limited", "server_error"]>;
28
28
  message: z.ZodString;
29
29
  details: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
30
30
  }, "strip", z.ZodTypeAny, {
31
- code: "invalid_request" | "unauthorized" | "out_of_stock" | "cart_locked" | "sku_not_found" | "category_not_found" | "amount_mismatch" | "duplicate_order" | "order_not_found" | "order_not_cancellable" | "cart_not_found" | "forbidden" | "invalid_transition" | "rate_limited" | "server_error";
31
+ code: "invalid_request" | "unauthorized" | "out_of_stock" | "cart_locked" | "sku_not_found" | "category_not_found" | "amount_mismatch" | "duplicate_order" | "order_not_found" | "order_not_cancellable" | "cart_not_found" | "support_ticket_not_found" | "forbidden" | "invalid_transition" | "rate_limited" | "server_error";
32
32
  message: string;
33
33
  details?: Record<string, unknown> | undefined;
34
34
  }, {
35
- code: "invalid_request" | "unauthorized" | "out_of_stock" | "cart_locked" | "sku_not_found" | "category_not_found" | "amount_mismatch" | "duplicate_order" | "order_not_found" | "order_not_cancellable" | "cart_not_found" | "forbidden" | "invalid_transition" | "rate_limited" | "server_error";
35
+ code: "invalid_request" | "unauthorized" | "out_of_stock" | "cart_locked" | "sku_not_found" | "category_not_found" | "amount_mismatch" | "duplicate_order" | "order_not_found" | "order_not_cancellable" | "cart_not_found" | "support_ticket_not_found" | "forbidden" | "invalid_transition" | "rate_limited" | "server_error";
36
36
  message: string;
37
37
  details?: Record<string, unknown> | undefined;
38
38
  }>;
@@ -252,6 +252,11 @@ export { CartSheetProvider }
252
252
  /**
253
253
  * Opens the cart as a bottom sheet.
254
254
  *
255
+ * Carries `data-shop-cart-trigger` in both forms. That is what the added-to-cart toast
256
+ * aims its caret at (Figma `.base/indicator`), and it has to survive the anchor/button
257
+ * split — the arrow points at the cart control, not at whichever element we happened to
258
+ * render it as.
259
+ *
255
260
  * Falls back to a link to `/cart` when no {@link CartSheetProvider} is above it, so the
256
261
  * cart is always reachable — including with JS unavailable, where the anchor still
257
262
  * navigates. The route renders the same CartView, so the fallback is the same cart, not
@@ -2067,6 +2072,10 @@ declare function createClient(options: ClientOptions): {
2067
2072
  attributes?: Record<string, string> | undefined;
2068
2073
  image?: string | undefined;
2069
2074
  title?: string | undefined;
2075
+ compare_at_unit_price?: {
2076
+ amount: number;
2077
+ currency: string;
2078
+ } | undefined;
2070
2079
  }[];
2071
2080
  totals: {
2072
2081
  shipping: {
@@ -2085,6 +2094,10 @@ declare function createClient(options: ClientOptions): {
2085
2094
  amount: number;
2086
2095
  currency: string;
2087
2096
  };
2097
+ discount?: {
2098
+ amount: number;
2099
+ currency: string;
2100
+ } | undefined;
2088
2101
  };
2089
2102
  order_ref: string;
2090
2103
  placed_at: string;
@@ -2104,6 +2117,7 @@ declare function createClient(options: ClientOptions): {
2104
2117
  current: boolean;
2105
2118
  at?: string | undefined;
2106
2119
  }[];
2120
+ email?: string | undefined;
2107
2121
  payment?: {
2108
2122
  brand: string;
2109
2123
  last4?: string | undefined;
@@ -2119,6 +2133,30 @@ declare function createClient(options: ClientOptions): {
2119
2133
  } | undefined;
2120
2134
  }>;
2121
2135
  };
2136
+ /**
2137
+ * The Help Center form (ADR-0021). Session-scoped: the ticket is filed against the
2138
+ * fan already signed in, and there is no parameter that names a different one.
2139
+ */
2140
+ support: {
2141
+ /**
2142
+ * Upload the one attachment and get the URL to put on the ticket.
2143
+ *
2144
+ * Call this first, then pass the returned `url` as `image_url`. Uploading nothing is
2145
+ * the normal case — the field is optional and the form's Send button does not wait
2146
+ * on it.
2147
+ */
2148
+ uploadAttachment: (file: Blob) => Promise<{
2149
+ url: string;
2150
+ content_type: string;
2151
+ bytes: number;
2152
+ }>;
2153
+ /** File the ticket. Repeating an identical one within a few minutes returns the first. */
2154
+ createTicket: (body: SupportTicketRequest) => Promise<{
2155
+ category: string;
2156
+ reference: string;
2157
+ created_at: string;
2158
+ }>;
2159
+ };
2122
2160
  auth: {
2123
2161
  /** Exchange a single-use DAZN identity JWT for a session (sets the cookie). */
2124
2162
  exchangeSession: (body: SessionExchangeRequest) => Promise<{
@@ -2284,7 +2322,7 @@ export declare interface EmptyStateProps {
2284
2322
  * | rate_limited | 429 | too many requests |
2285
2323
  * | server_error | 500 | unexpected error (safe to retry idempotent) |
2286
2324
  */
2287
- declare const ErrorCode: z.ZodEnum<["invalid_request", "unauthorized", "out_of_stock", "cart_locked", "sku_not_found", "category_not_found", "amount_mismatch", "duplicate_order", "order_not_found", "order_not_cancellable", "cart_not_found", "forbidden", "invalid_transition", "rate_limited", "server_error"]>;
2325
+ declare const ErrorCode: z.ZodEnum<["invalid_request", "unauthorized", "out_of_stock", "cart_locked", "sku_not_found", "category_not_found", "amount_mismatch", "duplicate_order", "order_not_found", "order_not_cancellable", "cart_not_found", "support_ticket_not_found", "forbidden", "invalid_transition", "rate_limited", "server_error"]>;
2288
2326
 
2289
2327
  declare type ErrorCode = z.infer<typeof ErrorCode>;
2290
2328
 
@@ -2307,7 +2345,7 @@ declare type ErrorCode = z.infer<typeof ErrorCode>;
2307
2345
  * | rate_limited | 429 | too many requests |
2308
2346
  * | server_error | 500 | unexpected error (safe to retry idempotent) |
2309
2347
  */
2310
- declare const ErrorCode_2: z.ZodEnum<["invalid_request", "unauthorized", "out_of_stock", "cart_locked", "sku_not_found", "category_not_found", "amount_mismatch", "duplicate_order", "order_not_found", "order_not_cancellable", "cart_not_found", "forbidden", "invalid_transition", "rate_limited", "server_error"]>;
2348
+ declare const ErrorCode_2: z.ZodEnum<["invalid_request", "unauthorized", "out_of_stock", "cart_locked", "sku_not_found", "category_not_found", "amount_mismatch", "duplicate_order", "order_not_found", "order_not_cancellable", "cart_not_found", "support_ticket_not_found", "forbidden", "invalid_transition", "rate_limited", "server_error"]>;
2311
2349
 
2312
2350
  declare type ErrorCode_2 = z.infer<typeof ErrorCode_2>;
2313
2351
 
@@ -2530,6 +2568,37 @@ export declare type Navigate = (to: ShopRoute) => void;
2530
2568
  */
2531
2569
  export declare type OnEvent = (event: ShopEvent) => void;
2532
2570
 
2571
+ /**
2572
+ * The order confirmation (Figma `5295:74053`).
2573
+ *
2574
+ * **A different screen from `OrderTrackingView`, not a state of it**, which is the answer
2575
+ * to the question DAZN asked on 20 Aug 2026. The two frames differ in their chrome
2576
+ * (close-only against back + cart + overflow), in their headline, and in their footer
2577
+ * action, and nothing in the payload can tell them apart: `status` is a fulfilment step
2578
+ * and cannot say "has just come back from paying", and time-since-placed guesses wrong for
2579
+ * anyone who opens the email an hour later. So the two screens are two routes, and the one
2580
+ * that navigates here is the one that knows — the checkout that has just finished.
2581
+ *
2582
+ * Read-only, like tracking. The frame's footer is "Done" rather than "Cancel order"
2583
+ * precisely because cancellation is DAZN's under ADR-0008 and ADR-0017.
2584
+ */
2585
+ export declare function OrderConfirmationView(props: OrderConfirmationViewProps): JSX.Element;
2586
+
2587
+ export declare interface OrderConfirmationViewProps {
2588
+ /** DAZN's order reference, e.g. `ord_GB26081021` or `787293`. */
2589
+ orderRef: string;
2590
+ /** Overrides the provider's locale for dates. */
2591
+ locale?: string;
2592
+ /**
2593
+ * The frame's "Done". Omit it and no button renders.
2594
+ *
2595
+ * Where it goes is the host's: in the embed this is the end of a checkout DAZN own, so
2596
+ * only they know whether it closes the webview, returns to the shop, or goes somewhere
2597
+ * else entirely.
2598
+ */
2599
+ onDone?: () => void;
2600
+ }
2601
+
2533
2602
  /**
2534
2603
  * The fan's orders (Figma `mobile/order/list`, ADR-0015).
2535
2604
  *
@@ -2615,7 +2684,7 @@ export declare interface OrderStatusBadgeProps {
2615
2684
  * The pricing breakdown. DISPLAY ONLY — every value is server-authoritative; the UI
2616
2685
  * never sums or computes anything here.
2617
2686
  */
2618
- export declare function OrderSummary({ pricing, deferred, hidden, rows, }: OrderSummaryProps): JSX.Element;
2687
+ export declare function OrderSummary({ pricing, deferred, hidden, rows, discount, }: OrderSummaryProps): JSX.Element;
2619
2688
 
2620
2689
  export declare interface OrderSummaryProps {
2621
2690
  pricing: Pricing;
@@ -2652,6 +2721,15 @@ export declare interface OrderSummaryProps {
2652
2721
  * this that zeroed the value would turn a CMS switch into a pricing change.
2653
2722
  */
2654
2723
  hidden?: DeferredLine[];
2724
+ /**
2725
+ * What came off, as a positive amount (contracts 2.34.0 `OrderTotals.discount`). Drawn
2726
+ * in the success tone with the minus sign written here.
2727
+ *
2728
+ * The sign belongs to the surface rather than the wire, so nothing downstream can add
2729
+ * this to a running total: every figure in this component is server-authoritative and
2730
+ * the grand total is DAZN's, never the sum of the rows above it.
2731
+ */
2732
+ discount?: Money;
2655
2733
  }
2656
2734
 
2657
2735
  /**
@@ -2997,7 +3075,7 @@ export declare function ProductDetail({ product, inventory, recommendations }: P
2997
3075
  export declare interface ProductDetailProps {
2998
3076
  product: Product;
2999
3077
  inventory: Inventory | null;
3000
- /** "You may like it" rail — related products from the engine. Empty = rail hidden. */
3078
+ /** "You may also like" rail — related products from the engine. Empty = rail hidden. */
3001
3079
  recommendations?: Product[];
3002
3080
  }
3003
3081
 
@@ -3288,7 +3366,16 @@ declare type SessionExchangeRequest = z.infer<typeof SessionExchangeRequest>;
3288
3366
  /**
3289
3367
  * PDP shipping & returns block (mobile/pdp/shipping-info). Static informational copy —
3290
3368
  * no free-shipping threshold (per design). The shopper picks the delivery tier at
3291
- * DAZN's checkout; this only signals that the options exist. Returns window is fixed.
3369
+ * DAZN's checkout; this only signals that the options exist.
3370
+ *
3371
+ * **The returns window is 14 days, and it used to be 30.** ADR-0016 kept 30 because the
3372
+ * design contradicted itself: this card said 14 on the PDP and 30 where the very same
3373
+ * component was placed in the cart, so ours was the number the file agreed with more
3374
+ * often. The current cart frame (5304:78218) says 14 as well, so the contradiction is
3375
+ * gone and 14 is what the design now says in both places.
3376
+ *
3377
+ * It is still not OUR number. Returns are DAZN's under ADR-0008 and this only reports
3378
+ * the policy — if 14 is wrong, it is wrong in the design and one word fixes it here.
3292
3379
  */
3293
3380
  export declare function ShippingInfo(): JSX.Element;
3294
3381
 
@@ -3376,7 +3463,7 @@ export declare type ShopEvent = {
3376
3463
  };
3377
3464
 
3378
3465
  /**
3379
- * The 56px shop header from Figma `mobile/header` (context=shop): back chevron on the
3466
+ * The 64px shop header from Figma `mobile/header` (context=shop): back chevron on the
3380
3467
  * left, cart and overflow on the right.
3381
3468
  *
3382
3469
  * **Optional, and off by default in every view.** In the real embed the DAZN app provides
@@ -3404,7 +3491,7 @@ export declare type ShopEvent = {
3404
3491
  * Mount it inside `DaznShopProvider`, and inside `CartSheet` if `showCart` is on, since
3405
3492
  * the trigger opens that sheet.
3406
3493
  */
3407
- export declare function ShopHeader({ onBack, onMenu, showCart, floating, backLabel, menuLabel, className, }: ShopHeaderProps): JSX.Element;
3494
+ export declare function ShopHeader(props: ShopHeaderProps): JSX.Element;
3408
3495
 
3409
3496
  export declare interface ShopHeaderProps {
3410
3497
  /**
@@ -3414,6 +3501,14 @@ export declare interface ShopHeaderProps {
3414
3501
  onBack?: () => void;
3415
3502
  /** Overflow menu. Omitted by default: a control that opens nothing is worse than none. */
3416
3503
  onMenu?: () => void;
3504
+ /**
3505
+ * The screen name, drawn between the back control and the icons (Figma `mobile/header`
3506
+ * carries "DAZN Shop" here on the shop entry).
3507
+ *
3508
+ * Optional, and the slot collapses without it rather than reserving space — the PDP
3509
+ * frames leave it empty, so a bar with nothing in the middle is a state the design has.
3510
+ */
3511
+ title?: string;
3417
3512
  /** The cart icon and its live count. */
3418
3513
  showCart?: boolean;
3419
3514
  /**
@@ -3424,9 +3519,31 @@ export declare interface ShopHeaderProps {
3424
3519
  * block, and the content beneath must expect nothing reserved for the bar.
3425
3520
  */
3426
3521
  floating?: boolean;
3522
+ /**
3523
+ * Force the overlaid bar's scrim on or off instead of letting it follow the scroll.
3524
+ *
3525
+ * Only meaningful with `floating`. A host that scrolls something we cannot observe —
3526
+ * a virtualised list, a native scroll view driving the webview — can drive it directly.
3527
+ */
3528
+ scrolled?: boolean;
3529
+ /**
3530
+ * Which of the bar's two contexts to draw. `mobile/header` declares both.
3531
+ *
3532
+ * - `shop` (default): back, title, cart, overflow. Every browsing screen.
3533
+ * - `checkout`: **close only**, with the title on the screen's centre line and no cart.
3534
+ * The design's reasoning is that a fan inside a completed flow has one way out of it,
3535
+ * and a cart icon there invites them back into shopping from a receipt.
3536
+ *
3537
+ * `checkout` never reads the cart, so mounting it after an order does not fire a cart
3538
+ * fetch for a badge that is not drawn.
3539
+ */
3540
+ context?: 'shop' | 'checkout';
3541
+ /** The close control, in `checkout` context. Omit it and the slot stays reserved. */
3542
+ onClose?: () => void;
3427
3543
  /** Accessible name for the back control, for a host that is not in English. */
3428
3544
  backLabel?: string;
3429
3545
  menuLabel?: string;
3546
+ closeLabel?: string;
3430
3547
  className?: string;
3431
3548
  }
3432
3549
 
@@ -3494,20 +3611,25 @@ export declare interface ShopLinkProps extends Omit<AnchorHTMLAttributes<HTMLAnc
3494
3611
  }
3495
3612
 
3496
3613
  /**
3497
- * The header's overflow menu (Figma `Settings`, 636:51006).
3614
+ * The header's overflow menu (Figma `menu-open`, 4613:58644).
3615
+ *
3616
+ * A light card anchored under the bar, over a scrim, with a close control and two rows.
3498
3617
  *
3499
- * A light card anchored under the bar, over a scrim, with a close control and three rows.
3618
+ * **"Redeem a code" is gone**, and the design is what removed it. The menu had three rows
3619
+ * from `Settings` (636:51006) on the page ADR-0022 retired; the frame of record draws
3620
+ * exactly two, orders and help. It is the one row this package rendered knowing it could
3621
+ * never work — promotions are DAZN's and nothing in the commerce API can redeem anything —
3622
+ * so a fan tapping it got a control that did nothing, every time, by design. Both sides
3623
+ * now agree it should not be there.
3500
3624
  *
3501
- * **A row with no handler renders and does nothing.** That is a deliberate exception to
3502
- * the rule this package follows everywhere else — `ShopHeader` omits its own menu button
3503
- * unless a host supplies `onMenu`, precisely because a control that opens nothing is worse
3504
- * than none. It is made here on instruction, so the menu matches the design in full while
3505
- * two of its three destinations do not yet exist on either side: code redemption has no
3506
- * mechanism in the commerce API at all, and help belongs to DAZN. An inert row is still
3507
- * marked `aria-disabled`, so a screen reader is told what a sighted fan discovers by
3508
- * tapping, rather than announcing a link to nowhere as though it worked.
3625
+ * **A row with no handler still renders and does nothing.** That is a deliberate exception
3626
+ * to the rule this package follows everywhere else — `ShopHeader` omits its own menu
3627
+ * button unless a host supplies `onMenu`, precisely because a control that opens nothing
3628
+ * is worse than none. It survives for help, which is DAZN's own surface and exists; a host
3629
+ * that has one passes `onHelp`. An inert row is marked `aria-disabled`, so a screen reader
3630
+ * is told what a sighted fan discovers by tapping.
3509
3631
  */
3510
- export declare function ShopMenuSheet({ open, onClose, onManageOrders, onRedeemCode, onHelp, closeLabel, label, }: ShopMenuSheetProps): JSX.Element | null;
3632
+ export declare function ShopMenuSheet({ open, onClose, onManageOrders, onHelp, closeLabel, label, }: ShopMenuSheetProps): JSX.Element | null;
3511
3633
 
3512
3634
  export declare interface ShopMenuSheetProps {
3513
3635
  open: boolean;
@@ -3517,11 +3639,6 @@ export declare interface ShopMenuSheetProps {
3517
3639
  * `OrderListView`.
3518
3640
  */
3519
3641
  onManageOrders?: () => void;
3520
- /**
3521
- * Code redemption. **Nothing in the commerce API can redeem a code** — promotions are
3522
- * DAZN's, and the row is inert until they give us somewhere to send it.
3523
- */
3524
- onRedeemCode?: () => void;
3525
3642
  /** Help. DAZN's own surface, so a host that has one passes it here. */
3526
3643
  onHelp?: () => void;
3527
3644
  closeLabel?: string;
@@ -3759,9 +3876,54 @@ declare type StockAlertRequest = z.infer<typeof StockAlertRequest>;
3759
3876
 
3760
3877
  declare interface SummaryRow {
3761
3878
  label: string;
3762
- key: keyof Pricing;
3879
+ /**
3880
+ * A figure from `pricing`, or `discount` — the one row whose value does not live there.
3881
+ *
3882
+ * `Pricing` is the cart's shape and has no discount in it, and adding one would change a
3883
+ * published schema for a row only the order screens draw. It comes in on its own prop
3884
+ * instead, and a row asking for it when nothing was discounted is simply not drawn.
3885
+ */
3886
+ key: keyof Pricing | 'discount';
3763
3887
  }
3764
3888
 
3889
+ /** `POST /v1/support/tickets` — the Help Center form, submitted. */
3890
+ declare const SupportTicketRequest: z.ZodObject<{
3891
+ /**
3892
+ * Where the fan wants the reply. Pre-filled from the account in the design, and
3893
+ * editable — so this is a contact address, not proof of identity.
3894
+ */
3895
+ email: z.ZodString;
3896
+ category: z.ZodString;
3897
+ /**
3898
+ * The fan's own words. Bounded at 4000 characters because an unbounded text column
3899
+ * reachable from the open internet is a storage-exhaustion vector, not because CS
3900
+ * asked for a limit — they have not, and this is the one number here we chose. It is
3901
+ * roughly two pages, and it is configuration away from being different.
3902
+ */
3903
+ description: z.ZodString;
3904
+ /**
3905
+ * One attachment, as a URL — the shape CS specified.
3906
+ *
3907
+ * The URL is not free-form: it must be one the engine issued from
3908
+ * `POST /v1/support/attachments`. A ticket carrying an arbitrary address would have a
3909
+ * CS agent's browser fetch whatever a stranger typed, from inside DAZN's network, on
3910
+ * a page showing another customer's data.
3911
+ */
3912
+ image_url: z.ZodOptional<z.ZodString>;
3913
+ }, "strict", z.ZodTypeAny, {
3914
+ email: string;
3915
+ category: string;
3916
+ description: string;
3917
+ image_url?: string | undefined;
3918
+ }, {
3919
+ email: string;
3920
+ category: string;
3921
+ description: string;
3922
+ image_url?: string | undefined;
3923
+ }>;
3924
+
3925
+ declare type SupportTicketRequest = z.infer<typeof SupportTicketRequest>;
3926
+
3765
3927
  export declare function swatchColour(name: string): string;
3766
3928
 
3767
3929
  /** An optional inline action, e.g. the undo offered after removing a cart line. */
@@ -3786,6 +3948,15 @@ declare interface ToastOptions {
3786
3948
  description?: string;
3787
3949
  /** 40×40 thumbnail. Decorative, so never given alt text. */
3788
3950
  image?: string;
3951
+ /**
3952
+ * Draw the caret pointing at the cart icon in the header (Figma `.base/indicator`).
3953
+ *
3954
+ * Opt-in rather than implied by `description`/`image`, because the caret is an
3955
+ * assertion about where the thing went. "We'll let you know" after a stock-alert
3956
+ * request is the same shaped card and did NOT go into anybody's cart; pointing it at
3957
+ * the cart badge would be a small lie told in the most literal way available.
3958
+ */
3959
+ anchor?: 'cart';
3789
3960
  }
3790
3961
 
3791
3962
  export declare function ToastProvider({ children }: {