UNPKG

@shopify/hydrogen-react

Version:

React components, hooks, and utilities for creating custom Shopify storefronts

162 lines (161 loc) • 7.06 kB
"use strict"; Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } }); const require$$0 = require("react"); const flattenConnection = require("./flatten-connection.js"); const jsxRuntime = require("react/jsx-runtime"); const ProductOptionsContext = require$$0.createContext(null); function ProductProvider({ children, data: product, initialVariantId: explicitVariantId }) { const variants = require$$0.useMemo(() => { var _a; return flattenConnection.flattenConnection((_a = product.variants) != null ? _a : {}); }, [product.variants]); if (!isProductVariantArray(variants)) { throw new Error(`<ProductProvider/> requires 'product.variants.nodes' or 'product.variants.edges'`); } const options = require$$0.useMemo(() => getOptions(variants), [variants]); const [selectedVariant, setSelectedVariant] = require$$0.useState(() => getVariantBasedOnIdProp(explicitVariantId, variants)); const [selectedOptions, setSelectedOptions] = require$$0.useState(() => getSelectedOptions(selectedVariant)); require$$0.useEffect(() => { const newSelectedVariant = getVariantBasedOnIdProp(explicitVariantId, variants); setSelectedVariant(newSelectedVariant); setSelectedOptions(getSelectedOptions(newSelectedVariant)); }, [explicitVariantId, variants]); const setSelectedOption = require$$0.useCallback((name, value2) => { setSelectedOptions((selectedOptions2) => { const opts = { ...selectedOptions2, [name]: value2 }; setSelectedVariant(getSelectedVariant(variants, opts)); return opts; }); }, [setSelectedOptions, variants]); const isOptionInStock = require$$0.useCallback((option, value2) => { var _a; const proposedVariant = getSelectedVariant(variants, { ...selectedOptions, ...{ [option]: value2 } }); return (_a = proposedVariant == null ? void 0 : proposedVariant.availableForSale) != null ? _a : true; }, [selectedOptions, variants]); const sellingPlanGroups = require$$0.useMemo(() => { var _a; return flattenConnection.flattenConnection((_a = product.sellingPlanGroups) != null ? _a : {}).map((sellingPlanGroup) => { var _a2; return { ...sellingPlanGroup, sellingPlans: flattenConnection.flattenConnection((_a2 = sellingPlanGroup == null ? void 0 : sellingPlanGroup.sellingPlans) != null ? _a2 : {}) }; }); }, [product.sellingPlanGroups]); const [selectedSellingPlan, setSelectedSellingPlan] = require$$0.useState(void 0); const selectedSellingPlanAllocation = require$$0.useMemo(() => { var _a, _b; if (!selectedVariant || !selectedSellingPlan) { return; } if (!((_a = selectedVariant.sellingPlanAllocations) == null ? void 0 : _a.nodes) && !((_b = selectedVariant.sellingPlanAllocations) == null ? void 0 : _b.edges)) { throw new Error(`<ProductProvider/>: You must include 'sellingPlanAllocations.nodes' or 'sellingPlanAllocations.edges' in your variants in order to calculate selectedSellingPlanAllocation`); } return flattenConnection.flattenConnection(selectedVariant.sellingPlanAllocations).find((allocation) => { var _a2; return ((_a2 = allocation == null ? void 0 : allocation.sellingPlan) == null ? void 0 : _a2.id) === selectedSellingPlan.id; }); }, [selectedVariant, selectedSellingPlan]); const value = require$$0.useMemo(() => ({ variants, variantsConnection: product.variants, options, selectedVariant, setSelectedVariant, selectedOptions, setSelectedOption, setSelectedOptions, isOptionInStock, selectedSellingPlan, setSelectedSellingPlan, selectedSellingPlanAllocation, sellingPlanGroups, sellingPlanGroupsConnection: product.sellingPlanGroups }), [isOptionInStock, options, product.sellingPlanGroups, product.variants, selectedOptions, selectedSellingPlan, selectedSellingPlanAllocation, selectedVariant, sellingPlanGroups, setSelectedOption, variants]); return /* @__PURE__ */ jsxRuntime.jsx(ProductOptionsContext.Provider, { value, children }); } function useProduct() { const context = require$$0.useContext(ProductOptionsContext); if (!context) { throw new Error(`'useProduct' must be a child of <ProductProvider />`); } return context; } function getSelectedVariant(variants, choices) { var _a, _b; if (!variants.length || ((_b = (_a = variants == null ? void 0 : variants[0]) == null ? void 0 : _a.selectedOptions) == null ? void 0 : _b.length) !== Object.keys(choices).length) { return; } return variants == null ? void 0 : variants.find((variant) => { return Object.entries(choices).every(([name, value]) => { var _a2; return (_a2 = variant == null ? void 0 : variant.selectedOptions) == null ? void 0 : _a2.some((option) => (option == null ? void 0 : option.name) === name && (option == null ? void 0 : option.value) === value); }); }); } function getOptions(variants) { const map = variants.reduce((memo, variant) => { var _a; if (!variant.selectedOptions) { throw new Error(`'getOptions' requires 'variant.selectedOptions'`); } (_a = variant == null ? void 0 : variant.selectedOptions) == null ? void 0 : _a.forEach((opt) => { var _a2, _b, _c, _d; memo[(_a2 = opt == null ? void 0 : opt.name) != null ? _a2 : ""] = memo[(_b = opt == null ? void 0 : opt.name) != null ? _b : ""] || /* @__PURE__ */ new Set(); memo[(_c = opt == null ? void 0 : opt.name) != null ? _c : ""].add((_d = opt == null ? void 0 : opt.value) != null ? _d : ""); }); return memo; }, {}); return Object.keys(map).map((option) => { return { name: option, values: Array.from(map[option]) }; }); } function getVariantBasedOnIdProp(explicitVariantId, variants) { if (explicitVariantId) { const foundVariant = variants.find((variant) => (variant == null ? void 0 : variant.id) === explicitVariantId); if (!foundVariant) { console.warn(`<ProductProvider/> received a 'initialVariantId' prop, but could not actually find a variant with that ID`); } return foundVariant; } if (explicitVariantId === null) { return null; } if (explicitVariantId === void 0) { return variants.find((variant) => variant == null ? void 0 : variant.availableForSale) || variants[0]; } } function getSelectedOptions(selectedVariant) { return (selectedVariant == null ? void 0 : selectedVariant.selectedOptions) ? selectedVariant.selectedOptions.reduce((memo, optionSet) => { var _a, _b; memo[(_a = optionSet == null ? void 0 : optionSet.name) != null ? _a : ""] = (_b = optionSet == null ? void 0 : optionSet.value) != null ? _b : ""; return memo; }, {}) : {}; } function isProductVariantArray(maybeVariantArray) { if (!maybeVariantArray || !Array.isArray(maybeVariantArray)) { return false; } return true; } exports.ProductProvider = ProductProvider; exports.useProduct = useProduct; //# sourceMappingURL=ProductProvider.js.map