@brytdesigns/shopify-product-info-components 3.3.3 → 3.4.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/main/components/product-variant-render.js +5 -1
- package/dist/main/components/product-variant-render.js.map +1 -1
- package/dist/main/hooks/useProduct.js +3 -3
- package/dist/main/hooks/useProduct.js.map +1 -1
- package/dist/main/hooks/useProductOptions.js +3 -3
- package/dist/main/hooks/useProductOptions.js.map +1 -1
- package/package.json +3 -3
- package/dist/esm/index.js +0 -385
- package/dist/esm/index.js.map +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useProduct } from "../hooks/useProduct.js";
|
|
2
2
|
import "../hooks/index.js";
|
|
3
|
+
import { cloneTemplate } from "@brytdesigns/web-component-core/utils";
|
|
3
4
|
import { createMemo } from "solid-js";
|
|
4
5
|
import { Show, createComponent } from "@solidjs/web";
|
|
5
6
|
//#region src/components/product-variant-render.tsx
|
|
@@ -21,7 +22,10 @@ var Component = (_, { element }) => {
|
|
|
21
22
|
},
|
|
22
23
|
fallback: fallbackChildren,
|
|
23
24
|
get children() {
|
|
24
|
-
return
|
|
25
|
+
return (() => {
|
|
26
|
+
const template = activeVariantTemplate();
|
|
27
|
+
return template ? cloneTemplate(template) : [];
|
|
28
|
+
})();
|
|
25
29
|
}
|
|
26
30
|
});
|
|
27
31
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"product-variant-render.js","names":["<Show when={!!activeVariantTemplate()} fallback={fallbackChildren}>\n\t\t\t{
|
|
1
|
+
{"version":3,"file":"product-variant-render.js","names":["<Show when={!!activeVariantTemplate()} fallback={fallbackChildren}>\n\t\t\t{(() => {\n\t\t\t\tconst template = activeVariantTemplate();\n\t\t\t\treturn template ? cloneTemplate(template) : [];\n\t\t\t})()}\n\t\t</Show>","fallback={fallbackChildren}"],"sources":["../../../src/components/product-variant-render.tsx"],"sourcesContent":["import {\n\ttype CorrectComponentType,\n\tcloneTemplate,\n} from \"@brytdesigns/web-component-core/utils\";\n\nimport { Show } from \"@solidjs/web\";\nimport { createMemo } from \"solid-js\";\n\nimport { useProduct } from \"../hooks/index.js\";\n\nexport type Props = {};\n\nexport const Name = `product-variant-render`;\n\nexport const Component: CorrectComponentType<Props> = (_, { element }) => {\n\tconst templates = Array.from(\n\t\telement.querySelectorAll<HTMLTemplateElement>(\"template[variant-id]\"),\n\t);\n\tif (!templates.length)\n\t\treturn console.warn(`${Name}: No variant templates found`);\n\tconst [state] = useProduct(element);\n\n\tconst fallbackChildren = Array.from(element.children);\n\n\tconst activeVariantTemplate = createMemo(() => {\n\t\tconst variantId = state.product?.selected_or_first_available_variant?.id;\n\t\tif (!variantId) return null;\n\t\tconst template = templates.find(\n\t\t\t(t) => t.getAttribute(\"variant-id\") === `${variantId}`,\n\t\t);\n\t\treturn template || null;\n\t});\n\n\telement.replaceChildren(...[]);\n\n\treturn (\n\t\t<Show when={!!activeVariantTemplate()} fallback={fallbackChildren}>\n\t\t\t{(() => {\n\t\t\t\tconst template = activeVariantTemplate();\n\t\t\t\treturn template ? cloneTemplate(template) : [];\n\t\t\t})()}\n\t\t</Show>\n\t);\n};\n"],"mappings":";;;;;;AAYA,IAAa,OAAO;AAEpB,IAAa,aAA0C,GAAG,EAAE,cAAc;CACzE,MAAM,YAAY,MAAM,KACvB,QAAQ,iBAAsC,sBAAsB,CACrE;CACA,IAAI,CAAC,UAAU,QACd,OAAO,QAAQ,KAAK,GAAG,KAAK,6BAA6B;CAC1D,MAAM,CAAC,SAAS,WAAW,OAAO;CAElC,MAAM,mBAAmB,MAAM,KAAK,QAAQ,QAAQ;CAEpD,MAAM,wBAAwB,iBAAiB;EAC9C,MAAM,YAAY,MAAM,SAAS,qCAAqC;EACtE,IAAI,CAAC,WAAW,OAAO;EAIvB,OAHiB,UAAU,MACzB,MAAM,EAAE,aAAa,YAAY,MAAM,GAAG,WAErC,KAAY;CACpB,CAAC;CAED,QAAQ,gBAAgB,GAAG,CAAC,CAAC;CAE7B,OACCA,gBAAAA,MAAAA;EAAM,IAAA,OAAA;GAAM,OAAA,CAAC,CAAC,sBAAsB;EAAC;EAAEC,UAAU;EAAjD,IAAA,WAAA;GACS,cAAA;IACP,MAAM,WAAW,sBAAsB;IACvC,OAAO,WAAW,cAAc,QAAQ,IAAI,CAAC;GAC9C,EAAA,CAAG;EACE;;AAER"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { createRemoteContext, getContextFromProvider } from "@brytdesigns/web-component-core/utils";
|
|
1
|
+
import { consumeContext, createRemoteContext, getContextFromProvider } from "@brytdesigns/web-component-core/utils";
|
|
2
2
|
import { merge, omit, untrack } from "solid-js";
|
|
3
|
-
import {
|
|
3
|
+
import { createContext, provide } from "component-register";
|
|
4
4
|
//#region src/hooks/useProduct.ts
|
|
5
5
|
function initializeProductContext(props) {
|
|
6
6
|
const publicProps = omit(props, "root");
|
|
@@ -34,7 +34,7 @@ var useProductContext = (context) => {
|
|
|
34
34
|
return context;
|
|
35
35
|
};
|
|
36
36
|
var useProduct = (element) => {
|
|
37
|
-
const context =
|
|
37
|
+
const context = consumeContext(ProductContextState, element);
|
|
38
38
|
if (!context) throw new Error("ProductInfoContext not found! Please ensure to wrap your custom element with product-info element.");
|
|
39
39
|
return useProductContext(context);
|
|
40
40
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useProduct.js","names":[],"sources":["../../../src/hooks/useProduct.ts"],"sourcesContent":["import {\n\tcreateRemoteContext,\n\tgetContextFromProvider,\n} from \"@brytdesigns/web-component-core/utils\";\nimport {\n\
|
|
1
|
+
{"version":3,"file":"useProduct.js","names":[],"sources":["../../../src/hooks/useProduct.ts"],"sourcesContent":["import {\n\tconsumeContext,\n\tcreateRemoteContext,\n\tgetContextFromProvider,\n} from \"@brytdesigns/web-component-core/utils\";\nimport {\n\tcreateContext,\n\ttype ICustomElement,\n\tprovide,\n} from \"component-register\";\nimport { merge, omit, untrack } from \"solid-js\";\n\nimport type { Product } from \"../types\";\n\ntype CreateContextOptions = {\n\troot: HTMLElement & ICustomElement;\n\tproduct: Product;\n};\n\ntype WalkableNode = Parameters<typeof provide>[2];\n\ntype ProductContext = ReturnType<typeof initializeProductContext>;\n\nfunction initializeProductContext(props: CreateContextOptions) {\n\t// `omit` returns only the rest; `root` is read straight off `props`.\n\tconst publicProps = omit(props, \"root\");\n\tconst state = merge(publicProps, {});\n\n\tfunction updateSelectedVariant(variantId: string | number) {\n\t\tconst product = untrack(() => state?.product);\n\t\tif (\n\t\t\ttypeof product?.selected_or_first_available_variant === \"undefined\" ||\n\t\t\ttypeof product === \"undefined\" ||\n\t\t\ttypeof product?.variants === \"undefined\"\n\t\t)\n\t\t\treturn;\n\t\tconst newVariant = product.variants.find(\n\t\t\t(variant) => variant?.id?.toString() === variantId.toString(),\n\t\t);\n\n\t\tif (\n\t\t\tnewVariant?.id?.toString() ===\n\t\t\tproduct.selected_or_first_available_variant?.id?.toString()\n\t\t)\n\t\t\treturn;\n\n\t\tconst newState = {\n\t\t\t...product,\n\t\t\tselected_or_first_available_variant: newVariant,\n\t\t};\n\n\t\tprops.root.setAttribute(\"product\", JSON.stringify(newState));\n\n\t\tprops.root.dispatchEvent(\n\t\t\tnew CustomEvent(\"variant-updated\", {\n\t\t\t\tdetail: {\n\t\t\t\t\tvariant: newVariant,\n\t\t\t\t\tproduct: newState,\n\t\t\t\t},\n\t\t\t\tbubbles: true,\n\t\t\t}),\n\t\t);\n\t}\n\n\treturn [\n\t\tstate,\n\t\t{\n\t\t\tvariant: {\n\t\t\t\tupdate: updateSelectedVariant,\n\t\t\t},\n\t\t},\n\t] as const;\n}\n\nconst ProductContextState = createContext(initializeProductContext);\n\nexport const provideProductContext = (\n\tinitialState: Omit<CreateContextOptions, \"root\">,\n\telement: WalkableNode,\n): ProductContext => {\n\tconst props = merge(initialState, { root: element });\n\treturn provide(ProductContextState, props, element);\n};\n\nexport const useProductContext = (context: ProductContext) => {\n\treturn context;\n};\n\nexport const useProduct = (element: HTMLElement & ICustomElement) => {\n\tconst context = consumeContext<ProductContext>(ProductContextState, element);\n\n\tif (!context) {\n\t\tthrow new Error(\n\t\t\t\"ProductInfoContext not found! Please ensure to wrap your custom element with product-info element.\",\n\t\t);\n\t}\n\n\treturn useProductContext(context);\n};\n\nexport const getProductContext = (element: Element) => {\n\tconst context = getContextFromProvider<ProductContext>(\n\t\tProductContextState,\n\t\telement,\n\t);\n\treturn useProductContext(context);\n};\n\nexport const useProductAt =\n\tcreateRemoteContext<ProductContext>(ProductContextState);\n"],"mappings":";;;;AAuBA,SAAS,yBAAyB,OAA6B;CAE9D,MAAM,cAAc,KAAK,OAAO,MAAM;CACtC,MAAM,QAAQ,MAAM,aAAa,CAAC,CAAC;CAEnC,SAAS,sBAAsB,WAA4B;EAC1D,MAAM,UAAU,cAAc,OAAO,OAAO;EAC5C,IACC,OAAO,SAAS,wCAAwC,eACxD,OAAO,YAAY,eACnB,OAAO,SAAS,aAAa,aAE7B;EACD,MAAM,aAAa,QAAQ,SAAS,MAClC,YAAY,SAAS,IAAI,SAAS,MAAM,UAAU,SAAS,CAC7D;EAEA,IACC,YAAY,IAAI,SAAS,MACzB,QAAQ,qCAAqC,IAAI,SAAS,GAE1D;EAED,MAAM,WAAW;GAChB,GAAG;GACH,qCAAqC;EACtC;EAEA,MAAM,KAAK,aAAa,WAAW,KAAK,UAAU,QAAQ,CAAC;EAE3D,MAAM,KAAK,cACV,IAAI,YAAY,mBAAmB;GAClC,QAAQ;IACP,SAAS;IACT,SAAS;GACV;GACA,SAAS;EACV,CAAC,CACF;CACD;CAEA,OAAO,CACN,OACA,EACC,SAAS,EACR,QAAQ,sBACT,EACD,CACD;AACD;AAEA,IAAM,sBAAsB,cAAc,wBAAwB;AAElE,IAAa,yBACZ,cACA,YACoB;CACpB,MAAM,QAAQ,MAAM,cAAc,EAAE,MAAM,QAAQ,CAAC;CACnD,OAAO,QAAQ,qBAAqB,OAAO,OAAO;AACnD;AAEA,IAAa,qBAAqB,YAA4B;CAC7D,OAAO;AACR;AAEA,IAAa,cAAc,YAA0C;CACpE,MAAM,UAAU,eAA+B,qBAAqB,OAAO;CAE3E,IAAI,CAAC,SACJ,MAAM,IAAI,MACT,oGACD;CAGD,OAAO,kBAAkB,OAAO;AACjC;AAEA,IAAa,qBAAqB,YAAqB;CAKtD,OAAO,kBAJS,uBACf,qBACA,OAEwB,CAAO;AACjC;AAEA,IAAa,eACZ,oBAAoC,mBAAmB"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useProduct } from "./useProduct.js";
|
|
2
|
-
import { createGuardedEffect, createRemoteContext, getContextFromProvider } from "@brytdesigns/web-component-core/utils";
|
|
2
|
+
import { consumeContext, createGuardedEffect, createRemoteContext, getContextFromProvider } from "@brytdesigns/web-component-core/utils";
|
|
3
3
|
import { merge, omit, untrack } from "solid-js";
|
|
4
|
-
import {
|
|
4
|
+
import { createContext, provide } from "component-register";
|
|
5
5
|
import { Events } from "@brytdesigns/shopify-utils";
|
|
6
6
|
//#region src/hooks/useProductOptions.ts
|
|
7
7
|
/** A variant in the shape Shopify's converter takes. */
|
|
@@ -68,7 +68,7 @@ var useProductOptionsContext = (context) => {
|
|
|
68
68
|
return context;
|
|
69
69
|
};
|
|
70
70
|
var useProductOptions = (element) => {
|
|
71
|
-
const context =
|
|
71
|
+
const context = consumeContext(ProductOptionsContextState, element);
|
|
72
72
|
if (!context) throw new Error("ProductOptionsContext not found! Please ensure to wrap your custom element with product-options element.");
|
|
73
73
|
return useProductOptionsContext(context);
|
|
74
74
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useProductOptions.js","names":[],"sources":["../../../src/hooks/useProductOptions.ts"],"sourcesContent":["import { Events } from \"@brytdesigns/shopify-utils\";\nimport {\n\tcreateGuardedEffect,\n\tcreateRemoteContext,\n\tgetContextFromProvider,\n} from \"@brytdesigns/web-component-core/utils\";\nimport {\n\
|
|
1
|
+
{"version":3,"file":"useProductOptions.js","names":[],"sources":["../../../src/hooks/useProductOptions.ts"],"sourcesContent":["import { Events } from \"@brytdesigns/shopify-utils\";\nimport {\n\tconsumeContext,\n\tcreateGuardedEffect,\n\tcreateRemoteContext,\n\tgetContextFromProvider,\n} from \"@brytdesigns/web-component-core/utils\";\nimport {\n\tcreateContext,\n\ttype ICustomElement,\n\tprovide,\n} from \"component-register\";\nimport { merge, omit, untrack } from \"solid-js\";\n\nimport type { Product, Variant } from \"../types.js\";\nimport { useProduct } from \"./useProduct.js\";\n\n/** A variant in the shape Shopify's converter takes. */\nconst liquidVariant = (variant: Variant): Events.LiquidVariant => {\n\tif (variant.price === undefined)\n\t\tthrow new Error(\n\t\t\t`Variant ${variant.id} has no price, so shopify:product:select cannot report one.`,\n\t\t);\n\treturn {\n\t\tid: variant.id,\n\t\ttitle: variant.title ?? variant.options.join(\" / \"),\n\t\tavailable: variant.available ?? false,\n\t\tprice: variant.price,\n\t\toptions: variant.options,\n\t};\n};\n\n/**\n * `shopify:product:select` for options a shopper has just chosen, resolving\n * with the variant they point at, or `null` when no variant matches.\n */\nconst announceSelection = (\n\ttarget: HTMLElement,\n\tproduct: Product,\n\toptions: string[],\n) => {\n\tconst names = product.options ?? [];\n\tEvents.productSelect(\n\t\t{\n\t\t\ttarget,\n\t\t\tproduct: {\n\t\t\t\tid: Events.gid(\"Product\", product.id),\n\t\t\t\ttitle: product.title ?? \"\",\n\t\t\t\thandle: product.handle ?? \"\",\n\t\t\t},\n\t\t\tselectedOptions: Events.selectedOptions(names, options),\n\t\t},\n\t\t() =>\n\t\t\tproduct.variants.find((variant) =>\n\t\t\t\toptions.every((option) => variant.options.includes(option)),\n\t\t\t) ?? null,\n\t\t{\n\t\t\ttoResult: (variant) => ({\n\t\t\t\tvariant:\n\t\t\t\t\tvariant === null\n\t\t\t\t\t\t? null\n\t\t\t\t\t\t: Events.variantFromJson(liquidVariant(variant), names),\n\t\t\t}),\n\t\t},\n\t).catch(() => {});\n};\n\ntype CreateContextOptions = {\n\troot: HTMLElement & ICustomElement;\n\tselectedOptions: string[];\n};\n\ntype WalkableNode = Parameters<typeof provide>[2];\n\ntype ProductOptionsContext = ReturnType<typeof initializeProductOptionsContext>;\n\nfunction initializeProductOptionsContext(props: CreateContextOptions) {\n\t// `omit` returns only the rest; `root` is read straight off `props`.\n\tconst publicProps = omit(props, \"root\");\n\tconst [context, methods] = useProduct(props.root);\n\n\tEvents.preload();\n\n\tfunction updateSelectedOptions(options: string[]) {\n\t\tconst previous = untrack(() => publicProps.selectedOptions);\n\t\tprops.root.setAttribute(\"selected-options\", JSON.stringify(options));\n\t\tif (JSON.stringify(previous) !== JSON.stringify(options))\n\t\t\tannounceSelection(\n\t\t\t\tprops.root,\n\t\t\t\tuntrack(() => context.product),\n\t\t\t\toptions,\n\t\t\t);\n\t}\n\n\tfunction updateSelectedOption(option: string, index: number) {\n\t\tconst current = untrack(() => publicProps.selectedOptions);\n\t\tconst options = [...current];\n\t\toptions[index] = option;\n\t\treturn updateSelectedOptions(options);\n\t}\n\n\tcreateGuardedEffect(\n\t\t() => {\n\t\t\tconst selectedOptions = publicProps.selectedOptions;\n\t\t\t// Resolved in the COMPUTE phase. `.find` walks the store's variant\n\t\t\t// array, and walking it here is what subscribes to it — so swapping\n\t\t\t// the product re-resolves the variant. Done from the apply phase, as\n\t\t\t// it was, those reads are untracked: the options were a dependency\n\t\t\t// but the variants were not, and a product replaced underneath this\n\t\t\t// context kept resolving against the previous one's list.\n\t\t\treturn context.product.variants.find((variant) =>\n\t\t\t\tselectedOptions.every((option) => variant.options.includes(option)),\n\t\t\t);\n\t\t},\n\t\t(variant) => {\n\t\t\tif (!variant) return;\n\t\t\t// The currently-selected id is read as a snapshot, deliberately, and\n\t\t\t// must NOT join the dependency list: `methods.variant.update` below\n\t\t\t// is what changes it, so tracking it would re-run this effect on its\n\t\t\t// own result.\n\t\t\tconst current = untrack(\n\t\t\t\t() => context.product.selected_or_first_available_variant.id,\n\t\t\t);\n\t\t\tif (variant.id === current) return;\n\t\t\tmethods.variant.update(variant.id);\n\t\t},\n\t);\n\n\treturn [\n\t\tpublicProps,\n\t\t{\n\t\t\toptions: {\n\t\t\t\tupdate: updateSelectedOptions,\n\t\t\t\tupdateOption: updateSelectedOption,\n\t\t\t},\n\t\t},\n\t] as const;\n}\n\nconst ProductOptionsContextState = createContext(\n\tinitializeProductOptionsContext,\n);\n\nexport const provideProductOptionsContext = (\n\tinitialState: Omit<CreateContextOptions, \"root\">,\n\telement: WalkableNode,\n): ProductOptionsContext => {\n\tconst props = merge(initialState, { root: element });\n\treturn provide(ProductOptionsContextState, props, element);\n};\n\nexport const useProductOptionsContext = (context: ProductOptionsContext) => {\n\treturn context;\n};\n\nexport const useProductOptions = (element: HTMLElement & ICustomElement) => {\n\tconst context = consumeContext<ProductOptionsContext>(\n\t\tProductOptionsContextState,\n\t\telement,\n\t);\n\n\tif (!context) {\n\t\tthrow new Error(\n\t\t\t\"ProductOptionsContext not found! Please ensure to wrap your custom element with product-options element.\",\n\t\t);\n\t}\n\n\treturn useProductOptionsContext(context);\n};\n\nexport const getProductOptionsContext = (element: Element) => {\n\tconst context = getContextFromProvider<ProductOptionsContext>(\n\t\tProductOptionsContextState,\n\t\telement,\n\t);\n\treturn useProductOptionsContext(context);\n};\n\nexport const useProductOptionsAt = createRemoteContext<ProductOptionsContext>(\n\tProductOptionsContextState,\n);\n"],"mappings":";;;;;;;AAkBA,IAAM,iBAAiB,YAA2C;CACjE,IAAI,QAAQ,UAAU,KAAA,GACrB,MAAM,IAAI,MACT,WAAW,QAAQ,GAAG,4DACvB;CACD,OAAO;EACN,IAAI,QAAQ;EACZ,OAAO,QAAQ,SAAS,QAAQ,QAAQ,KAAK,KAAK;EAClD,WAAW,QAAQ,aAAa;EAChC,OAAO,QAAQ;EACf,SAAS,QAAQ;CAClB;AACD;;;;;AAMA,IAAM,qBACL,QACA,SACA,YACI;CACJ,MAAM,QAAQ,QAAQ,WAAW,CAAC;CAClC,OAAO,cACN;EACC;EACA,SAAS;GACR,IAAI,OAAO,IAAI,WAAW,QAAQ,EAAE;GACpC,OAAO,QAAQ,SAAS;GACxB,QAAQ,QAAQ,UAAU;EAC3B;EACA,iBAAiB,OAAO,gBAAgB,OAAO,OAAO;CACvD,SAEC,QAAQ,SAAS,MAAM,YACtB,QAAQ,OAAO,WAAW,QAAQ,QAAQ,SAAS,MAAM,CAAC,CAC3D,KAAK,MACN,EACC,WAAW,aAAa,EACvB,SACC,YAAY,OACT,OACA,OAAO,gBAAgB,cAAc,OAAO,GAAG,KAAK,EACzD,GACD,CACD,CAAC,CAAC,YAAY,CAAC,CAAC;AACjB;AAWA,SAAS,gCAAgC,OAA6B;CAErE,MAAM,cAAc,KAAK,OAAO,MAAM;CACtC,MAAM,CAAC,SAAS,WAAW,WAAW,MAAM,IAAI;CAEhD,OAAO,QAAQ;CAEf,SAAS,sBAAsB,SAAmB;EACjD,MAAM,WAAW,cAAc,YAAY,eAAe;EAC1D,MAAM,KAAK,aAAa,oBAAoB,KAAK,UAAU,OAAO,CAAC;EACnE,IAAI,KAAK,UAAU,QAAQ,MAAM,KAAK,UAAU,OAAO,GACtD,kBACC,MAAM,MACN,cAAc,QAAQ,OAAO,GAC7B,OACD;CACF;CAEA,SAAS,qBAAqB,QAAgB,OAAe;EAE5D,MAAM,UAAU,CAAC,GADD,cAAc,YAAY,eACtB,CAAO;EAC3B,QAAQ,SAAS;EACjB,OAAO,sBAAsB,OAAO;CACrC;CAEA,0BACO;EACL,MAAM,kBAAkB,YAAY;EAOpC,OAAO,QAAQ,QAAQ,SAAS,MAAM,YACrC,gBAAgB,OAAO,WAAW,QAAQ,QAAQ,SAAS,MAAM,CAAC,CACnE;CACD,IACC,YAAY;EACZ,IAAI,CAAC,SAAS;EAKd,MAAM,UAAU,cACT,QAAQ,QAAQ,oCAAoC,EAC3D;EACA,IAAI,QAAQ,OAAO,SAAS;EAC5B,QAAQ,QAAQ,OAAO,QAAQ,EAAE;CAClC,CACD;CAEA,OAAO,CACN,aACA,EACC,SAAS;EACR,QAAQ;EACR,cAAc;CACf,EACD,CACD;AACD;AAEA,IAAM,6BAA6B,cAClC,+BACD;AAEA,IAAa,gCACZ,cACA,YAC2B;CAC3B,MAAM,QAAQ,MAAM,cAAc,EAAE,MAAM,QAAQ,CAAC;CACnD,OAAO,QAAQ,4BAA4B,OAAO,OAAO;AAC1D;AAEA,IAAa,4BAA4B,YAAmC;CAC3E,OAAO;AACR;AAEA,IAAa,qBAAqB,YAA0C;CAC3E,MAAM,UAAU,eACf,4BACA,OACD;CAEA,IAAI,CAAC,SACJ,MAAM,IAAI,MACT,0GACD;CAGD,OAAO,yBAAyB,OAAO;AACxC;AAEA,IAAa,4BAA4B,YAAqB;CAK7D,OAAO,yBAJS,uBACf,4BACA,OAE+B,CAAO;AACxC;AAEA,IAAa,sBAAsB,oBAClC,0BACD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brytdesigns/shopify-product-info-components",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"description": "Headless web components used to render product information based on active product variants",
|
|
5
5
|
"main": "./dist/main/index.js",
|
|
6
6
|
"module": "./dist/main/index.js",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"author": "Bryt Designs",
|
|
20
20
|
"license": "ISC",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@brytdesigns/shopify-utils": "3.
|
|
23
|
-
"@brytdesigns/web-component-core": "3.
|
|
22
|
+
"@brytdesigns/shopify-utils": "3.4.0",
|
|
23
|
+
"@brytdesigns/web-component-core": "3.4.0",
|
|
24
24
|
"@solidjs/web": "2.0.0-rc.14",
|
|
25
25
|
"component-register": "0.8.7",
|
|
26
26
|
"solid-js": "2.0.0-rc.14"
|
package/dist/esm/index.js
DELETED
|
@@ -1,385 +0,0 @@
|
|
|
1
|
-
import { createWithElementContext, customShadowlessElement, correctElementType, getContextFromProvider } from '@brytdesigns/web-component-core/utils';
|
|
2
|
-
import { splitProps, mergeProps, createEffect, untrack, createMemo, Show, on, onCleanup, observable } from 'solid-js';
|
|
3
|
-
import { createContext, consume, provide } from 'component-register';
|
|
4
|
-
import html from 'solid-js/html';
|
|
5
|
-
|
|
6
|
-
var __defProp = Object.defineProperty;
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
// src/components/product-info.ts
|
|
13
|
-
var product_info_exports = {};
|
|
14
|
-
__export(product_info_exports, {
|
|
15
|
-
Component: () => Component,
|
|
16
|
-
Name: () => Name
|
|
17
|
-
});
|
|
18
|
-
function initializeProductContext(props) {
|
|
19
|
-
const [privateProps, publicProps] = splitProps(props, ["root"]);
|
|
20
|
-
const state = mergeProps(publicProps, {});
|
|
21
|
-
function updateSelectedVariant(variantId) {
|
|
22
|
-
const product = untrack(() => state?.product);
|
|
23
|
-
if (typeof product?.selected_or_first_available_variant === "undefined" || typeof product === "undefined" || typeof product?.variants === "undefined")
|
|
24
|
-
return;
|
|
25
|
-
const newVariant = product.variants.find(
|
|
26
|
-
(variant) => variant?.id?.toString() === variantId.toString()
|
|
27
|
-
);
|
|
28
|
-
if (newVariant?.id?.toString() === product.selected_or_first_available_variant?.id?.toString())
|
|
29
|
-
return;
|
|
30
|
-
const newState = {
|
|
31
|
-
...product,
|
|
32
|
-
selected_or_first_available_variant: newVariant
|
|
33
|
-
};
|
|
34
|
-
privateProps.root.setAttribute("product", JSON.stringify(newState));
|
|
35
|
-
privateProps.root.dispatchEvent(
|
|
36
|
-
new CustomEvent("variant-updated", {
|
|
37
|
-
detail: {
|
|
38
|
-
variant: newVariant,
|
|
39
|
-
product: newState
|
|
40
|
-
},
|
|
41
|
-
bubbles: true
|
|
42
|
-
})
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
return [
|
|
46
|
-
state,
|
|
47
|
-
{
|
|
48
|
-
variant: {
|
|
49
|
-
update: updateSelectedVariant
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
];
|
|
53
|
-
}
|
|
54
|
-
var ProductContextState = createContext(initializeProductContext);
|
|
55
|
-
var provideProductContext = (initialState, element) => {
|
|
56
|
-
const props = mergeProps(initialState, { root: element });
|
|
57
|
-
return provide(ProductContextState, props, element);
|
|
58
|
-
};
|
|
59
|
-
var useProductContext = (context) => {
|
|
60
|
-
return context;
|
|
61
|
-
};
|
|
62
|
-
var useProduct = (element) => {
|
|
63
|
-
const context = consume(ProductContextState, element);
|
|
64
|
-
if (!context) {
|
|
65
|
-
throw console.error(
|
|
66
|
-
"ProductInfoContext not found! Please ensure to wrap your custom element with product-info element."
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
return useProductContext(context);
|
|
70
|
-
};
|
|
71
|
-
var getProductContext = (element) => {
|
|
72
|
-
const context = getContextFromProvider(
|
|
73
|
-
ProductContextState,
|
|
74
|
-
element
|
|
75
|
-
);
|
|
76
|
-
return useProductContext(context);
|
|
77
|
-
};
|
|
78
|
-
var withProductElementContext = createWithElementContext(ProductContextState);
|
|
79
|
-
function initializeProductOptionsContext(props) {
|
|
80
|
-
const [privateProps, publicProps] = splitProps(props, ["root"]);
|
|
81
|
-
const [context, methods] = useProduct(privateProps.root);
|
|
82
|
-
function updateSelectedOptions(options) {
|
|
83
|
-
privateProps.root.setAttribute("selected-options", JSON.stringify(options));
|
|
84
|
-
}
|
|
85
|
-
function updateSelectedOption(option, index) {
|
|
86
|
-
const current = untrack(() => publicProps.selectedOptions);
|
|
87
|
-
const options = [...current];
|
|
88
|
-
options[index] = option;
|
|
89
|
-
return updateSelectedOptions(options);
|
|
90
|
-
}
|
|
91
|
-
createEffect(() => {
|
|
92
|
-
const variant = context.product.variants.find((variant2) => {
|
|
93
|
-
return publicProps.selectedOptions.every(
|
|
94
|
-
(option) => variant2.options.includes(option)
|
|
95
|
-
);
|
|
96
|
-
});
|
|
97
|
-
if (!variant) return;
|
|
98
|
-
if (variant.id === context.product.selected_or_first_available_variant.id)
|
|
99
|
-
return;
|
|
100
|
-
methods.variant.update(variant.id);
|
|
101
|
-
});
|
|
102
|
-
return [
|
|
103
|
-
publicProps,
|
|
104
|
-
{
|
|
105
|
-
options: {
|
|
106
|
-
update: updateSelectedOptions,
|
|
107
|
-
updateOption: updateSelectedOption
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
];
|
|
111
|
-
}
|
|
112
|
-
var ProductOptionsContextState = createContext(
|
|
113
|
-
initializeProductOptionsContext
|
|
114
|
-
);
|
|
115
|
-
var provideProductOptionsContext = (initialState, element) => {
|
|
116
|
-
const props = mergeProps(initialState, { root: element });
|
|
117
|
-
return provide(ProductOptionsContextState, props, element);
|
|
118
|
-
};
|
|
119
|
-
var useProductOptionsContext = (context) => {
|
|
120
|
-
return context;
|
|
121
|
-
};
|
|
122
|
-
var useProductOptions = (element) => {
|
|
123
|
-
const context = consume(
|
|
124
|
-
ProductOptionsContextState,
|
|
125
|
-
element
|
|
126
|
-
);
|
|
127
|
-
if (!context) {
|
|
128
|
-
throw console.error(
|
|
129
|
-
"ProductOptionsContext not found! Please ensure to wrap your custom element with product-options element."
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
return useProductOptionsContext(context);
|
|
133
|
-
};
|
|
134
|
-
var getProductOptionsContext = (element) => {
|
|
135
|
-
const context = getContextFromProvider(
|
|
136
|
-
ProductOptionsContextState,
|
|
137
|
-
element
|
|
138
|
-
);
|
|
139
|
-
return useProductOptionsContext(context);
|
|
140
|
-
};
|
|
141
|
-
var withProductOptionsElementContext = createWithElementContext(ProductOptionsContextState);
|
|
142
|
-
|
|
143
|
-
// src/components/product-info.ts
|
|
144
|
-
var Name = `product-info`;
|
|
145
|
-
var Component = (props, { element }) => {
|
|
146
|
-
if (!props.product)
|
|
147
|
-
return console.warn(`${Name}: product attribute is required`);
|
|
148
|
-
if (!props.product.variants)
|
|
149
|
-
return console.warn(`${Name}: product attribute needs variants array`);
|
|
150
|
-
if (!props.product.selected_or_first_available_variant)
|
|
151
|
-
return console.warn(
|
|
152
|
-
`${Name}: product attribute needs selected or first available variant object`
|
|
153
|
-
);
|
|
154
|
-
provideProductContext(props, element);
|
|
155
|
-
const url = createMemo(() => {
|
|
156
|
-
const url2 = new URL(window.location.href);
|
|
157
|
-
const variant = props?.product?.selected_or_first_available_variant;
|
|
158
|
-
if (props.product && variant && variant?.id) {
|
|
159
|
-
url2.searchParams.set("variant", variant.id.toString());
|
|
160
|
-
} else {
|
|
161
|
-
url2.searchParams.delete("variant");
|
|
162
|
-
}
|
|
163
|
-
return url2;
|
|
164
|
-
});
|
|
165
|
-
function subscribe(cb) {
|
|
166
|
-
return observable(() => props.product).subscribe(cb).unsubscribe;
|
|
167
|
-
}
|
|
168
|
-
Object.assign(element, {
|
|
169
|
-
subscribe
|
|
170
|
-
});
|
|
171
|
-
createEffect(() => {
|
|
172
|
-
if (!props.isProductPage) return;
|
|
173
|
-
window.history.replaceState(null, "", url());
|
|
174
|
-
});
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
// src/components/product-variant-render.ts
|
|
178
|
-
var product_variant_render_exports = {};
|
|
179
|
-
__export(product_variant_render_exports, {
|
|
180
|
-
Component: () => Component2,
|
|
181
|
-
Name: () => Name2
|
|
182
|
-
});
|
|
183
|
-
var Name2 = `product-variant-render`;
|
|
184
|
-
var Component2 = (_, { element }) => {
|
|
185
|
-
const templates = Array.from(
|
|
186
|
-
element.querySelectorAll("template[variant-id]")
|
|
187
|
-
);
|
|
188
|
-
if (!templates.length)
|
|
189
|
-
return console.warn(`${Name2}: No variant templates found`);
|
|
190
|
-
const [state] = useProduct(element);
|
|
191
|
-
const fallbackChildren = Array.from(element.children);
|
|
192
|
-
const activeVariantTemplate = createMemo(() => {
|
|
193
|
-
const variantId = state.product?.selected_or_first_available_variant?.id;
|
|
194
|
-
if (!variantId) return null;
|
|
195
|
-
const template = templates.find(
|
|
196
|
-
(t) => t.getAttribute("variant-id") === `${variantId}`
|
|
197
|
-
);
|
|
198
|
-
return template || null;
|
|
199
|
-
});
|
|
200
|
-
element.replaceChildren(...[]);
|
|
201
|
-
return html`
|
|
202
|
-
<${Show}
|
|
203
|
-
when=${() => !!activeVariantTemplate()}
|
|
204
|
-
fallback=${fallbackChildren}
|
|
205
|
-
>
|
|
206
|
-
${() => Array.from(
|
|
207
|
-
activeVariantTemplate()?.content.cloneNode(true).childNodes || []
|
|
208
|
-
)}
|
|
209
|
-
<//>
|
|
210
|
-
`;
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
// src/components/product-options.ts
|
|
214
|
-
var product_options_exports = {};
|
|
215
|
-
__export(product_options_exports, {
|
|
216
|
-
Component: () => Component3,
|
|
217
|
-
Name: () => Name3
|
|
218
|
-
});
|
|
219
|
-
var Name3 = `product-options`;
|
|
220
|
-
var Component3 = (props, { element }) => {
|
|
221
|
-
if (!props.selectedOptions)
|
|
222
|
-
return console.warn(`${Name3}: selected-options attribute is required`);
|
|
223
|
-
provideProductOptionsContext(props, element);
|
|
224
|
-
};
|
|
225
|
-
|
|
226
|
-
// src/components/product-option-group.ts
|
|
227
|
-
var product_option_group_exports = {};
|
|
228
|
-
__export(product_option_group_exports, {
|
|
229
|
-
Component: () => Component4,
|
|
230
|
-
Name: () => Name4
|
|
231
|
-
});
|
|
232
|
-
var Name4 = `product-option-group`;
|
|
233
|
-
var Component4 = (props, { element }) => {
|
|
234
|
-
const [context, methods] = useProductOptions(element);
|
|
235
|
-
createEffect(
|
|
236
|
-
on(
|
|
237
|
-
() => ({
|
|
238
|
-
selectedOption: context.selectedOptions[props.position - 1],
|
|
239
|
-
position: props.position,
|
|
240
|
-
name: props.name,
|
|
241
|
-
inputType: props.inputType
|
|
242
|
-
}),
|
|
243
|
-
({ selectedOption, position, name, inputType }) => {
|
|
244
|
-
if (inputType !== "radio" && inputType !== "select") return;
|
|
245
|
-
const optionName = `${name}-${position}`;
|
|
246
|
-
if (inputType === "radio") {
|
|
247
|
-
const inputs = element.querySelectorAll(
|
|
248
|
-
`input[name="${optionName}"]`
|
|
249
|
-
);
|
|
250
|
-
inputs.forEach((input) => {
|
|
251
|
-
const prevValue = input.checked;
|
|
252
|
-
if (input.value === selectedOption) input.checked = true;
|
|
253
|
-
else input.checked = false;
|
|
254
|
-
if (prevValue !== input.checked) {
|
|
255
|
-
input.dispatchEvent(new Event("change", { bubbles: true }));
|
|
256
|
-
}
|
|
257
|
-
});
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
260
|
-
const select = element.querySelector(
|
|
261
|
-
`select[name="${optionName}"]`
|
|
262
|
-
);
|
|
263
|
-
if (!select || !selectedOption) return;
|
|
264
|
-
select.value = selectedOption;
|
|
265
|
-
select.dispatchEvent(new Event("change", { bubbles: true }));
|
|
266
|
-
}
|
|
267
|
-
)
|
|
268
|
-
);
|
|
269
|
-
createEffect(() => {
|
|
270
|
-
const position = props.position;
|
|
271
|
-
function handleChange(event) {
|
|
272
|
-
const target = event.target;
|
|
273
|
-
if (!target) return;
|
|
274
|
-
const selectedOption = target.value;
|
|
275
|
-
if (context.selectedOptions[position - 1] === selectedOption) return;
|
|
276
|
-
element.dispatchEvent(
|
|
277
|
-
new CustomEvent("option-updated", {
|
|
278
|
-
detail: {
|
|
279
|
-
group: props.name,
|
|
280
|
-
position,
|
|
281
|
-
selectedOption
|
|
282
|
-
},
|
|
283
|
-
bubbles: true
|
|
284
|
-
})
|
|
285
|
-
);
|
|
286
|
-
methods.options.updateOption(selectedOption, position - 1);
|
|
287
|
-
}
|
|
288
|
-
element.addEventListener("change", handleChange);
|
|
289
|
-
return onCleanup(() => {
|
|
290
|
-
element.removeEventListener("change", handleChange);
|
|
291
|
-
});
|
|
292
|
-
});
|
|
293
|
-
};
|
|
294
|
-
|
|
295
|
-
// src/components/product-variant-input.ts
|
|
296
|
-
var product_variant_input_exports = {};
|
|
297
|
-
__export(product_variant_input_exports, {
|
|
298
|
-
Component: () => Component5,
|
|
299
|
-
Name: () => Name5
|
|
300
|
-
});
|
|
301
|
-
var Name5 = `product-variant-input`;
|
|
302
|
-
var Component5 = (props, { element }) => {
|
|
303
|
-
const [productContext, productContextMethods] = useProduct(element);
|
|
304
|
-
const [_, optionsMethods] = useProductOptions(element);
|
|
305
|
-
createEffect(() => {
|
|
306
|
-
let target = null;
|
|
307
|
-
if (props.target) target = element.querySelector(props.target);
|
|
308
|
-
if (!target) target = element;
|
|
309
|
-
const preventDefault = props.preventDefault;
|
|
310
|
-
function handleChange(event) {
|
|
311
|
-
if (preventDefault) event.preventDefault();
|
|
312
|
-
const target2 = event.target;
|
|
313
|
-
if (!target2) return;
|
|
314
|
-
const value = target2.value;
|
|
315
|
-
if (value === productContext?.product?.selected_or_first_available_variant?.id)
|
|
316
|
-
return;
|
|
317
|
-
const variant = productContext?.product?.variants.find(
|
|
318
|
-
(variant2) => variant2.id.toString() === value.toString()
|
|
319
|
-
);
|
|
320
|
-
if (!variant) return;
|
|
321
|
-
if (optionsMethods) optionsMethods.options.update(variant.options);
|
|
322
|
-
else productContextMethods.variant.update(variant.id);
|
|
323
|
-
}
|
|
324
|
-
target.addEventListener("change", handleChange);
|
|
325
|
-
return onCleanup(() => {
|
|
326
|
-
target.removeEventListener("change", handleChange);
|
|
327
|
-
});
|
|
328
|
-
});
|
|
329
|
-
createEffect(() => {
|
|
330
|
-
let target = null;
|
|
331
|
-
if (props.target)
|
|
332
|
-
target = element.querySelector(props.target);
|
|
333
|
-
if (!target)
|
|
334
|
-
target = element.querySelector("input[name='id']");
|
|
335
|
-
if (!target) return console.warn(`${Name5}: target input not found`);
|
|
336
|
-
const variantId = productContext?.product?.selected_or_first_available_variant?.id;
|
|
337
|
-
if (!variantId) return;
|
|
338
|
-
if (target.value === variantId.toString()) return;
|
|
339
|
-
target.value = variantId.toString();
|
|
340
|
-
target.dispatchEvent(new Event("change", { bubbles: true }));
|
|
341
|
-
});
|
|
342
|
-
};
|
|
343
|
-
|
|
344
|
-
// src/index.ts
|
|
345
|
-
customShadowlessElement(
|
|
346
|
-
product_info_exports.Name,
|
|
347
|
-
{
|
|
348
|
-
product: void 0,
|
|
349
|
-
isProductPage: false
|
|
350
|
-
},
|
|
351
|
-
correctElementType(product_info_exports.Component)
|
|
352
|
-
);
|
|
353
|
-
customShadowlessElement(
|
|
354
|
-
product_options_exports.Name,
|
|
355
|
-
{
|
|
356
|
-
selectedOptions: []
|
|
357
|
-
},
|
|
358
|
-
correctElementType(product_options_exports.Component)
|
|
359
|
-
);
|
|
360
|
-
customShadowlessElement(
|
|
361
|
-
product_option_group_exports.Name,
|
|
362
|
-
{
|
|
363
|
-
position: 0,
|
|
364
|
-
name: "",
|
|
365
|
-
inputType: "radio"
|
|
366
|
-
},
|
|
367
|
-
correctElementType(product_option_group_exports.Component)
|
|
368
|
-
);
|
|
369
|
-
customShadowlessElement(
|
|
370
|
-
product_variant_input_exports.Name,
|
|
371
|
-
{
|
|
372
|
-
target: "",
|
|
373
|
-
preventDefault: true
|
|
374
|
-
},
|
|
375
|
-
correctElementType(product_variant_input_exports.Component)
|
|
376
|
-
);
|
|
377
|
-
customShadowlessElement(
|
|
378
|
-
product_variant_render_exports.Name,
|
|
379
|
-
{},
|
|
380
|
-
correctElementType(product_variant_render_exports.Component)
|
|
381
|
-
);
|
|
382
|
-
|
|
383
|
-
export { getProductContext, getProductOptionsContext, useProduct, useProductOptions, withProductElementContext, withProductOptionsElementContext };
|
|
384
|
-
//# sourceMappingURL=index.js.map
|
|
385
|
-
//# sourceMappingURL=index.js.map
|
package/dist/esm/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/product-info.ts","../../src/hooks/useProduct.ts","../../src/hooks/useProductOptions.ts","../../src/components/product-variant-render.ts","../../src/components/product-options.ts","../../src/components/product-option-group.ts","../../src/components/product-variant-input.ts","../../src/index.ts"],"names":["splitProps","untrack","variant","createContext","mergeProps","provide","consume","getContextFromProvider","createWithElementContext","url","createEffect","Component","Name","createMemo","target","onCleanup"],"mappings":"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","file":"index.js","sourcesContent":["import type { CorrectComponentType } from \"@brytdesigns/web-component-core/utils\";\n\nimport { createEffect, createMemo, observable } from \"solid-js\";\n\nimport { provideProductContext } from \"../hooks/index.js\";\n\nimport type { Product } from \"../types.js\";\n\nexport type Props = {\n product?: Product;\n isProductPage?: boolean;\n};\n\nexport const Name = `product-info`;\n\nexport const Component: CorrectComponentType<Props> = (props, { element }) => {\n if (!props.product)\n return console.warn(`${Name}: product attribute is required`);\n if (!props.product.variants)\n return console.warn(`${Name}: product attribute needs variants array`);\n if (!props.product.selected_or_first_available_variant)\n return console.warn(\n `${Name}: product attribute needs selected or first available variant object`,\n );\n provideProductContext(props as any, element);\n\n const url = createMemo(() => {\n const url = new URL(window.location.href);\n const variant = props?.product?.selected_or_first_available_variant;\n if (props.product && variant && variant?.id) {\n url.searchParams.set(\"variant\", variant.id.toString());\n } else {\n url.searchParams.delete(\"variant\");\n }\n return url;\n });\n\n function subscribe(cb: (product: Product | undefined) => void) {\n return observable(() => props.product).subscribe(cb).unsubscribe;\n }\n\n Object.assign(element, {\n subscribe,\n });\n\n createEffect(() => {\n if (!props.isProductPage) return;\n window.history.replaceState(null, \"\", url());\n });\n};\n","import {\n type ICustomElement,\n createContext,\n provide,\n consume,\n} from \"component-register\";\nimport { mergeProps, splitProps, untrack } from \"solid-js\";\nimport {\n getContextFromProvider,\n createWithElementContext,\n} from \"@brytdesigns/web-component-core/utils\";\n\nimport type { Product } from \"../types\";\n\ntype CreateContextOptions = {\n root: HTMLElement & ICustomElement;\n product: Product;\n};\n\ntype WalkableNode = Parameters<typeof provide>[2];\n\ntype ProductContext = ReturnType<typeof initializeProductContext>;\n\nfunction initializeProductContext(props: CreateContextOptions) {\n const [privateProps, publicProps] = splitProps(props, [\"root\"]);\n const state = mergeProps(publicProps, {});\n\n function updateSelectedVariant(variantId: string | number) {\n const product = untrack(() => state?.product);\n if (\n typeof product?.selected_or_first_available_variant === \"undefined\" ||\n typeof product === \"undefined\" ||\n typeof product?.variants === \"undefined\"\n )\n return;\n const newVariant = product.variants.find(\n (variant) => variant?.id?.toString() === variantId.toString(),\n );\n\n if (\n newVariant?.id?.toString() ===\n product.selected_or_first_available_variant?.id?.toString()\n )\n return;\n\n const newState = {\n ...product,\n selected_or_first_available_variant: newVariant,\n };\n\n privateProps.root.setAttribute(\"product\", JSON.stringify(newState));\n\n privateProps.root.dispatchEvent(\n new CustomEvent(\"variant-updated\", {\n detail: {\n variant: newVariant,\n product: newState,\n },\n bubbles: true,\n }),\n );\n }\n\n return [\n state,\n {\n variant: {\n update: updateSelectedVariant,\n },\n },\n ] as const;\n}\n\nconst ProductContextState = createContext(initializeProductContext);\n\nexport const provideProductContext = (\n initialState: Omit<CreateContextOptions, \"root\">,\n element: WalkableNode,\n): ProductContext => {\n const props = mergeProps(initialState, { root: element });\n return provide(ProductContextState, props, element);\n};\n\nexport const useProductContext = (context: ProductContext) => {\n return context;\n};\n\nexport const useProduct = (element: HTMLElement & ICustomElement) => {\n const context: ProductContext = consume(ProductContextState, element);\n\n if (!context) {\n throw console.error(\n \"ProductInfoContext not found! Please ensure to wrap your custom element with product-info element.\",\n );\n }\n\n return useProductContext(context);\n};\n\nexport const getProductContext = (element: Element) => {\n const context = getContextFromProvider<ProductContext>(\n ProductContextState,\n element,\n );\n return useProductContext(context);\n};\n\nexport const withProductElementContext = createWithElementContext<\n typeof ProductContextState,\n ProductContext\n>(ProductContextState);\n","import {\n type ICustomElement,\n createContext,\n provide,\n consume,\n} from \"component-register\";\nimport { createEffect, mergeProps, splitProps, untrack } from \"solid-js\";\nimport {\n getContextFromProvider,\n createWithElementContext,\n} from \"@brytdesigns/web-component-core/utils\";\n\nimport { useProduct } from \"./useProduct.js\";\n\ntype CreateContextOptions = {\n root: HTMLElement & ICustomElement;\n selectedOptions: string[];\n};\n\ntype WalkableNode = Parameters<typeof provide>[2];\n\ntype ProductOptionsContext = ReturnType<typeof initializeProductOptionsContext>;\n\nfunction initializeProductOptionsContext(props: CreateContextOptions) {\n const [privateProps, publicProps] = splitProps(props, [\"root\"]);\n const [context, methods] = useProduct(privateProps.root);\n\n function updateSelectedOptions(options: string[]) {\n privateProps.root.setAttribute(\"selected-options\", JSON.stringify(options));\n }\n\n function updateSelectedOption(option: string, index: number) {\n const current = untrack(() => publicProps.selectedOptions);\n const options = [...current];\n options[index] = option;\n return updateSelectedOptions(options);\n }\n\n createEffect(() => {\n const variant = context.product.variants.find((variant) => {\n return publicProps.selectedOptions.every((option) =>\n variant.options.includes(option),\n );\n });\n if (!variant) return;\n if (variant.id === context.product.selected_or_first_available_variant.id)\n return;\n methods.variant.update(variant.id);\n });\n\n return [\n publicProps,\n {\n options: {\n update: updateSelectedOptions,\n updateOption: updateSelectedOption,\n },\n },\n ] as const;\n}\n\nconst ProductOptionsContextState = createContext(\n initializeProductOptionsContext,\n);\n\nexport const provideProductOptionsContext = (\n initialState: Omit<CreateContextOptions, \"root\">,\n element: WalkableNode,\n): ProductOptionsContext => {\n const props = mergeProps(initialState, { root: element });\n return provide(ProductOptionsContextState, props, element);\n};\n\nexport const useProductOptionsContext = (context: ProductOptionsContext) => {\n return context;\n};\n\nexport const useProductOptions = (element: HTMLElement & ICustomElement) => {\n const context: ProductOptionsContext = consume(\n ProductOptionsContextState,\n element,\n );\n\n if (!context) {\n throw console.error(\n \"ProductOptionsContext not found! Please ensure to wrap your custom element with product-options element.\",\n );\n }\n\n return useProductOptionsContext(context);\n};\n\nexport const getProductOptionsContext = (element: Element) => {\n const context = getContextFromProvider<ProductOptionsContext>(\n ProductOptionsContextState,\n element,\n );\n return useProductOptionsContext(context);\n};\n\nexport const withProductOptionsElementContext = createWithElementContext<\n typeof ProductOptionsContextState,\n ProductOptionsContext\n>(ProductOptionsContextState);\n","import type { CorrectComponentType } from \"@brytdesigns/web-component-core/utils\";\n\nimport { createMemo, Show } from \"solid-js\";\nimport html from \"solid-js/html\";\n\nimport { useProduct } from \"../hooks/index.js\";\n\nexport type Props = {};\n\nexport const Name = `product-variant-render`;\n\nexport const Component: CorrectComponentType<Props> = (_, { element }) => {\n const templates = Array.from(\n element.querySelectorAll<HTMLTemplateElement>(\"template[variant-id]\"),\n );\n if (!templates.length)\n return console.warn(`${Name}: No variant templates found`);\n const [state] = useProduct(element);\n\n const fallbackChildren = Array.from(element.children);\n\n const activeVariantTemplate = createMemo(() => {\n const variantId = state.product?.selected_or_first_available_variant?.id;\n if (!variantId) return null;\n const template = templates.find(\n (t) => t.getAttribute(\"variant-id\") === `${variantId}`,\n );\n return template || null;\n });\n\n element.replaceChildren(...[]);\n\n return html`\n <${Show}\n when=${() => !!activeVariantTemplate()}\n fallback=${fallbackChildren}\n >\n ${() =>\n Array.from(\n activeVariantTemplate()?.content.cloneNode(true).childNodes || [],\n )}\n <//>\n `;\n};\n","import type { CorrectComponentType } from \"@brytdesigns/web-component-core/utils\";\nimport { provideProductOptionsContext } from \"../hooks/index.js\";\n\nexport type Props = {\n selectedOptions: string[];\n};\n\nexport const Name = `product-options`;\n\nexport const Component: CorrectComponentType<Props> = (props, { element }) => {\n if (!props.selectedOptions)\n return console.warn(`${Name}: selected-options attribute is required`);\n provideProductOptionsContext(props, element);\n};\n","import type { CorrectComponentType } from \"@brytdesigns/web-component-core/utils\";\n\nimport { createEffect, on, onCleanup } from \"solid-js\";\n\nimport { useProductOptions } from \"../hooks/index.js\";\n\nexport type Props = {\n position: number;\n name: string;\n inputType: \"radio\" | \"select\";\n};\n\nexport const Name = `product-option-group`;\n\nexport const Component: CorrectComponentType<Props> = (props, { element }) => {\n const [context, methods] = useProductOptions(element);\n\n createEffect(\n on(\n () => ({\n selectedOption: context.selectedOptions[props.position - 1],\n position: props.position,\n name: props.name,\n inputType: props.inputType,\n }),\n ({ selectedOption, position, name, inputType }) => {\n if (inputType !== \"radio\" && inputType !== \"select\") return;\n\n const optionName = `${name}-${position}`;\n\n if (inputType === \"radio\") {\n const inputs = element.querySelectorAll<HTMLInputElement>(\n `input[name=\"${optionName}\"]`,\n );\n inputs.forEach((input) => {\n const prevValue = input.checked;\n if (input.value === selectedOption) input.checked = true;\n else input.checked = false;\n if (prevValue !== input.checked) {\n input.dispatchEvent(new Event(\"change\", { bubbles: true }));\n }\n });\n return;\n }\n\n const select = element.querySelector<HTMLSelectElement>(\n `select[name=\"${optionName}\"]`,\n );\n if (!select || !selectedOption) return;\n select.value = selectedOption;\n select.dispatchEvent(new Event(\"change\", { bubbles: true }));\n },\n ),\n );\n\n createEffect(() => {\n const position = props.position;\n\n function handleChange(event: Event) {\n const target = event.target as HTMLInputElement;\n if (!target) return;\n const selectedOption = target.value;\n if (context.selectedOptions[position - 1] === selectedOption) return;\n\n element.dispatchEvent(\n new CustomEvent(\"option-updated\", {\n detail: {\n group: props.name,\n position: position,\n selectedOption,\n },\n bubbles: true,\n }),\n );\n\n methods.options.updateOption(selectedOption, position - 1);\n }\n\n element.addEventListener(\"change\", handleChange);\n\n return onCleanup(() => {\n element.removeEventListener(\"change\", handleChange);\n });\n });\n};\n","import type { CorrectComponentType } from \"@brytdesigns/web-component-core/utils\";\n\nimport { createEffect, onCleanup } from \"solid-js\";\n\nimport { useProduct, useProductOptions } from \"../hooks/index.js\";\n\nexport type Props = {\n target: string | null;\n preventDefault?: boolean;\n};\n\nexport const Name = `product-variant-input`;\n\nexport const Component: CorrectComponentType<Props> = (props, { element }) => {\n const [productContext, productContextMethods] = useProduct(element);\n const [_, optionsMethods] = useProductOptions(element);\n\n createEffect(() => {\n let target = null;\n if (props.target) target = element.querySelector(props.target);\n if (!target) target = element;\n\n const preventDefault = props.preventDefault;\n\n function handleChange(event: Event) {\n if (preventDefault) event.preventDefault();\n const target = event.target as HTMLInputElement;\n if (!target) return;\n const value = target.value;\n if (\n value ===\n productContext?.product?.selected_or_first_available_variant?.id\n )\n return;\n const variant = productContext?.product?.variants.find(\n (variant) => variant.id.toString() === value.toString(),\n );\n if (!variant) return;\n if (optionsMethods) optionsMethods.options.update(variant.options);\n else productContextMethods.variant.update(variant.id);\n }\n\n target.addEventListener(\"change\", handleChange);\n\n return onCleanup(() => {\n target.removeEventListener(\"change\", handleChange);\n });\n });\n\n createEffect(() => {\n let target = null;\n if (props.target)\n target = element.querySelector<HTMLInputElement>(props.target);\n if (!target)\n target = element.querySelector<HTMLInputElement>(\"input[name='id']\");\n if (!target) return console.warn(`${Name}: target input not found`);\n\n const variantId =\n productContext?.product?.selected_or_first_available_variant?.id;\n if (!variantId) return;\n if (target.value === variantId.toString()) return;\n target.value = variantId.toString();\n target.dispatchEvent(new Event(\"change\", { bubbles: true }));\n });\n};\n","import {\n customShadowlessElement,\n correctElementType,\n} from \"@brytdesigns/web-component-core/utils\";\n\nimport {\n ProductInfo,\n ProductOptions,\n ProductOptionGroup,\n ProductVariantInput,\n ProductVariantRender,\n} from \"./components/index.js\";\n\nexport type ProductInfoProps = ProductInfo.Props;\nexport type ProductOptionsProps = ProductOptions.Props;\nexport type ProductOptionGroupProps = ProductOptionGroup.Props;\nexport type ProductVariantInputProps = ProductVariantInput.Props;\nexport type ProductVariantRenderProps = ProductVariantRender.Props;\n\ncustomShadowlessElement(\n ProductInfo.Name,\n {\n product: undefined,\n isProductPage: false,\n },\n correctElementType(ProductInfo.Component),\n);\n\ncustomShadowlessElement(\n ProductOptions.Name,\n {\n selectedOptions: [],\n },\n correctElementType(ProductOptions.Component),\n);\n\ncustomShadowlessElement(\n ProductOptionGroup.Name,\n {\n position: 0,\n name: \"\",\n inputType: \"radio\",\n },\n correctElementType(ProductOptionGroup.Component),\n);\n\ncustomShadowlessElement(\n ProductVariantInput.Name,\n {\n target: \"\",\n preventDefault: true,\n },\n correctElementType(ProductVariantInput.Component),\n);\n\ncustomShadowlessElement(\n ProductVariantRender.Name,\n {},\n correctElementType(ProductVariantRender.Component),\n);\n\nexport {\n useProduct,\n useProductOptions,\n getProductContext,\n getProductOptionsContext,\n withProductElementContext,\n withProductOptionsElementContext,\n} from \"./hooks/index.js\";\n"]}
|