@shopify/hydrogen-react
Version:
React components, hooks, and utilities for creating custom Shopify storefronts
162 lines (161 loc) • 7.06 kB
JavaScript
;
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