@gem-sdk/components 2.1.14 → 2.1.16

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.
Files changed (24) hide show
  1. package/dist/cjs/post-purchase/product/components/ProductDiscountTag.js +2 -5
  2. package/dist/cjs/post-purchase/product/components/ProductOffer.js +3 -16
  3. package/dist/cjs/post-purchase/product/components/ProductPrice.js +1 -3
  4. package/dist/cjs/post-purchase/product/components/ProductPriceBreakdown.js +21 -9
  5. package/dist/cjs/post-purchase/product/settings/ProductOffer.js +0 -26
  6. package/dist/cjs/product/components/ProductDescription/common.js +28 -0
  7. package/dist/cjs/product/components/ProductDescription/const.js +5 -0
  8. package/dist/cjs/product/components/ProductDescription.js +38 -10
  9. package/dist/cjs/product/components/ProductDescription.liquid.js +3 -1
  10. package/dist/esm/post-purchase/product/components/ProductDiscountTag.js +2 -5
  11. package/dist/esm/post-purchase/product/components/ProductOffer.js +3 -16
  12. package/dist/esm/post-purchase/product/components/ProductPrice.js +1 -3
  13. package/dist/esm/post-purchase/product/components/ProductPriceBreakdown.js +21 -9
  14. package/dist/esm/post-purchase/product/settings/ProductOffer.js +0 -26
  15. package/dist/esm/product/components/ProductDescription/common.js +26 -0
  16. package/dist/esm/product/components/ProductDescription/const.js +3 -0
  17. package/dist/esm/product/components/ProductDescription.js +38 -10
  18. package/dist/esm/product/components/ProductDescription.liquid.js +3 -1
  19. package/dist/types/index.d.ts +0 -1
  20. package/package.json +2 -2
  21. package/dist/cjs/post-purchase/product/constants/ProductOfferPlaceholder.js +0 -127
  22. package/dist/cjs/post-purchase/product/hooks/useDynamicProduct.js +0 -28
  23. package/dist/esm/post-purchase/product/constants/ProductOfferPlaceholder.js +0 -125
  24. package/dist/esm/post-purchase/product/hooks/useDynamicProduct.js +0 -26
@@ -5,29 +5,26 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var core = require('@gem-sdk/core');
7
7
  var Text = require('../../text/Text.js');
8
- var useDynamicProduct = require('../hooks/useDynamicProduct.js');
9
8
 
10
9
  const PostPurchaseProductDiscountTag = ({ setting = {}, styles = {}, style, builderAttrs, builderProps, children })=>{
11
10
  const currentProduct = core.useProduct();
12
11
  const currentProductId = currentProduct?.baseID?.replace('gid://shopify/Product/', '');
13
12
  const currentOfferDiscount = core.useProductOfferDiscount();
14
- const { isDynamicProduct, isEnableDynamicDiscount } = useDynamicProduct.useDynamicProduct();
15
13
  const { typo } = styles;
16
14
  const { message } = setting;
17
- const hasDiscount = !!currentOfferDiscount || isDynamicProduct && isEnableDynamicDiscount;
18
15
  return /*#__PURE__*/ jsxRuntime.jsxs("div", {
19
16
  ...builderAttrs,
20
17
  className: core.cls(builderProps?.uid, 'gp-flex gp-w-full'),
21
18
  style: {
22
19
  ...style,
23
- opacity: hasDiscount ? 1 : 0.2
20
+ opacity: currentOfferDiscount ? 1 : 0.2
24
21
  },
25
22
  id: `shopify-text-element-${builderProps?.uid}`,
26
23
  "data-product-id": currentProductId,
27
24
  children: [
28
25
  /*#__PURE__*/ jsxRuntime.jsx(Text.default, {
29
26
  setting: {
30
- text: hasDiscount ? message : message?.replace(new RegExp(/\{\{Discount\}\}/, 'gi'), '0%')
27
+ text: currentOfferDiscount ? message : message?.replace(new RegExp(/\{\{Discount\}\}/, 'gi'), '0%')
31
28
  },
32
29
  styles: {
33
30
  typo
@@ -11,20 +11,14 @@ var Loading = require('../../../common/components/Loading.js');
11
11
  var ProductVariant = require('./ProductVariant.js');
12
12
  var helper = require('../../utils/helper.js');
13
13
  var index = require('../helpers/index.js');
14
- var ProductOfferPlaceholder = require('../constants/ProductOfferPlaceholder.js');
15
- var useDynamicProduct = require('../hooks/useDynamicProduct.js');
16
14
 
17
15
  const PostPurchaseProductOffer = ({ styles, builderAttrs, builderProps, children, setting })=>{
18
16
  const mode = core.useEditorMode();
19
- const { productSetting, productOfferLayout, inlineAlignment, discountAndShippingFee, ...rowSetting } = setting || {};
17
+ const { productSetting, productOfferLayout, inlineAlignment, ...rowSetting } = setting || {};
20
18
  const { productOfferColumnGap, productOfferVerticalGutter, productOfferWidth, ...rowStyles } = styles || {};
21
19
  const productOffers = core.usePageStore((s)=>s.productOffers);
22
20
  const publicStoreFrontData = core.usePageStore((s)=>s.publicStoreFrontData);
23
- const { isDynamicProduct } = useDynamicProduct.useDynamicProduct();
24
- const dynamicDiscountOffer = core.usePageStore((s)=>s.dynamicDiscountOffer);
25
- const totalProduct = React.useMemo(()=>isDynamicProduct ? dynamicDiscountOffer?.appliedProductCount : productOffers?.length, [
26
- dynamicDiscountOffer?.appliedProductCount,
27
- isDynamicProduct,
21
+ const totalProduct = React.useMemo(()=>productOffers?.length, [
28
22
  productOffers?.length
29
23
  ]);
30
24
  const sortedProductBaseIDs = React.useMemo(()=>{
@@ -50,14 +44,7 @@ const PostPurchaseProductOffer = ({ styles, builderAttrs, builderProps, children
50
44
  const products = React.useMemo(()=>core.flattenConnection(productData.data?.products), [
51
45
  productData.data?.products
52
46
  ]);
53
- const productSortedById = React.useMemo(()=>{
54
- return isDynamicProduct && dynamicDiscountOffer?.appliedProductCount ? Array(dynamicDiscountOffer.appliedProductCount).fill(ProductOfferPlaceholder.productOfferPlaceholder) : sortedProductBaseIDs?.map((id)=>products?.find((el)=>el?.baseID === id)).filter(Boolean);
55
- }, [
56
- isDynamicProduct,
57
- dynamicDiscountOffer?.appliedProductCount,
58
- sortedProductBaseIDs,
59
- products
60
- ]);
47
+ const productSortedById = sortedProductBaseIDs?.map((id)=>products?.find((el)=>el?.baseID === id)).filter(Boolean);
61
48
  const getStyles = ()=>{
62
49
  return {
63
50
  ...core.makeStyleResponsive('cg', productOfferColumnGap),
@@ -6,7 +6,6 @@ var jsxRuntime = require('react/jsx-runtime');
6
6
  var core = require('@gem-sdk/core');
7
7
  var React = require('react');
8
8
  var Text = require('../../text/Text.js');
9
- var useDynamicProduct = require('../hooks/useDynamicProduct.js');
10
9
 
11
10
  const PostPurchaseProductPrice = ({ styles, style, builderAttrs, builderProps, children })=>{
12
11
  const currentVariant = core.useCurrentVariant();
@@ -14,7 +13,6 @@ const PostPurchaseProductPrice = ({ styles, style, builderAttrs, builderProps, c
14
13
  const price = currentVariant?.price ?? 0;
15
14
  const salePrice = currentVariant?.salePrice ?? 0;
16
15
  const discount = parseFloat(core.shopifyPriceRounding(core.useProductOfferDiscount(), 2));
17
- const { isDynamicProduct } = useDynamicProduct.useDynamicProduct();
18
16
  const priceShow = React.useMemo(()=>{
19
17
  if (!discount) {
20
18
  if (styles?.priceType === 'compare') {
@@ -55,7 +53,7 @@ const PostPurchaseProductPrice = ({ styles, style, builderAttrs, builderProps, c
55
53
  /*#__PURE__*/ jsxRuntime.jsx(Text.default, {
56
54
  styles: styles,
57
55
  setting: {
58
- text: isDynamicProduct ? '$???' : moneyFormatted
56
+ text: moneyFormatted
59
57
  },
60
58
  className: core.cls({
61
59
  'gp-money': styles?.priceType === 'regular',
@@ -7,7 +7,6 @@ var core = require('@gem-sdk/core');
7
7
  var React = require('react');
8
8
  var helper = require('../../utils/helper.js');
9
9
  var MoneyLine = require('./priceBreakdown/MoneyLine.js');
10
- var useDynamicProduct = require('../hooks/useDynamicProduct.js');
11
10
 
12
11
  const PostPurchaseProductPriceBreakdown = ({ setting = {}, styles = {}, style, builderAttrs, builderProps, children })=>{
13
12
  const currentVariant = core.useCurrentVariant();
@@ -22,7 +21,6 @@ const PostPurchaseProductPriceBreakdown = ({ setting = {}, styles = {}, style, b
22
21
  const discountShopifyFormat = core.shopifyPriceRounding(discountWithQuantity, 2);
23
22
  const totalMoneyFormatted = core.useFormatMoney(subTotal - parseFloat(discountShopifyFormat), false);
24
23
  const currentProductId = currentProduct?.baseID?.replace('gid://shopify/Product/', '');
25
- const { isDynamicProduct, dynamicPrice, dynamicDiscount, isEnableDynamicDiscount } = useDynamicProduct.useDynamicProduct();
26
24
  const { labelStyle, moneyStyle, spacing, width, align, isShowPrice } = styles;
27
25
  const itemGap = React.useMemo(()=>{
28
26
  return helper.postPurchaseSpacing[spacing || 'none'];
@@ -35,19 +33,19 @@ const PostPurchaseProductPriceBreakdown = ({ setting = {}, styles = {}, style, b
35
33
  }, [
36
34
  isShowPrice
37
35
  ]);
38
- const getMoneyLines = ()=>{
36
+ const moneyLines = React.useMemo(()=>{
39
37
  const data = [];
40
38
  if (styles.isShowSubTotalLabel !== false) {
41
39
  data.push({
42
40
  title: setting.subTotalLabel,
43
- money: isDynamicProduct ? dynamicPrice : subTotalMoneyFormatted,
41
+ money: subTotalMoneyFormatted,
44
42
  uniqueId: 'subTotalLabel'
45
43
  });
46
44
  }
47
45
  if (styles.isShowDiscountLabel !== false) {
48
46
  data.push({
49
47
  title: setting.discountLabel,
50
- money: isDynamicProduct && dynamicDiscount && isEnableDynamicDiscount ? dynamicPrice : discount > 0 ? discountMoneyFormatted : 'No discount',
48
+ money: discount > 0 ? discountMoneyFormatted : 'No discount',
51
49
  uniqueId: 'discountLabel'
52
50
  });
53
51
  }
@@ -73,11 +71,25 @@ const PostPurchaseProductPriceBreakdown = ({ setting = {}, styles = {}, style, b
73
71
  }
74
72
  data.push({
75
73
  title: setting.totalLabel,
76
- money: isDynamicProduct ? dynamicPrice : totalMoneyFormatted,
74
+ money: totalMoneyFormatted,
77
75
  uniqueId: 'totalLabel'
78
76
  });
79
77
  return data;
80
- };
78
+ }, [
79
+ discount,
80
+ discountMoneyFormatted,
81
+ setting.discountLabel,
82
+ setting.shippingLabel,
83
+ setting.subTotalLabel,
84
+ setting.taxesLabel,
85
+ setting.totalLabel,
86
+ styles.isShowSubTotalLabel,
87
+ styles.isShowDiscountLabel,
88
+ styles.isShowShippingLabel,
89
+ styles.isShowTaxesLabel,
90
+ subTotalMoneyFormatted,
91
+ totalMoneyFormatted
92
+ ]);
81
93
  return /*#__PURE__*/ jsxRuntime.jsxs(jsxRuntime.Fragment, {
82
94
  children: [
83
95
  /*#__PURE__*/ jsxRuntime.jsxs("div", {
@@ -128,9 +140,9 @@ const PostPurchaseProductPriceBreakdown = ({ setting = {}, styles = {}, style, b
128
140
  ...core.makeStyleResponsive('w', width),
129
141
  gap: itemGap
130
142
  },
131
- children: getMoneyLines().map((item)=>/*#__PURE__*/ jsxRuntime.jsxs(React.Fragment, {
143
+ children: moneyLines.map((item)=>/*#__PURE__*/ jsxRuntime.jsxs(React.Fragment, {
132
144
  children: [
133
- item.uniqueId === 'totalLabel' && getMoneyLines().length > 1 && /*#__PURE__*/ jsxRuntime.jsx("hr", {}),
145
+ item.uniqueId === 'totalLabel' && moneyLines.length > 1 && /*#__PURE__*/ jsxRuntime.jsx("hr", {}),
134
146
  /*#__PURE__*/ jsxRuntime.jsx("div", {
135
147
  children: /*#__PURE__*/ jsxRuntime.jsx(MoneyLine.default, {
136
148
  uniqueId: item.uniqueId,
@@ -184,14 +184,6 @@ const config = {
184
184
  }
185
185
  }
186
186
  },
187
- {
188
- id: 'dynamicOfferQuantity',
189
- type: 'dynamic-offer-quantity',
190
- min: 1,
191
- max: 4,
192
- default: 2,
193
- isOnlyAcceptInteger: true
194
- },
195
187
  {
196
188
  id: 'discountAndShippingFee',
197
189
  type: 'discount-and-shipping-fee-product-offer',
@@ -385,24 +377,6 @@ const config = {
385
377
  },
386
378
  layout: 'vertical'
387
379
  },
388
- {
389
- type: 'group',
390
- label: {
391
- en: 'Product offers'
392
- },
393
- controls: [
394
- {
395
- type: 'control',
396
- label: {
397
- en: 'Quantity'
398
- },
399
- setting: {
400
- id: 'dynamicOfferQuantity'
401
- }
402
- }
403
- ],
404
- condition: 'false'
405
- },
406
380
  {
407
381
  type: 'control',
408
382
  label: {
@@ -0,0 +1,28 @@
1
+ 'use strict';
2
+
3
+ var core = require('@gem-sdk/core');
4
+ var _const = require('./const.js');
5
+
6
+ const getMaxHeightStyleDefault = (setting)=>{
7
+ let result = {
8
+ desktop: 'none'
9
+ };
10
+ const devices = [
11
+ 'desktop',
12
+ 'mobile',
13
+ 'tablet'
14
+ ];
15
+ devices.forEach((device)=>{
16
+ const lineClamp = core.getResponsiveValueByScreen(setting?.lineClamp, device);
17
+ const hasLineClamp = core.getResponsiveValueByScreen(setting?.hasLineClamp, device);
18
+ const maxHeight = hasLineClamp && lineClamp ? `${lineClamp * _const.DESCRIPTION_LINE_HEIGHT_DEFAULT}px` : 'none';
19
+ result = {
20
+ ...result,
21
+ [device]: maxHeight
22
+ };
23
+ });
24
+ const style = core.makeStyleResponsive('maxh', result);
25
+ return style;
26
+ };
27
+
28
+ exports.getMaxHeightStyleDefault = getMaxHeightStyleDefault;
@@ -0,0 +1,5 @@
1
+ 'use strict';
2
+
3
+ const DESCRIPTION_LINE_HEIGHT_DEFAULT = 21;
4
+
5
+ exports.DESCRIPTION_LINE_HEIGHT_DEFAULT = DESCRIPTION_LINE_HEIGHT_DEFAULT;
@@ -5,6 +5,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var core = require('@gem-sdk/core');
7
7
  var React = require('react');
8
+ var common = require('./ProductDescription/common.js');
9
+ var _const = require('./ProductDescription/const.js');
8
10
 
9
11
  const ProductDescription = ({ setting, builderProps })=>{
10
12
  const [open, setOpen] = React.useState(false);
@@ -18,14 +20,18 @@ const ProductDescription = ({ setting, builderProps })=>{
18
20
  React.useEffect(()=>{
19
21
  const dom = ref.current;
20
22
  setOpen(false);
21
- if (dom && hasLineClamp && product?.description) {
23
+ if (!dom) return;
24
+ const enableShowMore = hasLineClamp && product?.descriptionHtml;
25
+ if (!enableShowMore) dom.style.maxHeight = 'none';
26
+ else {
22
27
  const value = lineClamp;
23
28
  setTimeout(()=>{
24
29
  const scrollHeight = dom?.scrollHeight ?? 0;
25
30
  const clientHeight = dom?.clientHeight ?? 0;
26
- const lineHeight = window.getComputedStyle(dom).getPropertyValue('line-height');
27
- const lineText = Math.round((scrollHeight ?? 0) / parseInt(lineHeight));
28
- const conditionCheckLine = core.isSafari() ? value && value < lineText : clientHeight < scrollHeight;
31
+ const lineHeight = getLineHeightFromDom();
32
+ const lineText = Math.round((scrollHeight ?? 0) / lineHeight);
33
+ dom.style.maxHeight = getMaxHeight(lineHeight);
34
+ const conditionCheckLine = value && value < lineText || clientHeight < scrollHeight;
29
35
  if (value && conditionCheckLine) {
30
36
  allowShowViewMore(()=>true);
31
37
  } else {
@@ -36,8 +42,19 @@ const ProductDescription = ({ setting, builderProps })=>{
36
42
  }, [
37
43
  hasLineClamp,
38
44
  lineClamp,
39
- product?.description
45
+ product?.description,
46
+ core.isSafari
40
47
  ]);
48
+ const getLineHeightFromDom = ()=>{
49
+ if (!ref.current) return _const.DESCRIPTION_LINE_HEIGHT_DEFAULT;
50
+ const lineHeight = window.getComputedStyle(ref.current).getPropertyValue('line-height');
51
+ return parseInt(lineHeight);
52
+ };
53
+ const getMaxHeight = (lineHeight)=>{
54
+ if (!hasLineClamp || !lineClamp) return 'auto';
55
+ if (lineHeight) return `${lineClamp * lineHeight}px`;
56
+ return 'auto';
57
+ };
41
58
  const Tag = htmlTag === 'html' ? 'div' : 'p';
42
59
  const appendTypoClass = core.composeTypographyClassName(setting?.typo, setting?.typography);
43
60
  const appendTypoStyle = core.composeTypographyStyle(setting?.typo, setting?.typography);
@@ -54,7 +71,17 @@ const ProductDescription = ({ setting, builderProps })=>{
54
71
  }
55
72
  `;
56
73
  const DescriptionNotFoundString = 'This product does not have a description';
57
- const hasDescription = product?.description && product.description?.trim() != '';
74
+ const noDescriptionHtml = !product?.descriptionHtml;
75
+ const handleToggleShowMore = ()=>{
76
+ if (!ref.current) return;
77
+ const lineHeight = getLineHeightFromDom();
78
+ if (open) {
79
+ ref.current.style.maxHeight = getMaxHeight(lineHeight);
80
+ } else {
81
+ ref.current.style.maxHeight = 'none';
82
+ }
83
+ setOpen((prev)=>!prev);
84
+ };
58
85
  return /*#__PURE__*/ jsxRuntime.jsx(jsxRuntime.Fragment, {
59
86
  children: !product ? null : /*#__PURE__*/ jsxRuntime.jsxs("div", {
60
87
  "data-id": builderProps?.uid,
@@ -65,7 +92,7 @@ const ProductDescription = ({ setting, builderProps })=>{
65
92
  /*#__PURE__*/ jsxRuntime.jsx(Tag, {
66
93
  ref: ref,
67
94
  "data-gp-text": true,
68
- className: core.cls('gp-p-description-text gp-break-words safari:[&_p]:gp-inline safari:[&_p]:after:gp-whitespace-pre', appendTypoClass, !hasDescription ? 'gp-p-2 gp-text-center gp-text-sm gp-font-semibold gp-text-gray-500 gp-py-2 !gp-text-center' : '', core.getGlobalColorClass('text', setting?.color)),
95
+ className: core.cls('gp-p-description-text gp-break-words safari:[&_p]:gp-inline safari:[&_p]:after:gp-whitespace-pre', appendTypoClass, noDescriptionHtml ? 'gp-p-2 gp-text-center gp-text-sm gp-font-semibold gp-text-gray-500 gp-py-2 !gp-text-center' : '', core.getGlobalColorClass('text', setting?.color)),
69
96
  style: {
70
97
  ...core.getStyleShadow({
71
98
  value: setting?.textShadow,
@@ -77,10 +104,11 @@ const ProductDescription = ({ setting, builderProps })=>{
77
104
  ...core.makeStyle({
78
105
  tt: setting?.transform
79
106
  }),
80
- ...appendTypoStyle
107
+ ...appendTypoStyle,
108
+ ...common.getMaxHeightStyleDefault(setting)
81
109
  },
82
110
  dangerouslySetInnerHTML: {
83
- __html: product?.descriptionHtml && hasDescription ? product.descriptionHtml : `${DescriptionNotFoundString}`
111
+ __html: product?.descriptionHtml || `${DescriptionNotFoundString}`
84
112
  }
85
113
  }),
86
114
  hasLineClamp && isShowViewMore && /*#__PURE__*/ jsxRuntime.jsxs("button", {
@@ -93,7 +121,7 @@ const ProductDescription = ({ setting, builderProps })=>{
93
121
  ...appendTypoStyle,
94
122
  ...core.getGlobalColorStyle(setting?.showMoreColor)
95
123
  },
96
- onClick: ()=>setOpen((prev)=>!prev),
124
+ onClick: handleToggleShowMore,
97
125
  children: [
98
126
  !open ? setting?.viewMoreText : setting?.viewLessText,
99
127
  setting?.enableViewMoreIcon && /*#__PURE__*/ jsxRuntime.jsx("svg", {
@@ -4,6 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var core = require('@gem-sdk/core');
6
6
  var helpers = require('../../helpers.js');
7
+ var common = require('./ProductDescription/common.js');
7
8
 
8
9
  const devices = [
9
10
  'desktop',
@@ -35,7 +36,8 @@ const ProductDescription = ({ setting, advanced, builderProps })=>{
35
36
  ...core.makeStyle({
36
37
  tt: setting?.transform
37
38
  }),
38
- ...appendTypoStyle
39
+ ...appendTypoStyle,
40
+ ...common.getMaxHeightStyleDefault(setting)
39
41
  };
40
42
  const collapseStyle = {
41
43
  ...defaultStyle,
@@ -1,29 +1,26 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { useProduct, useProductOfferDiscount, cls } from '@gem-sdk/core';
3
3
  import Text from '../../text/Text.js';
4
- import { useDynamicProduct } from '../hooks/useDynamicProduct.js';
5
4
 
6
5
  const PostPurchaseProductDiscountTag = ({ setting = {}, styles = {}, style, builderAttrs, builderProps, children })=>{
7
6
  const currentProduct = useProduct();
8
7
  const currentProductId = currentProduct?.baseID?.replace('gid://shopify/Product/', '');
9
8
  const currentOfferDiscount = useProductOfferDiscount();
10
- const { isDynamicProduct, isEnableDynamicDiscount } = useDynamicProduct();
11
9
  const { typo } = styles;
12
10
  const { message } = setting;
13
- const hasDiscount = !!currentOfferDiscount || isDynamicProduct && isEnableDynamicDiscount;
14
11
  return /*#__PURE__*/ jsxs("div", {
15
12
  ...builderAttrs,
16
13
  className: cls(builderProps?.uid, 'gp-flex gp-w-full'),
17
14
  style: {
18
15
  ...style,
19
- opacity: hasDiscount ? 1 : 0.2
16
+ opacity: currentOfferDiscount ? 1 : 0.2
20
17
  },
21
18
  id: `shopify-text-element-${builderProps?.uid}`,
22
19
  "data-product-id": currentProductId,
23
20
  children: [
24
21
  /*#__PURE__*/ jsx(Text, {
25
22
  setting: {
26
- text: hasDiscount ? message : message?.replace(new RegExp(/\{\{Discount\}\}/, 'gi'), '0%')
23
+ text: currentOfferDiscount ? message : message?.replace(new RegExp(/\{\{Discount\}\}/, 'gi'), '0%')
27
24
  },
28
25
  styles: {
29
26
  typo
@@ -7,20 +7,14 @@ import Loading from '../../../common/components/Loading.js';
7
7
  import { DEVICES } from './ProductVariant.js';
8
8
  import { postPurchaseViewSpacing } from '../../utils/helper.js';
9
9
  import { hasPublicStoreFrontData, createStoreFrontFetcher } from '../helpers/index.js';
10
- import { productOfferPlaceholder } from '../constants/ProductOfferPlaceholder.js';
11
- import { useDynamicProduct } from '../hooks/useDynamicProduct.js';
12
10
 
13
11
  const PostPurchaseProductOffer = ({ styles, builderAttrs, builderProps, children, setting })=>{
14
12
  const mode = useEditorMode();
15
- const { productSetting, productOfferLayout, inlineAlignment, discountAndShippingFee, ...rowSetting } = setting || {};
13
+ const { productSetting, productOfferLayout, inlineAlignment, ...rowSetting } = setting || {};
16
14
  const { productOfferColumnGap, productOfferVerticalGutter, productOfferWidth, ...rowStyles } = styles || {};
17
15
  const productOffers = usePageStore((s)=>s.productOffers);
18
16
  const publicStoreFrontData = usePageStore((s)=>s.publicStoreFrontData);
19
- const { isDynamicProduct } = useDynamicProduct();
20
- const dynamicDiscountOffer = usePageStore((s)=>s.dynamicDiscountOffer);
21
- const totalProduct = useMemo(()=>isDynamicProduct ? dynamicDiscountOffer?.appliedProductCount : productOffers?.length, [
22
- dynamicDiscountOffer?.appliedProductCount,
23
- isDynamicProduct,
17
+ const totalProduct = useMemo(()=>productOffers?.length, [
24
18
  productOffers?.length
25
19
  ]);
26
20
  const sortedProductBaseIDs = useMemo(()=>{
@@ -46,14 +40,7 @@ const PostPurchaseProductOffer = ({ styles, builderAttrs, builderProps, children
46
40
  const products = useMemo(()=>flattenConnection(productData.data?.products), [
47
41
  productData.data?.products
48
42
  ]);
49
- const productSortedById = useMemo(()=>{
50
- return isDynamicProduct && dynamicDiscountOffer?.appliedProductCount ? Array(dynamicDiscountOffer.appliedProductCount).fill(productOfferPlaceholder) : sortedProductBaseIDs?.map((id)=>products?.find((el)=>el?.baseID === id)).filter(Boolean);
51
- }, [
52
- isDynamicProduct,
53
- dynamicDiscountOffer?.appliedProductCount,
54
- sortedProductBaseIDs,
55
- products
56
- ]);
43
+ const productSortedById = sortedProductBaseIDs?.map((id)=>products?.find((el)=>el?.baseID === id)).filter(Boolean);
57
44
  const getStyles = ()=>{
58
45
  return {
59
46
  ...makeStyleResponsive('cg', productOfferColumnGap),
@@ -2,7 +2,6 @@ import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { useCurrentVariant, useProduct, shopifyPriceRounding, useProductOfferDiscount, useFormatMoney, cls } from '@gem-sdk/core';
3
3
  import { useMemo } from 'react';
4
4
  import Text from '../../text/Text.js';
5
- import { useDynamicProduct } from '../hooks/useDynamicProduct.js';
6
5
 
7
6
  const PostPurchaseProductPrice = ({ styles, style, builderAttrs, builderProps, children })=>{
8
7
  const currentVariant = useCurrentVariant();
@@ -10,7 +9,6 @@ const PostPurchaseProductPrice = ({ styles, style, builderAttrs, builderProps, c
10
9
  const price = currentVariant?.price ?? 0;
11
10
  const salePrice = currentVariant?.salePrice ?? 0;
12
11
  const discount = parseFloat(shopifyPriceRounding(useProductOfferDiscount(), 2));
13
- const { isDynamicProduct } = useDynamicProduct();
14
12
  const priceShow = useMemo(()=>{
15
13
  if (!discount) {
16
14
  if (styles?.priceType === 'compare') {
@@ -51,7 +49,7 @@ const PostPurchaseProductPrice = ({ styles, style, builderAttrs, builderProps, c
51
49
  /*#__PURE__*/ jsx(Text, {
52
50
  styles: styles,
53
51
  setting: {
54
- text: isDynamicProduct ? '$???' : moneyFormatted
52
+ text: moneyFormatted
55
53
  },
56
54
  className: cls({
57
55
  'gp-money': styles?.priceType === 'regular',
@@ -3,7 +3,6 @@ import { useCurrentVariant, useProduct, useQuantity, useProductOfferDiscount, us
3
3
  import { useMemo, useState, useEffect, Fragment as Fragment$1 } from 'react';
4
4
  import { postPurchaseSpacing } from '../../utils/helper.js';
5
5
  import MoneyLine from './priceBreakdown/MoneyLine.js';
6
- import { useDynamicProduct } from '../hooks/useDynamicProduct.js';
7
6
 
8
7
  const PostPurchaseProductPriceBreakdown = ({ setting = {}, styles = {}, style, builderAttrs, builderProps, children })=>{
9
8
  const currentVariant = useCurrentVariant();
@@ -18,7 +17,6 @@ const PostPurchaseProductPriceBreakdown = ({ setting = {}, styles = {}, style, b
18
17
  const discountShopifyFormat = shopifyPriceRounding(discountWithQuantity, 2);
19
18
  const totalMoneyFormatted = useFormatMoney(subTotal - parseFloat(discountShopifyFormat), false);
20
19
  const currentProductId = currentProduct?.baseID?.replace('gid://shopify/Product/', '');
21
- const { isDynamicProduct, dynamicPrice, dynamicDiscount, isEnableDynamicDiscount } = useDynamicProduct();
22
20
  const { labelStyle, moneyStyle, spacing, width, align, isShowPrice } = styles;
23
21
  const itemGap = useMemo(()=>{
24
22
  return postPurchaseSpacing[spacing || 'none'];
@@ -31,19 +29,19 @@ const PostPurchaseProductPriceBreakdown = ({ setting = {}, styles = {}, style, b
31
29
  }, [
32
30
  isShowPrice
33
31
  ]);
34
- const getMoneyLines = ()=>{
32
+ const moneyLines = useMemo(()=>{
35
33
  const data = [];
36
34
  if (styles.isShowSubTotalLabel !== false) {
37
35
  data.push({
38
36
  title: setting.subTotalLabel,
39
- money: isDynamicProduct ? dynamicPrice : subTotalMoneyFormatted,
37
+ money: subTotalMoneyFormatted,
40
38
  uniqueId: 'subTotalLabel'
41
39
  });
42
40
  }
43
41
  if (styles.isShowDiscountLabel !== false) {
44
42
  data.push({
45
43
  title: setting.discountLabel,
46
- money: isDynamicProduct && dynamicDiscount && isEnableDynamicDiscount ? dynamicPrice : discount > 0 ? discountMoneyFormatted : 'No discount',
44
+ money: discount > 0 ? discountMoneyFormatted : 'No discount',
47
45
  uniqueId: 'discountLabel'
48
46
  });
49
47
  }
@@ -69,11 +67,25 @@ const PostPurchaseProductPriceBreakdown = ({ setting = {}, styles = {}, style, b
69
67
  }
70
68
  data.push({
71
69
  title: setting.totalLabel,
72
- money: isDynamicProduct ? dynamicPrice : totalMoneyFormatted,
70
+ money: totalMoneyFormatted,
73
71
  uniqueId: 'totalLabel'
74
72
  });
75
73
  return data;
76
- };
74
+ }, [
75
+ discount,
76
+ discountMoneyFormatted,
77
+ setting.discountLabel,
78
+ setting.shippingLabel,
79
+ setting.subTotalLabel,
80
+ setting.taxesLabel,
81
+ setting.totalLabel,
82
+ styles.isShowSubTotalLabel,
83
+ styles.isShowDiscountLabel,
84
+ styles.isShowShippingLabel,
85
+ styles.isShowTaxesLabel,
86
+ subTotalMoneyFormatted,
87
+ totalMoneyFormatted
88
+ ]);
77
89
  return /*#__PURE__*/ jsxs(Fragment, {
78
90
  children: [
79
91
  /*#__PURE__*/ jsxs("div", {
@@ -124,9 +136,9 @@ const PostPurchaseProductPriceBreakdown = ({ setting = {}, styles = {}, style, b
124
136
  ...makeStyleResponsive('w', width),
125
137
  gap: itemGap
126
138
  },
127
- children: getMoneyLines().map((item)=>/*#__PURE__*/ jsxs(Fragment$1, {
139
+ children: moneyLines.map((item)=>/*#__PURE__*/ jsxs(Fragment$1, {
128
140
  children: [
129
- item.uniqueId === 'totalLabel' && getMoneyLines().length > 1 && /*#__PURE__*/ jsx("hr", {}),
141
+ item.uniqueId === 'totalLabel' && moneyLines.length > 1 && /*#__PURE__*/ jsx("hr", {}),
130
142
  /*#__PURE__*/ jsx("div", {
131
143
  children: /*#__PURE__*/ jsx(MoneyLine, {
132
144
  uniqueId: item.uniqueId,
@@ -180,14 +180,6 @@ const config = {
180
180
  }
181
181
  }
182
182
  },
183
- {
184
- id: 'dynamicOfferQuantity',
185
- type: 'dynamic-offer-quantity',
186
- min: 1,
187
- max: 4,
188
- default: 2,
189
- isOnlyAcceptInteger: true
190
- },
191
183
  {
192
184
  id: 'discountAndShippingFee',
193
185
  type: 'discount-and-shipping-fee-product-offer',
@@ -381,24 +373,6 @@ const config = {
381
373
  },
382
374
  layout: 'vertical'
383
375
  },
384
- {
385
- type: 'group',
386
- label: {
387
- en: 'Product offers'
388
- },
389
- controls: [
390
- {
391
- type: 'control',
392
- label: {
393
- en: 'Quantity'
394
- },
395
- setting: {
396
- id: 'dynamicOfferQuantity'
397
- }
398
- }
399
- ],
400
- condition: 'false'
401
- },
402
376
  {
403
377
  type: 'control',
404
378
  label: {
@@ -0,0 +1,26 @@
1
+ import { getResponsiveValueByScreen, makeStyleResponsive } from '@gem-sdk/core';
2
+ import { DESCRIPTION_LINE_HEIGHT_DEFAULT } from './const.js';
3
+
4
+ const getMaxHeightStyleDefault = (setting)=>{
5
+ let result = {
6
+ desktop: 'none'
7
+ };
8
+ const devices = [
9
+ 'desktop',
10
+ 'mobile',
11
+ 'tablet'
12
+ ];
13
+ devices.forEach((device)=>{
14
+ const lineClamp = getResponsiveValueByScreen(setting?.lineClamp, device);
15
+ const hasLineClamp = getResponsiveValueByScreen(setting?.hasLineClamp, device);
16
+ const maxHeight = hasLineClamp && lineClamp ? `${lineClamp * DESCRIPTION_LINE_HEIGHT_DEFAULT}px` : 'none';
17
+ result = {
18
+ ...result,
19
+ [device]: maxHeight
20
+ };
21
+ });
22
+ const style = makeStyleResponsive('maxh', result);
23
+ return style;
24
+ };
25
+
26
+ export { getMaxHeightStyleDefault };
@@ -0,0 +1,3 @@
1
+ const DESCRIPTION_LINE_HEIGHT_DEFAULT = 21;
2
+
3
+ export { DESCRIPTION_LINE_HEIGHT_DEFAULT };
@@ -1,6 +1,8 @@
1
1
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
2
2
  import { useProduct, useCurrentDevice, getResponsiveValueByScreen, isSafari, composeTypographyClassName, composeTypographyStyle, cls, getGlobalColorClass, getStyleShadow, makeStyleResponsive, makeStyle, getGlobalColorStyle } from '@gem-sdk/core';
3
3
  import { useState, useRef, useEffect } from 'react';
4
+ import { getMaxHeightStyleDefault } from './ProductDescription/common.js';
5
+ import { DESCRIPTION_LINE_HEIGHT_DEFAULT } from './ProductDescription/const.js';
4
6
 
5
7
  const ProductDescription = ({ setting, builderProps })=>{
6
8
  const [open, setOpen] = useState(false);
@@ -14,14 +16,18 @@ const ProductDescription = ({ setting, builderProps })=>{
14
16
  useEffect(()=>{
15
17
  const dom = ref.current;
16
18
  setOpen(false);
17
- if (dom && hasLineClamp && product?.description) {
19
+ if (!dom) return;
20
+ const enableShowMore = hasLineClamp && product?.descriptionHtml;
21
+ if (!enableShowMore) dom.style.maxHeight = 'none';
22
+ else {
18
23
  const value = lineClamp;
19
24
  setTimeout(()=>{
20
25
  const scrollHeight = dom?.scrollHeight ?? 0;
21
26
  const clientHeight = dom?.clientHeight ?? 0;
22
- const lineHeight = window.getComputedStyle(dom).getPropertyValue('line-height');
23
- const lineText = Math.round((scrollHeight ?? 0) / parseInt(lineHeight));
24
- const conditionCheckLine = isSafari() ? value && value < lineText : clientHeight < scrollHeight;
27
+ const lineHeight = getLineHeightFromDom();
28
+ const lineText = Math.round((scrollHeight ?? 0) / lineHeight);
29
+ dom.style.maxHeight = getMaxHeight(lineHeight);
30
+ const conditionCheckLine = value && value < lineText || clientHeight < scrollHeight;
25
31
  if (value && conditionCheckLine) {
26
32
  allowShowViewMore(()=>true);
27
33
  } else {
@@ -32,8 +38,19 @@ const ProductDescription = ({ setting, builderProps })=>{
32
38
  }, [
33
39
  hasLineClamp,
34
40
  lineClamp,
35
- product?.description
41
+ product?.description,
42
+ isSafari
36
43
  ]);
44
+ const getLineHeightFromDom = ()=>{
45
+ if (!ref.current) return DESCRIPTION_LINE_HEIGHT_DEFAULT;
46
+ const lineHeight = window.getComputedStyle(ref.current).getPropertyValue('line-height');
47
+ return parseInt(lineHeight);
48
+ };
49
+ const getMaxHeight = (lineHeight)=>{
50
+ if (!hasLineClamp || !lineClamp) return 'auto';
51
+ if (lineHeight) return `${lineClamp * lineHeight}px`;
52
+ return 'auto';
53
+ };
37
54
  const Tag = htmlTag === 'html' ? 'div' : 'p';
38
55
  const appendTypoClass = composeTypographyClassName(setting?.typo, setting?.typography);
39
56
  const appendTypoStyle = composeTypographyStyle(setting?.typo, setting?.typography);
@@ -50,7 +67,17 @@ const ProductDescription = ({ setting, builderProps })=>{
50
67
  }
51
68
  `;
52
69
  const DescriptionNotFoundString = 'This product does not have a description';
53
- const hasDescription = product?.description && product.description?.trim() != '';
70
+ const noDescriptionHtml = !product?.descriptionHtml;
71
+ const handleToggleShowMore = ()=>{
72
+ if (!ref.current) return;
73
+ const lineHeight = getLineHeightFromDom();
74
+ if (open) {
75
+ ref.current.style.maxHeight = getMaxHeight(lineHeight);
76
+ } else {
77
+ ref.current.style.maxHeight = 'none';
78
+ }
79
+ setOpen((prev)=>!prev);
80
+ };
54
81
  return /*#__PURE__*/ jsx(Fragment, {
55
82
  children: !product ? null : /*#__PURE__*/ jsxs("div", {
56
83
  "data-id": builderProps?.uid,
@@ -61,7 +88,7 @@ const ProductDescription = ({ setting, builderProps })=>{
61
88
  /*#__PURE__*/ jsx(Tag, {
62
89
  ref: ref,
63
90
  "data-gp-text": true,
64
- className: cls('gp-p-description-text gp-break-words safari:[&_p]:gp-inline safari:[&_p]:after:gp-whitespace-pre', appendTypoClass, !hasDescription ? 'gp-p-2 gp-text-center gp-text-sm gp-font-semibold gp-text-gray-500 gp-py-2 !gp-text-center' : '', getGlobalColorClass('text', setting?.color)),
91
+ className: cls('gp-p-description-text gp-break-words safari:[&_p]:gp-inline safari:[&_p]:after:gp-whitespace-pre', appendTypoClass, noDescriptionHtml ? 'gp-p-2 gp-text-center gp-text-sm gp-font-semibold gp-text-gray-500 gp-py-2 !gp-text-center' : '', getGlobalColorClass('text', setting?.color)),
65
92
  style: {
66
93
  ...getStyleShadow({
67
94
  value: setting?.textShadow,
@@ -73,10 +100,11 @@ const ProductDescription = ({ setting, builderProps })=>{
73
100
  ...makeStyle({
74
101
  tt: setting?.transform
75
102
  }),
76
- ...appendTypoStyle
103
+ ...appendTypoStyle,
104
+ ...getMaxHeightStyleDefault(setting)
77
105
  },
78
106
  dangerouslySetInnerHTML: {
79
- __html: product?.descriptionHtml && hasDescription ? product.descriptionHtml : `${DescriptionNotFoundString}`
107
+ __html: product?.descriptionHtml || `${DescriptionNotFoundString}`
80
108
  }
81
109
  }),
82
110
  hasLineClamp && isShowViewMore && /*#__PURE__*/ jsxs("button", {
@@ -89,7 +117,7 @@ const ProductDescription = ({ setting, builderProps })=>{
89
117
  ...appendTypoStyle,
90
118
  ...getGlobalColorStyle(setting?.showMoreColor)
91
119
  },
92
- onClick: ()=>setOpen((prev)=>!prev),
120
+ onClick: handleToggleShowMore,
93
121
  children: [
94
122
  !open ? setting?.viewMoreText : setting?.viewLessText,
95
123
  setting?.enableViewMoreIcon && /*#__PURE__*/ jsx("svg", {
@@ -1,5 +1,6 @@
1
1
  import { composeTypographyClassName, composeTypographyStyle, getStyleShadow, makeStyleResponsive, getGlobalColorStyle, makeStyle, makeLineClamp, template, cls, getGlobalColorClass, RenderIf, isLocalEnv, baseAssetURL } from '@gem-sdk/core';
2
2
  import { getSettingPreloadData } from '../../helpers.js';
3
+ import { getMaxHeightStyleDefault } from './ProductDescription/common.js';
3
4
 
4
5
  const devices = [
5
6
  'desktop',
@@ -31,7 +32,8 @@ const ProductDescription = ({ setting, advanced, builderProps })=>{
31
32
  ...makeStyle({
32
33
  tt: setting?.transform
33
34
  }),
34
- ...appendTypoStyle
35
+ ...appendTypoStyle,
36
+ ...getMaxHeightStyleDefault(setting)
35
37
  };
36
38
  const collapseStyle = {
37
39
  ...defaultStyle,
@@ -4458,7 +4458,6 @@ type ProductOfferSettings = Omit<ProductSetting, 'productSetting'> & {
4458
4458
  productIds?: string[];
4459
4459
  };
4460
4460
  productOfferLayout: ObjectDevices<'1col' | '2col'>;
4461
- dynamicOfferQuantity?: number;
4462
4461
  discountAndShippingFee?: boolean;
4463
4462
  };
4464
4463
  type ProductOfferStyles = RowProps$1['styles'] & {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gem-sdk/components",
3
- "version": "2.1.14",
3
+ "version": "2.1.16",
4
4
  "license": "MIT",
5
5
  "sideEffects": false,
6
6
  "main": "dist/cjs/index.js",
@@ -21,7 +21,7 @@
21
21
  "format": "prettier --write \"./src/**/*.{ts,tsx}\""
22
22
  },
23
23
  "devDependencies": {
24
- "@gem-sdk/core": "2.1.13",
24
+ "@gem-sdk/core": "2.1.15",
25
25
  "@gem-sdk/styles": "2.1.0",
26
26
  "@types/react-transition-group": "^4.4.5"
27
27
  },
@@ -1,127 +0,0 @@
1
- 'use strict';
2
-
3
- const productOfferPlaceholder = {
4
- id: '',
5
- title: 'Dynamic product',
6
- description: 'This is a dynamic product. The actual product will appear here based on your setup',
7
- descriptionHtml: '<p class="QN2lPu">This is a dynamic product. The actual product will</p>\n<p class="QN2lPu">appear here based on your setup</p>',
8
- createdAt: '2024-07-01T04:19:51.286753Z',
9
- handle: 'dynamic-product',
10
- averageRating: 0,
11
- isStorefront: true,
12
- isSample: false,
13
- baseID: '',
14
- sku: '',
15
- options: [
16
- {
17
- id: '1',
18
- name: 'Variant',
19
- optionType: '',
20
- values: [
21
- {
22
- id: '1',
23
- label: 'Variant option',
24
- isDefault: true,
25
- baseID: '1'
26
- }
27
- ]
28
- }
29
- ],
30
- vendor: '',
31
- featuredImage: {
32
- id: '542178560626918105',
33
- contentType: 'IMAGE',
34
- previewImage: '',
35
- src: 'https://cdn.shopify.com/s/files/1/0858/3168/0279/files/gempages_502328832959710176-312cf60c-d923-4913-9873-66545effe9cc.png',
36
- width: 449,
37
- height: 449,
38
- alt: ''
39
- },
40
- collections: {
41
- edges: [
42
- {
43
- node: {
44
- id: '502321959132988135',
45
- title: 'Home page'
46
- }
47
- },
48
- {
49
- node: {
50
- id: '539286505089204764',
51
- title: 'b'
52
- }
53
- },
54
- {
55
- node: {
56
- id: '539286505089401372',
57
- title: 'e'
58
- }
59
- }
60
- ]
61
- },
62
- tags: [],
63
- medias: {
64
- edges: [
65
- {
66
- cursor: 'gqFpzweGNIc/AALZoXYB',
67
- node: {
68
- id: '542178560626918105',
69
- contentType: 'IMAGE',
70
- previewImage: '',
71
- src: 'https://cdn.shopify.com/s/files/1/0858/3168/0279/files/gempages_502328832959710176-312cf60c-d923-4913-9873-66545effe9cc.png',
72
- width: 449,
73
- height: 449,
74
- alt: ''
75
- }
76
- }
77
- ],
78
- pageInfo: {
79
- endCursor: 'gqFpzweGNIc/AALZoXYB',
80
- hasNextPage: true
81
- }
82
- },
83
- variants: {
84
- edges: [
85
- {
86
- cursor: 'gqFpzwc5ZqRtDAMIoXYC',
87
- node: {
88
- id: '520560088328176392',
89
- title: 'Default Title',
90
- barcode: '',
91
- baseID: 'gid://shopify/ProductVariant/49298248925463',
92
- costPrice: 88,
93
- height: 0,
94
- inventoryPolicy: 'DENY',
95
- inventoryQuantity: 211,
96
- inventoryStatus: '',
97
- isDigital: true,
98
- length: 0,
99
- lowInventoryAmount: 0,
100
- manageInventory: false,
101
- mediaId: '0',
102
- platform: 'SHOPIFY',
103
- price: 88,
104
- salePrice: 88,
105
- sku: '',
106
- soldIndividually: false,
107
- weight: 0,
108
- width: 0,
109
- selectedOptions: [
110
- {
111
- name: 'Variant',
112
- value: 'Variant option',
113
- optionType: ''
114
- }
115
- ],
116
- media: undefined
117
- }
118
- }
119
- ],
120
- pageInfo: {
121
- hasNextPage: false,
122
- endCursor: 'gaFpzwc5ZqRtDAMI'
123
- }
124
- }
125
- };
126
-
127
- exports.productOfferPlaceholder = productOfferPlaceholder;
@@ -1,28 +0,0 @@
1
- 'use strict';
2
-
3
- var core = require('@gem-sdk/core');
4
- var React = require('react');
5
-
6
- const useDynamicProduct = ()=>{
7
- const dynamicDiscountOffer = core.usePageStore((s)=>s.dynamicDiscountOffer);
8
- const isDynamicProduct = React.useMemo(()=>{
9
- return !!dynamicDiscountOffer;
10
- }, [
11
- dynamicDiscountOffer
12
- ]);
13
- // false = No discount
14
- const isEnableDynamicDiscount = React.useMemo(()=>{
15
- return dynamicDiscountOffer?.isEnabled;
16
- }, [
17
- dynamicDiscountOffer
18
- ]);
19
- const dynamicPrice = '$???';
20
- return {
21
- isDynamicProduct,
22
- dynamicPrice,
23
- dynamicDiscount: dynamicDiscountOffer,
24
- isEnableDynamicDiscount
25
- };
26
- };
27
-
28
- exports.useDynamicProduct = useDynamicProduct;
@@ -1,125 +0,0 @@
1
- const productOfferPlaceholder = {
2
- id: '',
3
- title: 'Dynamic product',
4
- description: 'This is a dynamic product. The actual product will appear here based on your setup',
5
- descriptionHtml: '<p class="QN2lPu">This is a dynamic product. The actual product will</p>\n<p class="QN2lPu">appear here based on your setup</p>',
6
- createdAt: '2024-07-01T04:19:51.286753Z',
7
- handle: 'dynamic-product',
8
- averageRating: 0,
9
- isStorefront: true,
10
- isSample: false,
11
- baseID: '',
12
- sku: '',
13
- options: [
14
- {
15
- id: '1',
16
- name: 'Variant',
17
- optionType: '',
18
- values: [
19
- {
20
- id: '1',
21
- label: 'Variant option',
22
- isDefault: true,
23
- baseID: '1'
24
- }
25
- ]
26
- }
27
- ],
28
- vendor: '',
29
- featuredImage: {
30
- id: '542178560626918105',
31
- contentType: 'IMAGE',
32
- previewImage: '',
33
- src: 'https://cdn.shopify.com/s/files/1/0858/3168/0279/files/gempages_502328832959710176-312cf60c-d923-4913-9873-66545effe9cc.png',
34
- width: 449,
35
- height: 449,
36
- alt: ''
37
- },
38
- collections: {
39
- edges: [
40
- {
41
- node: {
42
- id: '502321959132988135',
43
- title: 'Home page'
44
- }
45
- },
46
- {
47
- node: {
48
- id: '539286505089204764',
49
- title: 'b'
50
- }
51
- },
52
- {
53
- node: {
54
- id: '539286505089401372',
55
- title: 'e'
56
- }
57
- }
58
- ]
59
- },
60
- tags: [],
61
- medias: {
62
- edges: [
63
- {
64
- cursor: 'gqFpzweGNIc/AALZoXYB',
65
- node: {
66
- id: '542178560626918105',
67
- contentType: 'IMAGE',
68
- previewImage: '',
69
- src: 'https://cdn.shopify.com/s/files/1/0858/3168/0279/files/gempages_502328832959710176-312cf60c-d923-4913-9873-66545effe9cc.png',
70
- width: 449,
71
- height: 449,
72
- alt: ''
73
- }
74
- }
75
- ],
76
- pageInfo: {
77
- endCursor: 'gqFpzweGNIc/AALZoXYB',
78
- hasNextPage: true
79
- }
80
- },
81
- variants: {
82
- edges: [
83
- {
84
- cursor: 'gqFpzwc5ZqRtDAMIoXYC',
85
- node: {
86
- id: '520560088328176392',
87
- title: 'Default Title',
88
- barcode: '',
89
- baseID: 'gid://shopify/ProductVariant/49298248925463',
90
- costPrice: 88,
91
- height: 0,
92
- inventoryPolicy: 'DENY',
93
- inventoryQuantity: 211,
94
- inventoryStatus: '',
95
- isDigital: true,
96
- length: 0,
97
- lowInventoryAmount: 0,
98
- manageInventory: false,
99
- mediaId: '0',
100
- platform: 'SHOPIFY',
101
- price: 88,
102
- salePrice: 88,
103
- sku: '',
104
- soldIndividually: false,
105
- weight: 0,
106
- width: 0,
107
- selectedOptions: [
108
- {
109
- name: 'Variant',
110
- value: 'Variant option',
111
- optionType: ''
112
- }
113
- ],
114
- media: undefined
115
- }
116
- }
117
- ],
118
- pageInfo: {
119
- hasNextPage: false,
120
- endCursor: 'gaFpzwc5ZqRtDAMI'
121
- }
122
- }
123
- };
124
-
125
- export { productOfferPlaceholder };
@@ -1,26 +0,0 @@
1
- import { usePageStore } from '@gem-sdk/core';
2
- import { useMemo } from 'react';
3
-
4
- const useDynamicProduct = ()=>{
5
- const dynamicDiscountOffer = usePageStore((s)=>s.dynamicDiscountOffer);
6
- const isDynamicProduct = useMemo(()=>{
7
- return !!dynamicDiscountOffer;
8
- }, [
9
- dynamicDiscountOffer
10
- ]);
11
- // false = No discount
12
- const isEnableDynamicDiscount = useMemo(()=>{
13
- return dynamicDiscountOffer?.isEnabled;
14
- }, [
15
- dynamicDiscountOffer
16
- ]);
17
- const dynamicPrice = '$???';
18
- return {
19
- isDynamicProduct,
20
- dynamicPrice,
21
- dynamicDiscount: dynamicDiscountOffer,
22
- isEnableDynamicDiscount
23
- };
24
- };
25
-
26
- export { useDynamicProduct };