@kotao/storefront 0.2.5 → 0.2.7
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/README.md +57 -2
- package/dist/bridge-CfNBWu0H.d.ts +260 -0
- package/dist/cart-documents-BLavRDiu.d.ts +89 -0
- package/dist/cart-documents.d.ts +1 -2
- package/dist/cart-documents.js +1 -1
- package/dist/{chunk-M7BPQ54D.js → chunk-2MRB6SMP.js} +4 -3
- package/dist/chunk-2MRB6SMP.js.map +1 -0
- package/dist/chunk-CKGI3Y7L.js +19 -0
- package/dist/chunk-CKGI3Y7L.js.map +1 -0
- package/dist/{chunk-GGOZELAA.js → chunk-DTKLAOKR.js} +231 -165
- package/dist/chunk-DTKLAOKR.js.map +1 -0
- package/dist/{chunk-MCIFKJQK.js → chunk-R4N565GX.js} +5 -2
- package/dist/chunk-R4N565GX.js.map +1 -0
- package/dist/chunk-RFKLO6TD.js +1594 -0
- package/dist/chunk-RFKLO6TD.js.map +1 -0
- package/dist/{chunk-XMTWFJCZ.js → chunk-RFM27BKZ.js} +31 -7
- package/dist/chunk-RFM27BKZ.js.map +1 -0
- package/dist/{chunk-MYDKIJRH.js → chunk-SVMYFYIA.js} +2 -2
- package/dist/{chunk-MYDKIJRH.js.map → chunk-SVMYFYIA.js.map} +1 -1
- package/dist/{chunk-H3D7BAOL.js → chunk-VOTBNOWH.js} +21 -3
- package/dist/chunk-VOTBNOWH.js.map +1 -0
- package/dist/{chunk-PXVDVUFX.js → chunk-W74FGUZH.js} +10 -3
- package/dist/chunk-W74FGUZH.js.map +1 -0
- package/dist/{chunk-2IWNUDSZ.js → chunk-WNXI3MPM.js} +2 -2
- package/dist/chunk-WNXI3MPM.js.map +1 -0
- package/dist/chunk-XXNCFWXT.js +2118 -0
- package/dist/chunk-XXNCFWXT.js.map +1 -0
- package/dist/{client-bsiNPHBi.d.ts → client-CwOPPpFF.d.ts} +11 -1
- package/dist/{createCartHandler-C4RrPwSG.d.ts → createCartHandler-7DdKB-GF.d.ts} +1 -1
- package/dist/custom-css-Bl7Ur3-H.d.ts +6 -0
- package/dist/editor.d.ts +57 -104
- package/dist/editor.js +270 -1
- package/dist/editor.js.map +1 -1
- package/dist/events-react.d.ts +4 -2
- package/dist/events-react.js +6 -4
- package/dist/events-react.js.map +1 -1
- package/dist/events.d.ts +3 -3
- package/dist/events.js +1 -1
- package/dist/{fetch-M3Y-fQrW.d.ts → fetch-Bq_cc8_G.d.ts} +5 -0
- package/dist/hydrogen-CqDMW3YC.d.ts +259 -0
- package/dist/index.d.ts +75 -51
- package/dist/index.js +19 -15
- package/dist/index.js.map +1 -1
- package/dist/react-router.d.ts +40 -9
- package/dist/react-router.js +16 -7
- package/dist/react-router.js.map +1 -1
- package/dist/react.d.ts +79 -11
- package/dist/react.js +279 -10
- package/dist/react.js.map +1 -1
- package/dist/{routing-sEonP93J.d.ts → routing-Bz3Cg0BW.d.ts} +36 -6
- package/dist/seo.d.ts +7 -4
- package/dist/seo.js +2 -2
- package/dist/settings.d.ts +14 -4
- package/dist/settings.js +2 -2
- package/dist/{shop-BJSvtmnV.d.ts → shop-CnrnSAJw.d.ts} +33 -6
- package/dist/{store-CtCWHI8H.d.ts → store-ZzoBbWir.d.ts} +1 -1
- package/dist/storefront-api-types.d.ts +12 -0
- package/dist/{types-BDhHWZsP.d.ts → types-BkY0yET-.d.ts} +3 -3
- package/dist/{types-bcbQzx87.d.ts → types-DZX8ScsJ.d.ts} +2 -0
- package/package.json +4 -4
- package/dist/cart-documents-CwwRTvm8.d.ts +0 -21
- package/dist/chunk-2IWNUDSZ.js.map +0 -1
- package/dist/chunk-GGOZELAA.js.map +0 -1
- package/dist/chunk-H3D7BAOL.js.map +0 -1
- package/dist/chunk-M7BPQ54D.js.map +0 -1
- package/dist/chunk-MCIFKJQK.js.map +0 -1
- package/dist/chunk-PXVDVUFX.js.map +0 -1
- package/dist/chunk-PXZ737N3.js +0 -439
- package/dist/chunk-PXZ737N3.js.map +0 -1
- package/dist/chunk-XMTWFJCZ.js.map +0 -1
package/dist/react.d.ts
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
import react__default, { ReactNode, ReactElement, ImgHTMLAttributes, VideoHTMLAttributes, ElementType, AnchorHTMLAttributes, CSSProperties, ComponentPropsWithoutRef } from 'react';
|
|
1
|
+
import react__default, { ReactNode, ReactElement, ImgHTMLAttributes, VideoHTMLAttributes, ElementType, AnchorHTMLAttributes, CSSProperties, ComponentPropsWithoutRef, ComponentType } from 'react';
|
|
2
2
|
import { FetcherWithComponents } from 'react-router';
|
|
3
|
-
import { j as CartFormAction, a as CartLineInput } from './types-
|
|
4
|
-
import { g as getCartFormInput, S as ShopAnalytics, A as AnalyticsContext, C as ConsentState, a as AnalyticsEmitter, b as AnalyticsBus } from './shop-
|
|
5
|
-
export { u as useNonce } from './shop-
|
|
3
|
+
import { j as CartFormAction, a as CartLineInput } from './types-DZX8ScsJ.js';
|
|
4
|
+
import { g as getCartFormInput, S as ShopAnalytics, A as AnalyticsContext, C as ConsentState, a as AnalyticsEmitter, b as AnalyticsBus } from './shop-CnrnSAJw.js';
|
|
5
|
+
export { u as useNonce } from './shop-CnrnSAJw.js';
|
|
6
6
|
import { Cart } from './storefront-api-types.js';
|
|
7
7
|
import { ImageAttrsOptions, ImageData, ImageCrop, ImageFormat } from './image.js';
|
|
8
8
|
import { C as Connection, P as PaginationInfo } from './pagination-DCrQk02Q.js';
|
|
9
|
-
import { S as SeoConfig } from './types-
|
|
10
|
-
import { T as ThemeSettingsStore, R as ResolvedSettings,
|
|
11
|
-
import { SmartCartMountConfig, CartAdapter } from '
|
|
12
|
-
export { R as REACT_SEAM_CART_DOCUMENTS, c as createStorefrontApiCartAdapter } from './cart-documents-
|
|
9
|
+
import { S as SeoConfig } from './types-BkY0yET-.js';
|
|
10
|
+
import { T as ThemeSettingsStore, R as ResolvedSettings, c as ThemeSettingsSnapshot } from './store-ZzoBbWir.js';
|
|
11
|
+
import { S as SmartCartMountConfig, C as CartAdapter } from './cart-documents-BLavRDiu.js';
|
|
12
|
+
export { R as REACT_SEAM_CART_DOCUMENTS, a as SmartCartBranding, b as SmartCartLine, c as SmartCartLineDiscount, d as SmartCartLineOption, e as SmartCartMoney, f as SmartCartState, g as createStorefrontApiCartAdapter } from './cart-documents-BLavRDiu.js';
|
|
13
13
|
import { P as PublicForm, a as FormAnswers, b as FormFieldErrors } from './types-CSNXbGFW.js';
|
|
14
|
+
import { a as HydrogenEditorPreviewRuntime, x as HydrogenEditorReconciliationReason, l as HydrogenEditorInstanceSnapshot } from './hydrogen-CqDMW3YC.js';
|
|
15
|
+
import '@kotao/storefront-contracts';
|
|
16
|
+
import './bridge-CfNBWu0H.js';
|
|
14
17
|
|
|
15
18
|
type CartFormInputValue = unknown;
|
|
16
19
|
type CartFormFetcher = FetcherWithComponents<unknown>;
|
|
@@ -71,7 +74,7 @@ interface AnalyticsProviderProps {
|
|
|
71
74
|
readonly shopId?: string;
|
|
72
75
|
readonly shop?: ShopAnalytics;
|
|
73
76
|
readonly geo?: AnalyticsContext['geo'];
|
|
74
|
-
/** Current page URL; changing it auto-emits `page_viewed` (themes pass it from
|
|
77
|
+
/** Current page URL; changing it auto-emits `page_viewed` (themes pass it from RR8 navigation). */
|
|
75
78
|
readonly url?: string;
|
|
76
79
|
/** Same-origin pixel endpoint (default '/api/storefront/pixel'). */
|
|
77
80
|
readonly pixelEndpoint?: string;
|
|
@@ -111,9 +114,11 @@ interface AnalyticsProductViewProps {
|
|
|
111
114
|
readonly products?: readonly {
|
|
112
115
|
readonly handle?: string | null;
|
|
113
116
|
readonly id?: string | null;
|
|
114
|
-
readonly price?: string | null;
|
|
117
|
+
readonly price?: number | string | null;
|
|
115
118
|
readonly productId?: string | null;
|
|
116
119
|
readonly quantity?: number | null;
|
|
120
|
+
readonly sku?: string | null;
|
|
121
|
+
readonly currency?: string | null;
|
|
117
122
|
readonly title?: string | null;
|
|
118
123
|
readonly variantId?: string | null;
|
|
119
124
|
readonly variantTitle?: string | null;
|
|
@@ -319,4 +324,67 @@ interface StorefrontFormFieldsProps {
|
|
|
319
324
|
declare function StorefrontFormFields({ form, locale, fallbackLocale, answers: initialAnswers, errors, onAnswersChange, idPrefix, }: StorefrontFormFieldsProps): react__default.JSX.Element;
|
|
320
325
|
declare function StorefrontForm({ form, locale, fallbackLocale, answers, errors, submitted, submitLabel, onAnswersChange, action, method, ...props }: StorefrontFormProps): react__default.JSX.Element;
|
|
321
326
|
|
|
322
|
-
|
|
327
|
+
interface HydrogenEditorRegisteredComponentProps {
|
|
328
|
+
readonly instanceId: string;
|
|
329
|
+
readonly props: Readonly<Record<string, unknown>>;
|
|
330
|
+
readonly styles: Readonly<Record<string, string | number>>;
|
|
331
|
+
readonly slots: Readonly<Record<string, readonly string[]>>;
|
|
332
|
+
readonly variantId?: string;
|
|
333
|
+
}
|
|
334
|
+
type HydrogenEditorRegisteredComponent = ComponentType<HydrogenEditorRegisteredComponentProps>;
|
|
335
|
+
interface HydrogenEditorProviderProps {
|
|
336
|
+
readonly preview: HydrogenEditorPreviewRuntime;
|
|
337
|
+
readonly documentId: string;
|
|
338
|
+
readonly route?: string;
|
|
339
|
+
readonly reconciliationReason?: HydrogenEditorReconciliationReason;
|
|
340
|
+
/**
|
|
341
|
+
* Changes when same-route loader data or an HMR generation reconciles. It is deliberately not
|
|
342
|
+
* interpreted as authority and is never sent across the bridge.
|
|
343
|
+
*/
|
|
344
|
+
readonly reconciliationKey?: string | number;
|
|
345
|
+
readonly components?: Readonly<Record<string, HydrogenEditorRegisteredComponent>>;
|
|
346
|
+
readonly viewportWidth?: number;
|
|
347
|
+
readonly children: ReactNode;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Activates the editor runtime for a route. Route/loader/HMR changes reconcile the existing
|
|
351
|
+
* preview store instead of replacing it, so source-backed draft operations and selection remain
|
|
352
|
+
* visible. The provider is editor-only and must not be mounted in ordinary public responses.
|
|
353
|
+
*/
|
|
354
|
+
declare function HydrogenEditorProvider({ children, components, documentId, preview, reconciliationKey, reconciliationReason, route, viewportWidth, }: HydrogenEditorProviderProps): ReactElement;
|
|
355
|
+
interface HydrogenEditorReactInstance {
|
|
356
|
+
readonly snapshot: HydrogenEditorInstanceSnapshot;
|
|
357
|
+
readonly props: Readonly<Record<string, unknown>>;
|
|
358
|
+
readonly styles: Readonly<Record<string, string | number>>;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Subscribes to exactly one component instance. A prop/style operation invalidates only this
|
|
362
|
+
* subscription; structural operations additionally invalidate the affected parent/slot.
|
|
363
|
+
*/
|
|
364
|
+
declare function useHydrogenEditorInstance(instanceId: string, sourceProps?: Readonly<Record<string, unknown>>): HydrogenEditorReactInstance | null;
|
|
365
|
+
declare function useHydrogenEditorSlot(parentInstanceId: string, slotId: string): readonly string[];
|
|
366
|
+
interface HydrogenEditorBoundaryProps {
|
|
367
|
+
readonly instanceId: string;
|
|
368
|
+
readonly children: ReactElement;
|
|
369
|
+
readonly applyPreviewProps?: boolean;
|
|
370
|
+
readonly viewportWidth?: number;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* A reconciliation and interaction boundary for one extracted JSX instance. It uses a
|
|
374
|
+
* `display: contents` marker only in editor mode, preserving the component's layout while clicks
|
|
375
|
+
* and pointer transitions remain attributable to the stable instance ID.
|
|
376
|
+
*/
|
|
377
|
+
declare function HydrogenEditorBoundary({ applyPreviewProps, children, instanceId, viewportWidth, }: HydrogenEditorBoundaryProps): ReactElement | null;
|
|
378
|
+
interface HydrogenEditorSlotProps {
|
|
379
|
+
readonly parentInstanceId: string;
|
|
380
|
+
readonly slotId: string;
|
|
381
|
+
/**
|
|
382
|
+
* Source-rendered children keyed by stable instance ID. Newly inserted instances fall through to
|
|
383
|
+
* the registered component library without replacing or regenerating existing route source.
|
|
384
|
+
*/
|
|
385
|
+
readonly existingChildren?: Readonly<Record<string, ReactElement>>;
|
|
386
|
+
readonly empty?: ReactNode;
|
|
387
|
+
}
|
|
388
|
+
declare function HydrogenEditorSlot({ empty, existingChildren, parentInstanceId, slotId, }: HydrogenEditorSlotProps): ReactElement;
|
|
389
|
+
|
|
390
|
+
export { Analytics, AnalyticsCartView, type AnalyticsCartViewProps, AnalyticsCollectionView, type AnalyticsCollectionViewProps, AnalyticsProductView, type AnalyticsProductViewProps, AnalyticsProvider, type AnalyticsProviderProps, AnalyticsSearchView, type AnalyticsSearchViewProps, CartAdapter, CartDrawerOverlay, type CartDrawerOverlayProps, CartForm, type CartFormFetcher, type CartFormProps, type CartQueryDataReturn, type CartReturn, ConsentBanner, type ConsentBannerProps, type ConsentBannerRenderProps, HydrogenEditorBoundary, type HydrogenEditorBoundaryProps, HydrogenEditorProvider, type HydrogenEditorProviderProps, type HydrogenEditorReactInstance, type HydrogenEditorRegisteredComponent, type HydrogenEditorRegisteredComponentProps, HydrogenEditorSlot, type HydrogenEditorSlotProps, Image, type ImageProps, MediaFile, type MediaFileImageOptions, type MediaFileProps, type MediaFileVideoOptions, Money, type MoneyData, type MoneyProps, type OptimisticCartLineInput, OptimisticInput, type OptimisticInputData, type OptimisticInputProps, Pagination, type PaginationProps, Seo, type SeoProps, ShopPayButton, type ShopPayButtonProps, SmartCartMountConfig, StorefrontForm, StorefrontFormFields, type StorefrontFormFieldsProps, type StorefrontFormProps, ThemeSettingsProvider, type ThemeSettingsProviderProps, type UseMoneyValue, openSmartCart, useAnalytics, useGlobalThemeTokens, useHydrogenEditorInstance, useHydrogenEditorSlot, useMoney, useOptimisticData, useSectionSettings, useThemeSettings };
|
package/dist/react.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { getCartFormInput, createAnalyticsBus, createPixelTransport } from './chunk-
|
|
2
|
-
export { useNonce } from './chunk-
|
|
1
|
+
import { getCartFormInput, createAnalyticsBus, collectAnalyticsAttribution, createPixelTransport } from './chunk-RFM27BKZ.js';
|
|
2
|
+
export { useNonce } from './chunk-RFM27BKZ.js';
|
|
3
3
|
import { getPaginationInfo } from './chunk-5QOFKGKD.js';
|
|
4
4
|
import { CART_FORM_ACTIONS, GRANTED_CONSENT, CONSENT_COOKIE, readConsentCookie, mergeConsent, buildConsentCookie } from './chunk-OGWYTYYS.js';
|
|
5
|
-
import { getSeoMeta, serializeJsonLd } from './chunk-
|
|
6
|
-
export { REACT_SEAM_CART_DOCUMENTS, createStorefrontApiCartAdapter } from './chunk-
|
|
5
|
+
import { getSeoMeta, serializeJsonLd } from './chunk-SVMYFYIA.js';
|
|
6
|
+
export { REACT_SEAM_CART_DOCUMENTS, createStorefrontApiCartAdapter } from './chunk-WNXI3MPM.js';
|
|
7
|
+
import { resolveHydrogenEditorStyles } from './chunk-XXNCFWXT.js';
|
|
7
8
|
export { StorefrontForm, StorefrontFormFields } from './chunk-VV653S52.js';
|
|
8
9
|
import './chunk-IIOHENCG.js';
|
|
9
10
|
import { buildImageAttrs } from './chunk-3YQXJNR7.js';
|
|
10
|
-
import { createContext, useState, useRef, useMemo, useEffect, useCallback, useContext, useSyncExternalStore } from 'react';
|
|
11
|
+
import { createContext, useState, useRef, useMemo, useEffect, useCallback, useContext, useSyncExternalStore, Children, isValidElement, cloneElement, createElement } from 'react';
|
|
11
12
|
import { useFetcher } from 'react-router';
|
|
12
13
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
13
14
|
|
|
@@ -37,6 +38,22 @@ function OptimisticInput({ id, data }) {
|
|
|
37
38
|
function useOptimisticData(_id) {
|
|
38
39
|
return void 0;
|
|
39
40
|
}
|
|
41
|
+
|
|
42
|
+
// src/analytics/anonymous-context.ts
|
|
43
|
+
function anonymousPageContext(candidateUrl, currentUrl) {
|
|
44
|
+
if (!candidateUrl || !currentUrl) return {};
|
|
45
|
+
try {
|
|
46
|
+
const current = new URL(currentUrl);
|
|
47
|
+
const candidate = new URL(candidateUrl, current);
|
|
48
|
+
if (!["http:", "https:"].includes(current.protocol)) return {};
|
|
49
|
+
if (!["http:", "https:"].includes(candidate.protocol)) return {};
|
|
50
|
+
if (candidate.origin !== current.origin) return {};
|
|
51
|
+
const pathname = /^\/checkout(?:\/|$)/.test(candidate.pathname) ? "/checkout" : candidate.pathname || "/";
|
|
52
|
+
return { url: `${candidate.origin}${pathname}` };
|
|
53
|
+
} catch {
|
|
54
|
+
return {};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
40
57
|
var beaconSend = (endpoint, body) => {
|
|
41
58
|
if (typeof navigator !== "undefined" && typeof navigator.sendBeacon === "function") {
|
|
42
59
|
if (navigator.sendBeacon(endpoint, new Blob([body], { type: "application/json" }))) return;
|
|
@@ -57,12 +74,21 @@ function AnalyticsProvider(props) {
|
|
|
57
74
|
const [mounted, setMounted] = useState(false);
|
|
58
75
|
const consentRef = useRef(consent);
|
|
59
76
|
consentRef.current = consent;
|
|
77
|
+
const pageUrlRef = useRef(props.url);
|
|
78
|
+
pageUrlRef.current = props.url;
|
|
60
79
|
const contextRef = useRef({});
|
|
61
80
|
const shopId = props.shopId ?? props.shop?.shopId ?? props.shop?.storefrontId;
|
|
81
|
+
const browserUrl = typeof window === "undefined" ? void 0 : (() => {
|
|
82
|
+
try {
|
|
83
|
+
return new URL(props.url ?? window.location.href, window.location.href).href;
|
|
84
|
+
} catch {
|
|
85
|
+
return props.url;
|
|
86
|
+
}
|
|
87
|
+
})();
|
|
62
88
|
contextRef.current = {
|
|
63
89
|
...shopId !== void 0 ? { shopId } : {},
|
|
64
90
|
...props.geo !== void 0 ? { geo: props.geo } : {},
|
|
65
|
-
...props.url !== void 0 ? { url: props.url } : {}
|
|
91
|
+
...browserUrl !== void 0 ? { url: browserUrl } : props.url !== void 0 ? { url: props.url } : {}
|
|
66
92
|
};
|
|
67
93
|
const endpointRef = useRef(props.pixelEndpoint);
|
|
68
94
|
const bus = useMemo(
|
|
@@ -72,7 +98,25 @@ function AnalyticsProvider(props) {
|
|
|
72
98
|
...endpointRef.current !== void 0 ? { endpoint: endpointRef.current } : {}
|
|
73
99
|
}),
|
|
74
100
|
getConsent: () => consentRef.current,
|
|
75
|
-
|
|
101
|
+
getAnonymousContext: () => {
|
|
102
|
+
if (typeof window === "undefined") return {};
|
|
103
|
+
return anonymousPageContext(
|
|
104
|
+
pageUrlRef.current ?? window.location.href,
|
|
105
|
+
window.location.href
|
|
106
|
+
);
|
|
107
|
+
},
|
|
108
|
+
// createAnalyticsBus calls this only after an explicit analytics grant. Keep every browser
|
|
109
|
+
// attribution/device read inside this lazy seam so denied visits never evaluate it.
|
|
110
|
+
getContext: () => ({
|
|
111
|
+
...collectAnalyticsAttribution(
|
|
112
|
+
typeof window === "undefined" || typeof document === "undefined" ? null : {
|
|
113
|
+
referrer: document.referrer,
|
|
114
|
+
search: window.location.search,
|
|
115
|
+
...typeof window.matchMedia === "function" ? { matchMedia: (query) => window.matchMedia(query) } : {}
|
|
116
|
+
}
|
|
117
|
+
),
|
|
118
|
+
...contextRef.current
|
|
119
|
+
})
|
|
76
120
|
}),
|
|
77
121
|
[]
|
|
78
122
|
);
|
|
@@ -144,13 +188,22 @@ function AnalyticsProductView({ data }) {
|
|
|
144
188
|
const product = data?.products?.[0];
|
|
145
189
|
const productId = product?.productId ?? product?.id ?? null;
|
|
146
190
|
const handle = product?.handle ?? void 0;
|
|
191
|
+
const price = product?.price == null ? void 0 : Number(product.price);
|
|
147
192
|
const payload = useMemo(() => {
|
|
148
193
|
if (productId == null) return null;
|
|
149
194
|
return {
|
|
150
195
|
productId,
|
|
151
|
-
...handle != null ? { handle } : {}
|
|
196
|
+
...handle != null ? { handle } : {},
|
|
197
|
+
...product?.variantId != null ? { variantId: product.variantId } : {},
|
|
198
|
+
...product?.title != null ? { title: product.title } : {},
|
|
199
|
+
...product?.variantTitle != null ? { variantTitle: product.variantTitle } : {},
|
|
200
|
+
...product?.vendor != null ? { vendor: product.vendor } : {},
|
|
201
|
+
...product?.sku != null ? { sku: product.sku } : {},
|
|
202
|
+
...price !== void 0 && Number.isFinite(price) ? { price } : {},
|
|
203
|
+
...product?.currency != null ? { currency: product.currency } : {},
|
|
204
|
+
...product?.quantity != null ? { quantity: product.quantity } : {}
|
|
152
205
|
};
|
|
153
|
-
}, [handle, productId]);
|
|
206
|
+
}, [handle, price, product, productId]);
|
|
154
207
|
usePublishAnalytics("product_viewed", payload);
|
|
155
208
|
return null;
|
|
156
209
|
}
|
|
@@ -1948,7 +2001,223 @@ function CartDrawerOverlay({ config, adapter }) {
|
|
|
1948
2001
|
}, [config, adapter]);
|
|
1949
2002
|
return null;
|
|
1950
2003
|
}
|
|
2004
|
+
var HydrogenEditorReactContext = createContext(null);
|
|
2005
|
+
var HYDROGEN_CANVAS_INTENT_EVENT = "kotao:hydrogen-canvas-intent";
|
|
2006
|
+
var HYDROGEN_CANVAS_RESULT_EVENT = "kotao:hydrogen-canvas-result";
|
|
2007
|
+
var HYDROGEN_CANVAS_STATE_EVENT = "kotao:hydrogen-canvas-state";
|
|
2008
|
+
var HYDROGEN_CANVAS_STATE_REQUEST_EVENT = "kotao:hydrogen-canvas-state-request";
|
|
2009
|
+
function useHydrogenEditorCanvasEvents(preview) {
|
|
2010
|
+
const snapshot = useSyncExternalStore(
|
|
2011
|
+
(listener) => preview.store.subscribe(listener),
|
|
2012
|
+
() => preview.store.getSnapshot(),
|
|
2013
|
+
() => preview.store.getSnapshot()
|
|
2014
|
+
);
|
|
2015
|
+
useEffect(() => {
|
|
2016
|
+
if (typeof document === "undefined" || typeof CustomEvent === "undefined") return;
|
|
2017
|
+
const dispatchState = () => {
|
|
2018
|
+
document.dispatchEvent(
|
|
2019
|
+
new CustomEvent(HYDROGEN_CANVAS_STATE_EVENT, {
|
|
2020
|
+
detail: {
|
|
2021
|
+
selectedInstanceId: snapshot.selectedInstanceId,
|
|
2022
|
+
hoveredInstanceId: snapshot.hoveredInstanceId,
|
|
2023
|
+
selectionStatus: snapshot.selectionStatus,
|
|
2024
|
+
revision: snapshot.revision
|
|
2025
|
+
}
|
|
2026
|
+
})
|
|
2027
|
+
);
|
|
2028
|
+
};
|
|
2029
|
+
dispatchState();
|
|
2030
|
+
document.addEventListener(HYDROGEN_CANVAS_STATE_REQUEST_EVENT, dispatchState);
|
|
2031
|
+
return () => document.removeEventListener(HYDROGEN_CANVAS_STATE_REQUEST_EVENT, dispatchState);
|
|
2032
|
+
}, [
|
|
2033
|
+
snapshot.hoveredInstanceId,
|
|
2034
|
+
snapshot.revision,
|
|
2035
|
+
snapshot.selectedInstanceId,
|
|
2036
|
+
snapshot.selectionStatus
|
|
2037
|
+
]);
|
|
2038
|
+
useEffect(() => {
|
|
2039
|
+
if (typeof document === "undefined" || typeof CustomEvent === "undefined") return;
|
|
2040
|
+
const onIntent = (event) => {
|
|
2041
|
+
if (!(event instanceof CustomEvent)) return;
|
|
2042
|
+
const result = preview.dispatchCanvasIntent(event.detail);
|
|
2043
|
+
document.dispatchEvent(new CustomEvent(HYDROGEN_CANVAS_RESULT_EVENT, { detail: result }));
|
|
2044
|
+
};
|
|
2045
|
+
document.addEventListener(HYDROGEN_CANVAS_INTENT_EVENT, onIntent);
|
|
2046
|
+
return () => document.removeEventListener(HYDROGEN_CANVAS_INTENT_EVENT, onIntent);
|
|
2047
|
+
}, [preview]);
|
|
2048
|
+
}
|
|
2049
|
+
function HydrogenEditorProvider({
|
|
2050
|
+
children,
|
|
2051
|
+
components = {},
|
|
2052
|
+
documentId,
|
|
2053
|
+
preview,
|
|
2054
|
+
reconciliationKey,
|
|
2055
|
+
reconciliationReason = "route",
|
|
2056
|
+
route,
|
|
2057
|
+
viewportWidth
|
|
2058
|
+
}) {
|
|
2059
|
+
useHydrogenEditorCanvasEvents(preview);
|
|
2060
|
+
const value = useMemo(
|
|
2061
|
+
() => ({
|
|
2062
|
+
preview,
|
|
2063
|
+
components,
|
|
2064
|
+
...viewportWidth !== void 0 ? { viewportWidth } : {}
|
|
2065
|
+
}),
|
|
2066
|
+
[components, preview, viewportWidth]
|
|
2067
|
+
);
|
|
2068
|
+
useEffect(() => {
|
|
2069
|
+
preview.reconcile(documentId, reconciliationReason, route);
|
|
2070
|
+
preview.ready();
|
|
2071
|
+
}, [documentId, preview, reconciliationKey, reconciliationReason, route]);
|
|
2072
|
+
return /* @__PURE__ */ jsx(HydrogenEditorReactContext.Provider, { value, children });
|
|
2073
|
+
}
|
|
2074
|
+
function useHydrogenEditorContext() {
|
|
2075
|
+
const context = useContext(HydrogenEditorReactContext);
|
|
2076
|
+
if (context === null) {
|
|
2077
|
+
throw new Error("Hydrogen editor hooks must be rendered inside HydrogenEditorProvider");
|
|
2078
|
+
}
|
|
2079
|
+
return context;
|
|
2080
|
+
}
|
|
2081
|
+
function useInstanceSnapshot(instanceId) {
|
|
2082
|
+
const { preview } = useHydrogenEditorContext();
|
|
2083
|
+
return useSyncExternalStore(
|
|
2084
|
+
(listener) => preview.store.subscribeInstance(instanceId, listener),
|
|
2085
|
+
() => preview.store.getInstanceSnapshot(instanceId),
|
|
2086
|
+
() => preview.store.getInstanceSnapshot(instanceId)
|
|
2087
|
+
);
|
|
2088
|
+
}
|
|
2089
|
+
function useHydrogenEditorInstance(instanceId, sourceProps = {}) {
|
|
2090
|
+
const { preview, viewportWidth } = useHydrogenEditorContext();
|
|
2091
|
+
const snapshot = useInstanceSnapshot(instanceId);
|
|
2092
|
+
return useMemo(() => {
|
|
2093
|
+
if (snapshot === null) return null;
|
|
2094
|
+
return {
|
|
2095
|
+
snapshot,
|
|
2096
|
+
props: { ...sourceProps, ...snapshot.resolvedProps },
|
|
2097
|
+
styles: resolveHydrogenEditorStyles(preview.manifest, snapshot.instance, viewportWidth)
|
|
2098
|
+
};
|
|
2099
|
+
}, [preview.manifest, snapshot, sourceProps, viewportWidth]);
|
|
2100
|
+
}
|
|
2101
|
+
function useHydrogenEditorSlot(parentInstanceId, slotId) {
|
|
2102
|
+
const snapshot = useInstanceSnapshot(parentInstanceId);
|
|
2103
|
+
return snapshot?.childInstanceIds[slotId] ?? [];
|
|
2104
|
+
}
|
|
2105
|
+
function HydrogenEditorBoundary({
|
|
2106
|
+
applyPreviewProps = true,
|
|
2107
|
+
children,
|
|
2108
|
+
instanceId,
|
|
2109
|
+
viewportWidth
|
|
2110
|
+
}) {
|
|
2111
|
+
const { preview, viewportWidth: contextViewportWidth } = useHydrogenEditorContext();
|
|
2112
|
+
const snapshot = useInstanceSnapshot(instanceId);
|
|
2113
|
+
useEffect(() => preview.registerInstance(instanceId), [instanceId, preview]);
|
|
2114
|
+
if (snapshot === null) return null;
|
|
2115
|
+
const child = Children.only(children);
|
|
2116
|
+
if (!isValidElement(child)) return null;
|
|
2117
|
+
const effectiveViewportWidth = viewportWidth ?? contextViewportWidth;
|
|
2118
|
+
const previewProps = applyPreviewProps ? snapshot.resolvedProps : {};
|
|
2119
|
+
const childStyle = isRecordStyle(child.props.style) ? child.props.style : {};
|
|
2120
|
+
const previewStyle = applyPreviewProps ? resolveHydrogenEditorStyles(preview.manifest, snapshot.instance, effectiveViewportWidth) : {};
|
|
2121
|
+
const renderedChild = cloneElement(child, {
|
|
2122
|
+
...previewProps,
|
|
2123
|
+
...Object.keys(previewStyle).length > 0 ? { style: { ...childStyle, ...previewStyle } } : {}
|
|
2124
|
+
});
|
|
2125
|
+
const blockingReason = snapshot.capabilityReasons.find((reason) => reason.severity === "blocking");
|
|
2126
|
+
const inlineProps = snapshot.component.props.filter(
|
|
2127
|
+
(control) => control.allowedBindings.includes("inline") && (snapshot.instance.props[control.propName] ?? control.defaultBinding)?.kind !== "external" && (control.control === "text" || control.control === "textarea" || control.control === "richtext")
|
|
2128
|
+
).map((control) => ({ propName: control.propName, label: control.label }));
|
|
2129
|
+
const layoutControls = snapshot.component.styles.layout.filter((control) => ["gap", "height", "margin", "padding", "width"].includes(control.control)).map((control) => ({
|
|
2130
|
+
controlId: control.controlId,
|
|
2131
|
+
control: control.control,
|
|
2132
|
+
label: control.label,
|
|
2133
|
+
allowedValues: control.allowedValues
|
|
2134
|
+
}));
|
|
2135
|
+
const onPointerEnter = (_event) => {
|
|
2136
|
+
preview.hoverInstance(instanceId);
|
|
2137
|
+
};
|
|
2138
|
+
const onPointerLeave = (_event) => {
|
|
2139
|
+
preview.hoverInstance(null);
|
|
2140
|
+
};
|
|
2141
|
+
const onClick = (event) => {
|
|
2142
|
+
event.preventDefault();
|
|
2143
|
+
event.stopPropagation();
|
|
2144
|
+
preview.selectInstance(instanceId);
|
|
2145
|
+
};
|
|
2146
|
+
return /* @__PURE__ */ jsx(
|
|
2147
|
+
"span",
|
|
2148
|
+
{
|
|
2149
|
+
"data-kotao-hydrogen-capability": snapshot.editable ? "editable" : "read-only",
|
|
2150
|
+
"data-kotao-hydrogen-capabilities": snapshot.component.capabilities.join(" "),
|
|
2151
|
+
"data-kotao-hydrogen-component": snapshot.component.componentId,
|
|
2152
|
+
"data-kotao-hydrogen-instance": instanceId,
|
|
2153
|
+
"data-kotao-hydrogen-inline-props": JSON.stringify(inlineProps),
|
|
2154
|
+
"data-kotao-hydrogen-label": snapshot.component.name,
|
|
2155
|
+
"data-kotao-hydrogen-layout-controls": JSON.stringify(layoutControls),
|
|
2156
|
+
"data-kotao-hydrogen-reason": blockingReason?.code,
|
|
2157
|
+
onClick,
|
|
2158
|
+
onPointerEnter,
|
|
2159
|
+
onPointerLeave,
|
|
2160
|
+
style: { display: "contents" },
|
|
2161
|
+
children: renderedChild
|
|
2162
|
+
}
|
|
2163
|
+
);
|
|
2164
|
+
}
|
|
2165
|
+
function isRecordStyle(value) {
|
|
2166
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2167
|
+
}
|
|
2168
|
+
function HydrogenEditorRegisteredInstance({
|
|
2169
|
+
instanceId
|
|
2170
|
+
}) {
|
|
2171
|
+
const { components } = useHydrogenEditorContext();
|
|
2172
|
+
const instance = useHydrogenEditorInstance(instanceId);
|
|
2173
|
+
if (instance === null) return null;
|
|
2174
|
+
const Component = components[instance.snapshot.component.componentId];
|
|
2175
|
+
if (Component === void 0) {
|
|
2176
|
+
return /* @__PURE__ */ jsx(
|
|
2177
|
+
"span",
|
|
2178
|
+
{
|
|
2179
|
+
"data-kotao-hydrogen-instance": instanceId,
|
|
2180
|
+
"data-kotao-hydrogen-reason": "COMPONENT_RENDERER_UNAVAILABLE",
|
|
2181
|
+
style: { display: "contents" }
|
|
2182
|
+
}
|
|
2183
|
+
);
|
|
2184
|
+
}
|
|
2185
|
+
return /* @__PURE__ */ jsx(HydrogenEditorBoundary, { applyPreviewProps: false, instanceId, children: createElement(Component, {
|
|
2186
|
+
instanceId,
|
|
2187
|
+
props: instance.props,
|
|
2188
|
+
styles: instance.styles,
|
|
2189
|
+
slots: instance.snapshot.childInstanceIds,
|
|
2190
|
+
...instance.snapshot.instance.variantId !== void 0 ? { variantId: instance.snapshot.instance.variantId } : {}
|
|
2191
|
+
}) });
|
|
2192
|
+
}
|
|
2193
|
+
function HydrogenEditorSlot({
|
|
2194
|
+
empty = null,
|
|
2195
|
+
existingChildren = {},
|
|
2196
|
+
parentInstanceId,
|
|
2197
|
+
slotId
|
|
2198
|
+
}) {
|
|
2199
|
+
const parent = useInstanceSnapshot(parentInstanceId);
|
|
2200
|
+
const instanceIds = useHydrogenEditorSlot(parentInstanceId, slotId);
|
|
2201
|
+
const slot = parent?.component.slots.find((candidate) => candidate.slotId === slotId);
|
|
2202
|
+
return /* @__PURE__ */ jsx(
|
|
2203
|
+
"span",
|
|
2204
|
+
{
|
|
2205
|
+
"data-kotao-hydrogen-slot": slotId,
|
|
2206
|
+
"data-kotao-hydrogen-slot-accepts": slot?.accepts.mode === "any" ? "*" : slot?.accepts.componentIds.join(" ") ?? "",
|
|
2207
|
+
"data-kotao-hydrogen-slot-count": instanceIds.length,
|
|
2208
|
+
"data-kotao-hydrogen-slot-insertion": slot?.insertion ?? "fixed",
|
|
2209
|
+
"data-kotao-hydrogen-slot-label": slot?.label ?? slotId,
|
|
2210
|
+
"data-kotao-hydrogen-slot-max": slot?.maxInstances ?? 0,
|
|
2211
|
+
"data-kotao-hydrogen-slot-parent": parentInstanceId,
|
|
2212
|
+
style: { display: "contents" },
|
|
2213
|
+
children: instanceIds.length === 0 ? empty : instanceIds.map((instanceId) => {
|
|
2214
|
+
const existing = existingChildren[instanceId];
|
|
2215
|
+
return existing === void 0 ? /* @__PURE__ */ jsx(HydrogenEditorRegisteredInstance, { instanceId }, instanceId) : /* @__PURE__ */ jsx(HydrogenEditorBoundary, { instanceId, children: existing }, instanceId);
|
|
2216
|
+
})
|
|
2217
|
+
}
|
|
2218
|
+
);
|
|
2219
|
+
}
|
|
1951
2220
|
|
|
1952
|
-
export { Analytics, AnalyticsCartView, AnalyticsCollectionView, AnalyticsProductView, AnalyticsProvider, AnalyticsSearchView, CartDrawerOverlay, CartForm, ConsentBanner, Image, MediaFile, Money, OptimisticInput, Pagination, Seo, ShopPayButton, ThemeSettingsProvider, openSmartCart, useAnalytics, useGlobalThemeTokens, useMoney, useOptimisticData, useSectionSettings, useThemeSettings };
|
|
2221
|
+
export { Analytics, AnalyticsCartView, AnalyticsCollectionView, AnalyticsProductView, AnalyticsProvider, AnalyticsSearchView, CartDrawerOverlay, CartForm, ConsentBanner, HydrogenEditorBoundary, HydrogenEditorProvider, HydrogenEditorSlot, Image, MediaFile, Money, OptimisticInput, Pagination, Seo, ShopPayButton, ThemeSettingsProvider, openSmartCart, useAnalytics, useGlobalThemeTokens, useHydrogenEditorInstance, useHydrogenEditorSlot, useMoney, useOptimisticData, useSectionSettings, useThemeSettings };
|
|
1953
2222
|
//# sourceMappingURL=react.js.map
|
|
1954
2223
|
//# sourceMappingURL=react.js.map
|