@shopify/hydrogen-react 2022.10.1 → 2022.10.2
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/dev/AddToCartButton.js +70 -0
- package/dist/dev/AddToCartButton.js.map +1 -0
- package/dist/dev/AddToCartButton.mjs +70 -0
- package/dist/dev/AddToCartButton.mjs.map +1 -0
- package/dist/dev/BaseButton.js +31 -0
- package/dist/dev/BaseButton.js.map +1 -0
- package/dist/dev/BaseButton.mjs +31 -0
- package/dist/dev/BaseButton.mjs.map +1 -0
- package/dist/dev/BuyNowButton.js +45 -0
- package/dist/dev/BuyNowButton.js.map +1 -0
- package/dist/dev/BuyNowButton.mjs +45 -0
- package/dist/dev/BuyNowButton.mjs.map +1 -0
- package/dist/dev/CartCheckoutButton.js +30 -0
- package/dist/dev/CartCheckoutButton.js.map +1 -0
- package/dist/dev/CartCheckoutButton.mjs +30 -0
- package/dist/dev/CartCheckoutButton.mjs.map +1 -0
- package/dist/dev/MediaFile.js.map +1 -1
- package/dist/dev/MediaFile.mjs.map +1 -1
- package/dist/dev/Metafield.js +6 -0
- package/dist/dev/Metafield.js.map +1 -1
- package/dist/dev/Metafield.mjs +6 -0
- package/dist/dev/Metafield.mjs.map +1 -1
- package/dist/dev/ProductPrice.js.map +1 -1
- package/dist/dev/ProductPrice.mjs.map +1 -1
- package/dist/dev/cart-hooks.js +2 -2
- package/dist/dev/cart-hooks.js.map +1 -1
- package/dist/dev/cart-hooks.mjs +3 -3
- package/dist/dev/cart-hooks.mjs.map +1 -1
- package/dist/dev/index.js +8 -0
- package/dist/dev/index.js.map +1 -1
- package/dist/dev/index.mjs +8 -0
- package/dist/dev/index.mjs.map +1 -1
- package/dist/dev/metafield-parser.js +103 -0
- package/dist/dev/metafield-parser.js.map +1 -0
- package/dist/dev/metafield-parser.mjs +103 -0
- package/dist/dev/metafield-parser.mjs.map +1 -0
- package/dist/prod/AddToCartButton.js +70 -0
- package/dist/prod/AddToCartButton.js.map +1 -0
- package/dist/prod/AddToCartButton.mjs +70 -0
- package/dist/prod/AddToCartButton.mjs.map +1 -0
- package/dist/prod/BaseButton.js +31 -0
- package/dist/prod/BaseButton.js.map +1 -0
- package/dist/prod/BaseButton.mjs +31 -0
- package/dist/prod/BaseButton.mjs.map +1 -0
- package/dist/prod/BuyNowButton.js +45 -0
- package/dist/prod/BuyNowButton.js.map +1 -0
- package/dist/prod/BuyNowButton.mjs +45 -0
- package/dist/prod/BuyNowButton.mjs.map +1 -0
- package/dist/prod/CartCheckoutButton.js +30 -0
- package/dist/prod/CartCheckoutButton.js.map +1 -0
- package/dist/prod/CartCheckoutButton.mjs +30 -0
- package/dist/prod/CartCheckoutButton.mjs.map +1 -0
- package/dist/prod/MediaFile.js.map +1 -1
- package/dist/prod/MediaFile.mjs.map +1 -1
- package/dist/prod/Metafield.js.map +1 -1
- package/dist/prod/Metafield.mjs.map +1 -1
- package/dist/prod/ProductPrice.js.map +1 -1
- package/dist/prod/ProductPrice.mjs.map +1 -1
- package/dist/prod/cart-hooks.js +2 -2
- package/dist/prod/cart-hooks.js.map +1 -1
- package/dist/prod/cart-hooks.mjs +3 -3
- package/dist/prod/cart-hooks.mjs.map +1 -1
- package/dist/prod/index.js +8 -0
- package/dist/prod/index.js.map +1 -1
- package/dist/prod/index.mjs +8 -0
- package/dist/prod/index.mjs.map +1 -1
- package/dist/prod/metafield-parser.js +114 -0
- package/dist/prod/metafield-parser.js.map +1 -0
- package/dist/prod/metafield-parser.mjs +114 -0
- package/dist/prod/metafield-parser.mjs.map +1 -0
- package/dist/types/AddToCartButton.d.ts +22 -0
- package/dist/types/BaseButton.d.ts +15 -0
- package/dist/types/BuyNowButton.d.ts +15 -0
- package/dist/types/CartCheckoutButton.d.ts +12 -0
- package/dist/types/CartCost.d.ts +13 -0
- package/dist/types/MediaFile.d.ts +3 -1
- package/dist/types/Metafield.d.ts +3 -0
- package/dist/types/ProductPrice.d.ts +1 -2
- package/dist/types/index.d.cts +4 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/metafield-parser.d.ts +222 -0
- package/dist/umd/hydrogen-react.dev.js +482 -203
- package/dist/umd/hydrogen-react.dev.js.map +1 -1
- package/dist/umd/hydrogen-react.prod.js +17 -17
- package/dist/umd/hydrogen-react.prod.js.map +1 -1
- package/package.json +12 -4
- package/dist/dev/node_modules/worktop/cookie/index.js +0 -27
- package/dist/dev/node_modules/worktop/cookie/index.js.map +0 -1
- package/dist/dev/node_modules/worktop/cookie/index.mjs +0 -27
- package/dist/dev/node_modules/worktop/cookie/index.mjs.map +0 -1
- package/dist/prod/node_modules/worktop/cookie/index.js +0 -27
- package/dist/prod/node_modules/worktop/cookie/index.js.map +0 -1
- package/dist/prod/node_modules/worktop/cookie/index.mjs +0 -27
- package/dist/prod/node_modules/worktop/cookie/index.mjs.map +0 -1
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const require$$0 = require("react");
|
|
4
|
+
const CartProvider = require("./CartProvider.js");
|
|
5
|
+
const ProductProvider = require("./ProductProvider.js");
|
|
6
|
+
const BaseButton = require("./BaseButton.js");
|
|
7
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
8
|
+
function AddToCartButton(props) {
|
|
9
|
+
var _a;
|
|
10
|
+
const [addingItem, setAddingItem] = require$$0.useState(false);
|
|
11
|
+
const {
|
|
12
|
+
variantId: explicitVariantId,
|
|
13
|
+
quantity = 1,
|
|
14
|
+
attributes,
|
|
15
|
+
sellingPlanId,
|
|
16
|
+
onClick,
|
|
17
|
+
children,
|
|
18
|
+
accessibleAddingToCartLabel,
|
|
19
|
+
...passthroughProps
|
|
20
|
+
} = props;
|
|
21
|
+
const {
|
|
22
|
+
status,
|
|
23
|
+
linesAdd
|
|
24
|
+
} = CartProvider.useCart();
|
|
25
|
+
const {
|
|
26
|
+
selectedVariant
|
|
27
|
+
} = ProductProvider.useProduct();
|
|
28
|
+
const variantId = (_a = explicitVariantId != null ? explicitVariantId : selectedVariant == null ? void 0 : selectedVariant.id) != null ? _a : "";
|
|
29
|
+
const disabled = explicitVariantId === null || variantId === "" || selectedVariant === null || addingItem || passthroughProps.disabled;
|
|
30
|
+
require$$0.useEffect(() => {
|
|
31
|
+
if (addingItem && status === "idle") {
|
|
32
|
+
setAddingItem(false);
|
|
33
|
+
}
|
|
34
|
+
}, [status, addingItem]);
|
|
35
|
+
const handleAddItem = require$$0.useCallback(() => {
|
|
36
|
+
setAddingItem(true);
|
|
37
|
+
linesAdd([{
|
|
38
|
+
quantity,
|
|
39
|
+
merchandiseId: variantId || "",
|
|
40
|
+
attributes,
|
|
41
|
+
sellingPlanId
|
|
42
|
+
}]);
|
|
43
|
+
}, [linesAdd, quantity, variantId, attributes, sellingPlanId]);
|
|
44
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
45
|
+
children: [/* @__PURE__ */ jsxRuntime.jsx(BaseButton.BaseButton, {
|
|
46
|
+
...passthroughProps,
|
|
47
|
+
disabled,
|
|
48
|
+
onClick,
|
|
49
|
+
defaultOnClick: handleAddItem,
|
|
50
|
+
children
|
|
51
|
+
}), accessibleAddingToCartLabel ? /* @__PURE__ */ jsxRuntime.jsx("p", {
|
|
52
|
+
style: {
|
|
53
|
+
position: "absolute",
|
|
54
|
+
width: "1px",
|
|
55
|
+
height: "1px",
|
|
56
|
+
padding: "0",
|
|
57
|
+
margin: "-1px",
|
|
58
|
+
overflow: "hidden",
|
|
59
|
+
clip: "rect(0, 0, 0, 0)",
|
|
60
|
+
whiteSpace: "nowrap",
|
|
61
|
+
borderWidth: "0"
|
|
62
|
+
},
|
|
63
|
+
role: "alert",
|
|
64
|
+
"aria-live": "assertive",
|
|
65
|
+
children: addingItem ? accessibleAddingToCartLabel : null
|
|
66
|
+
}) : null]
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
exports.AddToCartButton = AddToCartButton;
|
|
70
|
+
//# sourceMappingURL=AddToCartButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AddToCartButton.js","sources":["../../src/AddToCartButton.tsx"],"sourcesContent":["import {useCallback, useEffect, useState} from 'react';\n\nimport {useCart} from './CartProvider.js';\nimport {useProduct} from './ProductProvider.js';\nimport {BaseButton, BaseButtonProps} from './BaseButton.js';\n\ninterface AddToCartButtonProps {\n /** An array of cart line attributes that belong to the item being added to the cart. */\n attributes?: {\n key: string;\n value: string;\n }[];\n /** The ID of the variant. */\n variantId?: string | null;\n /** The item quantity. */\n quantity?: number;\n /** The text that is announced by the screen reader when the item is being added to the cart. Used for accessibility purposes only and not displayed on the page. */\n accessibleAddingToCartLabel?: string;\n /** The selling plan ID of the subscription variant */\n sellingPlanId?: string;\n}\n\n/**\n * The `AddToCartButton` component renders a button that adds an item to the cart when pressed.\n * It must be a descendent of the `CartProvider` component.\n */\nexport function AddToCartButton<AsType extends React.ElementType = 'button'>(\n props: AddToCartButtonProps & BaseButtonProps<AsType>\n) {\n const [addingItem, setAddingItem] = useState<boolean>(false);\n const {\n variantId: explicitVariantId,\n quantity = 1,\n attributes,\n sellingPlanId,\n onClick,\n children,\n accessibleAddingToCartLabel,\n ...passthroughProps\n } = props;\n const {status, linesAdd} = useCart();\n const {selectedVariant} = useProduct();\n const variantId = explicitVariantId ?? selectedVariant?.id ?? '';\n const disabled =\n explicitVariantId === null ||\n variantId === '' ||\n selectedVariant === null ||\n addingItem ||\n passthroughProps.disabled;\n\n useEffect(() => {\n if (addingItem && status === 'idle') {\n setAddingItem(false);\n }\n }, [status, addingItem]);\n\n const handleAddItem = useCallback(() => {\n setAddingItem(true);\n linesAdd([\n {\n quantity,\n merchandiseId: variantId || '',\n attributes,\n sellingPlanId,\n },\n ]);\n }, [linesAdd, quantity, variantId, attributes, sellingPlanId]);\n\n return (\n <>\n <BaseButton\n {...passthroughProps}\n disabled={disabled}\n onClick={onClick}\n defaultOnClick={handleAddItem}\n >\n {children}\n </BaseButton>\n {accessibleAddingToCartLabel ? (\n <p\n style={{\n position: 'absolute',\n width: '1px',\n height: '1px',\n padding: '0',\n margin: '-1px',\n overflow: 'hidden',\n clip: 'rect(0, 0, 0, 0)',\n whiteSpace: 'nowrap',\n borderWidth: '0',\n }}\n role=\"alert\"\n aria-live=\"assertive\"\n >\n {addingItem ? accessibleAddingToCartLabel : null}\n </p>\n ) : null}\n </>\n );\n}\n"],"names":["AddToCartButton","props","addingItem","setAddingItem","useState","variantId","explicitVariantId","quantity","attributes","sellingPlanId","onClick","children","accessibleAddingToCartLabel","passthroughProps","status","linesAdd","useCart","selectedVariant","useProduct","id","disabled","useEffect","handleAddItem","useCallback","merchandiseId","_Fragment","_jsx","BaseButton","position","width","height","padding","margin","overflow","clip","whiteSpace","borderWidth"],"mappings":";;;;;;;AA0BO,SAASA,gBACdC,OACA;;AACA,QAAM,CAACC,YAAYC,aAAb,IAA8BC,oBAAkB,KAAV;AACtC,QAAA;AAAA,IACJC,WAAWC;AAAAA,IACXC,WAAW;AAAA,IACXC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,OACGC;AAAAA,EACDZ,IAAAA;AACE,QAAA;AAAA,IAACa;AAAAA,IAAQC;AAAAA,MAAYC,aAA3B,QAAA;AACM,QAAA;AAAA,IAACC;AAAAA,MAAmBC,gBAA1B,WAAA;AACMb,QAAAA,aAAYC,qDAAqBW,mDAAiBE,OAAtCb,YAA4C;AACxDc,QAAAA,WACJd,sBAAsB,QACtBD,cAAc,MACdY,oBAAoB,QACpBf,cACAW,iBAAiBO;AAEnBC,aAAAA,UAAU,MAAM;AACVnB,QAAAA,cAAcY,WAAW,QAAQ;AACnCX,oBAAc,KAAD;AAAA,IACd;AAAA,EAAA,GACA,CAACW,QAAQZ,UAAT,CAJM;AAMHoB,QAAAA,gBAAgBC,WAAAA,YAAY,MAAM;AACtCpB,kBAAc,IAAD;AACbY,aAAS,CACP;AAAA,MACER;AAAAA,MACAiB,eAAenB,aAAa;AAAA,MAC5BG;AAAAA,MACAC;AAAAA,IALK,CAAA,CAAD;AAAA,EAAA,GAQP,CAACM,UAAUR,UAAUF,WAAWG,YAAYC,aAA5C,CAV8B;AAYjC,yCACEgB,WAAAA,UAAA;AAAA,IAAA,UACE,CAAAC,2BAAA,IAACC,uBAAD;AAAA,MAAA,GACMd;AAAAA,MACJ;AAAA,MACA;AAAA,MACA,gBAAgBS;AAAAA,MAJlB;AAAA,IAAA,CADF,GASGV,8BACCc,2BAAA,IAAA,KAAA;AAAA,MACE,OAAO;AAAA,QACLE,UAAU;AAAA,QACVC,OAAO;AAAA,QACPC,QAAQ;AAAA,QACRC,SAAS;AAAA,QACTC,QAAQ;AAAA,QACRC,UAAU;AAAA,QACVC,MAAM;AAAA,QACNC,YAAY;AAAA,QACZC,aAAa;AAAA,MATR;AAAA,MAWP,MAAK;AAAA,MACL,aAAU;AAAA,MAbZ,UAeGlC,aAAaU,8BAA8B;AAAA,IAf9C,CAAA,IAiBE,IA3BN;AAAA,EAAA,CADF;AA+BD;;"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { useState, useEffect, useCallback } from "react";
|
|
2
|
+
import { useCart } from "./CartProvider.mjs";
|
|
3
|
+
import { useProduct } from "./ProductProvider.mjs";
|
|
4
|
+
import { BaseButton } from "./BaseButton.mjs";
|
|
5
|
+
import { jsxs, Fragment, jsx } from "react/jsx-runtime";
|
|
6
|
+
function AddToCartButton(props) {
|
|
7
|
+
var _a;
|
|
8
|
+
const [addingItem, setAddingItem] = useState(false);
|
|
9
|
+
const {
|
|
10
|
+
variantId: explicitVariantId,
|
|
11
|
+
quantity = 1,
|
|
12
|
+
attributes,
|
|
13
|
+
sellingPlanId,
|
|
14
|
+
onClick,
|
|
15
|
+
children,
|
|
16
|
+
accessibleAddingToCartLabel,
|
|
17
|
+
...passthroughProps
|
|
18
|
+
} = props;
|
|
19
|
+
const {
|
|
20
|
+
status,
|
|
21
|
+
linesAdd
|
|
22
|
+
} = useCart();
|
|
23
|
+
const {
|
|
24
|
+
selectedVariant
|
|
25
|
+
} = useProduct();
|
|
26
|
+
const variantId = (_a = explicitVariantId != null ? explicitVariantId : selectedVariant == null ? void 0 : selectedVariant.id) != null ? _a : "";
|
|
27
|
+
const disabled = explicitVariantId === null || variantId === "" || selectedVariant === null || addingItem || passthroughProps.disabled;
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (addingItem && status === "idle") {
|
|
30
|
+
setAddingItem(false);
|
|
31
|
+
}
|
|
32
|
+
}, [status, addingItem]);
|
|
33
|
+
const handleAddItem = useCallback(() => {
|
|
34
|
+
setAddingItem(true);
|
|
35
|
+
linesAdd([{
|
|
36
|
+
quantity,
|
|
37
|
+
merchandiseId: variantId || "",
|
|
38
|
+
attributes,
|
|
39
|
+
sellingPlanId
|
|
40
|
+
}]);
|
|
41
|
+
}, [linesAdd, quantity, variantId, attributes, sellingPlanId]);
|
|
42
|
+
return /* @__PURE__ */ jsxs(Fragment, {
|
|
43
|
+
children: [/* @__PURE__ */ jsx(BaseButton, {
|
|
44
|
+
...passthroughProps,
|
|
45
|
+
disabled,
|
|
46
|
+
onClick,
|
|
47
|
+
defaultOnClick: handleAddItem,
|
|
48
|
+
children
|
|
49
|
+
}), accessibleAddingToCartLabel ? /* @__PURE__ */ jsx("p", {
|
|
50
|
+
style: {
|
|
51
|
+
position: "absolute",
|
|
52
|
+
width: "1px",
|
|
53
|
+
height: "1px",
|
|
54
|
+
padding: "0",
|
|
55
|
+
margin: "-1px",
|
|
56
|
+
overflow: "hidden",
|
|
57
|
+
clip: "rect(0, 0, 0, 0)",
|
|
58
|
+
whiteSpace: "nowrap",
|
|
59
|
+
borderWidth: "0"
|
|
60
|
+
},
|
|
61
|
+
role: "alert",
|
|
62
|
+
"aria-live": "assertive",
|
|
63
|
+
children: addingItem ? accessibleAddingToCartLabel : null
|
|
64
|
+
}) : null]
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
export {
|
|
68
|
+
AddToCartButton
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=AddToCartButton.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AddToCartButton.mjs","sources":["../../src/AddToCartButton.tsx"],"sourcesContent":["import {useCallback, useEffect, useState} from 'react';\n\nimport {useCart} from './CartProvider.js';\nimport {useProduct} from './ProductProvider.js';\nimport {BaseButton, BaseButtonProps} from './BaseButton.js';\n\ninterface AddToCartButtonProps {\n /** An array of cart line attributes that belong to the item being added to the cart. */\n attributes?: {\n key: string;\n value: string;\n }[];\n /** The ID of the variant. */\n variantId?: string | null;\n /** The item quantity. */\n quantity?: number;\n /** The text that is announced by the screen reader when the item is being added to the cart. Used for accessibility purposes only and not displayed on the page. */\n accessibleAddingToCartLabel?: string;\n /** The selling plan ID of the subscription variant */\n sellingPlanId?: string;\n}\n\n/**\n * The `AddToCartButton` component renders a button that adds an item to the cart when pressed.\n * It must be a descendent of the `CartProvider` component.\n */\nexport function AddToCartButton<AsType extends React.ElementType = 'button'>(\n props: AddToCartButtonProps & BaseButtonProps<AsType>\n) {\n const [addingItem, setAddingItem] = useState<boolean>(false);\n const {\n variantId: explicitVariantId,\n quantity = 1,\n attributes,\n sellingPlanId,\n onClick,\n children,\n accessibleAddingToCartLabel,\n ...passthroughProps\n } = props;\n const {status, linesAdd} = useCart();\n const {selectedVariant} = useProduct();\n const variantId = explicitVariantId ?? selectedVariant?.id ?? '';\n const disabled =\n explicitVariantId === null ||\n variantId === '' ||\n selectedVariant === null ||\n addingItem ||\n passthroughProps.disabled;\n\n useEffect(() => {\n if (addingItem && status === 'idle') {\n setAddingItem(false);\n }\n }, [status, addingItem]);\n\n const handleAddItem = useCallback(() => {\n setAddingItem(true);\n linesAdd([\n {\n quantity,\n merchandiseId: variantId || '',\n attributes,\n sellingPlanId,\n },\n ]);\n }, [linesAdd, quantity, variantId, attributes, sellingPlanId]);\n\n return (\n <>\n <BaseButton\n {...passthroughProps}\n disabled={disabled}\n onClick={onClick}\n defaultOnClick={handleAddItem}\n >\n {children}\n </BaseButton>\n {accessibleAddingToCartLabel ? (\n <p\n style={{\n position: 'absolute',\n width: '1px',\n height: '1px',\n padding: '0',\n margin: '-1px',\n overflow: 'hidden',\n clip: 'rect(0, 0, 0, 0)',\n whiteSpace: 'nowrap',\n borderWidth: '0',\n }}\n role=\"alert\"\n aria-live=\"assertive\"\n >\n {addingItem ? accessibleAddingToCartLabel : null}\n </p>\n ) : null}\n </>\n );\n}\n"],"names":["AddToCartButton","props","addingItem","setAddingItem","useState","variantId","explicitVariantId","quantity","attributes","sellingPlanId","onClick","children","accessibleAddingToCartLabel","passthroughProps","status","linesAdd","useCart","selectedVariant","useProduct","id","disabled","useEffect","handleAddItem","useCallback","merchandiseId","_Fragment","_jsx","position","width","height","padding","margin","overflow","clip","whiteSpace","borderWidth"],"mappings":";;;;;AA0BO,SAASA,gBACdC,OACA;;AACA,QAAM,CAACC,YAAYC,aAAb,IAA8BC,SAAkB,KAAV;AACtC,QAAA;AAAA,IACJC,WAAWC;AAAAA,IACXC,WAAW;AAAA,IACXC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,OACGC;AAAAA,EACDZ,IAAAA;AACE,QAAA;AAAA,IAACa;AAAAA,IAAQC;AAAAA,MAAYC,QAA3B;AACM,QAAA;AAAA,IAACC;AAAAA,MAAmBC,WAA1B;AACMb,QAAAA,aAAYC,qDAAqBW,mDAAiBE,OAAtCb,YAA4C;AACxDc,QAAAA,WACJd,sBAAsB,QACtBD,cAAc,MACdY,oBAAoB,QACpBf,cACAW,iBAAiBO;AAEnBC,YAAU,MAAM;AACVnB,QAAAA,cAAcY,WAAW,QAAQ;AACnCX,oBAAc,KAAD;AAAA,IACd;AAAA,EAAA,GACA,CAACW,QAAQZ,UAAT,CAJM;AAMHoB,QAAAA,gBAAgBC,YAAY,MAAM;AACtCpB,kBAAc,IAAD;AACbY,aAAS,CACP;AAAA,MACER;AAAAA,MACAiB,eAAenB,aAAa;AAAA,MAC5BG;AAAAA,MACAC;AAAAA,IALK,CAAA,CAAD;AAAA,EAAA,GAQP,CAACM,UAAUR,UAAUF,WAAWG,YAAYC,aAA5C,CAV8B;AAYjC,8BACEgB,UAAA;AAAA,IAAA,UACE,CAAAC,oBAAC,YAAD;AAAA,MAAA,GACMb;AAAAA,MACJ;AAAA,MACA;AAAA,MACA,gBAAgBS;AAAAA,MAJlB;AAAA,IAAA,CADF,GASGV,8BACCc,oBAAA,KAAA;AAAA,MACE,OAAO;AAAA,QACLC,UAAU;AAAA,QACVC,OAAO;AAAA,QACPC,QAAQ;AAAA,QACRC,SAAS;AAAA,QACTC,QAAQ;AAAA,QACRC,UAAU;AAAA,QACVC,MAAM;AAAA,QACNC,YAAY;AAAA,QACZC,aAAa;AAAA,MATR;AAAA,MAWP,MAAK;AAAA,MACL,aAAU;AAAA,MAbZ,UAeGjC,aAAaU,8BAA8B;AAAA,IAf9C,CAAA,IAiBE,IA3BN;AAAA,EAAA,CADF;AA+BD;"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const require$$0 = require("react");
|
|
4
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
5
|
+
function BaseButton(props) {
|
|
6
|
+
const {
|
|
7
|
+
as,
|
|
8
|
+
onClick,
|
|
9
|
+
defaultOnClick,
|
|
10
|
+
children,
|
|
11
|
+
buttonRef,
|
|
12
|
+
...passthroughProps
|
|
13
|
+
} = props;
|
|
14
|
+
const handleOnClick = require$$0.useCallback((event) => {
|
|
15
|
+
if (onClick) {
|
|
16
|
+
const clickShouldContinue = onClick(event);
|
|
17
|
+
if (typeof clickShouldContinue === "boolean" && clickShouldContinue === false || (event == null ? void 0 : event.defaultPrevented))
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
defaultOnClick == null ? void 0 : defaultOnClick(event);
|
|
21
|
+
}, [defaultOnClick, onClick]);
|
|
22
|
+
const Component = as || "button";
|
|
23
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Component, {
|
|
24
|
+
ref: buttonRef,
|
|
25
|
+
onClick: handleOnClick,
|
|
26
|
+
...passthroughProps,
|
|
27
|
+
children
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
exports.BaseButton = BaseButton;
|
|
31
|
+
//# sourceMappingURL=BaseButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseButton.js","sources":["../../src/BaseButton.tsx"],"sourcesContent":["import {ReactNode, Ref, useCallback} from 'react';\n\nexport interface CustomBaseButtonProps<AsType> {\n /** Provide a React element or component to render as the underlying button. Note: for accessibility compliance, almost always you should use a `button` element, or a component that renders an underlying button. */\n as?: AsType;\n /** Any ReactNode elements. */\n children: ReactNode;\n /** Click event handler. Default behaviour triggers unless prevented */\n onClick?: (\n event?: React.MouseEvent<HTMLButtonElement, MouseEvent>\n ) => void | boolean;\n /** A default onClick behavior */\n defaultOnClick?: (\n event?: React.MouseEvent<HTMLButtonElement, MouseEvent>\n ) => void | boolean;\n /** A ref to the underlying button */\n buttonRef?: Ref<HTMLButtonElement>;\n}\n\nexport type BaseButtonProps<AsType extends React.ElementType> =\n CustomBaseButtonProps<AsType> &\n Omit<\n React.ComponentPropsWithoutRef<AsType>,\n keyof CustomBaseButtonProps<AsType>\n >;\n\nexport function BaseButton<AsType extends React.ElementType = 'button'>(\n props: BaseButtonProps<AsType>\n) {\n const {\n as,\n onClick,\n defaultOnClick,\n children,\n buttonRef,\n ...passthroughProps\n } = props;\n\n const handleOnClick = useCallback(\n (event?: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {\n if (onClick) {\n const clickShouldContinue = onClick(event);\n if (\n (typeof clickShouldContinue === 'boolean' &&\n clickShouldContinue === false) ||\n event?.defaultPrevented\n )\n return;\n }\n\n defaultOnClick?.(event);\n },\n [defaultOnClick, onClick]\n );\n\n const Component = as || 'button';\n\n return (\n <Component ref={buttonRef} onClick={handleOnClick} {...passthroughProps}>\n {children}\n </Component>\n );\n}\n"],"names":["BaseButton","props","as","onClick","defaultOnClick","children","buttonRef","passthroughProps","handleOnClick","useCallback","event","clickShouldContinue","defaultPrevented","Component"],"mappings":";;;;AA0BO,SAASA,WACdC,OACA;AACM,QAAA;AAAA,IACJC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,OACGC;AAAAA,EACDN,IAAAA;AAEEO,QAAAA,gBAAgBC,uBACpB,CAACC,UAA4D;AAC3D,QAAIP,SAAS;AACLQ,YAAAA,sBAAsBR,QAAQO,KAAD;AACnC,UACG,OAAOC,wBAAwB,aAC9BA,wBAAwB,UAC1BD,+BAAOE;AAEP;AAAA,IACH;AAEDR,qDAAiBM;AAAAA,EAAH,GAEhB,CAACN,gBAAgBD,OAAjB,CAd+B;AAiBjC,QAAMU,YAAYX,MAAM;AAExB,wCACG,WAAD;AAAA,IAAW,KAAKI;AAAAA,IAAW,SAASE;AAAAA,IAApC,GAAuDD;AAAAA,IAAvD;AAAA,EAAA,CADF;AAKD;;"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
function BaseButton(props) {
|
|
4
|
+
const {
|
|
5
|
+
as,
|
|
6
|
+
onClick,
|
|
7
|
+
defaultOnClick,
|
|
8
|
+
children,
|
|
9
|
+
buttonRef,
|
|
10
|
+
...passthroughProps
|
|
11
|
+
} = props;
|
|
12
|
+
const handleOnClick = useCallback((event) => {
|
|
13
|
+
if (onClick) {
|
|
14
|
+
const clickShouldContinue = onClick(event);
|
|
15
|
+
if (typeof clickShouldContinue === "boolean" && clickShouldContinue === false || (event == null ? void 0 : event.defaultPrevented))
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
defaultOnClick == null ? void 0 : defaultOnClick(event);
|
|
19
|
+
}, [defaultOnClick, onClick]);
|
|
20
|
+
const Component = as || "button";
|
|
21
|
+
return /* @__PURE__ */ jsx(Component, {
|
|
22
|
+
ref: buttonRef,
|
|
23
|
+
onClick: handleOnClick,
|
|
24
|
+
...passthroughProps,
|
|
25
|
+
children
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
BaseButton
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=BaseButton.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseButton.mjs","sources":["../../src/BaseButton.tsx"],"sourcesContent":["import {ReactNode, Ref, useCallback} from 'react';\n\nexport interface CustomBaseButtonProps<AsType> {\n /** Provide a React element or component to render as the underlying button. Note: for accessibility compliance, almost always you should use a `button` element, or a component that renders an underlying button. */\n as?: AsType;\n /** Any ReactNode elements. */\n children: ReactNode;\n /** Click event handler. Default behaviour triggers unless prevented */\n onClick?: (\n event?: React.MouseEvent<HTMLButtonElement, MouseEvent>\n ) => void | boolean;\n /** A default onClick behavior */\n defaultOnClick?: (\n event?: React.MouseEvent<HTMLButtonElement, MouseEvent>\n ) => void | boolean;\n /** A ref to the underlying button */\n buttonRef?: Ref<HTMLButtonElement>;\n}\n\nexport type BaseButtonProps<AsType extends React.ElementType> =\n CustomBaseButtonProps<AsType> &\n Omit<\n React.ComponentPropsWithoutRef<AsType>,\n keyof CustomBaseButtonProps<AsType>\n >;\n\nexport function BaseButton<AsType extends React.ElementType = 'button'>(\n props: BaseButtonProps<AsType>\n) {\n const {\n as,\n onClick,\n defaultOnClick,\n children,\n buttonRef,\n ...passthroughProps\n } = props;\n\n const handleOnClick = useCallback(\n (event?: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {\n if (onClick) {\n const clickShouldContinue = onClick(event);\n if (\n (typeof clickShouldContinue === 'boolean' &&\n clickShouldContinue === false) ||\n event?.defaultPrevented\n )\n return;\n }\n\n defaultOnClick?.(event);\n },\n [defaultOnClick, onClick]\n );\n\n const Component = as || 'button';\n\n return (\n <Component ref={buttonRef} onClick={handleOnClick} {...passthroughProps}>\n {children}\n </Component>\n );\n}\n"],"names":["BaseButton","props","as","onClick","defaultOnClick","children","buttonRef","passthroughProps","handleOnClick","useCallback","event","clickShouldContinue","defaultPrevented","Component"],"mappings":";;AA0BO,SAASA,WACdC,OACA;AACM,QAAA;AAAA,IACJC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,OACGC;AAAAA,EACDN,IAAAA;AAEEO,QAAAA,gBAAgBC,YACpB,CAACC,UAA4D;AAC3D,QAAIP,SAAS;AACLQ,YAAAA,sBAAsBR,QAAQO,KAAD;AACnC,UACG,OAAOC,wBAAwB,aAC9BA,wBAAwB,UAC1BD,+BAAOE;AAEP;AAAA,IACH;AAEDR,qDAAiBM;AAAAA,EAAH,GAEhB,CAACN,gBAAgBD,OAAjB,CAd+B;AAiBjC,QAAMU,YAAYX,MAAM;AAExB,6BACG,WAAD;AAAA,IAAW,KAAKI;AAAAA,IAAW,SAASE;AAAAA,IAApC,GAAuDD;AAAAA,IAAvD;AAAA,EAAA,CADF;AAKD;"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const require$$0 = require("react");
|
|
4
|
+
const CartProvider = require("./CartProvider.js");
|
|
5
|
+
const BaseButton = require("./BaseButton.js");
|
|
6
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
7
|
+
function BuyNowButton(props) {
|
|
8
|
+
const {
|
|
9
|
+
cartCreate,
|
|
10
|
+
checkoutUrl
|
|
11
|
+
} = CartProvider.useCart();
|
|
12
|
+
const [loading, setLoading] = require$$0.useState(false);
|
|
13
|
+
const {
|
|
14
|
+
quantity,
|
|
15
|
+
variantId,
|
|
16
|
+
onClick,
|
|
17
|
+
attributes,
|
|
18
|
+
children,
|
|
19
|
+
...passthroughProps
|
|
20
|
+
} = props;
|
|
21
|
+
require$$0.useEffect(() => {
|
|
22
|
+
if (checkoutUrl) {
|
|
23
|
+
window.location.href = checkoutUrl;
|
|
24
|
+
}
|
|
25
|
+
}, [checkoutUrl]);
|
|
26
|
+
const handleBuyNow = require$$0.useCallback(() => {
|
|
27
|
+
setLoading(true);
|
|
28
|
+
cartCreate({
|
|
29
|
+
lines: [{
|
|
30
|
+
quantity: quantity != null ? quantity : 1,
|
|
31
|
+
merchandiseId: variantId,
|
|
32
|
+
attributes
|
|
33
|
+
}]
|
|
34
|
+
});
|
|
35
|
+
}, [cartCreate, quantity, variantId, attributes]);
|
|
36
|
+
return /* @__PURE__ */ jsxRuntime.jsx(BaseButton.BaseButton, {
|
|
37
|
+
disabled: loading != null ? loading : passthroughProps.disabled,
|
|
38
|
+
...passthroughProps,
|
|
39
|
+
onClick,
|
|
40
|
+
defaultOnClick: handleBuyNow,
|
|
41
|
+
children
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
exports.BuyNowButton = BuyNowButton;
|
|
45
|
+
//# sourceMappingURL=BuyNowButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BuyNowButton.js","sources":["../../src/BuyNowButton.tsx"],"sourcesContent":["import {useEffect, useState, useCallback} from 'react';\nimport {useCart} from './CartProvider.js';\nimport {BaseButton, BaseButtonProps} from './BaseButton.js';\n\ninterface BuyNowButtonProps {\n /** The item quantity. Defaults to 1. */\n quantity?: number;\n /** The ID of the variant. */\n variantId: string;\n /** An array of cart line attributes that belong to the item being added to the cart. */\n attributes?: {\n key: string;\n value: string;\n }[];\n}\n\n/** The `BuyNowButton` component renders a button that adds an item to the cart and redirects the customer to checkout. */\nexport function BuyNowButton<AsType extends React.ElementType = 'button'>(\n props: BuyNowButtonProps & BaseButtonProps<AsType>\n) {\n const {cartCreate, checkoutUrl} = useCart();\n const [loading, setLoading] = useState<boolean>(false);\n\n const {\n quantity,\n variantId,\n onClick,\n attributes,\n children,\n ...passthroughProps\n } = props;\n\n useEffect(() => {\n if (checkoutUrl) {\n window.location.href = checkoutUrl;\n }\n }, [checkoutUrl]);\n\n const handleBuyNow = useCallback(() => {\n setLoading(true);\n cartCreate({\n lines: [\n {\n quantity: quantity ?? 1,\n merchandiseId: variantId,\n attributes,\n },\n ],\n });\n }, [cartCreate, quantity, variantId, attributes]);\n\n return (\n <BaseButton\n disabled={loading ?? passthroughProps.disabled}\n {...passthroughProps}\n onClick={onClick}\n defaultOnClick={handleBuyNow}\n >\n {children}\n </BaseButton>\n );\n}\n"],"names":["BuyNowButton","props","cartCreate","checkoutUrl","useCart","loading","setLoading","useState","quantity","variantId","onClick","attributes","children","passthroughProps","useEffect","window","location","href","handleBuyNow","useCallback","lines","merchandiseId","BaseButton","disabled"],"mappings":";;;;;;AAiBO,SAASA,aACdC,OACA;AACM,QAAA;AAAA,IAACC;AAAAA,IAAYC;AAAAA,MAAeC,aAAlC,QAAA;AACA,QAAM,CAACC,SAASC,UAAV,IAAwBC,oBAAkB,KAAV;AAEhC,QAAA;AAAA,IACJC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,OACGC;AAAAA,EACDZ,IAAAA;AAEJa,aAAAA,UAAU,MAAM;AACd,QAAIX,aAAa;AACfY,aAAOC,SAASC,OAAOd;AAAAA,IACxB;AAAA,EAAA,GACA,CAACA,WAAD,CAJM;AAMHe,QAAAA,eAAeC,WAAAA,YAAY,MAAM;AACrCb,eAAW,IAAD;AACC,eAAA;AAAA,MACTc,OAAO,CACL;AAAA,QACEZ,UAAUA,8BAAY;AAAA,QACtBa,eAAeZ;AAAAA,QACfE;AAAAA,MAAAA,CAJG;AAAA,IAAA,CADC;AAAA,KAST,CAACT,YAAYM,UAAUC,WAAWE,UAAlC,CAX6B;AAahC,wCACGW,WAAAA,YAAD;AAAA,IACE,UAAUjB,4BAAWQ,iBAAiBU;AAAAA,IADxC,GAEMV;AAAAA,IACJ;AAAA,IACA,gBAAgBK;AAAAA,IAJlB;AAAA,EAAA,CADF;AAUD;;"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { useState, useEffect, useCallback } from "react";
|
|
2
|
+
import { useCart } from "./CartProvider.mjs";
|
|
3
|
+
import { BaseButton } from "./BaseButton.mjs";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
function BuyNowButton(props) {
|
|
6
|
+
const {
|
|
7
|
+
cartCreate,
|
|
8
|
+
checkoutUrl
|
|
9
|
+
} = useCart();
|
|
10
|
+
const [loading, setLoading] = useState(false);
|
|
11
|
+
const {
|
|
12
|
+
quantity,
|
|
13
|
+
variantId,
|
|
14
|
+
onClick,
|
|
15
|
+
attributes,
|
|
16
|
+
children,
|
|
17
|
+
...passthroughProps
|
|
18
|
+
} = props;
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (checkoutUrl) {
|
|
21
|
+
window.location.href = checkoutUrl;
|
|
22
|
+
}
|
|
23
|
+
}, [checkoutUrl]);
|
|
24
|
+
const handleBuyNow = useCallback(() => {
|
|
25
|
+
setLoading(true);
|
|
26
|
+
cartCreate({
|
|
27
|
+
lines: [{
|
|
28
|
+
quantity: quantity != null ? quantity : 1,
|
|
29
|
+
merchandiseId: variantId,
|
|
30
|
+
attributes
|
|
31
|
+
}]
|
|
32
|
+
});
|
|
33
|
+
}, [cartCreate, quantity, variantId, attributes]);
|
|
34
|
+
return /* @__PURE__ */ jsx(BaseButton, {
|
|
35
|
+
disabled: loading != null ? loading : passthroughProps.disabled,
|
|
36
|
+
...passthroughProps,
|
|
37
|
+
onClick,
|
|
38
|
+
defaultOnClick: handleBuyNow,
|
|
39
|
+
children
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
export {
|
|
43
|
+
BuyNowButton
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=BuyNowButton.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BuyNowButton.mjs","sources":["../../src/BuyNowButton.tsx"],"sourcesContent":["import {useEffect, useState, useCallback} from 'react';\nimport {useCart} from './CartProvider.js';\nimport {BaseButton, BaseButtonProps} from './BaseButton.js';\n\ninterface BuyNowButtonProps {\n /** The item quantity. Defaults to 1. */\n quantity?: number;\n /** The ID of the variant. */\n variantId: string;\n /** An array of cart line attributes that belong to the item being added to the cart. */\n attributes?: {\n key: string;\n value: string;\n }[];\n}\n\n/** The `BuyNowButton` component renders a button that adds an item to the cart and redirects the customer to checkout. */\nexport function BuyNowButton<AsType extends React.ElementType = 'button'>(\n props: BuyNowButtonProps & BaseButtonProps<AsType>\n) {\n const {cartCreate, checkoutUrl} = useCart();\n const [loading, setLoading] = useState<boolean>(false);\n\n const {\n quantity,\n variantId,\n onClick,\n attributes,\n children,\n ...passthroughProps\n } = props;\n\n useEffect(() => {\n if (checkoutUrl) {\n window.location.href = checkoutUrl;\n }\n }, [checkoutUrl]);\n\n const handleBuyNow = useCallback(() => {\n setLoading(true);\n cartCreate({\n lines: [\n {\n quantity: quantity ?? 1,\n merchandiseId: variantId,\n attributes,\n },\n ],\n });\n }, [cartCreate, quantity, variantId, attributes]);\n\n return (\n <BaseButton\n disabled={loading ?? passthroughProps.disabled}\n {...passthroughProps}\n onClick={onClick}\n defaultOnClick={handleBuyNow}\n >\n {children}\n </BaseButton>\n );\n}\n"],"names":["BuyNowButton","props","cartCreate","checkoutUrl","useCart","loading","setLoading","useState","quantity","variantId","onClick","attributes","children","passthroughProps","useEffect","window","location","href","handleBuyNow","useCallback","lines","merchandiseId","disabled"],"mappings":";;;;AAiBO,SAASA,aACdC,OACA;AACM,QAAA;AAAA,IAACC;AAAAA,IAAYC;AAAAA,MAAeC,QAAlC;AACA,QAAM,CAACC,SAASC,UAAV,IAAwBC,SAAkB,KAAV;AAEhC,QAAA;AAAA,IACJC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,IACAC;AAAAA,OACGC;AAAAA,EACDZ,IAAAA;AAEJa,YAAU,MAAM;AACd,QAAIX,aAAa;AACfY,aAAOC,SAASC,OAAOd;AAAAA,IACxB;AAAA,EAAA,GACA,CAACA,WAAD,CAJM;AAMHe,QAAAA,eAAeC,YAAY,MAAM;AACrCb,eAAW,IAAD;AACC,eAAA;AAAA,MACTc,OAAO,CACL;AAAA,QACEZ,UAAUA,8BAAY;AAAA,QACtBa,eAAeZ;AAAAA,QACfE;AAAAA,MAAAA,CAJG;AAAA,IAAA,CADC;AAAA,KAST,CAACT,YAAYM,UAAUC,WAAWE,UAAlC,CAX6B;AAahC,6BACG,YAAD;AAAA,IACE,UAAUN,4BAAWQ,iBAAiBS;AAAAA,IADxC,GAEMT;AAAAA,IACJ;AAAA,IACA,gBAAgBK;AAAAA,IAJlB;AAAA,EAAA,CADF;AAUD;"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const require$$0 = require("react");
|
|
4
|
+
const CartProvider = require("./CartProvider.js");
|
|
5
|
+
const BaseButton = require("./BaseButton.js");
|
|
6
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
7
|
+
function CartCheckoutButton(props) {
|
|
8
|
+
const [requestedCheckout, setRequestedCheckout] = require$$0.useState(false);
|
|
9
|
+
const {
|
|
10
|
+
status,
|
|
11
|
+
checkoutUrl
|
|
12
|
+
} = CartProvider.useCart();
|
|
13
|
+
const {
|
|
14
|
+
children,
|
|
15
|
+
...passthroughProps
|
|
16
|
+
} = props;
|
|
17
|
+
require$$0.useEffect(() => {
|
|
18
|
+
if (requestedCheckout && checkoutUrl && status === "idle") {
|
|
19
|
+
window.location.href = checkoutUrl;
|
|
20
|
+
}
|
|
21
|
+
}, [requestedCheckout, status, checkoutUrl]);
|
|
22
|
+
return /* @__PURE__ */ jsxRuntime.jsx(BaseButton.BaseButton, {
|
|
23
|
+
...passthroughProps,
|
|
24
|
+
disabled: requestedCheckout || passthroughProps.disabled,
|
|
25
|
+
onClick: () => setRequestedCheckout(true),
|
|
26
|
+
children
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
exports.CartCheckoutButton = CartCheckoutButton;
|
|
30
|
+
//# sourceMappingURL=CartCheckoutButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CartCheckoutButton.js","sources":["../../src/CartCheckoutButton.tsx"],"sourcesContent":["import {ReactNode, useEffect, useState} from 'react';\nimport {useCart} from './CartProvider.js';\nimport {BaseButton, BaseButtonProps} from './BaseButton.js';\n\ntype PropsWeControl = 'onClick';\n\n/**\n * The `CartCheckoutButton` component renders a button that redirects to the checkout URL for the cart.\n * It must be a descendent of a `CartProvider` component.\n */\nexport function CartCheckoutButton(\n props: Omit<BaseButtonProps<'button'>, PropsWeControl> & {\n /** A `ReactNode` element. */\n children: ReactNode;\n }\n) {\n const [requestedCheckout, setRequestedCheckout] = useState(false);\n const {status, checkoutUrl} = useCart();\n const {children, ...passthroughProps} = props;\n\n useEffect(() => {\n if (requestedCheckout && checkoutUrl && status === 'idle') {\n window.location.href = checkoutUrl;\n }\n }, [requestedCheckout, status, checkoutUrl]);\n\n return (\n <BaseButton\n {...passthroughProps}\n disabled={requestedCheckout || passthroughProps.disabled}\n onClick={() => setRequestedCheckout(true)}\n >\n {children}\n </BaseButton>\n );\n}\n"],"names":["CartCheckoutButton","props","requestedCheckout","setRequestedCheckout","useState","status","checkoutUrl","useCart","children","passthroughProps","useEffect","window","location","href","BaseButton","disabled"],"mappings":";;;;;;AAUO,SAASA,mBACdC,OAIA;AACA,QAAM,CAACC,mBAAmBC,oBAApB,IAA4CC,oBAAS,KAAD;AACpD,QAAA;AAAA,IAACC;AAAAA,IAAQC;AAAAA,MAAeC,aAA9B,QAAA;AACM,QAAA;AAAA,IAACC;AAAAA,OAAaC;AAAAA,EAAoBR,IAAAA;AAExCS,aAAAA,UAAU,MAAM;AACVR,QAAAA,qBAAqBI,eAAeD,WAAW,QAAQ;AACzDM,aAAOC,SAASC,OAAOP;AAAAA,IACxB;AAAA,EACA,GAAA,CAACJ,mBAAmBG,QAAQC,WAA5B,CAJM;AAMT,wCACGQ,WAAAA,YAAD;AAAA,IAAA,GACML;AAAAA,IACJ,UAAUP,qBAAqBO,iBAAiBM;AAAAA,IAChD,SAAS,MAAMZ,qBAAqB,IAAD;AAAA,IAHrC;AAAA,EAAA,CADF;AASD;;"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { useState, useEffect } from "react";
|
|
2
|
+
import { useCart } from "./CartProvider.mjs";
|
|
3
|
+
import { BaseButton } from "./BaseButton.mjs";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
function CartCheckoutButton(props) {
|
|
6
|
+
const [requestedCheckout, setRequestedCheckout] = useState(false);
|
|
7
|
+
const {
|
|
8
|
+
status,
|
|
9
|
+
checkoutUrl
|
|
10
|
+
} = useCart();
|
|
11
|
+
const {
|
|
12
|
+
children,
|
|
13
|
+
...passthroughProps
|
|
14
|
+
} = props;
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (requestedCheckout && checkoutUrl && status === "idle") {
|
|
17
|
+
window.location.href = checkoutUrl;
|
|
18
|
+
}
|
|
19
|
+
}, [requestedCheckout, status, checkoutUrl]);
|
|
20
|
+
return /* @__PURE__ */ jsx(BaseButton, {
|
|
21
|
+
...passthroughProps,
|
|
22
|
+
disabled: requestedCheckout || passthroughProps.disabled,
|
|
23
|
+
onClick: () => setRequestedCheckout(true),
|
|
24
|
+
children
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
export {
|
|
28
|
+
CartCheckoutButton
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=CartCheckoutButton.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CartCheckoutButton.mjs","sources":["../../src/CartCheckoutButton.tsx"],"sourcesContent":["import {ReactNode, useEffect, useState} from 'react';\nimport {useCart} from './CartProvider.js';\nimport {BaseButton, BaseButtonProps} from './BaseButton.js';\n\ntype PropsWeControl = 'onClick';\n\n/**\n * The `CartCheckoutButton` component renders a button that redirects to the checkout URL for the cart.\n * It must be a descendent of a `CartProvider` component.\n */\nexport function CartCheckoutButton(\n props: Omit<BaseButtonProps<'button'>, PropsWeControl> & {\n /** A `ReactNode` element. */\n children: ReactNode;\n }\n) {\n const [requestedCheckout, setRequestedCheckout] = useState(false);\n const {status, checkoutUrl} = useCart();\n const {children, ...passthroughProps} = props;\n\n useEffect(() => {\n if (requestedCheckout && checkoutUrl && status === 'idle') {\n window.location.href = checkoutUrl;\n }\n }, [requestedCheckout, status, checkoutUrl]);\n\n return (\n <BaseButton\n {...passthroughProps}\n disabled={requestedCheckout || passthroughProps.disabled}\n onClick={() => setRequestedCheckout(true)}\n >\n {children}\n </BaseButton>\n );\n}\n"],"names":["CartCheckoutButton","props","requestedCheckout","setRequestedCheckout","useState","status","checkoutUrl","useCart","children","passthroughProps","useEffect","window","location","href","disabled"],"mappings":";;;;AAUO,SAASA,mBACdC,OAIA;AACA,QAAM,CAACC,mBAAmBC,oBAApB,IAA4CC,SAAS,KAAD;AACpD,QAAA;AAAA,IAACC;AAAAA,IAAQC;AAAAA,MAAeC,QAA9B;AACM,QAAA;AAAA,IAACC;AAAAA,OAAaC;AAAAA,EAAoBR,IAAAA;AAExCS,YAAU,MAAM;AACVR,QAAAA,qBAAqBI,eAAeD,WAAW,QAAQ;AACzDM,aAAOC,SAASC,OAAOP;AAAAA,IACxB;AAAA,EACA,GAAA,CAACJ,mBAAmBG,QAAQC,WAA5B,CAJM;AAMT,6BACG,YAAD;AAAA,IAAA,GACMG;AAAAA,IACJ,UAAUP,qBAAqBO,iBAAiBK;AAAAA,IAChD,SAAS,MAAMX,qBAAqB,IAAD;AAAA,IAHrC;AAAA,EAAA,CADF;AASD;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MediaFile.js","sources":["../../src/MediaFile.tsx"],"sourcesContent":["import {Image, type ShopifyImageProps} from './Image.js';\nimport {Video} from './Video.js';\nimport {ExternalVideo} from './ExternalVideo.js';\nimport {ModelViewer} from './ModelViewer.js';\nimport type {MediaEdge as MediaEdgeType} from './storefront-api-types.js';\nimport type {PartialDeep} from 'type-fest';\n\
|
|
1
|
+
{"version":3,"file":"MediaFile.js","sources":["../../src/MediaFile.tsx"],"sourcesContent":["import {Image, type ShopifyImageProps} from './Image.js';\nimport {Video} from './Video.js';\nimport {ExternalVideo} from './ExternalVideo.js';\nimport {ModelViewer} from './ModelViewer.js';\nimport type {MediaEdge as MediaEdgeType} from './storefront-api-types.js';\nimport type {PartialDeep} from 'type-fest';\nimport type {ModelViewerElement} from '@google/model-viewer/lib/model-viewer.js';\n\ntype BaseProps = React.HTMLAttributes<\n HTMLImageElement | HTMLVideoElement | HTMLIFrameElement | ModelViewerElement\n>;\nexport interface MediaFileProps extends BaseProps {\n /** An object with fields that correspond to the Storefront API's [Media object](https://shopify.dev/api/storefront/reference/products/media). */\n data: PartialDeep<MediaEdgeType['node'], {recurseIntoArrays: true}>;\n /** The options for the `Image`, `Video`, or `ExternalVideo` components. */\n mediaOptions?: {\n /** Props that will only apply when an `<Image />` is rendered */\n image: Omit<ShopifyImageProps, 'data'>;\n /** Props that will only apply when a `<Video />` is rendered */\n video: Omit<React.ComponentProps<typeof Video>, 'data'>;\n /** Props that will only apply when an `<ExternalVideo />` is rendered */\n externalVideo: Omit<\n React.ComponentProps<typeof ExternalVideo>['options'],\n 'data'\n >;\n /** Props that will only apply when a `<ModelViewer />` is rendered */\n modelViewer: Omit<typeof ModelViewer, 'data'>;\n };\n}\n\n/**\n * The `MediaFile` component renders the media for the Storefront API's\n * [Media object](https://shopify.dev/api/storefront/reference/products/media). It renders an `Image`, a\n * `Video`, an `ExternalVideo`, or a `ModelViewer` depending on the `__typename` of the `data` prop.\n */\nexport function MediaFile({\n data,\n mediaOptions,\n ...passthroughProps\n}: MediaFileProps) {\n switch (data.__typename) {\n case 'MediaImage': {\n if (!data.image) {\n const noDataImage = `<MediaFile/>: 'data.image' does not exist for __typename of 'MediaImage'; rendering 'null' by default.`;\n if (__HYDROGEN_DEV__) {\n throw new Error(noDataImage);\n } else {\n console.warn(noDataImage);\n return null;\n }\n }\n\n return (\n <Image\n {...passthroughProps}\n {...mediaOptions?.image}\n data={data.image}\n />\n );\n }\n case 'Video': {\n return (\n <Video {...passthroughProps} {...mediaOptions?.video} data={data} />\n );\n }\n case 'ExternalVideo': {\n return (\n <ExternalVideo\n {...passthroughProps}\n {...mediaOptions?.externalVideo}\n data={data}\n />\n );\n }\n case 'Model3d': {\n return (\n // @ts-expect-error There are issues with the inferred HTML attribute types here for ModelViewer (and contentEditable), but I think that's a little bit beyond me at the moment\n <ModelViewer\n {...passthroughProps}\n {...mediaOptions?.modelViewer}\n data={data}\n />\n );\n }\n default: {\n const typenameMissingMessage = `<MediaFile /> requires the '__typename' property to exist on the 'data' prop in order to correctly render the correct component for this media. Rendering 'null' by default`;\n if (__HYDROGEN_DEV__) {\n throw new Error(typenameMissingMessage);\n } else {\n console.error(typenameMissingMessage);\n return null;\n }\n }\n }\n}\n"],"names":["MediaFile","data","mediaOptions","passthroughProps","__typename","image","noDataImage","Error","Image","Video","video","ExternalVideo","externalVideo","ModelViewer","modelViewer","typenameMissingMessage"],"mappings":";;;;;;;AAmCO,SAASA,UAAU;AAAA,EACxBC;AAAAA,EACAC;AAAAA,KACGC;AAHqB,GAIP;AACjB,UAAQF,KAAKG,YAAb;AAAA,IACE,KAAK,cAAc;AACb,UAAA,CAACH,KAAKI,OAAO;AACf,cAAMC,cAAe;AACC;AACd,gBAAA,IAAIC,MAAMD,WAAV;AAAA,QAIP;AAAA,MACF;AAED,4CACGE,MAAAA,OAAD;AAAA,QAAA,GACML;AAAAA,QADN,GAEMD,6CAAcG;AAAAA,QAClB,MAAMJ,KAAKI;AAAAA,MAAAA,CAJf;AAAA,IAOD;AAAA,IACD,KAAK,SAAS;AACZ,4CACGI,MAAAA,OAAD;AAAA,QAAA,GAAWN;AAAAA,QAAX,GAAiCD,6CAAcQ;AAAAA,QAAO;AAAA,MAAA,CADxD;AAAA,IAGD;AAAA,IACD,KAAK,iBAAiB;AACpB,4CACGC,cAAAA,eAAD;AAAA,QAAA,GACMR;AAAAA,QADN,GAEMD,6CAAcU;AAAAA,QAClB;AAAA,MAAA,CAJJ;AAAA,IAOD;AAAA,IACD,KAAK,WAAW;AACd,4CAEGC,YAAAA;WACKV;AAAAA,QADN,GAEMD,6CAAcY;AAAAA,QAClB;AAAA,MAAA,CAHF;AAAA,IAMH;AAAA,IACD,SAAS;AACP,YAAMC,yBAA0B;AACV;AACd,cAAA,IAAIR,MAAMQ,sBAAV;AAAA,MAIP;AAAA,IACF;AAAA,EApDH;AAsDD;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MediaFile.mjs","sources":["../../src/MediaFile.tsx"],"sourcesContent":["import {Image, type ShopifyImageProps} from './Image.js';\nimport {Video} from './Video.js';\nimport {ExternalVideo} from './ExternalVideo.js';\nimport {ModelViewer} from './ModelViewer.js';\nimport type {MediaEdge as MediaEdgeType} from './storefront-api-types.js';\nimport type {PartialDeep} from 'type-fest';\n\
|
|
1
|
+
{"version":3,"file":"MediaFile.mjs","sources":["../../src/MediaFile.tsx"],"sourcesContent":["import {Image, type ShopifyImageProps} from './Image.js';\nimport {Video} from './Video.js';\nimport {ExternalVideo} from './ExternalVideo.js';\nimport {ModelViewer} from './ModelViewer.js';\nimport type {MediaEdge as MediaEdgeType} from './storefront-api-types.js';\nimport type {PartialDeep} from 'type-fest';\nimport type {ModelViewerElement} from '@google/model-viewer/lib/model-viewer.js';\n\ntype BaseProps = React.HTMLAttributes<\n HTMLImageElement | HTMLVideoElement | HTMLIFrameElement | ModelViewerElement\n>;\nexport interface MediaFileProps extends BaseProps {\n /** An object with fields that correspond to the Storefront API's [Media object](https://shopify.dev/api/storefront/reference/products/media). */\n data: PartialDeep<MediaEdgeType['node'], {recurseIntoArrays: true}>;\n /** The options for the `Image`, `Video`, or `ExternalVideo` components. */\n mediaOptions?: {\n /** Props that will only apply when an `<Image />` is rendered */\n image: Omit<ShopifyImageProps, 'data'>;\n /** Props that will only apply when a `<Video />` is rendered */\n video: Omit<React.ComponentProps<typeof Video>, 'data'>;\n /** Props that will only apply when an `<ExternalVideo />` is rendered */\n externalVideo: Omit<\n React.ComponentProps<typeof ExternalVideo>['options'],\n 'data'\n >;\n /** Props that will only apply when a `<ModelViewer />` is rendered */\n modelViewer: Omit<typeof ModelViewer, 'data'>;\n };\n}\n\n/**\n * The `MediaFile` component renders the media for the Storefront API's\n * [Media object](https://shopify.dev/api/storefront/reference/products/media). It renders an `Image`, a\n * `Video`, an `ExternalVideo`, or a `ModelViewer` depending on the `__typename` of the `data` prop.\n */\nexport function MediaFile({\n data,\n mediaOptions,\n ...passthroughProps\n}: MediaFileProps) {\n switch (data.__typename) {\n case 'MediaImage': {\n if (!data.image) {\n const noDataImage = `<MediaFile/>: 'data.image' does not exist for __typename of 'MediaImage'; rendering 'null' by default.`;\n if (__HYDROGEN_DEV__) {\n throw new Error(noDataImage);\n } else {\n console.warn(noDataImage);\n return null;\n }\n }\n\n return (\n <Image\n {...passthroughProps}\n {...mediaOptions?.image}\n data={data.image}\n />\n );\n }\n case 'Video': {\n return (\n <Video {...passthroughProps} {...mediaOptions?.video} data={data} />\n );\n }\n case 'ExternalVideo': {\n return (\n <ExternalVideo\n {...passthroughProps}\n {...mediaOptions?.externalVideo}\n data={data}\n />\n );\n }\n case 'Model3d': {\n return (\n // @ts-expect-error There are issues with the inferred HTML attribute types here for ModelViewer (and contentEditable), but I think that's a little bit beyond me at the moment\n <ModelViewer\n {...passthroughProps}\n {...mediaOptions?.modelViewer}\n data={data}\n />\n );\n }\n default: {\n const typenameMissingMessage = `<MediaFile /> requires the '__typename' property to exist on the 'data' prop in order to correctly render the correct component for this media. Rendering 'null' by default`;\n if (__HYDROGEN_DEV__) {\n throw new Error(typenameMissingMessage);\n } else {\n console.error(typenameMissingMessage);\n return null;\n }\n }\n }\n}\n"],"names":["MediaFile","data","mediaOptions","passthroughProps","__typename","image","noDataImage","Error","video","externalVideo","modelViewer","typenameMissingMessage"],"mappings":";;;;;AAmCO,SAASA,UAAU;AAAA,EACxBC;AAAAA,EACAC;AAAAA,KACGC;AAHqB,GAIP;AACjB,UAAQF,KAAKG,YAAb;AAAA,IACE,KAAK,cAAc;AACb,UAAA,CAACH,KAAKI,OAAO;AACf,cAAMC,cAAe;AACC;AACd,gBAAA,IAAIC,MAAMD,WAAV;AAAA,QAIP;AAAA,MACF;AAED,iCACG,OAAD;AAAA,QAAA,GACMH;AAAAA,QADN,GAEMD,6CAAcG;AAAAA,QAClB,MAAMJ,KAAKI;AAAAA,MAAAA,CAJf;AAAA,IAOD;AAAA,IACD,KAAK,SAAS;AACZ,iCACG,OAAD;AAAA,QAAA,GAAWF;AAAAA,QAAX,GAAiCD,6CAAcM;AAAAA,QAAO;AAAA,MAAA,CADxD;AAAA,IAGD;AAAA,IACD,KAAK,iBAAiB;AACpB,iCACG,eAAD;AAAA,QAAA,GACML;AAAAA,QADN,GAEMD,6CAAcO;AAAAA,QAClB;AAAA,MAAA,CAJJ;AAAA,IAOD;AAAA,IACD,KAAK,WAAW;AACd,iCAEG;WACKN;AAAAA,QADN,GAEMD,6CAAcQ;AAAAA,QAClB;AAAA,MAAA,CAHF;AAAA,IAMH;AAAA,IACD,SAAS;AACP,YAAMC,yBAA0B;AACV;AACd,cAAA,IAAIJ,MAAMI,sBAAV;AAAA,MAIP;AAAA,IACF;AAAA,EApDH;AAsDD;"}
|
package/dist/dev/Metafield.js
CHANGED
|
@@ -145,6 +145,9 @@ function Metafield(props) {
|
|
|
145
145
|
});
|
|
146
146
|
}
|
|
147
147
|
function parseMetafield(metafield) {
|
|
148
|
+
{
|
|
149
|
+
console.info(`'parseMetafield()' will have a breaking change in a future version; its behavior will match that of 'metafieldParser()'`);
|
|
150
|
+
}
|
|
148
151
|
if (!metafield) {
|
|
149
152
|
{
|
|
150
153
|
console.warn(`'parseMetafield' was not passed any value for the 'metafield' argument`);
|
|
@@ -160,6 +163,9 @@ function parseMetafield(metafield) {
|
|
|
160
163
|
};
|
|
161
164
|
}
|
|
162
165
|
function parseMetafieldValue(metafield) {
|
|
166
|
+
{
|
|
167
|
+
console.info(`'parseMetafieldValue()' will be removed in a future version`);
|
|
168
|
+
}
|
|
163
169
|
if (!metafield) {
|
|
164
170
|
return null;
|
|
165
171
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Metafield.js","sources":["../../src/Metafield.tsx"],"sourcesContent":["import {type ElementType, useMemo, type ComponentPropsWithoutRef} from 'react';\nimport {useShop} from './ShopifyProvider.js';\nimport {Image} from './Image.js';\nimport type {\n MediaImage,\n Page,\n ProductVariant,\n Product,\n GenericFile,\n Video as VideoType,\n Metafield as MetafieldType,\n} from './storefront-api-types.js';\nimport {Video} from './Video.js';\nimport {flattenConnection} from './flatten-connection.js';\nimport type {PartialDeep, JsonValue} from 'type-fest';\n\ninterface BaseProps<ComponentGeneric extends ElementType> {\n /** An object with fields that correspond to the Storefront API's [Metafield object](https://shopify.dev/api/storefront/reference/common-objects/metafield). */\n data: PartialDeep<MetafieldType, {recurseIntoArrays: true}> | null;\n /** An HTML tag or React component to be rendered as the base element wrapper. The default value varies depending on [metafield.type](https://shopify.dev/apps/metafields/types). */\n as?: ComponentGeneric;\n}\n\nexport type MetafieldProps<ComponentGeneric extends ElementType> =\n ComponentPropsWithoutRef<ComponentGeneric> & BaseProps<ComponentGeneric>;\n\n/**\n * The `Metafield` component renders the value of a Storefront\n * API's [Metafield object](https://shopify.dev/api/storefront/reference/common-objects/metafield).\n * Relies on the `locale` property of the `useShop()` hook, so it must be a desendent of `<ShopifyProvider/>`\n *\n * Renders a smart default of the Metafield's `value`. For more information, refer to the [Default output](#default-output) section.\n */\nexport function Metafield<ComponentGeneric extends ElementType>(\n props: MetafieldProps<ComponentGeneric>\n) {\n const {data, as, ...passthroughProps} = props;\n const {locale} = useShop();\n\n const parsedMetafield = useMemo(() => parseMetafield(data), [data]);\n\n if (!parsedMetafield) {\n const noDataPropWarning = `<Metafield/>: nothing was passed to the data prop 'data'. Rendering 'null'`;\n if (__HYDROGEN_DEV__) {\n throw new Error(noDataPropWarning);\n } else {\n console.warn(noDataPropWarning);\n }\n return null;\n }\n\n if (parsedMetafield.value === null || parsedMetafield.value === undefined) {\n const noValueWarning = `<Metafield/>: No metafield value for metafield ${\n parsedMetafield.id ?? parsedMetafield.key\n }. Rendering 'null'`;\n if (__HYDROGEN_DEV__) {\n throw new Error(noValueWarning);\n } else {\n console.warn(noValueWarning);\n }\n return null;\n }\n\n switch (parsedMetafield.type) {\n case 'date': {\n const Wrapper = as ?? 'time';\n return (\n <Wrapper {...passthroughProps}>\n {(parsedMetafield.value as Date).toLocaleDateString(locale)}\n </Wrapper>\n );\n }\n case 'date_time': {\n const Wrapper = as ?? 'time';\n return (\n <Wrapper {...passthroughProps}>\n {(parsedMetafield.value as Date).toLocaleString(locale)}\n </Wrapper>\n );\n }\n case 'weight':\n case 'dimension':\n case 'volume': {\n const Wrapper = as ?? 'span';\n return (\n <Wrapper {...passthroughProps}>\n {getMeasurementAsString(parsedMetafield.value as Measurement, locale)}\n </Wrapper>\n );\n }\n case 'rating': {\n const Wrapper = as ?? 'span';\n return (\n <Wrapper {...passthroughProps}>\n {(parsedMetafield.value as Rating).value}\n </Wrapper>\n );\n }\n case 'single_line_text_field': {\n const Wrapper = as ?? 'span';\n return (\n <Wrapper\n {...passthroughProps}\n dangerouslySetInnerHTML={{__html: parsedMetafield.value as string}}\n />\n );\n }\n case 'multi_line_text_field': {\n const Wrapper = as ?? 'div';\n return (\n <Wrapper\n {...passthroughProps}\n dangerouslySetInnerHTML={{\n __html: (parsedMetafield.value as string).split('\\n').join('<br/>'),\n }}\n />\n );\n }\n case 'url': {\n const protocolLessUrl = new URL(parsedMetafield.value as string);\n return (\n <a\n href={protocolLessUrl.href.replace(protocolLessUrl.protocol, '')}\n {...passthroughProps}\n >\n {parsedMetafield.value as string}\n </a>\n );\n }\n case 'json': {\n const Wrapper = as ?? 'span';\n return (\n <Wrapper {...passthroughProps}>\n {JSON.stringify(parsedMetafield.value)}\n </Wrapper>\n );\n }\n case 'product_reference':\n case 'variant_reference':\n case 'page_reference': {\n const Wrapper = as ?? 'span';\n const ref = parsedMetafield.reference as Page | ProductVariant | Product;\n return (\n <Wrapper {...passthroughProps}>{ref?.title ?? ref?.id ?? ''}</Wrapper>\n );\n }\n case 'list.single_line_text_field': {\n const Wrapper = as ?? 'ul';\n\n const refArray = parsedMetafield.references\n ? (flattenConnection(parsedMetafield.references) as string[])\n : [];\n return (\n <Wrapper {...passthroughProps}>\n {refArray.map((ref, index) => (\n // there's no unique way to identify these strings, so we do our best by combining the string with the index for the key\n // eslint-disable-next-line react/no-array-index-key\n <li key={`${ref ?? ''}-${index}`}>{ref}</li>\n ))}\n </Wrapper>\n );\n }\n case 'file_reference': {\n if (parsedMetafield.reference?.__typename === 'MediaImage') {\n const ref = parsedMetafield.reference as MediaImage;\n return ref.image ? (\n <Image data={ref.image} {...passthroughProps} />\n ) : null;\n } else if (parsedMetafield.reference?.__typename === 'GenericFile') {\n const ref = parsedMetafield.reference as GenericFile;\n return ref.previewImage ? (\n <a href={parsedMetafield.reference?.url ?? ''} {...passthroughProps}>\n <Image data={ref.previewImage} />\n </a>\n ) : null;\n } else if (parsedMetafield.reference?.__typename === 'Video') {\n const ref = parsedMetafield.reference as VideoType;\n return <Video {...passthroughProps} data={ref} />;\n }\n }\n }\n\n const Wrapper = as ?? 'span';\n return (\n <Wrapper {...passthroughProps}>{parsedMetafield.value?.toString()}</Wrapper>\n );\n}\n\n/**\n * The `parseMetafield` utility transforms a [Metafield](https://shopify.dev/api/storefront/reference/common-objects/Metafield)\n * into a new object whose `values` have been parsed according to the metafield `type`.\n * If the metafield is `null`, then it returns `null` back.\n */\nexport function parseMetafield(\n /** A [Metafield](https://shopify.dev/api/storefront/reference/common-objects/Metafield) or null */\n metafield: PartialDeep<MetafieldType, {recurseIntoArrays: true}> | null\n): PartialDeep<ParsedMetafield, {recurseIntoArrays: true}> | null {\n if (!metafield) {\n if (__HYDROGEN_DEV__) {\n console.warn(\n `'parseMetafield' was not passed any value for the 'metafield' argument`\n );\n }\n return null;\n }\n if (\n __HYDROGEN_DEV__ &&\n (metafield.value === null || metafield.value === undefined)\n ) {\n console.warn(\n `'parseMetafield()' was passed ${metafield.value} for 'metafield.value'`\n );\n }\n\n return {\n ...metafield,\n value: parseMetafieldValue(metafield),\n };\n}\n\n/**\n * The `parseMetafieldValue` function parses a [Metafield](https://shopify.dev/api/storefront/reference/common-objects/metafield)'s `value` from a string into a sensible type corresponding to the [Metafield](https://shopify.dev/api/storefront/reference/common-objects/metafield)'s `type`.\n */\nexport function parseMetafieldValue(\n metafield: PartialDeep<MetafieldType, {recurseIntoArrays: true}> | null\n): ParsedMetafield['value'] {\n if (!metafield) {\n return null;\n }\n\n if (metafield.value === null || metafield.value === undefined) {\n if (__HYDROGEN_DEV__) {\n console.warn(\n `'parseMetafieldValue()' was passed ${metafield.value} for 'metafield.value'`\n );\n }\n return metafield.value;\n }\n\n switch (metafield.type) {\n case 'boolean':\n return metafield.value === 'true';\n case 'number_integer':\n return parseInt(metafield.value);\n case 'number_decimal':\n return parseFloat(metafield.value);\n case 'date':\n case 'date_time':\n return new Date(metafield.value);\n case 'json':\n case 'weight':\n case 'dimension':\n case 'volume':\n case 'rating':\n return parseJSON(metafield.value);\n case 'color':\n case 'single_line_text_field':\n case 'multi_line_text_field':\n case 'product_reference':\n case 'page_reference':\n case 'variant_reference':\n case 'file_reference':\n case 'url':\n default:\n return metafield.value;\n }\n}\n\n/**\n * Parses a JSON string while preventing prototype injection attacks.\n */\nexport function parseJSON(json: string) {\n if (String(json).includes('__proto__')) {\n return JSON.parse(json, (k, v) => {\n if (k !== '__proto__') return v;\n });\n }\n\n return JSON.parse(json);\n}\n\nconst UNIT_MAPPING: Record<string, string> = {\n // Dimension\n mm: 'millimeter',\n cm: 'centimeter',\n m: 'meter',\n in: 'inch',\n ft: 'foot',\n yd: 'yard',\n // Volume\n ml: 'milliliter',\n l: 'liter',\n us_fl_oz: 'fluid-ounce',\n us_gal: 'gallon',\n // Weight\n kg: 'kilogram',\n g: 'gram',\n lb: 'pound',\n oz: 'ounce',\n};\n\nexport function getMeasurementAsString(\n measurement: Measurement,\n locale = 'en-us',\n options: Intl.NumberFormatOptions = {}\n) {\n let measure: {value: number; unit: string} = {\n value: measurement.value,\n unit: UNIT_MAPPING[measurement.unit],\n };\n\n if (measure.unit == null) {\n measure = convertToSupportedUnit(measurement.value, measurement.unit);\n }\n\n return new Intl.NumberFormat(locale, {\n ...options,\n unit: measure.unit,\n style: 'unit',\n }).format(measure.value);\n}\n\nfunction convertToSupportedUnit(value: number, unit: string) {\n switch (unit) {\n case 'cl':\n return {\n value: value / 1000,\n unit: 'liter',\n };\n case 'm3':\n return {\n value: value * 1000,\n unit: 'liter',\n };\n case 'us_pt':\n return {\n value: value * 0.125,\n unit: 'gallon',\n };\n case 'us_qt':\n return {\n value: value * 0.5,\n unit: 'gallon',\n };\n case 'us_oz':\n return {\n value: value / 128,\n unit: 'gallon',\n };\n case 'imp_pt':\n return {\n value: value / 6.661, // approximate conversion\n unit: 'gallon',\n };\n case 'imp_qt':\n return {\n value: value / 3.331, // approximate conversion\n unit: 'gallon',\n };\n case 'imp_gal':\n return {\n value: value / 1.201, // approximate conversion\n unit: 'gallon',\n };\n case 'imp_fl_oz':\n return {\n value: value * 0.96076, // approximate conversion\n unit: 'fluid-ounce',\n };\n default:\n throw new Error(`Unit not supported: ${unit}`);\n }\n}\n\ntype ParsedMetafield = Omit<\n PartialDeep<MetafieldType, {recurseIntoArrays: true}>,\n 'value'\n> & {\n value?: string | number | boolean | JsonValue | Date | Rating | Measurement;\n};\n\nexport interface Rating {\n value: number;\n scale_min: number;\n scale_max: number;\n}\n\ninterface Measurement {\n unit: string;\n value: number;\n}\n"],"names":["Metafield","props","data","as","passthroughProps","locale","useShop","parsedMetafield","useMemo","parseMetafield","noDataPropWarning","Error","value","undefined","noValueWarning","id","key","type","Wrapper","toLocaleDateString","toLocaleString","getMeasurementAsString","__html","split","join","protocolLessUrl","URL","href","replace","protocol","JSON","stringify","ref","reference","title","refArray","references","flattenConnection","map","index","__typename","image","_jsx","Image","previewImage","url","Video","toString","metafield","console","warn","parseMetafieldValue","parseInt","parseFloat","Date","parseJSON","json","String","includes","parse","k","v","UNIT_MAPPING","mm","cm","m","in","ft","yd","ml","l","us_fl_oz","us_gal","kg","g","lb","oz","measurement","options","measure","unit","convertToSupportedUnit","Intl","NumberFormat","style","format"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Metafield.js","sources":["../../src/Metafield.tsx"],"sourcesContent":["import {type ElementType, useMemo, type ComponentPropsWithoutRef} from 'react';\nimport {useShop} from './ShopifyProvider.js';\nimport {Image} from './Image.js';\nimport type {\n MediaImage,\n Page,\n ProductVariant,\n Product,\n GenericFile,\n Video as VideoType,\n Metafield as MetafieldType,\n} from './storefront-api-types.js';\nimport {Video} from './Video.js';\nimport {flattenConnection} from './flatten-connection.js';\nimport type {PartialDeep, JsonValue} from 'type-fest';\n\ninterface BaseProps<ComponentGeneric extends ElementType> {\n /** An object with fields that correspond to the Storefront API's [Metafield object](https://shopify.dev/api/storefront/reference/common-objects/metafield). */\n data: PartialDeep<MetafieldType, {recurseIntoArrays: true}> | null;\n /** An HTML tag or React component to be rendered as the base element wrapper. The default value varies depending on [metafield.type](https://shopify.dev/apps/metafields/types). */\n as?: ComponentGeneric;\n}\n\nexport type MetafieldProps<ComponentGeneric extends ElementType> =\n ComponentPropsWithoutRef<ComponentGeneric> & BaseProps<ComponentGeneric>;\n\n/**\n * The `Metafield` component renders the value of a Storefront\n * API's [Metafield object](https://shopify.dev/api/storefront/reference/common-objects/metafield).\n * Relies on the `locale` property of the `useShop()` hook, so it must be a desendent of `<ShopifyProvider/>`\n *\n * Renders a smart default of the Metafield's `value`. For more information, refer to the [Default output](#default-output) section.\n */\nexport function Metafield<ComponentGeneric extends ElementType>(\n props: MetafieldProps<ComponentGeneric>\n) {\n const {data, as, ...passthroughProps} = props;\n const {locale} = useShop();\n\n const parsedMetafield = useMemo(() => parseMetafield(data), [data]);\n\n if (!parsedMetafield) {\n const noDataPropWarning = `<Metafield/>: nothing was passed to the data prop 'data'. Rendering 'null'`;\n if (__HYDROGEN_DEV__) {\n throw new Error(noDataPropWarning);\n } else {\n console.warn(noDataPropWarning);\n }\n return null;\n }\n\n if (parsedMetafield.value === null || parsedMetafield.value === undefined) {\n const noValueWarning = `<Metafield/>: No metafield value for metafield ${\n parsedMetafield.id ?? parsedMetafield.key\n }. Rendering 'null'`;\n if (__HYDROGEN_DEV__) {\n throw new Error(noValueWarning);\n } else {\n console.warn(noValueWarning);\n }\n return null;\n }\n\n switch (parsedMetafield.type) {\n case 'date': {\n const Wrapper = as ?? 'time';\n return (\n <Wrapper {...passthroughProps}>\n {(parsedMetafield.value as Date).toLocaleDateString(locale)}\n </Wrapper>\n );\n }\n case 'date_time': {\n const Wrapper = as ?? 'time';\n return (\n <Wrapper {...passthroughProps}>\n {(parsedMetafield.value as Date).toLocaleString(locale)}\n </Wrapper>\n );\n }\n case 'weight':\n case 'dimension':\n case 'volume': {\n const Wrapper = as ?? 'span';\n return (\n <Wrapper {...passthroughProps}>\n {getMeasurementAsString(parsedMetafield.value as Measurement, locale)}\n </Wrapper>\n );\n }\n case 'rating': {\n const Wrapper = as ?? 'span';\n return (\n <Wrapper {...passthroughProps}>\n {(parsedMetafield.value as Rating).value}\n </Wrapper>\n );\n }\n case 'single_line_text_field': {\n const Wrapper = as ?? 'span';\n return (\n <Wrapper\n {...passthroughProps}\n dangerouslySetInnerHTML={{__html: parsedMetafield.value as string}}\n />\n );\n }\n case 'multi_line_text_field': {\n const Wrapper = as ?? 'div';\n return (\n <Wrapper\n {...passthroughProps}\n dangerouslySetInnerHTML={{\n __html: (parsedMetafield.value as string).split('\\n').join('<br/>'),\n }}\n />\n );\n }\n case 'url': {\n const protocolLessUrl = new URL(parsedMetafield.value as string);\n return (\n <a\n href={protocolLessUrl.href.replace(protocolLessUrl.protocol, '')}\n {...passthroughProps}\n >\n {parsedMetafield.value as string}\n </a>\n );\n }\n case 'json': {\n const Wrapper = as ?? 'span';\n return (\n <Wrapper {...passthroughProps}>\n {JSON.stringify(parsedMetafield.value)}\n </Wrapper>\n );\n }\n case 'product_reference':\n case 'variant_reference':\n case 'page_reference': {\n const Wrapper = as ?? 'span';\n const ref = parsedMetafield.reference as Page | ProductVariant | Product;\n return (\n <Wrapper {...passthroughProps}>{ref?.title ?? ref?.id ?? ''}</Wrapper>\n );\n }\n case 'list.single_line_text_field': {\n const Wrapper = as ?? 'ul';\n\n const refArray = parsedMetafield.references\n ? (flattenConnection(parsedMetafield.references) as string[])\n : [];\n return (\n <Wrapper {...passthroughProps}>\n {refArray.map((ref, index) => (\n // there's no unique way to identify these strings, so we do our best by combining the string with the index for the key\n // eslint-disable-next-line react/no-array-index-key\n <li key={`${ref ?? ''}-${index}`}>{ref}</li>\n ))}\n </Wrapper>\n );\n }\n case 'file_reference': {\n if (parsedMetafield.reference?.__typename === 'MediaImage') {\n const ref = parsedMetafield.reference as MediaImage;\n return ref.image ? (\n <Image data={ref.image} {...passthroughProps} />\n ) : null;\n } else if (parsedMetafield.reference?.__typename === 'GenericFile') {\n const ref = parsedMetafield.reference as GenericFile;\n return ref.previewImage ? (\n <a href={parsedMetafield.reference?.url ?? ''} {...passthroughProps}>\n <Image data={ref.previewImage} />\n </a>\n ) : null;\n } else if (parsedMetafield.reference?.__typename === 'Video') {\n const ref = parsedMetafield.reference as VideoType;\n return <Video {...passthroughProps} data={ref} />;\n }\n }\n }\n\n const Wrapper = as ?? 'span';\n return (\n <Wrapper {...passthroughProps}>{parsedMetafield.value?.toString()}</Wrapper>\n );\n}\n\n/**\n * The `parseMetafield` utility transforms a [Metafield](https://shopify.dev/api/storefront/reference/common-objects/Metafield)\n * into a new object whose `values` have been parsed according to the metafield `type`.\n * If the metafield is `null`, then it returns `null` back.\n *\n * Note that `parseMetafield()` will have a breaking change in a future version; it will change to behave like `metafieldParser()`.\n */\nexport function parseMetafield(\n /** A [Metafield](https://shopify.dev/api/storefront/reference/common-objects/Metafield) or null */\n metafield: PartialDeep<MetafieldType, {recurseIntoArrays: true}> | null\n): PartialDeep<ParsedMetafield, {recurseIntoArrays: true}> | null {\n if (__HYDROGEN_DEV__) {\n console.info(\n `'parseMetafield()' will have a breaking change in a future version; its behavior will match that of 'metafieldParser()'`\n );\n }\n\n if (!metafield) {\n if (__HYDROGEN_DEV__) {\n console.warn(\n `'parseMetafield' was not passed any value for the 'metafield' argument`\n );\n }\n return null;\n }\n if (\n __HYDROGEN_DEV__ &&\n (metafield.value === null || metafield.value === undefined)\n ) {\n console.warn(\n `'parseMetafield()' was passed ${metafield.value} for 'metafield.value'`\n );\n }\n\n return {\n ...metafield,\n value: parseMetafieldValue(metafield),\n };\n}\n\n/**\n * The `parseMetafieldValue` function parses a [Metafield](https://shopify.dev/api/storefront/reference/common-objects/metafield)'s `value` from a string into a sensible type corresponding to the [Metafield](https://shopify.dev/api/storefront/reference/common-objects/metafield)'s `type`.\n * @deprecated `parseMetafieldValue()` is unsupported and will be removed in a future version.\n */\nexport function parseMetafieldValue(\n metafield: PartialDeep<MetafieldType, {recurseIntoArrays: true}> | null\n): ParsedMetafield['value'] {\n if (__HYDROGEN_DEV__) {\n console.info(`'parseMetafieldValue()' will be removed in a future version`);\n }\n\n if (!metafield) {\n return null;\n }\n\n if (metafield.value === null || metafield.value === undefined) {\n if (__HYDROGEN_DEV__) {\n console.warn(\n `'parseMetafieldValue()' was passed ${metafield.value} for 'metafield.value'`\n );\n }\n return metafield.value;\n }\n\n switch (metafield.type) {\n case 'boolean':\n return metafield.value === 'true';\n case 'number_integer':\n return parseInt(metafield.value);\n case 'number_decimal':\n return parseFloat(metafield.value);\n case 'date':\n case 'date_time':\n return new Date(metafield.value);\n case 'json':\n case 'weight':\n case 'dimension':\n case 'volume':\n case 'rating':\n return parseJSON(metafield.value);\n case 'color':\n case 'single_line_text_field':\n case 'multi_line_text_field':\n case 'product_reference':\n case 'page_reference':\n case 'variant_reference':\n case 'file_reference':\n case 'url':\n default:\n return metafield.value;\n }\n}\n\n/**\n * Parses a JSON string while preventing prototype injection attacks.\n */\nexport function parseJSON(json: string) {\n if (String(json).includes('__proto__')) {\n return JSON.parse(json, (k, v) => {\n if (k !== '__proto__') return v;\n });\n }\n\n return JSON.parse(json);\n}\n\nconst UNIT_MAPPING: Record<string, string> = {\n // Dimension\n mm: 'millimeter',\n cm: 'centimeter',\n m: 'meter',\n in: 'inch',\n ft: 'foot',\n yd: 'yard',\n // Volume\n ml: 'milliliter',\n l: 'liter',\n us_fl_oz: 'fluid-ounce',\n us_gal: 'gallon',\n // Weight\n kg: 'kilogram',\n g: 'gram',\n lb: 'pound',\n oz: 'ounce',\n};\n\nexport function getMeasurementAsString(\n measurement: Measurement,\n locale = 'en-us',\n options: Intl.NumberFormatOptions = {}\n) {\n let measure: Measurement = {\n value: measurement.value,\n unit: UNIT_MAPPING[measurement.unit],\n };\n\n if (measure.unit == null) {\n measure = convertToSupportedUnit(measurement.value, measurement.unit);\n }\n\n return new Intl.NumberFormat(locale, {\n ...options,\n unit: measure.unit,\n style: 'unit',\n }).format(measure.value);\n}\n\nfunction convertToSupportedUnit(value: number, unit: string): Measurement {\n switch (unit) {\n case 'cl':\n return {\n value: value / 1000,\n unit: 'liter',\n };\n case 'm3':\n return {\n value: value * 1000,\n unit: 'liter',\n };\n case 'us_pt':\n return {\n value: value * 0.125,\n unit: 'gallon',\n };\n case 'us_qt':\n return {\n value: value * 0.5,\n unit: 'gallon',\n };\n case 'us_oz':\n return {\n value: value / 128,\n unit: 'gallon',\n };\n case 'imp_pt':\n return {\n value: value / 6.661, // approximate conversion\n unit: 'gallon',\n };\n case 'imp_qt':\n return {\n value: value / 3.331, // approximate conversion\n unit: 'gallon',\n };\n case 'imp_gal':\n return {\n value: value / 1.201, // approximate conversion\n unit: 'gallon',\n };\n case 'imp_fl_oz':\n return {\n value: value * 0.96076, // approximate conversion\n unit: 'fluid-ounce',\n };\n default:\n throw new Error(`Unit not supported: ${unit}`);\n }\n}\n\ntype ParsedMetafield = Omit<\n PartialDeep<MetafieldType, {recurseIntoArrays: true}>,\n 'value'\n> & {\n value?: string | number | boolean | JsonValue | Date | Rating | Measurement;\n};\n\nexport interface Rating {\n value: number;\n scale_min: number;\n scale_max: number;\n}\n\ninterface Measurement {\n unit: string;\n value: number;\n}\n"],"names":["Metafield","props","data","as","passthroughProps","locale","useShop","parsedMetafield","useMemo","parseMetafield","noDataPropWarning","Error","value","undefined","noValueWarning","id","key","type","Wrapper","toLocaleDateString","toLocaleString","getMeasurementAsString","__html","split","join","protocolLessUrl","URL","href","replace","protocol","JSON","stringify","ref","reference","title","refArray","references","flattenConnection","map","index","__typename","image","_jsx","Image","previewImage","url","Video","toString","metafield","console","info","warn","parseMetafieldValue","parseInt","parseFloat","Date","parseJSON","json","String","includes","parse","k","v","UNIT_MAPPING","mm","cm","m","in","ft","yd","ml","l","us_fl_oz","us_gal","kg","g","lb","oz","measurement","options","measure","unit","convertToSupportedUnit","Intl","NumberFormat","style","format"],"mappings":";;;;;;;;AAiCO,SAASA,UACdC,OACA;;AACM,QAAA;AAAA,IAACC;AAAAA,IAAMC;AAAAA,OAAOC;AAAAA,EAAoBH,IAAAA;AAClC,QAAA;AAAA,IAACI;AAAAA,MAAUC,gBAAjB,QAAA;AAEMC,QAAAA,kBAAkBC,WAAAA,QAAQ,MAAMC,eAAeP,IAAD,GAAQ,CAACA,IAAD,CAA7B;AAE/B,MAAI,CAACK,iBAAiB;AACpB,UAAMG,oBAAqB;AACL;AACd,YAAA,IAAIC,MAAMD,iBAAV;AAAA,IAGP;AAAA,EAEF;AAED,MAAIH,gBAAgBK,UAAU,QAAQL,gBAAgBK,UAAUC,QAAW;AACzE,UAAMC,iBAAkB,mDACtBP,qBAAgBQ,OAAhBR,YAAsBA,gBAAgBS;AAElB;AACd,YAAA,IAAIL,MAAMG,cAAV;AAAA,IAGP;AAAA,EAEF;AAED,UAAQP,gBAAgBU,MAAxB;AAAA,IACE,KAAK,QAAQ;AACX,YAAMC,WAAUf,kBAAM;AACtB,4CACGe,UAAD;AAAA,QAAA,GAAad;AAAAA,QAAb,UACIG,gBAAgBK,MAAeO,mBAAmBd,MAAnD;AAAA,MAAA,CAFL;AAAA,IAKD;AAAA,IACD,KAAK,aAAa;AAChB,YAAMa,WAAUf,kBAAM;AACtB,4CACGe,UAAD;AAAA,QAAA,GAAad;AAAAA,QAAb,UACIG,gBAAgBK,MAAeQ,eAAef,MAA/C;AAAA,MAAA,CAFL;AAAA,IAKD;AAAA,IACD,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK,UAAU;AACb,YAAMa,WAAUf,kBAAM;AACtB,4CACGe,UAAD;AAAA,QAAA,GAAad;AAAAA,QAAb,UACGiB,uBAAuBd,gBAAgBK,OAAsBP,MAAvC;AAAA,MAAA,CAF3B;AAAA,IAKD;AAAA,IACD,KAAK,UAAU;AACb,YAAMa,WAAUf,kBAAM;AACtB,4CACGe,UAAD;AAAA,QAAA,GAAad;AAAAA,QAAb,UACIG,gBAAgBK,MAAiBA;AAAAA,MAAAA,CAFvC;AAAA,IAKD;AAAA,IACD,KAAK,0BAA0B;AAC7B,YAAMM,WAAUf,kBAAM;AACtB,4CACGe,UAAD;AAAA,QAAA,GACMd;AAAAA,QACJ,yBAAyB;AAAA,UAACkB,QAAQf,gBAAgBK;AAAAA,QAAzB;AAAA,MAAA,CAH7B;AAAA,IAMD;AAAA,IACD,KAAK,yBAAyB;AAC5B,YAAMM,WAAUf,kBAAM;AACtB,4CACGe,UAAD;AAAA,QAAA,GACMd;AAAAA,QACJ,yBAAyB;AAAA,UACvBkB,QAASf,gBAAgBK,MAAiBW,MAAM,IAAxC,EAA8CC,KAAK,OAAnD;AAAA,QADe;AAAA,MAAA,CAH7B;AAAA,IAQD;AAAA,IACD,KAAK,OAAO;AACV,YAAMC,kBAAkB,IAAIC,IAAInB,gBAAgBK,KAAhD;AACA,4CACE,KAAA;AAAA,QACE,MAAMa,gBAAgBE,KAAKC,QAAQH,gBAAgBI,UAAU,EAAvD;AAAA,QADR,GAEMzB;AAAAA,QAFN,UAIGG,gBAAgBK;AAAAA,MAAAA,CALrB;AAAA,IAQD;AAAA,IACD,KAAK,QAAQ;AACX,YAAMM,WAAUf,kBAAM;AACtB,4CACGe,UAAD;AAAA,QAAA,GAAad;AAAAA,QAAb,UACG0B,KAAKC,UAAUxB,gBAAgBK,KAA/B;AAAA,MAAA,CAFL;AAAA,IAKD;AAAA,IACD,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK,kBAAkB;AACrB,YAAMM,WAAUf,kBAAM;AACtB,YAAM6B,MAAMzB,gBAAgB0B;AAC5B,4CACGf,UAAD;AAAA,QAAA,GAAad;AAAAA,QAAb,WAAgC4B,sCAAKE,UAALF,YAAcA,2BAAKjB,OAAnBiB,YAAyB;AAAA,MAAA,CAD3D;AAAA,IAGD;AAAA,IACD,KAAK,+BAA+B;AAClC,YAAMd,WAAUf,kBAAM;AAEtB,YAAMgC,WAAW5B,gBAAgB6B,aAC5BC,oCAAkB9B,gBAAgB6B,UAAjB,IAClB;AACJ,4CACGlB,UAAD;AAAA,QAAA,GAAad;AAAAA,QAAb,UACG+B,SAASG,IAAI,CAACN,KAAKO,yCAGlB,MAAA;AAAA,UAAA,UAAmCP;AAAAA,QAAAA,GAAzB,GAAEA,oBAAO,MAAMO,OAAzB,CAHD;AAAA,MAAA,CAFL;AAAA,IASD;AAAA,IACD,KAAK,kBAAkB;AACjBhC,YAAAA,qBAAgB0B,cAAhB1B,mBAA2BiC,gBAAe,cAAc;AAC1D,cAAMR,MAAMzB,gBAAgB0B;AACrBD,eAAAA,IAAIS,QACTC,2BAAA,IAACC,aAAD;AAAA,UAAO,MAAMX,IAAIS;AAAAA,UAAjB,GAA4BrC;AAAAA,QAA5B,CAAA,IACE;AAAA,MACKG,aAAAA,qBAAgB0B,cAAhB1B,mBAA2BiC,gBAAe,eAAe;AAClE,cAAMR,MAAMzB,gBAAgB0B;AACrBD,eAAAA,IAAIY,eACTF,2BAAA,IAAA,KAAA;AAAA,UAAG,OAAMnC,2BAAgB0B,cAAhB1B,mBAA2BsC,QAA3BtC,YAAkC;AAAA,UAA3C,GAAmDH;AAAAA,UAAnD,yCACGuC,aAAD;AAAA,YAAO,MAAMX,IAAIY;AAAAA,UAAAA,CAAjB;AAAA,QADF,CAAA,IAGE;AAAA,MACKrC,aAAAA,qBAAgB0B,cAAhB1B,mBAA2BiC,gBAAe,SAAS;AAC5D,cAAMR,MAAMzB,gBAAgB0B;AAC5B,8CAAQa,MAAAA,OAAD;AAAA,UAAA,GAAW1C;AAAAA,UAAkB,MAAM4B;AAAAA,QAAAA,CAA1C;AAAA,MACD;AAAA,IACF;AAAA,EApHH;AAuHA,QAAMd,UAAUf,kBAAM;AACtB,wCACG,SAAD;AAAA,IAAA,GAAaC;AAAAA,IAAb,WAAgCG,qBAAgBK,UAAhBL,mBAAuBwC;AAAAA,EAAvB,CADlC;AAGD;AASM,SAAStC,eAEduC,WACgE;AAC1C;AACpBC,YAAQC,KACL,yHADH;AAAA,EAGD;AAED,MAAI,CAACF,WAAW;AACQ;AACpBC,cAAQE,KACL,wEADH;AAAA,IAGD;AACM,WAAA;AAAA,EACR;AACD,MAEGH,UAAUpC,UAAU,QAAQoC,UAAUpC,UAAUC,QACjD;AACQsC,YAAAA,KACL,iCAAgCH,UAAUpC,6BAD7C;AAAA,EAGD;AAEM,SAAA;AAAA,IACL,GAAGoC;AAAAA,IACHpC,OAAOwC,oBAAoBJ,SAAD;AAAA,EAAA;AAE7B;AAMM,SAASI,oBACdJ,WAC0B;AACJ;AACpBC,YAAQC,KAAM,6DAAd;AAAA,EACD;AAED,MAAI,CAACF,WAAW;AACP,WAAA;AAAA,EACR;AAED,MAAIA,UAAUpC,UAAU,QAAQoC,UAAUpC,UAAUC,QAAW;AACvC;AACZsC,cAAAA,KACL,sCAAqCH,UAAUpC,6BADlD;AAAA,IAGD;AACD,WAAOoC,UAAUpC;AAAAA,EAClB;AAED,UAAQoC,UAAU/B,MAAlB;AAAA,IACE,KAAK;AACH,aAAO+B,UAAUpC,UAAU;AAAA,IAC7B,KAAK;AACIyC,aAAAA,SAASL,UAAUpC,KAAX;AAAA,IACjB,KAAK;AACI0C,aAAAA,WAAWN,UAAUpC,KAAX;AAAA,IACnB,KAAK;AAAA,IACL,KAAK;AACI,aAAA,IAAI2C,KAAKP,UAAUpC,KAAnB;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACI4C,aAAAA,UAAUR,UAAUpC,KAAX;AAAA,IAClB,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL;AACE,aAAOoC,UAAUpC;AAAAA,EAzBrB;AA2BD;AAKM,SAAS4C,UAAUC,MAAc;AACtC,MAAIC,OAAOD,IAAD,EAAOE,SAAS,WAAtB,GAAoC;AACtC,WAAO7B,KAAK8B,MAAMH,MAAM,CAACI,GAAGC,MAAM;AAChC,UAAID,MAAM;AAAoBC,eAAAA;AAAAA,IAAAA,CADzB;AAAA,EAGR;AAEMhC,SAAAA,KAAK8B,MAAMH,IAAX;AACR;AAED,MAAMM,eAAuC;AAAA,EAE3CC,IAAI;AAAA,EACJC,IAAI;AAAA,EACJC,GAAG;AAAA,EACHC,IAAI;AAAA,EACJC,IAAI;AAAA,EACJC,IAAI;AAAA,EAEJC,IAAI;AAAA,EACJC,GAAG;AAAA,EACHC,UAAU;AAAA,EACVC,QAAQ;AAAA,EAERC,IAAI;AAAA,EACJC,GAAG;AAAA,EACHC,IAAI;AAAA,EACJC,IAAI;AAjBuC;AAoBtC,SAASxD,uBACdyD,aACAzE,SAAS,SACT0E,UAAoC,CAAA,GACpC;AACA,MAAIC,UAAuB;AAAA,IACzBpE,OAAOkE,YAAYlE;AAAAA,IACnBqE,MAAMlB,aAAae,YAAYG;AAAAA,EAAAA;AAG7BD,MAAAA,QAAQC,QAAQ,MAAM;AACxBD,cAAUE,uBAAuBJ,YAAYlE,OAAOkE,YAAYG,IAAhC;AAAA,EACjC;AAEM,SAAA,IAAIE,KAAKC,aAAa/E,QAAQ;AAAA,IACnC,GAAG0E;AAAAA,IACHE,MAAMD,QAAQC;AAAAA,IACdI,OAAO;AAAA,EAHF,CAAA,EAIJC,OAAON,QAAQpE,KAJX;AAKR;AAED,SAASsE,uBAAuBtE,OAAeqE,MAA2B;AACxE,UAAQA,MAAR;AAAA,IACE,KAAK;AACI,aAAA;AAAA,QACLrE,OAAOA,QAAQ;AAAA,QACfqE,MAAM;AAAA,MAAA;AAAA,IAEV,KAAK;AACI,aAAA;AAAA,QACLrE,OAAOA,QAAQ;AAAA,QACfqE,MAAM;AAAA,MAAA;AAAA,IAEV,KAAK;AACI,aAAA;AAAA,QACLrE,OAAOA,QAAQ;AAAA,QACfqE,MAAM;AAAA,MAAA;AAAA,IAEV,KAAK;AACI,aAAA;AAAA,QACLrE,OAAOA,QAAQ;AAAA,QACfqE,MAAM;AAAA,MAAA;AAAA,IAEV,KAAK;AACI,aAAA;AAAA,QACLrE,OAAOA,QAAQ;AAAA,QACfqE,MAAM;AAAA,MAAA;AAAA,IAEV,KAAK;AACI,aAAA;AAAA,QACLrE,OAAOA,QAAQ;AAAA,QACfqE,MAAM;AAAA,MAAA;AAAA,IAEV,KAAK;AACI,aAAA;AAAA,QACLrE,OAAOA,QAAQ;AAAA,QACfqE,MAAM;AAAA,MAAA;AAAA,IAEV,KAAK;AACI,aAAA;AAAA,QACLrE,OAAOA,QAAQ;AAAA,QACfqE,MAAM;AAAA,MAAA;AAAA,IAEV,KAAK;AACI,aAAA;AAAA,QACLrE,OAAOA,QAAQ;AAAA,QACfqE,MAAM;AAAA,MAAA;AAAA,IAEV;AACQ,YAAA,IAAItE,MAAO,uBAAsBsE,MAAjC;AAAA,EA/CV;AAiDD;;;;;;"}
|
package/dist/dev/Metafield.mjs
CHANGED
|
@@ -143,6 +143,9 @@ function Metafield(props) {
|
|
|
143
143
|
});
|
|
144
144
|
}
|
|
145
145
|
function parseMetafield(metafield) {
|
|
146
|
+
{
|
|
147
|
+
console.info(`'parseMetafield()' will have a breaking change in a future version; its behavior will match that of 'metafieldParser()'`);
|
|
148
|
+
}
|
|
146
149
|
if (!metafield) {
|
|
147
150
|
{
|
|
148
151
|
console.warn(`'parseMetafield' was not passed any value for the 'metafield' argument`);
|
|
@@ -158,6 +161,9 @@ function parseMetafield(metafield) {
|
|
|
158
161
|
};
|
|
159
162
|
}
|
|
160
163
|
function parseMetafieldValue(metafield) {
|
|
164
|
+
{
|
|
165
|
+
console.info(`'parseMetafieldValue()' will be removed in a future version`);
|
|
166
|
+
}
|
|
161
167
|
if (!metafield) {
|
|
162
168
|
return null;
|
|
163
169
|
}
|