@nevios/storefront-kit 0.1.0
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.cjs +3057 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +931 -0
- package/dist/index.d.ts +931 -0
- package/dist/index.js +2979 -0
- package/dist/index.js.map +1 -0
- package/package.json +41 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,931 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { StorefrontClient, Money, Product, ProductMedia, ProductVariant, CollectionDetail, ProductSort, Cart, AddLineInput, CartLine, Checkout, CreateCheckoutInput, SetAddressInput, ShippingQuote, PaymentMethod, OrderStatus, Customer, MagicLinkResult, ReorderResult } from '@nevios/storefront-js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* NeviosProvider — puts a configured storefront client on React context so
|
|
6
|
+
* every kit component + hook can reach it. Wrap your app once at the root.
|
|
7
|
+
*
|
|
8
|
+
* import { createStorefrontClient } from "@nevios/storefront-js";
|
|
9
|
+
* import { NeviosProvider } from "@nevios/storefront-kit";
|
|
10
|
+
*
|
|
11
|
+
* const client = createStorefrontClient({ publishableKey, market });
|
|
12
|
+
* <NeviosProvider client={client}>{children}</NeviosProvider>
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
interface NeviosProviderProps {
|
|
16
|
+
client: StorefrontClient;
|
|
17
|
+
children: React.ReactNode;
|
|
18
|
+
}
|
|
19
|
+
declare function NeviosProvider({ client, children }: NeviosProviderProps): React.ReactElement;
|
|
20
|
+
/** Access the storefront client from any kit component / hook. */
|
|
21
|
+
declare function useStorefront(): StorefrontClient;
|
|
22
|
+
/** Non-throwing client access — returns null when no <NeviosProvider> is
|
|
23
|
+
* mounted. For presentational components that want optional client config
|
|
24
|
+
* (e.g. `imageBase` for responsive images) but must still render standalone. */
|
|
25
|
+
declare function useStorefrontOptional(): StorefrontClient | null;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Theme contract — the customization surface (layer 1) merchants edit in
|
|
29
|
+
* `nevios.config.ts`. Tokens are injected as CSS custom properties on a
|
|
30
|
+
* wrapper, so every kit component reads `var(--nv-…)` and re-skins with zero
|
|
31
|
+
* code. Mirrors the internal `/design` token model, pointed outward.
|
|
32
|
+
*
|
|
33
|
+
* <ThemeProvider theme={{ brand: "#b1442e", radius: "12px" }}>
|
|
34
|
+
* {storefront}
|
|
35
|
+
* </ThemeProvider>
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
/** The full token set. All optional — unset tokens fall back to defaults. */
|
|
39
|
+
interface StorefrontTheme {
|
|
40
|
+
/** Primary brand / CTA color. */
|
|
41
|
+
brand?: string;
|
|
42
|
+
brandForeground?: string;
|
|
43
|
+
background?: string;
|
|
44
|
+
foreground?: string;
|
|
45
|
+
muted?: string;
|
|
46
|
+
border?: string;
|
|
47
|
+
/** Corner radius for cards/inputs/buttons. */
|
|
48
|
+
radius?: string;
|
|
49
|
+
/** Base font family. */
|
|
50
|
+
fontFamily?: string;
|
|
51
|
+
}
|
|
52
|
+
/** Resolve a theme into the CSS-var style object the provider applies. */
|
|
53
|
+
declare function themeToCssVars(theme?: StorefrontTheme): React.CSSProperties;
|
|
54
|
+
interface ThemeProviderProps {
|
|
55
|
+
theme?: StorefrontTheme;
|
|
56
|
+
children: React.ReactNode;
|
|
57
|
+
/** Wrapper element (default `div`). */
|
|
58
|
+
as?: keyof React.JSX.IntrinsicElements;
|
|
59
|
+
}
|
|
60
|
+
declare function ThemeProvider({ theme, children, as: Tag, }: ThemeProviderProps): React.ReactElement;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* English message bundle — the canonical key set. Every other locale bundle is
|
|
64
|
+
* typed as `Messages` (a `Record<MessageKey, string>`), so the compiler forces
|
|
65
|
+
* it to define exactly these keys: a missing or stray key is a type error.
|
|
66
|
+
*
|
|
67
|
+
* Keys are dot-namespaced by surface (`cart.*`, `checkout.*`, `order.*`).
|
|
68
|
+
* `{name}` placeholders are interpolated by `t(key, { name })`. Plural keys end
|
|
69
|
+
* in a CLDR category (`.one` / `.few` / `.many` / `.other`); call them via the
|
|
70
|
+
* base key with a `count` var — `t("shipping.days", { count })` — and the
|
|
71
|
+
* provider picks the category for the active locale via `Intl.PluralRules`.
|
|
72
|
+
*/
|
|
73
|
+
declare const en: {
|
|
74
|
+
"common.free": string;
|
|
75
|
+
"common.close": string;
|
|
76
|
+
"common.loadingShort": string;
|
|
77
|
+
"catalog.addToCart": string;
|
|
78
|
+
"catalog.noProducts": string;
|
|
79
|
+
"catalog.soldOut": string;
|
|
80
|
+
"catalog.addError": string;
|
|
81
|
+
"catalog.inStock": string;
|
|
82
|
+
"catalog.preorder": string;
|
|
83
|
+
"catalog.filters.sort": string;
|
|
84
|
+
"catalog.filters.sortNewest": string;
|
|
85
|
+
"catalog.filters.sortOldest": string;
|
|
86
|
+
"catalog.filters.sortTitleAsc": string;
|
|
87
|
+
"catalog.filters.sortTitleDesc": string;
|
|
88
|
+
"catalog.filters.sortPriceAsc": string;
|
|
89
|
+
"catalog.filters.sortPriceDesc": string;
|
|
90
|
+
"catalog.filters.priceRange": string;
|
|
91
|
+
"catalog.filters.min": string;
|
|
92
|
+
"catalog.filters.max": string;
|
|
93
|
+
"catalog.filters.tags": string;
|
|
94
|
+
"catalog.filters.inStockOnly": string;
|
|
95
|
+
"catalog.filters.clear": string;
|
|
96
|
+
"catalog.backInStock.prompt": string;
|
|
97
|
+
"catalog.backInStock.email": string;
|
|
98
|
+
"catalog.backInStock.notify": string;
|
|
99
|
+
"catalog.backInStock.success": string;
|
|
100
|
+
"catalog.backInStock.error": string;
|
|
101
|
+
"cart.title": string;
|
|
102
|
+
"cart.empty": string;
|
|
103
|
+
"cart.remove": string;
|
|
104
|
+
"cart.increaseQty": string;
|
|
105
|
+
"cart.decreaseQty": string;
|
|
106
|
+
"cart.checkout": string;
|
|
107
|
+
"cart.subtotal": string;
|
|
108
|
+
"cart.tax": string;
|
|
109
|
+
"cart.total": string;
|
|
110
|
+
"totals.subtotal": string;
|
|
111
|
+
"totals.discount": string;
|
|
112
|
+
"totals.shipping": string;
|
|
113
|
+
"totals.paymentFee": string;
|
|
114
|
+
"totals.taxIncluded": string;
|
|
115
|
+
"totals.total": string;
|
|
116
|
+
"checkout.stepAddress": string;
|
|
117
|
+
"checkout.stepShipping": string;
|
|
118
|
+
"checkout.stepPayment": string;
|
|
119
|
+
"checkout.loading": string;
|
|
120
|
+
"checkout.empty": string;
|
|
121
|
+
"checkout.shippingAddress": string;
|
|
122
|
+
"checkout.continueToShipping": string;
|
|
123
|
+
"checkout.email": string;
|
|
124
|
+
"checkout.firstName": string;
|
|
125
|
+
"checkout.lastName": string;
|
|
126
|
+
"checkout.company": string;
|
|
127
|
+
"checkout.address": string;
|
|
128
|
+
"checkout.apartment": string;
|
|
129
|
+
"checkout.city": string;
|
|
130
|
+
"checkout.postalCode": string;
|
|
131
|
+
"checkout.country": string;
|
|
132
|
+
"checkout.phone": string;
|
|
133
|
+
"checkout.shippingMethod": string;
|
|
134
|
+
"checkout.continueToPayment": string;
|
|
135
|
+
"checkout.loadingShipping": string;
|
|
136
|
+
"checkout.noShipping": string;
|
|
137
|
+
"checkout.payment": string;
|
|
138
|
+
"checkout.loadingPayment": string;
|
|
139
|
+
"checkout.noPayment": string;
|
|
140
|
+
"checkout.payNow": string;
|
|
141
|
+
"checkout.placeOrder": string;
|
|
142
|
+
"checkout.gatewayRedirectNote": string;
|
|
143
|
+
"checkout.thankYou": string;
|
|
144
|
+
"checkout.orderPlacedBody": string;
|
|
145
|
+
"shipping.days.one": string;
|
|
146
|
+
"shipping.days.few": string;
|
|
147
|
+
"shipping.days.many": string;
|
|
148
|
+
"shipping.days.other": string;
|
|
149
|
+
"shipping.daysRange": string;
|
|
150
|
+
"order.title": string;
|
|
151
|
+
"order.placedOn": string;
|
|
152
|
+
"order.loading": string;
|
|
153
|
+
"order.loadError": string;
|
|
154
|
+
"order.notFound": string;
|
|
155
|
+
"order.confirmLoading": string;
|
|
156
|
+
"order.confirmLoadError": string;
|
|
157
|
+
"order.confirmed": string;
|
|
158
|
+
"order.items": string;
|
|
159
|
+
"order.shipping": string;
|
|
160
|
+
"order.shipsTo": string;
|
|
161
|
+
"order.tracking": string;
|
|
162
|
+
"order.payment": string;
|
|
163
|
+
"order.method": string;
|
|
164
|
+
"order.status": string;
|
|
165
|
+
"order.downloadInvoice": string;
|
|
166
|
+
"order.contactSupport": string;
|
|
167
|
+
"order.trackOrder": string;
|
|
168
|
+
"order.phase.placed": string;
|
|
169
|
+
"order.phase.paid": string;
|
|
170
|
+
"order.phase.fulfilled": string;
|
|
171
|
+
"order.phase.shipped": string;
|
|
172
|
+
"order.phase.delivered": string;
|
|
173
|
+
"order.terminal.cancelled": string;
|
|
174
|
+
"order.terminal.refunded": string;
|
|
175
|
+
"order.terminal.returned": string;
|
|
176
|
+
"error.notFound.title": string;
|
|
177
|
+
"error.notFound.body": string;
|
|
178
|
+
"error.generic.title": string;
|
|
179
|
+
"error.generic.body": string;
|
|
180
|
+
"error.home": string;
|
|
181
|
+
"account.title": string;
|
|
182
|
+
"account.signIn": string;
|
|
183
|
+
"account.signInBlurb": string;
|
|
184
|
+
"account.email": string;
|
|
185
|
+
"account.sendLink": string;
|
|
186
|
+
"account.checkEmail": string;
|
|
187
|
+
"account.signOut": string;
|
|
188
|
+
"account.greeting": string;
|
|
189
|
+
"account.orders": string;
|
|
190
|
+
"account.noOrders": string;
|
|
191
|
+
"account.addresses": string;
|
|
192
|
+
"account.noAddresses": string;
|
|
193
|
+
"account.viewOrder": string;
|
|
194
|
+
"account.verifying": string;
|
|
195
|
+
"account.verifyError": string;
|
|
196
|
+
"account.openDevLink": string;
|
|
197
|
+
"account.profile": string;
|
|
198
|
+
"account.editProfile": string;
|
|
199
|
+
"account.firstName": string;
|
|
200
|
+
"account.lastName": string;
|
|
201
|
+
"account.phone": string;
|
|
202
|
+
"account.acceptsMarketing": string;
|
|
203
|
+
"account.save": string;
|
|
204
|
+
"account.cancel": string;
|
|
205
|
+
"account.saved": string;
|
|
206
|
+
"account.saveError": string;
|
|
207
|
+
"account.addAddress": string;
|
|
208
|
+
"account.editAddress": string;
|
|
209
|
+
"account.deleteAddress": string;
|
|
210
|
+
"account.confirmDelete": string;
|
|
211
|
+
"account.setDefault": string;
|
|
212
|
+
"account.default": string;
|
|
213
|
+
"account.company": string;
|
|
214
|
+
"account.address": string;
|
|
215
|
+
"account.addressLine2": string;
|
|
216
|
+
"account.city": string;
|
|
217
|
+
"account.postalCode": string;
|
|
218
|
+
"account.country": string;
|
|
219
|
+
"account.reorder": string;
|
|
220
|
+
"account.reorderDone": string;
|
|
221
|
+
"account.reorderPartial": string;
|
|
222
|
+
"account.reorderError": string;
|
|
223
|
+
};
|
|
224
|
+
/** Every message key, derived from the English bundle (the source of truth). */
|
|
225
|
+
type MessageKey = keyof typeof en;
|
|
226
|
+
/** A complete message bundle for one locale. */
|
|
227
|
+
type Messages = Record<MessageKey, string>;
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* I18nProvider + useT — the kit's translation layer. UI strings are bundled
|
|
231
|
+
* (zero network calls); product/collection *content* is localized server-side
|
|
232
|
+
* via the SDK's `X-Locale`. Wrap your app once with the resolved locale:
|
|
233
|
+
*
|
|
234
|
+
* <I18nProvider locale="cs-CZ">{app}</I18nProvider> // auto-picks the cs pack
|
|
235
|
+
* <I18nProvider locale="fr-FR" messages={fr}>… // bring your own pack
|
|
236
|
+
*
|
|
237
|
+
* Components call `const t = useT()` and `t("checkout.payNow")`. Pluralize with
|
|
238
|
+
* a `count` var — `t("shipping.days", { count })` — resolved via Intl.PluralRules
|
|
239
|
+
* for the active locale. With no provider mounted, `useT` falls back to English,
|
|
240
|
+
* so kit components never crash un-wrapped.
|
|
241
|
+
*/
|
|
242
|
+
|
|
243
|
+
type TVars = Record<string, string | number>;
|
|
244
|
+
type TFunction = (key: MessageKey | (string & {}), vars?: TVars) => string;
|
|
245
|
+
/** Pick a bundled pack by language subtag ("cs-CZ" → cs); default English. */
|
|
246
|
+
declare function bundledMessages(locale?: string): Messages;
|
|
247
|
+
interface I18nValue {
|
|
248
|
+
locale: string;
|
|
249
|
+
messages: Messages;
|
|
250
|
+
t: TFunction;
|
|
251
|
+
}
|
|
252
|
+
interface I18nProviderProps {
|
|
253
|
+
/** BCP-47 locale — drives pluralization + (when `messages` is omitted) which
|
|
254
|
+
* bundled pack is used. */
|
|
255
|
+
locale?: string;
|
|
256
|
+
/** Override / extend the messages. Merged over the bundled pack for `locale`,
|
|
257
|
+
* so you can ship custom copy or add a locale the kit doesn't bundle. */
|
|
258
|
+
messages?: Partial<Messages>;
|
|
259
|
+
children: React.ReactNode;
|
|
260
|
+
}
|
|
261
|
+
declare function I18nProvider({ locale, messages, children, }: I18nProviderProps): React.ReactElement;
|
|
262
|
+
/** Full i18n context — locale + messages + t. Falls back to English when no
|
|
263
|
+
* <I18nProvider> is mounted. */
|
|
264
|
+
declare function useI18n(): I18nValue;
|
|
265
|
+
/** The translate function for the active locale. */
|
|
266
|
+
declare function useT(): TFunction;
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Czech message bundle. Typed as `Messages`, so the compiler guarantees it
|
|
270
|
+
* stays in sync with the canonical English key set in `en.ts`. Czech uses four
|
|
271
|
+
* plural categories (one / few / many / other) — see `shipping.days.*`.
|
|
272
|
+
*/
|
|
273
|
+
|
|
274
|
+
declare const cs: Messages;
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* MarketSwitcher — lets a shopper change market (and with it currency + locale).
|
|
278
|
+
* Headless about *how* you switch: pass `hrefFor` to navigate to each market's
|
|
279
|
+
* domain/path (the storefront resolves the market from there), or `onSelect`
|
|
280
|
+
* to handle it yourself (e.g. set a cookie + reload). Feed it the list from
|
|
281
|
+
* `client.markets()`.
|
|
282
|
+
*
|
|
283
|
+
* <MarketSwitcher markets={markets} current={market}
|
|
284
|
+
* hrefFor={(m) => m.domain ? `https://${m.domain}` : `/${m.handle}`} />
|
|
285
|
+
*/
|
|
286
|
+
|
|
287
|
+
/** The minimal market shape the switcher needs. Both the SDK's
|
|
288
|
+
* `StorefrontMarket` (from `client.markets()`) and a hand-written config entry
|
|
289
|
+
* satisfy it — `label` wins for display, else `name (CURRENCY)`. */
|
|
290
|
+
interface MarketOption {
|
|
291
|
+
handle: string;
|
|
292
|
+
label?: string;
|
|
293
|
+
name?: string;
|
|
294
|
+
currency?: string;
|
|
295
|
+
locale?: string;
|
|
296
|
+
domain?: string | null;
|
|
297
|
+
}
|
|
298
|
+
interface MarketSwitcherProps {
|
|
299
|
+
markets: readonly MarketOption[];
|
|
300
|
+
/** Current market handle (the selected option). */
|
|
301
|
+
current?: string;
|
|
302
|
+
/** Map a market → the URL to switch to. When set, changing the select
|
|
303
|
+
* navigates there. */
|
|
304
|
+
hrefFor?: (market: MarketOption) => string;
|
|
305
|
+
/** Or handle the switch yourself (cookie + reload). Takes precedence over
|
|
306
|
+
* `hrefFor` if both are given. */
|
|
307
|
+
onSelect?: (market: MarketOption) => void;
|
|
308
|
+
/** Option label. Default: `label`, else `"Name (CURRENCY)"`, else handle. */
|
|
309
|
+
renderLabel?: (market: MarketOption) => string;
|
|
310
|
+
"aria-label"?: string;
|
|
311
|
+
className?: string;
|
|
312
|
+
style?: React.CSSProperties;
|
|
313
|
+
}
|
|
314
|
+
declare function MarketSwitcher({ markets, current, hrefFor, onSelect, renderLabel, "aria-label": ariaLabel, className, style, }: MarketSwitcherProps): React.ReactElement | null;
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Money formatting + display. `formatMoney` is the headless helper; `PriceMoney`
|
|
318
|
+
* renders the display price with an optional struck-through compare-at.
|
|
319
|
+
*/
|
|
320
|
+
|
|
321
|
+
/** Format minor units (cents) + currency → a localized string ("2 999,00 Kč"). */
|
|
322
|
+
declare function formatCents(cents: number, currency: string, locale?: string): string;
|
|
323
|
+
/** Format a Money → a localized currency string. */
|
|
324
|
+
declare function formatMoney(money: Money, locale?: string): string;
|
|
325
|
+
interface PriceMoneyProps {
|
|
326
|
+
money: Money;
|
|
327
|
+
/** Show the struck-through compare-at price when one is set. */
|
|
328
|
+
showCompareAt?: boolean;
|
|
329
|
+
/** Override the formatting locale (defaults to the I18nProvider locale). */
|
|
330
|
+
locale?: string;
|
|
331
|
+
}
|
|
332
|
+
declare function PriceMoney({ money, showCompareAt, locale, }: PriceMoneyProps): React.ReactElement;
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* ProductCard — a product tile for grids (collection pages, search). Image +
|
|
336
|
+
* title + price range. Presentational: pass a `Product`; pass `href` to make
|
|
337
|
+
* the whole tile a link to the PDP. Override via the slot registry to restyle
|
|
338
|
+
* just this without touching the rest.
|
|
339
|
+
*/
|
|
340
|
+
|
|
341
|
+
interface ProductCardProps {
|
|
342
|
+
product: Product;
|
|
343
|
+
/** When set, the whole card links here (the eshop owns its URL scheme). */
|
|
344
|
+
href?: string;
|
|
345
|
+
locale?: string;
|
|
346
|
+
}
|
|
347
|
+
declare function ProductCard({ product, href, locale }: ProductCardProps): React.ReactElement;
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* ProductGallery — the PDP image gallery: a main image + thumbnail strip.
|
|
351
|
+
* Client-interactive (thumbnail selects the main image). Presentational data.
|
|
352
|
+
*/
|
|
353
|
+
|
|
354
|
+
interface ProductGalleryProps {
|
|
355
|
+
media: ProductMedia[];
|
|
356
|
+
alt?: string;
|
|
357
|
+
}
|
|
358
|
+
declare function ProductGallery({ media, alt }: ProductGalleryProps): React.ReactElement;
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* VariantPicker — one selector row per product option (Color, Size…). Resolves
|
|
362
|
+
* the matching variant from the selected values and reports it via `onChange`,
|
|
363
|
+
* so the PDP knows which variant to price + add to cart. Defaults to the first
|
|
364
|
+
* variant. Single-option-less products (one default variant) render nothing.
|
|
365
|
+
*/
|
|
366
|
+
|
|
367
|
+
interface VariantPickerProps {
|
|
368
|
+
product: Product;
|
|
369
|
+
onChange?: (variant: ProductVariant | null) => void;
|
|
370
|
+
}
|
|
371
|
+
declare function VariantPicker({ product, onChange }: VariantPickerProps): React.ReactElement | null;
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* ProductDetailPage — the PDP composition: gallery + title + live price for the
|
|
375
|
+
* selected variant + variant picker + an add-to-cart slot. Presentational:
|
|
376
|
+
* the Remix loader fetches the `Product`, this renders it. `addToCart` is a
|
|
377
|
+
* render slot the cart phase (P2) fills with an <AddToCart> bound to the
|
|
378
|
+
* currently-selected variant.
|
|
379
|
+
*/
|
|
380
|
+
|
|
381
|
+
interface ProductDetailPageProps {
|
|
382
|
+
product: Product;
|
|
383
|
+
locale?: string;
|
|
384
|
+
/** Render slot for the add-to-cart control, bound to the selected variant. */
|
|
385
|
+
addToCart?: (variant: ProductVariant | null) => React.ReactNode;
|
|
386
|
+
}
|
|
387
|
+
declare function ProductDetailPage({ product, locale, addToCart, }: ProductDetailPageProps): React.ReactElement;
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* CollectionPage — collection header + a responsive grid of ProductCards in the
|
|
391
|
+
* collection's curated order. Presentational: the Remix loader fetches the
|
|
392
|
+
* `CollectionDetail` (collection + its products), this renders it. `productHref`
|
|
393
|
+
* lets the eshop own its URL scheme.
|
|
394
|
+
*/
|
|
395
|
+
|
|
396
|
+
interface CollectionPageProps {
|
|
397
|
+
collection: CollectionDetail;
|
|
398
|
+
/** Map a product → its PDP URL (the eshop owns routing). */
|
|
399
|
+
productHref?: (product: Product) => string;
|
|
400
|
+
locale?: string;
|
|
401
|
+
}
|
|
402
|
+
declare function CollectionPage({ collection, productHref, locale, }: CollectionPageProps): React.ReactElement;
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* StockBadge — a small availability pill for a variant. Reads
|
|
406
|
+
* `variant.availability.status` (in_stock | preorder | out_of_stock) and renders
|
|
407
|
+
* a themed label. Renders nothing for an untracked in-stock variant when
|
|
408
|
+
* `hideInStock` is set (keeps the PDP quiet for always-available goods).
|
|
409
|
+
*/
|
|
410
|
+
|
|
411
|
+
interface StockBadgeProps {
|
|
412
|
+
variant: ProductVariant | null;
|
|
413
|
+
/** Don't render anything when the variant is in stock (default false). */
|
|
414
|
+
hideInStock?: boolean;
|
|
415
|
+
}
|
|
416
|
+
declare function StockBadge({ variant, hideInStock }: StockBadgeProps): React.ReactElement | null;
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* BackInStockForm — an email capture shown when a variant is out of stock.
|
|
420
|
+
* Submits to `client.catalog.inventory.subscribe(variantId, email)`. Renders
|
|
421
|
+
* nothing unless the variant's status is `out_of_stock`, so it's safe to drop
|
|
422
|
+
* straight into a PDP next to (or instead of) the add-to-cart button.
|
|
423
|
+
*/
|
|
424
|
+
|
|
425
|
+
interface BackInStockFormProps {
|
|
426
|
+
variant: ProductVariant | null;
|
|
427
|
+
/** Prefill the email (e.g. the signed-in customer's). */
|
|
428
|
+
defaultEmail?: string;
|
|
429
|
+
onSuccess?: () => void;
|
|
430
|
+
}
|
|
431
|
+
declare function BackInStockForm({ variant, defaultEmail, onSuccess, }: BackInStockFormProps): React.ReactElement | null;
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Product list filter + sort controls — presentational + controlled. Each holds
|
|
435
|
+
* no state; the parent owns a `ProductListOptions` object, passes the current
|
|
436
|
+
* value in, and re-queries on change. Themeable via `--nv-*`.
|
|
437
|
+
*
|
|
438
|
+
* const [opts, setOpts] = React.useState<ProductListOptions>({ sort: "newest" });
|
|
439
|
+
* <SortSelect value={opts.sort} onChange={(sort) => setOpts({ ...opts, sort, offset: 0 })} />
|
|
440
|
+
* // re-run client.catalog.products(opts) when opts changes
|
|
441
|
+
*/
|
|
442
|
+
|
|
443
|
+
interface SortSelectProps {
|
|
444
|
+
value?: ProductSort;
|
|
445
|
+
onChange: (sort: ProductSort) => void;
|
|
446
|
+
}
|
|
447
|
+
declare function SortSelect({ value, onChange }: SortSelectProps): React.ReactElement;
|
|
448
|
+
interface AvailabilityFilterProps {
|
|
449
|
+
checked?: boolean;
|
|
450
|
+
onChange: (checked: boolean) => void;
|
|
451
|
+
}
|
|
452
|
+
declare function AvailabilityFilter({ checked, onChange, }: AvailabilityFilterProps): React.ReactElement;
|
|
453
|
+
interface PriceRangeFilterProps {
|
|
454
|
+
/** Current bounds in cents (undefined = open-ended). */
|
|
455
|
+
minCents?: number;
|
|
456
|
+
maxCents?: number;
|
|
457
|
+
currency: string;
|
|
458
|
+
onChange: (minCents: number | undefined, maxCents: number | undefined) => void;
|
|
459
|
+
locale?: string;
|
|
460
|
+
}
|
|
461
|
+
/** Two minor-unit (cents) inputs. Emits cents; renders the currency symbol as a
|
|
462
|
+
* hint via the active locale. Empty input → undefined (open-ended). */
|
|
463
|
+
declare function PriceRangeFilter({ minCents, maxCents, currency, onChange, locale, }: PriceRangeFilterProps): React.ReactElement;
|
|
464
|
+
interface TagFilterProps {
|
|
465
|
+
/** All selectable tags (the eshop supplies these, e.g. from its nav). */
|
|
466
|
+
tags: string[];
|
|
467
|
+
selected?: string[];
|
|
468
|
+
onChange: (selected: string[]) => void;
|
|
469
|
+
}
|
|
470
|
+
/** Toggleable tag chips. Multi-select; emits the selected list. */
|
|
471
|
+
declare function TagFilter({ tags, selected, onChange }: TagFilterProps): React.ReactElement | null;
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* CartProvider + useCart — shared cart state for the whole app. The drawer, the
|
|
475
|
+
* PDP add-to-cart, and a header cart count all read the same cart and re-render
|
|
476
|
+
* together. Wraps the SDK's cart namespace (which holds the token) with React
|
|
477
|
+
* state. Mount once inside <NeviosProvider>.
|
|
478
|
+
*
|
|
479
|
+
* <NeviosProvider client={client}>
|
|
480
|
+
* <CartProvider>{app}</CartProvider>
|
|
481
|
+
* </NeviosProvider>
|
|
482
|
+
*/
|
|
483
|
+
|
|
484
|
+
interface CartState {
|
|
485
|
+
cart: Cart | null;
|
|
486
|
+
/** True while a cart request is in flight. */
|
|
487
|
+
loading: boolean;
|
|
488
|
+
itemCount: number;
|
|
489
|
+
addLine(input: AddLineInput): Promise<Cart>;
|
|
490
|
+
updateLine(lineId: string, quantity: number): Promise<Cart>;
|
|
491
|
+
removeLine(lineId: string): Promise<Cart>;
|
|
492
|
+
/** Re-fetch the cart from the server. */
|
|
493
|
+
refresh(): Promise<void>;
|
|
494
|
+
}
|
|
495
|
+
declare function CartProvider({ children }: {
|
|
496
|
+
children: React.ReactNode;
|
|
497
|
+
}): React.ReactElement;
|
|
498
|
+
declare function useCart(): CartState;
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* AddToCart — the PDP buy button. Bound to a selected variant; adds it to the
|
|
502
|
+
* shared cart. Drop into ProductDetailPage's `addToCart` slot:
|
|
503
|
+
*
|
|
504
|
+
* <ProductDetailPage product={p} addToCart={(v) => <AddToCart variant={v} />} />
|
|
505
|
+
*/
|
|
506
|
+
|
|
507
|
+
interface AddToCartProps {
|
|
508
|
+
variant: ProductVariant | null;
|
|
509
|
+
quantity?: number;
|
|
510
|
+
/** Button label. Defaults to "Add to cart". */
|
|
511
|
+
children?: React.ReactNode;
|
|
512
|
+
onAdded?: () => void;
|
|
513
|
+
}
|
|
514
|
+
declare function AddToCart({ variant, quantity, children, onAdded, }: AddToCartProps): React.ReactElement;
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* CartLineItem — one cart row: thumbnail, title + variant, a quantity stepper,
|
|
518
|
+
* line total, and remove. Wired to the shared cart (update/remove).
|
|
519
|
+
*/
|
|
520
|
+
|
|
521
|
+
interface CartLineItemProps {
|
|
522
|
+
line: CartLine;
|
|
523
|
+
locale?: string;
|
|
524
|
+
}
|
|
525
|
+
declare function CartLineItem({ line, locale }: CartLineItemProps): React.ReactElement;
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* CartSummary — subtotal / tax / total + a checkout CTA. Reads the shared cart.
|
|
529
|
+
* The checkout action is the eshop's (a link to its checkout route, or a
|
|
530
|
+
* callback) — the P3 checkout phase wires it.
|
|
531
|
+
*/
|
|
532
|
+
|
|
533
|
+
interface CartSummaryProps {
|
|
534
|
+
/** Checkout button label (defaults to the localized "Checkout"). */
|
|
535
|
+
checkoutLabel?: string;
|
|
536
|
+
/** Link to the eshop's checkout route. */
|
|
537
|
+
checkoutHref?: string;
|
|
538
|
+
/** Or a callback (e.g. checkout.create() then navigate). */
|
|
539
|
+
onCheckout?: () => void;
|
|
540
|
+
locale?: string;
|
|
541
|
+
}
|
|
542
|
+
declare function CartSummary({ checkoutLabel, checkoutHref, onCheckout, locale, }: CartSummaryProps): React.ReactElement | null;
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* CartDrawer — a slide-in panel with the cart lines + summary. Controlled
|
|
546
|
+
* (`open`/`onClose`). Reads the shared cart; the checkout CTA is passed through
|
|
547
|
+
* to CartSummary.
|
|
548
|
+
*/
|
|
549
|
+
|
|
550
|
+
interface CartDrawerProps extends CartSummaryProps {
|
|
551
|
+
open: boolean;
|
|
552
|
+
onClose: () => void;
|
|
553
|
+
/** Drawer heading (defaults to the localized "Cart"). */
|
|
554
|
+
title?: string;
|
|
555
|
+
}
|
|
556
|
+
declare function CartDrawer({ open, onClose, title, ...summary }: CartDrawerProps): React.ReactElement | null;
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* CheckoutProvider + useCheckout — shared checkout state for the flow. Wraps the
|
|
560
|
+
* SDK's checkout namespace (which holds the token, created from the cart token)
|
|
561
|
+
* with React state, so AddressForm, ShippingPicker, PaymentSection, and
|
|
562
|
+
* OrderSummary all read and mutate the same checkout and re-render together.
|
|
563
|
+
*
|
|
564
|
+
* Mount inside <NeviosProvider> on the checkout route:
|
|
565
|
+
* <CheckoutProvider>{<CheckoutFlow />}</CheckoutProvider>
|
|
566
|
+
*
|
|
567
|
+
* The provider resumes an in-progress checkout from the stored token on mount;
|
|
568
|
+
* call `create(cartToken)` from the cart's "Checkout" CTA to start one.
|
|
569
|
+
*/
|
|
570
|
+
|
|
571
|
+
/** Outcome of `pay()` — a gateway redirect, or a placed order. */
|
|
572
|
+
type PayResult = {
|
|
573
|
+
kind: "redirect";
|
|
574
|
+
url: string;
|
|
575
|
+
} | {
|
|
576
|
+
kind: "order";
|
|
577
|
+
checkout: Checkout;
|
|
578
|
+
};
|
|
579
|
+
interface PayOptions {
|
|
580
|
+
/** Where the gateway returns the customer after paying. */
|
|
581
|
+
returnUrl?: string;
|
|
582
|
+
/** Where the gateway returns the customer on cancel. */
|
|
583
|
+
cancelUrl?: string;
|
|
584
|
+
/** Idempotency key for the place-order call. Defaults to the checkout token,
|
|
585
|
+
* which makes completing the same checkout retry-safe. */
|
|
586
|
+
idempotencyKey?: string;
|
|
587
|
+
/** Redirect the browser to the gateway automatically (gateway methods only).
|
|
588
|
+
* Default true; pass false to handle the redirect yourself. */
|
|
589
|
+
redirect?: boolean;
|
|
590
|
+
}
|
|
591
|
+
interface CheckoutState {
|
|
592
|
+
checkout: Checkout | null;
|
|
593
|
+
/** True while a checkout request is in flight. */
|
|
594
|
+
loading: boolean;
|
|
595
|
+
/** The last error from a checkout op (cleared on the next successful op). */
|
|
596
|
+
error: Error | null;
|
|
597
|
+
/** Snapshot the cart into a fresh checkout and hold its token. */
|
|
598
|
+
create(cartToken: string, input?: CreateCheckoutInput): Promise<Checkout>;
|
|
599
|
+
/** Set email + shipping (and optional billing) address. */
|
|
600
|
+
setAddress(input: SetAddressInput): Promise<Checkout>;
|
|
601
|
+
/** Available shipping options for the current address. */
|
|
602
|
+
shippingQuotes(): Promise<ShippingQuote[]>;
|
|
603
|
+
/** Choose a shipping method + rate. */
|
|
604
|
+
setShippingMethod(methodId: string, rateId: string): Promise<Checkout>;
|
|
605
|
+
/** Apply / remove a discount code. */
|
|
606
|
+
applyDiscount(code: string): Promise<Checkout>;
|
|
607
|
+
removeDiscount(code: string): Promise<Checkout>;
|
|
608
|
+
/** Enabled payment methods for the market — the picker rows. */
|
|
609
|
+
paymentMethods(): Promise<PaymentMethod[]>;
|
|
610
|
+
/** Choose a payment method (folds any surcharge into the total). */
|
|
611
|
+
setPaymentMethod(method: string): Promise<Checkout>;
|
|
612
|
+
/** Place the order. Gateway methods start the payment and (by default)
|
|
613
|
+
* redirect the browser to the gateway; cod/bank/manual complete directly. */
|
|
614
|
+
pay(opts?: PayOptions): Promise<PayResult>;
|
|
615
|
+
/** Re-fetch the checkout from the server. */
|
|
616
|
+
refresh(): Promise<void>;
|
|
617
|
+
/** Forget the checkout token (e.g. after the order is placed). */
|
|
618
|
+
clear(): void;
|
|
619
|
+
}
|
|
620
|
+
declare function CheckoutProvider({ children, }: {
|
|
621
|
+
children: React.ReactNode;
|
|
622
|
+
}): React.ReactElement;
|
|
623
|
+
declare function useCheckout(): CheckoutState;
|
|
624
|
+
|
|
625
|
+
/**
|
|
626
|
+
* CheckoutFlow — the multi-step checkout, composed: address → shipping →
|
|
627
|
+
* payment, with a live OrderSummary alongside. Drop it onto your checkout route
|
|
628
|
+
* inside <CheckoutProvider>; it resumes the checkout from the stored token.
|
|
629
|
+
*
|
|
630
|
+
* <CheckoutProvider>
|
|
631
|
+
* <CheckoutFlow onOrderPlaced={(c) => navigate(`/order/${c.order_id}`)} />
|
|
632
|
+
* </CheckoutProvider>
|
|
633
|
+
*
|
|
634
|
+
* Each step is a standalone component (AddressForm / ShippingPicker /
|
|
635
|
+
* PaymentSection) — use them directly for a fully custom layout.
|
|
636
|
+
*/
|
|
637
|
+
|
|
638
|
+
interface CheckoutFlowProps {
|
|
639
|
+
/** If set and no checkout exists yet, create one from this cart token. */
|
|
640
|
+
cartToken?: string;
|
|
641
|
+
/** Called when a (non-gateway) order is placed. Gateway flows redirect away
|
|
642
|
+
* before this fires. */
|
|
643
|
+
onOrderPlaced?: (checkout: Checkout) => void;
|
|
644
|
+
/** Rendered when there's nothing to check out (no checkout, no cart token). */
|
|
645
|
+
emptyState?: React.ReactNode;
|
|
646
|
+
/** Rendered after a successful order (else a default confirmation). */
|
|
647
|
+
renderConfirmation?: (checkout: Checkout) => React.ReactNode;
|
|
648
|
+
/** Gateway return/cancel URLs (forwarded to PaymentSection). */
|
|
649
|
+
returnUrl?: string;
|
|
650
|
+
cancelUrl?: string;
|
|
651
|
+
locale?: string;
|
|
652
|
+
}
|
|
653
|
+
declare function CheckoutFlow({ cartToken, onOrderPlaced, emptyState, renderConfirmation, returnUrl, cancelUrl, locale, }: CheckoutFlowProps): React.ReactElement;
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* AddressForm — collects email + shipping address (the checkout's first step).
|
|
657
|
+
* On submit it calls `setAddress` on the shared checkout, then `onComplete`.
|
|
658
|
+
* Controlled locally; seeds from the checkout if one already has an address
|
|
659
|
+
* (resumed flow). Billing defaults to the shipping address (same_as_shipping).
|
|
660
|
+
*/
|
|
661
|
+
|
|
662
|
+
interface AddressFormProps {
|
|
663
|
+
/** Override the section heading (defaults to the localized "Shipping address"). */
|
|
664
|
+
title?: string;
|
|
665
|
+
/** Override the submit label (defaults to the localized "Continue to shipping"). */
|
|
666
|
+
submitLabel?: string;
|
|
667
|
+
/** Called after the address is saved. */
|
|
668
|
+
onComplete?: () => void;
|
|
669
|
+
}
|
|
670
|
+
declare function AddressForm({ title, submitLabel, onComplete, }: AddressFormProps): React.ReactElement;
|
|
671
|
+
|
|
672
|
+
/**
|
|
673
|
+
* ShippingPicker — fetches the shipping options for the checkout's address and
|
|
674
|
+
* lets the customer pick one. Selecting a row calls `setShippingMethod` (which
|
|
675
|
+
* recomputes totals). Requires the address step to be done first.
|
|
676
|
+
*/
|
|
677
|
+
|
|
678
|
+
interface ShippingPickerProps {
|
|
679
|
+
/** Override the section heading (defaults to the localized "Shipping method"). */
|
|
680
|
+
title?: string;
|
|
681
|
+
/** Override the submit label (defaults to "Continue to payment"). */
|
|
682
|
+
submitLabel?: string;
|
|
683
|
+
/** Called once a method is selected and saved. */
|
|
684
|
+
onComplete?: () => void;
|
|
685
|
+
locale?: string;
|
|
686
|
+
}
|
|
687
|
+
declare function ShippingPicker({ title, submitLabel, onComplete, locale, }: ShippingPickerProps): React.ReactElement;
|
|
688
|
+
|
|
689
|
+
/**
|
|
690
|
+
* PaymentSection — lists the enabled payment methods, lets the customer pick
|
|
691
|
+
* one, and places the order. The category drives the final action:
|
|
692
|
+
* • gateway → `pay()` starts the payment and redirects to the gateway
|
|
693
|
+
* • cod/bank/manual → `pay()` completes the order directly → `onOrderPlaced`
|
|
694
|
+
* The storefront never embeds a gateway — paying a card means a redirect.
|
|
695
|
+
*/
|
|
696
|
+
|
|
697
|
+
interface PaymentSectionProps {
|
|
698
|
+
title?: string;
|
|
699
|
+
/** Where the gateway returns the customer after paying (gateway methods).
|
|
700
|
+
* Defaults to the current URL. */
|
|
701
|
+
returnUrl?: string;
|
|
702
|
+
cancelUrl?: string;
|
|
703
|
+
/** Called when a non-gateway order is placed (gateway flows redirect away). */
|
|
704
|
+
onOrderPlaced?: (checkout: Checkout) => void;
|
|
705
|
+
locale?: string;
|
|
706
|
+
}
|
|
707
|
+
declare function PaymentSection({ title, returnUrl, cancelUrl, onOrderPlaced, locale, }: PaymentSectionProps): React.ReactElement;
|
|
708
|
+
|
|
709
|
+
/**
|
|
710
|
+
* OrderSummary — the checkout's running total: line items + the full breakdown
|
|
711
|
+
* (subtotal · discount · shipping · tax · surcharge · total). Reads the shared
|
|
712
|
+
* checkout; pass `checkout` explicitly to render it standalone (e.g. SSR).
|
|
713
|
+
*/
|
|
714
|
+
|
|
715
|
+
interface OrderSummaryProps {
|
|
716
|
+
/** Override the shared checkout (else read from <CheckoutProvider>). */
|
|
717
|
+
checkout?: Checkout;
|
|
718
|
+
/** Hide the line items, show totals only. */
|
|
719
|
+
totalsOnly?: boolean;
|
|
720
|
+
locale?: string;
|
|
721
|
+
}
|
|
722
|
+
declare function OrderSummary({ checkout: override, totalsOnly, locale, }: OrderSummaryProps): React.ReactElement | null;
|
|
723
|
+
|
|
724
|
+
interface OrderStatusState {
|
|
725
|
+
order: OrderStatus | null;
|
|
726
|
+
loading: boolean;
|
|
727
|
+
error: Error | null;
|
|
728
|
+
reload(): void;
|
|
729
|
+
}
|
|
730
|
+
declare function useOrderStatus(statusToken: string | null, initial?: OrderStatus | null): OrderStatusState;
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
* OrderConfirmation — the compact post-checkout "thank you" block. Drop it on
|
|
734
|
+
* the return route after `checkout.complete()` / a gateway redirect back, keyed
|
|
735
|
+
* by the order's status token (`checkout.order_status_token`). Pass a
|
|
736
|
+
* pre-fetched `order` to render server-side.
|
|
737
|
+
*/
|
|
738
|
+
|
|
739
|
+
interface OrderConfirmationProps {
|
|
740
|
+
/** The order's status token (from `checkout.order_status_token`). */
|
|
741
|
+
statusToken?: string | null;
|
|
742
|
+
/** Pre-fetched order (SSR / loader) — skips the client fetch. */
|
|
743
|
+
order?: OrderStatus;
|
|
744
|
+
/** Link to the full order status page. */
|
|
745
|
+
statusHref?: string;
|
|
746
|
+
/** Heading copy (defaults to the localized "Thank you for your order!"). */
|
|
747
|
+
title?: string;
|
|
748
|
+
locale?: string;
|
|
749
|
+
}
|
|
750
|
+
declare function OrderConfirmation({ statusToken, order: initial, statusHref, title, locale, }: OrderConfirmationProps): React.ReactElement;
|
|
751
|
+
|
|
752
|
+
/**
|
|
753
|
+
* OrderStatusPage — the full post-purchase status view: phase timeline (or a
|
|
754
|
+
* terminal banner), line items, totals, shipping method + tracking, the
|
|
755
|
+
* redacted delivery location, and payment. Keyed by the order's status token;
|
|
756
|
+
* pass a pre-fetched `order` to render server-side (Remix loader).
|
|
757
|
+
*/
|
|
758
|
+
|
|
759
|
+
interface OrderStatusPageProps {
|
|
760
|
+
statusToken?: string | null;
|
|
761
|
+
/** Pre-fetched order (SSR / loader) — skips the client fetch. */
|
|
762
|
+
order?: OrderStatus;
|
|
763
|
+
/** Contact-support callback (shown when the order allows it). */
|
|
764
|
+
onContactSupport?: () => void;
|
|
765
|
+
locale?: string;
|
|
766
|
+
}
|
|
767
|
+
declare function OrderStatusPage({ statusToken, order: initial, onContactSupport, locale, }: OrderStatusPageProps): React.ReactElement;
|
|
768
|
+
|
|
769
|
+
/**
|
|
770
|
+
* AccountProvider + useAccount — shared logged-in-customer state. Resolves the
|
|
771
|
+
* session on mount (account.me); LoginForm / AccountDashboard / OrderHistory all
|
|
772
|
+
* read the same customer. Mount inside <NeviosProvider> (it needs the client).
|
|
773
|
+
*/
|
|
774
|
+
|
|
775
|
+
interface AccountState {
|
|
776
|
+
customer: Customer | null;
|
|
777
|
+
signedIn: boolean;
|
|
778
|
+
/** True until the initial session check resolves. */
|
|
779
|
+
loading: boolean;
|
|
780
|
+
requestMagicLink(email: string): Promise<MagicLinkResult>;
|
|
781
|
+
/** Exchange a magic token for a session (sets `customer`). */
|
|
782
|
+
verify(token: string): Promise<Customer>;
|
|
783
|
+
logout(): Promise<void>;
|
|
784
|
+
refresh(): Promise<void>;
|
|
785
|
+
}
|
|
786
|
+
declare function AccountProvider({ children }: {
|
|
787
|
+
children: React.ReactNode;
|
|
788
|
+
}): React.ReactElement;
|
|
789
|
+
declare function useAccount(): AccountState;
|
|
790
|
+
type VerifyStatus = "idle" | "verifying" | "success" | "error";
|
|
791
|
+
/** Drive the magic-link callback route: pass the token from the URL, get back a
|
|
792
|
+
* status to render (and redirect on "success"). */
|
|
793
|
+
declare function useMagicLinkVerify(token: string | null): {
|
|
794
|
+
status: VerifyStatus;
|
|
795
|
+
};
|
|
796
|
+
|
|
797
|
+
/**
|
|
798
|
+
* LoginForm — passwordless sign-in. Enter an email → we email a one-time link →
|
|
799
|
+
* "check your email". For test keys the API returns the link, which we surface
|
|
800
|
+
* as a dev shortcut so you can sign in without a real inbox.
|
|
801
|
+
*/
|
|
802
|
+
|
|
803
|
+
interface LoginFormProps {
|
|
804
|
+
/** Route that handles the magic link (default "/account/verify"). The dev
|
|
805
|
+
* shortcut links here as `${verifyPath}?token=…`. */
|
|
806
|
+
verifyPath?: string;
|
|
807
|
+
onSent?: (email: string) => void;
|
|
808
|
+
}
|
|
809
|
+
declare function LoginForm({ verifyPath, onSent }: LoginFormProps): React.ReactElement;
|
|
810
|
+
|
|
811
|
+
/**
|
|
812
|
+
* AccountDashboard — the signed-in header: greeting + sign-out. Compose
|
|
813
|
+
* OrderHistory / AddressBook (or your own) beneath it. Renders nothing while the
|
|
814
|
+
* session is still resolving; render <LoginForm> yourself when not signed in.
|
|
815
|
+
*/
|
|
816
|
+
|
|
817
|
+
interface AccountDashboardProps {
|
|
818
|
+
children?: React.ReactNode;
|
|
819
|
+
}
|
|
820
|
+
declare function AccountDashboard({ children }: AccountDashboardProps): React.ReactElement | null;
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* OrderHistory — the signed-in customer's past orders, each linking to its
|
|
824
|
+
* public status page. Fetches on mount once signed in.
|
|
825
|
+
*/
|
|
826
|
+
|
|
827
|
+
interface OrderHistoryProps {
|
|
828
|
+
/** Map an order's status token → its status-page URL (default `/order/{token}`). */
|
|
829
|
+
statusHref?: (statusToken: string) => string;
|
|
830
|
+
/** Where to send the shopper after a successful reorder (default `/cart`).
|
|
831
|
+
* Ignored when `onReorder` is provided. */
|
|
832
|
+
cartHref?: string;
|
|
833
|
+
/** Called after a reorder succeeds — override the default navigation. */
|
|
834
|
+
onReorder?: (result: ReorderResult) => void;
|
|
835
|
+
locale?: string;
|
|
836
|
+
}
|
|
837
|
+
declare function OrderHistory({ statusHref, cartHref, onReorder, locale, }: OrderHistoryProps): React.ReactElement;
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* AddressBook — the signed-in customer's saved addresses with full management:
|
|
841
|
+
* add, edit, delete, and set-default. Each mutation calls the SDK then refetches
|
|
842
|
+
* the list. The form is the shared <AddressForm>.
|
|
843
|
+
*/
|
|
844
|
+
|
|
845
|
+
declare function AddressBook(): React.ReactElement;
|
|
846
|
+
|
|
847
|
+
/**
|
|
848
|
+
* ProfileEditor — view + edit the signed-in customer's name, phone, and
|
|
849
|
+
* marketing consent (email is identity, shown read-only). Calls
|
|
850
|
+
* `account.updateProfile` and refreshes the shared account state on save.
|
|
851
|
+
*/
|
|
852
|
+
|
|
853
|
+
declare function ProfileEditor(): React.ReactElement | null;
|
|
854
|
+
|
|
855
|
+
/**
|
|
856
|
+
* ProductJsonLd — schema.org/Product structured data for rich results (price,
|
|
857
|
+
* availability, brand). Drop it in the PDP <head> (or anywhere; it's a script).
|
|
858
|
+
* Availability maps from the variant stock state the storefront now projects.
|
|
859
|
+
*
|
|
860
|
+
* <ProductJsonLd product={product} url={`https://shop.example.com/products/${product.handle}`} />
|
|
861
|
+
*/
|
|
862
|
+
|
|
863
|
+
interface ProductJsonLdProps {
|
|
864
|
+
product: Product;
|
|
865
|
+
/** Absolute canonical URL of this product page. */
|
|
866
|
+
url: string;
|
|
867
|
+
/** Origin used to absolutize relative media URLs (defaults to `url`'s origin). */
|
|
868
|
+
baseUrl?: string;
|
|
869
|
+
/** Brand name (defaults to `product.vendor`). */
|
|
870
|
+
brandName?: string;
|
|
871
|
+
}
|
|
872
|
+
declare function ProductJsonLd({ product, url, baseUrl, brandName, }: ProductJsonLdProps): React.ReactElement;
|
|
873
|
+
|
|
874
|
+
/**
|
|
875
|
+
* BreadcrumbJsonLd — schema.org/BreadcrumbList for the trail Google shows under
|
|
876
|
+
* a result. Pass the crumbs in order (Home → Collection → Product); each needs
|
|
877
|
+
* an absolute URL.
|
|
878
|
+
*
|
|
879
|
+
* <BreadcrumbJsonLd items={[
|
|
880
|
+
* { name: "Home", url: "https://shop.example.com/" },
|
|
881
|
+
* { name: "Shoes", url: "https://shop.example.com/collections/shoes" },
|
|
882
|
+
* { name: product.title, url: productUrl },
|
|
883
|
+
* ]} />
|
|
884
|
+
*/
|
|
885
|
+
|
|
886
|
+
interface BreadcrumbItem {
|
|
887
|
+
name: string;
|
|
888
|
+
url: string;
|
|
889
|
+
}
|
|
890
|
+
interface BreadcrumbJsonLdProps {
|
|
891
|
+
items: BreadcrumbItem[];
|
|
892
|
+
}
|
|
893
|
+
declare function BreadcrumbJsonLd({ items }: BreadcrumbJsonLdProps): React.ReactElement | null;
|
|
894
|
+
|
|
895
|
+
/**
|
|
896
|
+
* OrganizationJsonLd — schema.org/Organization for the shop itself. Mount once
|
|
897
|
+
* (e.g. in the root layout): one Organization per domain is the best practice.
|
|
898
|
+
*
|
|
899
|
+
* <OrganizationJsonLd name={shop.name} url="https://shop.example.com" logo={shop.logo} />
|
|
900
|
+
*/
|
|
901
|
+
|
|
902
|
+
interface OrganizationJsonLdProps {
|
|
903
|
+
name: string;
|
|
904
|
+
url?: string;
|
|
905
|
+
/** Logo URL (absolute). */
|
|
906
|
+
logo?: string;
|
|
907
|
+
/** Social / profile URLs. */
|
|
908
|
+
sameAs?: string[];
|
|
909
|
+
}
|
|
910
|
+
declare function OrganizationJsonLd({ name, url, logo, sameAs, }: OrganizationJsonLdProps): React.ReactElement;
|
|
911
|
+
|
|
912
|
+
/**
|
|
913
|
+
* JSON-LD helpers. Structured data is *data*, but it's embedded in an inline
|
|
914
|
+
* `<script>` in the HTML, so it must be escaped against the one thing that can
|
|
915
|
+
* break out of that context: a literal `</script>` (and stray `<`, `>`, `&`).
|
|
916
|
+
* `serializeJsonLd` hex-escapes those; `<JsonLd>` renders the script tag.
|
|
917
|
+
*/
|
|
918
|
+
|
|
919
|
+
/** JSON-safe + HTML-script-safe serialization for embedding in `<script>`. */
|
|
920
|
+
declare function serializeJsonLd(data: unknown): string;
|
|
921
|
+
/** Strip HTML tags + collapse whitespace → plain text (for JSON-LD descriptions). */
|
|
922
|
+
declare function stripHtml(html: string | null | undefined): string | undefined;
|
|
923
|
+
/** Absolutize a possibly-relative URL against an origin. */
|
|
924
|
+
declare function absoluteUrl(url: string, base?: string): string;
|
|
925
|
+
interface JsonLdProps {
|
|
926
|
+
data: unknown;
|
|
927
|
+
}
|
|
928
|
+
/** Render a JSON-LD `<script>` for the given (already-shaped) data object. */
|
|
929
|
+
declare function JsonLd({ data }: JsonLdProps): React.ReactElement;
|
|
930
|
+
|
|
931
|
+
export { AccountDashboard, type AccountDashboardProps, AccountProvider, type AccountState, AddToCart, type AddToCartProps, AddressBook, AddressForm, type AddressFormProps, AvailabilityFilter, type AvailabilityFilterProps, BackInStockForm, type BackInStockFormProps, type BreadcrumbItem, BreadcrumbJsonLd, type BreadcrumbJsonLdProps, CartDrawer, type CartDrawerProps, CartLineItem, type CartLineItemProps, CartProvider, type CartState, CartSummary, type CartSummaryProps, CheckoutFlow, type CheckoutFlowProps, CheckoutProvider, type CheckoutState, CollectionPage, type CollectionPageProps, I18nProvider, type I18nProviderProps, type I18nValue, JsonLd, type JsonLdProps, LoginForm, type LoginFormProps, type MarketOption, MarketSwitcher, type MarketSwitcherProps, type MessageKey, type Messages, NeviosProvider, type NeviosProviderProps, OrderConfirmation, type OrderConfirmationProps, OrderHistory, type OrderHistoryProps, OrderStatusPage, type OrderStatusPageProps, type OrderStatusState, OrderSummary, type OrderSummaryProps, OrganizationJsonLd, type OrganizationJsonLdProps, type PayOptions, type PayResult, PaymentSection, type PaymentSectionProps, PriceMoney, type PriceMoneyProps, PriceRangeFilter, type PriceRangeFilterProps, ProductCard, type ProductCardProps, ProductDetailPage, type ProductDetailPageProps, ProductGallery, type ProductGalleryProps, ProductJsonLd, type ProductJsonLdProps, ProfileEditor, ShippingPicker, type ShippingPickerProps, SortSelect, type SortSelectProps, StockBadge, type StockBadgeProps, type StorefrontTheme, type TFunction, type TVars, TagFilter, type TagFilterProps, ThemeProvider, type ThemeProviderProps, VariantPicker, type VariantPickerProps, type VerifyStatus, absoluteUrl, bundledMessages, cs, en, formatCents, formatMoney, serializeJsonLd, stripHtml, themeToCssVars, useAccount, useCart, useCheckout, useI18n, useMagicLinkVerify, useOrderStatus, useStorefront, useStorefrontOptional, useT };
|