@brytdesigns/shopify-product-info-components 3.3.2 → 3.3.3

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.
@@ -0,0 +1,385 @@
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
@@ -0,0 +1 @@
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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brytdesigns/shopify-product-info-components",
3
- "version": "3.3.2",
3
+ "version": "3.3.3",
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.3.2",
23
- "@brytdesigns/web-component-core": "3.3.2",
22
+ "@brytdesigns/shopify-utils": "3.3.3",
23
+ "@brytdesigns/web-component-core": "3.3.3",
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"