@gem-sdk/core 1.12.0-next.10 → 1.12.0-next.12

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.
@@ -16,20 +16,35 @@ const componentTexts = [
16
16
  'Text',
17
17
  'Heading'
18
18
  ];
19
- const Render = ({ uid , builder , components , parentId , ...passProps })=>{
19
+ const Render = ({ uid , builder , components , parentId , extraFiles ={} , ...passProps })=>{
20
20
  const item = builder[uid];
21
21
  const Component = components[item?.tag];
22
22
  if (!Component) {
23
23
  console.log('Miss component: ', item);
24
- return '';
24
+ return {
25
+ liquid: '',
26
+ extraFiles
27
+ };
28
+ }
29
+ if (!item) {
30
+ return {
31
+ liquid: '',
32
+ extraFiles
33
+ };
25
34
  }
26
- if (!item) return null;
27
35
  if (item?.type === 'section') {
28
- return '';
36
+ return {
37
+ liquid: '',
38
+ extraFiles
39
+ };
29
40
  } else {
41
+ const customProps = {
42
+ extraFiles: {}
43
+ };
30
44
  const style = composeAdvanceStyle.composeAdvanceStyle(item.advanced, item.tag);
45
+ let liquid = '';
31
46
  if (constant.disableWrap.includes(item.tag)) {
32
- return render.RenderIf(item?.childrens?.length, ()=>{
47
+ liquid = render.RenderIf(item?.childrens?.length, ()=>{
33
48
  return Component({
34
49
  builderProps: {
35
50
  uid,
@@ -46,17 +61,19 @@ const Render = ({ uid , builder , components , parentId , ...passProps })=>{
46
61
  ...builder[id],
47
62
  uid: id,
48
63
  builder,
49
- components
64
+ components,
65
+ customProps
50
66
  };
51
67
  }),
52
- children: item.childrens.map((id)=>Render({
68
+ children: item.childrens.map((id)=>RenderChildren({
53
69
  uid: id,
54
70
  builder,
55
71
  components,
56
- parentId: uid
72
+ customProps
57
73
  })).join('')
58
74
  });
59
- }, ()=>Component({
75
+ }, ()=>{
76
+ return Component({
60
77
  builderProps: {
61
78
  uid,
62
79
  builderData: item
@@ -68,10 +85,12 @@ const Render = ({ uid , builder , components , parentId , ...passProps })=>{
68
85
  isText: componentTexts.includes(item.tag) ? true : null,
69
86
  parentId: componentsRenderWithParentId.includes(item.tag) ? parentId : null,
70
87
  ...passProps
71
- }));
88
+ });
89
+ });
72
90
  }
73
- return render.template`<div style="${style}" class="${item.uid}">
74
- ${render.RenderIf(item?.childrens?.length, ()=>Component({
91
+ liquid = render.template`<div style="${style}" class="${item.uid}">
92
+ ${render.RenderIf(item?.childrens?.length, ()=>{
93
+ return Component({
75
94
  builderProps: {
76
95
  uid,
77
96
  builderData: item
@@ -84,15 +103,19 @@ const Render = ({ uid , builder , components , parentId , ...passProps })=>{
84
103
  ...builder[id],
85
104
  uid: id,
86
105
  builder,
87
- components
106
+ components,
107
+ customProps
88
108
  };
89
109
  }),
90
- children: item.childrens.map((id)=>Render({
110
+ children: item.childrens.map((id)=>RenderChildren({
91
111
  uid: id,
92
112
  builder,
93
- components
113
+ components,
114
+ customProps
94
115
  })).join('')
95
- }), ()=>Component({
116
+ });
117
+ }, ()=>{
118
+ return Component({
96
119
  builderProps: {
97
120
  uid,
98
121
  builderData: item
@@ -101,9 +124,34 @@ const Render = ({ uid , builder , components , parentId , ...passProps })=>{
101
124
  setting: item.settings,
102
125
  isText: componentTexts.includes(item.tag) ? true : null,
103
126
  ...passProps
104
- }))}
127
+ });
128
+ })}
105
129
  </div>`;
130
+ return {
131
+ liquid,
132
+ extraFiles: customProps.extraFiles
133
+ };
134
+ }
135
+ };
136
+ const RenderChildren = (props)=>{
137
+ const data = Render(props);
138
+ // Append to prop parent
139
+ for(const key in data.extraFiles){
140
+ if (Object.prototype.hasOwnProperty.call(data.extraFiles, key)) {
141
+ const value = data.extraFiles[key];
142
+ props.customProps.extraFiles[key] = value;
143
+ }
144
+ }
145
+ // Fix limit 256kb
146
+ const textEncoder = new TextEncoder();
147
+ const size = data?.liquid ? textEncoder.encode(data.liquid).length : 0;
148
+ if (Math.ceil(size / 1024) >= 180) {
149
+ const fileName = `gp-section-snippet-${props.uid}`;
150
+ props.customProps.extraFiles[fileName] = data.liquid;
151
+ return `{% render '${fileName}', product: product, variant: variant, product_form_id: product_form_id %}`;
106
152
  }
153
+ return data.liquid;
107
154
  };
108
155
 
156
+ exports.RenderChildren = RenderChildren;
109
157
  exports.default = Render;
@@ -39,6 +39,9 @@ const styles = (strings, ...keys)=>{
39
39
  }
40
40
  return styleArr.join(';');
41
41
  };
42
+ const dataStringify = (obj)=>{
43
+ return JSON.stringify(obj).replace(/\\"/g, '"');
44
+ };
42
45
  const template = (strings, ...keys)=>{
43
46
  let str = '';
44
47
  strings.forEach((item, index)=>{
@@ -59,6 +62,7 @@ const template = (strings, ...keys)=>{
59
62
  };
60
63
 
61
64
  exports.RenderIf = RenderIf;
65
+ exports.dataStringify = dataStringify;
62
66
  exports.props = props;
63
67
  exports.styles = styles;
64
68
  exports.template = template;
@@ -26,6 +26,17 @@ const useCurrency = ()=>{
26
26
  changeCurrency
27
27
  ]);
28
28
  };
29
+ const useMoneyFormat = ()=>{
30
+ const moneyFormat = ShopContext.useShopStore((state)=>state.moneyFormat);
31
+ const moneyWithCurrencyFormat = ShopContext.useShopStore((state)=>state.moneyWithCurrencyFormat);
32
+ return react.useMemo(()=>({
33
+ moneyFormat,
34
+ moneyWithCurrencyFormat
35
+ }), [
36
+ moneyFormat,
37
+ moneyWithCurrencyFormat
38
+ ]);
39
+ };
29
40
  const useSwatches = ()=>{
30
41
  const swatches = ShopContext.useShopStore((state)=>state.swatches);
31
42
  const changeSwatches = ShopContext.useShopStore((state)=>state.changeSwatches);
@@ -108,6 +119,7 @@ exports.useIsStorefrontProduct = useIsStorefrontProduct;
108
119
  exports.useLocale = useLocale;
109
120
  exports.useMatchMutate = useMatchMutate;
110
121
  exports.useMobileOnly = useMobileOnly;
122
+ exports.useMoneyFormat = useMoneyFormat;
111
123
  exports.usePageType = usePageType;
112
124
  exports.usePluginEnable = usePluginEnable;
113
125
  exports.useStoreFront = useStoreFront;
@@ -1,21 +1,61 @@
1
1
  'use strict';
2
2
 
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var react = require('react');
6
3
  var shop = require('./shop.js');
7
4
 
8
- const useFormatMoney = ()=>{
9
- const { locale } = shop.useLocale();
10
- const formatMoney = react.useCallback((value, options)=>new Intl.NumberFormat(locale, {
11
- style: 'currency',
12
- ...options
13
- }).format(value), [
14
- locale
15
- ]);
16
- return {
17
- formatMoney
5
+ const useFormatMoney = (amount, withCurrency)=>{
6
+ const { moneyFormat , moneyWithCurrencyFormat } = shop.useMoneyFormat();
7
+ const formatMoney = function(cents, format) {
8
+ let value = '';
9
+ const placeholderRegex = /\{\{\s*(\w+)\s*\}\}/;
10
+ const formatString = format || '${{amount}}';
11
+ if (typeof cents == 'string') {
12
+ cents = cents.replace('.', '');
13
+ }
14
+ /**
15
+ * check default
16
+ * @param opt opt
17
+ * @param def def
18
+ * @returns any
19
+ */ function defaultOption(opt, def) {
20
+ return typeof opt == 'undefined' ? def : opt;
21
+ }
22
+ /**
23
+ * formatWithDelimiters
24
+ * @param number number
25
+ * @param precision precision
26
+ * @param thousands thousands
27
+ * @param decimal decimal
28
+ * @returns any
29
+ */ // eslint-disable-next-line max-params
30
+ function formatWithDelimiters(number, precision, thousands, decimal) {
31
+ precision = defaultOption(precision, 2);
32
+ thousands = defaultOption(thousands, ',');
33
+ decimal = defaultOption(decimal, '.');
34
+ if (isNaN(number) || number == null) {
35
+ return 0;
36
+ }
37
+ // shopify làm tròn bằng cách cắt đi các số ở đằng sau chứ không sử dụng toFixed để làm tròn như toán học
38
+ number = (number / 100.0).toFixed(Number(precision) + 1).slice(0, -1);
39
+ const parts = number.split('.'), dollars = parts[0]?.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + thousands), cents = parts[1] ? decimal + parts[1] : '';
40
+ return dollars + cents;
41
+ }
42
+ switch(formatString.match(placeholderRegex)[1]){
43
+ case 'amount':
44
+ value = formatWithDelimiters(cents, 2);
45
+ break;
46
+ case 'amount_no_decimals':
47
+ value = formatWithDelimiters(cents, 0);
48
+ break;
49
+ case 'amount_with_comma_separator':
50
+ value = formatWithDelimiters(cents, 2, '.', ',');
51
+ break;
52
+ case 'amount_no_decimals_with_comma_separator':
53
+ value = formatWithDelimiters(cents, 0, '.', ',');
54
+ break;
55
+ }
56
+ return formatString.replace(placeholderRegex, value);
18
57
  };
58
+ return withCurrency ? formatMoney(`${amount}`, moneyWithCurrencyFormat || moneyFormat) : formatMoney(`${amount}`, moneyFormat);
19
59
  };
20
60
 
21
- exports.default = useFormatMoney;
61
+ exports.useFormatMoney = useFormatMoney;
@@ -5,182 +5,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var react = require('react');
6
6
  var shop = require('./shop.js');
7
7
 
8
- const NARROW_SYMBOL_MAP = {
9
- AED: 'د.إ',
10
- AFN: '؋',
11
- ALL: 'L',
12
- AMD: 'դր.',
13
- ANG: 'ƒ',
14
- AOA: 'Kz',
15
- ARS: '$',
16
- AUD: '$',
17
- AWG: 'ƒ',
18
- AZN: '₼',
19
- BAM: 'КМ',
20
- BBD: '$',
21
- BDT: '৳',
22
- BGN: 'лв.',
23
- BHD: 'ب.د',
24
- BIF: 'Fr',
25
- BMD: '$',
26
- BND: '$',
27
- BOB: 'Bs.',
28
- BRL: 'R$',
29
- BSD: '$',
30
- BTN: 'Nu.',
31
- BWP: 'P',
32
- BYN: 'Br',
33
- BYR: 'Br',
34
- BZD: '$',
35
- CAD: '$',
36
- CDF: 'Fr',
37
- CHF: 'CHF',
38
- CLF: 'UF',
39
- CLP: '$',
40
- CNY: '¥',
41
- COP: '$',
42
- CRC: '₡',
43
- CUC: '$',
44
- CUP: '$',
45
- CVE: '$',
46
- CZK: 'Kč',
47
- DJF: 'Fdj',
48
- DKK: 'kr.',
49
- DOP: '$',
50
- DZD: 'د.ج',
51
- EGP: 'ج.م',
52
- ERN: 'Nfk',
53
- ETB: 'Br',
54
- EUR: '€',
55
- FJD: '$',
56
- FKP: '£',
57
- GBP: '£',
58
- GEL: 'ლ',
59
- GHS: '₵',
60
- GIP: '£',
61
- GMD: 'D',
62
- GNF: 'Fr',
63
- GTQ: 'Q',
64
- GYD: '$',
65
- HKD: '$',
66
- HNL: 'L',
67
- HRK: 'kn',
68
- HTG: 'G',
69
- HUF: 'Ft',
70
- IDR: 'Rp',
71
- ILS: '₪',
72
- INR: '₹',
73
- IQD: 'ع.د',
74
- IRR: '﷼',
75
- ISK: 'kr',
76
- JMD: '$',
77
- JOD: 'د.ا',
78
- JPY: '¥',
79
- KES: 'KSh',
80
- KGS: 'som',
81
- KHR: '៛',
82
- KMF: 'Fr',
83
- KPW: '₩',
84
- KRW: '₩',
85
- KWD: 'د.ك',
86
- KYD: '$',
87
- KZT: '〒',
88
- LAK: '₭',
89
- LBP: 'ل.ل',
90
- LKR: '₨',
91
- LRD: '$',
92
- LSL: 'L',
93
- LTL: 'Lt',
94
- LVL: 'Ls',
95
- LYD: 'ل.د',
96
- MAD: 'د.م.',
97
- MDL: 'L',
98
- MGA: 'Ar',
99
- MKD: 'ден',
100
- MMK: 'K',
101
- MNT: '₮',
102
- MOP: 'P',
103
- MRU: 'UM',
104
- MUR: '₨',
105
- MVR: 'MVR',
106
- MWK: 'MK',
107
- MXN: '$',
108
- MYR: 'RM',
109
- MZN: 'MTn',
110
- NAD: '$',
111
- NGN: '₦',
112
- NIO: 'C$',
113
- NOK: 'kr',
114
- NPR: '₨',
115
- NZD: '$',
116
- OMR: 'ر.ع.',
117
- PAB: 'B/.',
118
- PEN: 'S/.',
119
- PGK: 'K',
120
- PHP: '₱',
121
- PKR: '₨',
122
- PLN: 'zł',
123
- PYG: '₲',
124
- QAR: 'ر.ق',
125
- RON: 'Lei',
126
- RSD: 'РСД',
127
- RUB: '₽',
128
- RWF: 'FRw',
129
- SAR: 'ر.س',
130
- SBD: '$',
131
- SCR: '₨',
132
- SDG: '£',
133
- SEK: 'kr',
134
- SGD: '$',
135
- SHP: '£',
136
- SKK: 'Sk',
137
- SLL: 'Le',
138
- SOS: 'Sh',
139
- SRD: '$',
140
- SSP: '£',
141
- STN: 'Db',
142
- SVC: '₡',
143
- SYP: '£S',
144
- SZL: 'E',
145
- THB: '฿',
146
- TJS: 'ЅМ',
147
- TMT: 'T',
148
- TND: 'د.ت',
149
- TOP: 'T$',
150
- TRY: '₺',
151
- TTD: '$',
152
- TWD: '$',
153
- TZS: 'Sh',
154
- UAH: '₴',
155
- UGX: 'USh',
156
- USD: '$',
157
- UYU: '$',
158
- UZS: '',
159
- VED: 'Bs.D.',
160
- VES: 'Bs.S.',
161
- VND: '₫',
162
- VUV: 'Vt',
163
- WST: 'T',
164
- XAF: 'Fr',
165
- XAG: 'oz t',
166
- XAU: 'oz t',
167
- XBA: '',
168
- XBB: '',
169
- XBC: '',
170
- XBD: '',
171
- XCD: '$',
172
- XDR: 'SDR',
173
- XOF: 'Fr',
174
- XPD: 'oz t',
175
- XPF: 'Fr',
176
- XPT: 'oz t',
177
- xts: '',
178
- YER: '﷼',
179
- ZAR: 'R',
180
- ZMK: 'ZK',
181
- ZMW: 'ZK'
182
- };
183
- const useMoney = (money)=>{
8
+ const useMoney = (amount)=>{
184
9
  const { locale } = shop.useLocale();
185
10
  const { currency } = shop.useCurrency();
186
11
  const options = react.useMemo(()=>({
@@ -189,43 +14,71 @@ const useMoney = (money)=>{
189
14
  }), [
190
15
  currency
191
16
  ]);
192
- const value = react.useMemo(()=>new Intl.NumberFormat(locale, options).format(money), [
193
- locale,
194
- options,
195
- money
196
- ]);
197
- const baseParts = new Intl.NumberFormat(locale, options).formatToParts(money);
198
- const nameParts = new Intl.NumberFormat(locale, {
17
+ const defaultFormatter = useLazyFormatter(locale, options);
18
+ const nameFormatter = useLazyFormatter(locale, {
199
19
  ...options,
200
20
  currencyDisplay: 'name'
201
- }).formatToParts(money);
202
- const narrowParts = new Intl.NumberFormat(locale, {
21
+ });
22
+ const narrowSymbolFormatter = useLazyFormatter(locale, {
203
23
  ...options,
204
24
  currencyDisplay: 'narrowSymbol'
205
- }).formatToParts(money);
206
- const moneyValue = react.useMemo(()=>({
207
- currencyCode: currency,
208
- currencyName: nameParts.find((part)=>part.type === 'currency')?.value ?? // e.g. "US dollars"
209
- currency,
210
- currencyNarrowSymbol: narrowParts.find((part)=>part.type === 'currency')?.value ?? // e.g. "$"
211
- (currency ? NARROW_SYMBOL_MAP[currency] : '') ?? '',
212
- parts: baseParts,
213
- localizedString: value,
214
- amount: baseParts.filter((part)=>[
215
- 'decimal',
216
- 'fraction',
217
- 'group',
218
- 'integer',
219
- 'literal'
220
- ].includes(part.type)).map((part)=>part.value).join('')
25
+ });
26
+ const withoutTrailingZerosFormatter = useLazyFormatter(locale, {
27
+ ...options,
28
+ minimumFractionDigits: 0,
29
+ maximumFractionDigits: 0
30
+ });
31
+ const withoutCurrencyFormatter = useLazyFormatter(locale);
32
+ const withoutTrailingZerosOrCurrencyFormatter = useLazyFormatter(locale, {
33
+ minimumFractionDigits: 0,
34
+ maximumFractionDigits: 0
35
+ });
36
+ const isPartCurrency = (part)=>part.type === 'currency';
37
+ // By wrapping these properties in functions, we only
38
+ // create formatters if they are going to be used.
39
+ const lazyFormatters = react.useMemo(()=>({
40
+ currencyCode: ()=>currency,
41
+ localizedString: ()=>defaultFormatter().format(amount),
42
+ parts: ()=>defaultFormatter().formatToParts(amount),
43
+ withoutTrailingZeros: ()=>amount % 1 === 0 ? withoutTrailingZerosFormatter().format(amount) : defaultFormatter().format(amount),
44
+ withoutTrailingZerosAndCurrency: ()=>amount % 1 === 0 ? withoutTrailingZerosOrCurrencyFormatter().format(amount) : withoutCurrencyFormatter().format(amount),
45
+ currencyName: ()=>nameFormatter().formatToParts(amount).find(isPartCurrency)?.value ?? currency,
46
+ currencySymbol: ()=>defaultFormatter().formatToParts(amount).find(isPartCurrency)?.value ?? currency,
47
+ currencyNarrowSymbol: ()=>narrowSymbolFormatter().formatToParts(amount).find(isPartCurrency)?.value ?? '',
48
+ amount: ()=>defaultFormatter().formatToParts(amount).filter((part)=>[
49
+ 'decimal',
50
+ 'fraction',
51
+ 'group',
52
+ 'integer',
53
+ 'literal'
54
+ ].includes(part.type)).map((part)=>part.value).join('')
221
55
  }), [
222
- baseParts,
223
- nameParts,
224
- narrowParts,
225
- value,
226
- currency
56
+ currency,
57
+ amount,
58
+ nameFormatter,
59
+ defaultFormatter,
60
+ narrowSymbolFormatter,
61
+ withoutCurrencyFormatter,
62
+ withoutTrailingZerosFormatter,
63
+ withoutTrailingZerosOrCurrencyFormatter
64
+ ]);
65
+ // Call functions automatically when the properties are accessed
66
+ // to keep these functions as an implementation detail.
67
+ return react.useMemo(()=>new Proxy(lazyFormatters, {
68
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
69
+ get: (target, key)=>Reflect.get(target, key)?.call(null)
70
+ }), [
71
+ lazyFormatters
227
72
  ]);
228
- return moneyValue;
229
73
  };
74
+ function useLazyFormatter(locale, options) {
75
+ return react.useMemo(()=>{
76
+ let memoized;
77
+ return ()=>memoized ??= new Intl.NumberFormat(locale, options);
78
+ }, [
79
+ locale,
80
+ options
81
+ ]);
82
+ }
230
83
 
231
84
  exports.default = useMoney;
package/dist/cjs/index.js CHANGED
@@ -67,12 +67,12 @@ var useCollectionsQuery = require('./hooks/shop/use-collections-query.js');
67
67
  var useProductQuery = require('./hooks/shop/use-product-query.js');
68
68
  var useProductsQuery = require('./hooks/shop/use-products-query.js');
69
69
  var useCurrentDevice = require('./hooks/use-current-device.js');
70
+ var useFormatMoney = require('./hooks/useFormatMoney.js');
70
71
  var useLazyVideo = require('./hooks/use-lazy-video.js');
71
72
  var useCartId = require('./hooks/useCartId.js');
72
73
  var useCartLine = require('./hooks/useCartLine.js');
73
74
  var useCartUI = require('./hooks/useCartUI.js');
74
75
  var useCollection = require('./hooks/useCollection.js');
75
- var useFormatMoney = require('./hooks/useFormatMoney.js');
76
76
  var react = require('react');
77
77
  var useIsomorphicLayoutEffect = require('./hooks/useIsomorphicLayoutEffect.js');
78
78
  var useLoadScript = require('./hooks/useLoadScript.js');
@@ -93,6 +93,7 @@ var getProductBySlug = require('./helpers/queries/get-product-by-slug.js');
93
93
  exports.AddOn = AddOn.default;
94
94
  exports.Render = Render.default;
95
95
  exports.RenderPreview = RenderPreview.default;
96
+ exports.RenderChildren = Render_liquid.RenderChildren;
96
97
  exports.RenderLiquid = Render_liquid.default;
97
98
  exports.AddonProvider = AddonContext.AddonProvider;
98
99
  exports.useAddon = AddonContext.useAddon;
@@ -190,6 +191,7 @@ exports.fpixel = fpixel;
190
191
  exports.gtag = gtag;
191
192
  exports.tiktokpixel = tiktokpixel;
192
193
  exports.RenderIf = render.RenderIf;
194
+ exports.dataStringify = render.dataStringify;
193
195
  exports.props = render.props;
194
196
  exports.styles = render.styles;
195
197
  exports.template = render.template;
@@ -225,6 +227,7 @@ exports.useIsStorefrontProduct = shop.useIsStorefrontProduct;
225
227
  exports.useLocale = shop.useLocale;
226
228
  exports.useMatchMutate = shop.useMatchMutate;
227
229
  exports.useMobileOnly = shop.useMobileOnly;
230
+ exports.useMoneyFormat = shop.useMoneyFormat;
228
231
  exports.usePageType = shop.usePageType;
229
232
  exports.usePluginEnable = shop.usePluginEnable;
230
233
  exports.useStoreFront = shop.useStoreFront;
@@ -234,12 +237,12 @@ exports.useCollectionsQuery = useCollectionsQuery.useCollectionsQuery;
234
237
  exports.useProductQuery = useProductQuery.useProductQuery;
235
238
  exports.useProductsQuery = useProductsQuery.useProductsQuery;
236
239
  exports.useCurrentDevice = useCurrentDevice.useCurrentDevice;
240
+ exports.useFormatMoney = useFormatMoney.useFormatMoney;
237
241
  exports.useLazyVideo = useLazyVideo.useLazyVideo;
238
242
  exports.useCartId = useCartId.default;
239
243
  exports.useCartLine = useCartLine.default;
240
244
  exports.useCartUI = useCartUI.default;
241
245
  exports.useCollection = useCollection.useCollection;
242
- exports.useFormatMoney = useFormatMoney.default;
243
246
  Object.defineProperty(exports, 'useId', {
244
247
  enumerable: true,
245
248
  get: function () { return react.useId; }
@@ -12,20 +12,35 @@ const componentTexts = [
12
12
  'Text',
13
13
  'Heading'
14
14
  ];
15
- const Render = ({ uid , builder , components , parentId , ...passProps })=>{
15
+ const Render = ({ uid , builder , components , parentId , extraFiles ={} , ...passProps })=>{
16
16
  const item = builder[uid];
17
17
  const Component = components[item?.tag];
18
18
  if (!Component) {
19
19
  console.log('Miss component: ', item);
20
- return '';
20
+ return {
21
+ liquid: '',
22
+ extraFiles
23
+ };
24
+ }
25
+ if (!item) {
26
+ return {
27
+ liquid: '',
28
+ extraFiles
29
+ };
21
30
  }
22
- if (!item) return null;
23
31
  if (item?.type === 'section') {
24
- return '';
32
+ return {
33
+ liquid: '',
34
+ extraFiles
35
+ };
25
36
  } else {
37
+ const customProps = {
38
+ extraFiles: {}
39
+ };
26
40
  const style = composeAdvanceStyle(item.advanced, item.tag);
41
+ let liquid = '';
27
42
  if (disableWrap.includes(item.tag)) {
28
- return RenderIf(item?.childrens?.length, ()=>{
43
+ liquid = RenderIf(item?.childrens?.length, ()=>{
29
44
  return Component({
30
45
  builderProps: {
31
46
  uid,
@@ -42,17 +57,19 @@ const Render = ({ uid , builder , components , parentId , ...passProps })=>{
42
57
  ...builder[id],
43
58
  uid: id,
44
59
  builder,
45
- components
60
+ components,
61
+ customProps
46
62
  };
47
63
  }),
48
- children: item.childrens.map((id)=>Render({
64
+ children: item.childrens.map((id)=>RenderChildren({
49
65
  uid: id,
50
66
  builder,
51
67
  components,
52
- parentId: uid
68
+ customProps
53
69
  })).join('')
54
70
  });
55
- }, ()=>Component({
71
+ }, ()=>{
72
+ return Component({
56
73
  builderProps: {
57
74
  uid,
58
75
  builderData: item
@@ -64,10 +81,12 @@ const Render = ({ uid , builder , components , parentId , ...passProps })=>{
64
81
  isText: componentTexts.includes(item.tag) ? true : null,
65
82
  parentId: componentsRenderWithParentId.includes(item.tag) ? parentId : null,
66
83
  ...passProps
67
- }));
84
+ });
85
+ });
68
86
  }
69
- return template`<div style="${style}" class="${item.uid}">
70
- ${RenderIf(item?.childrens?.length, ()=>Component({
87
+ liquid = template`<div style="${style}" class="${item.uid}">
88
+ ${RenderIf(item?.childrens?.length, ()=>{
89
+ return Component({
71
90
  builderProps: {
72
91
  uid,
73
92
  builderData: item
@@ -80,15 +99,19 @@ const Render = ({ uid , builder , components , parentId , ...passProps })=>{
80
99
  ...builder[id],
81
100
  uid: id,
82
101
  builder,
83
- components
102
+ components,
103
+ customProps
84
104
  };
85
105
  }),
86
- children: item.childrens.map((id)=>Render({
106
+ children: item.childrens.map((id)=>RenderChildren({
87
107
  uid: id,
88
108
  builder,
89
- components
109
+ components,
110
+ customProps
90
111
  })).join('')
91
- }), ()=>Component({
112
+ });
113
+ }, ()=>{
114
+ return Component({
92
115
  builderProps: {
93
116
  uid,
94
117
  builderData: item
@@ -97,9 +120,33 @@ const Render = ({ uid , builder , components , parentId , ...passProps })=>{
97
120
  setting: item.settings,
98
121
  isText: componentTexts.includes(item.tag) ? true : null,
99
122
  ...passProps
100
- }))}
123
+ });
124
+ })}
101
125
  </div>`;
126
+ return {
127
+ liquid,
128
+ extraFiles: customProps.extraFiles
129
+ };
130
+ }
131
+ };
132
+ const RenderChildren = (props)=>{
133
+ const data = Render(props);
134
+ // Append to prop parent
135
+ for(const key in data.extraFiles){
136
+ if (Object.prototype.hasOwnProperty.call(data.extraFiles, key)) {
137
+ const value = data.extraFiles[key];
138
+ props.customProps.extraFiles[key] = value;
139
+ }
140
+ }
141
+ // Fix limit 256kb
142
+ const textEncoder = new TextEncoder();
143
+ const size = data?.liquid ? textEncoder.encode(data.liquid).length : 0;
144
+ if (Math.ceil(size / 1024) >= 180) {
145
+ const fileName = `gp-section-snippet-${props.uid}`;
146
+ props.customProps.extraFiles[fileName] = data.liquid;
147
+ return `{% render '${fileName}', product: product, variant: variant, product_form_id: product_form_id %}`;
102
148
  }
149
+ return data.liquid;
103
150
  };
104
151
 
105
- export { Render as default };
152
+ export { RenderChildren, Render as default };
@@ -37,6 +37,9 @@ const styles = (strings, ...keys)=>{
37
37
  }
38
38
  return styleArr.join(';');
39
39
  };
40
+ const dataStringify = (obj)=>{
41
+ return JSON.stringify(obj).replace(/\\"/g, '"');
42
+ };
40
43
  const template = (strings, ...keys)=>{
41
44
  let str = '';
42
45
  strings.forEach((item, index)=>{
@@ -56,4 +59,4 @@ const template = (strings, ...keys)=>{
56
59
  return str;
57
60
  };
58
61
 
59
- export { RenderIf, props, styles, template };
62
+ export { RenderIf, dataStringify, props, styles, template };
@@ -24,6 +24,17 @@ const useCurrency = ()=>{
24
24
  changeCurrency
25
25
  ]);
26
26
  };
27
+ const useMoneyFormat = ()=>{
28
+ const moneyFormat = useShopStore((state)=>state.moneyFormat);
29
+ const moneyWithCurrencyFormat = useShopStore((state)=>state.moneyWithCurrencyFormat);
30
+ return useMemo(()=>({
31
+ moneyFormat,
32
+ moneyWithCurrencyFormat
33
+ }), [
34
+ moneyFormat,
35
+ moneyWithCurrencyFormat
36
+ ]);
37
+ };
27
38
  const useSwatches = ()=>{
28
39
  const swatches = useShopStore((state)=>state.swatches);
29
40
  const changeSwatches = useShopStore((state)=>state.changeSwatches);
@@ -97,4 +108,4 @@ function useCheckoutUrl(url) {
97
108
  return storefrontToken ? `${url}?access_token=${storefrontToken}` : url;
98
109
  }
99
110
 
100
- export { useCheckoutUrl, useConnectedShopify, useCurrency, useEditorMode, useIsSampleProduct, useIsStorefrontProduct, useLocale, useMatchMutate, useMobileOnly, usePageType, usePluginEnable, useStoreFront, useSwatches };
111
+ export { useCheckoutUrl, useConnectedShopify, useCurrency, useEditorMode, useIsSampleProduct, useIsStorefrontProduct, useLocale, useMatchMutate, useMobileOnly, useMoneyFormat, usePageType, usePluginEnable, useStoreFront, useSwatches };
@@ -1,17 +1,59 @@
1
- import { useCallback } from 'react';
2
- import { useLocale } from './shop.js';
1
+ import { useMoneyFormat } from './shop.js';
3
2
 
4
- const useFormatMoney = ()=>{
5
- const { locale } = useLocale();
6
- const formatMoney = useCallback((value, options)=>new Intl.NumberFormat(locale, {
7
- style: 'currency',
8
- ...options
9
- }).format(value), [
10
- locale
11
- ]);
12
- return {
13
- formatMoney
3
+ const useFormatMoney = (amount, withCurrency)=>{
4
+ const { moneyFormat , moneyWithCurrencyFormat } = useMoneyFormat();
5
+ const formatMoney = function(cents, format) {
6
+ let value = '';
7
+ const placeholderRegex = /\{\{\s*(\w+)\s*\}\}/;
8
+ const formatString = format || '${{amount}}';
9
+ if (typeof cents == 'string') {
10
+ cents = cents.replace('.', '');
11
+ }
12
+ /**
13
+ * check default
14
+ * @param opt opt
15
+ * @param def def
16
+ * @returns any
17
+ */ function defaultOption(opt, def) {
18
+ return typeof opt == 'undefined' ? def : opt;
19
+ }
20
+ /**
21
+ * formatWithDelimiters
22
+ * @param number number
23
+ * @param precision precision
24
+ * @param thousands thousands
25
+ * @param decimal decimal
26
+ * @returns any
27
+ */ // eslint-disable-next-line max-params
28
+ function formatWithDelimiters(number, precision, thousands, decimal) {
29
+ precision = defaultOption(precision, 2);
30
+ thousands = defaultOption(thousands, ',');
31
+ decimal = defaultOption(decimal, '.');
32
+ if (isNaN(number) || number == null) {
33
+ return 0;
34
+ }
35
+ // shopify làm tròn bằng cách cắt đi các số ở đằng sau chứ không sử dụng toFixed để làm tròn như toán học
36
+ number = (number / 100.0).toFixed(Number(precision) + 1).slice(0, -1);
37
+ const parts = number.split('.'), dollars = parts[0]?.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + thousands), cents = parts[1] ? decimal + parts[1] : '';
38
+ return dollars + cents;
39
+ }
40
+ switch(formatString.match(placeholderRegex)[1]){
41
+ case 'amount':
42
+ value = formatWithDelimiters(cents, 2);
43
+ break;
44
+ case 'amount_no_decimals':
45
+ value = formatWithDelimiters(cents, 0);
46
+ break;
47
+ case 'amount_with_comma_separator':
48
+ value = formatWithDelimiters(cents, 2, '.', ',');
49
+ break;
50
+ case 'amount_no_decimals_with_comma_separator':
51
+ value = formatWithDelimiters(cents, 0, '.', ',');
52
+ break;
53
+ }
54
+ return formatString.replace(placeholderRegex, value);
14
55
  };
56
+ return withCurrency ? formatMoney(`${amount}`, moneyWithCurrencyFormat || moneyFormat) : formatMoney(`${amount}`, moneyFormat);
15
57
  };
16
58
 
17
- export { useFormatMoney as default };
59
+ export { useFormatMoney };
@@ -1,182 +1,7 @@
1
1
  import { useMemo } from 'react';
2
2
  import { useLocale, useCurrency } from './shop.js';
3
3
 
4
- const NARROW_SYMBOL_MAP = {
5
- AED: 'د.إ',
6
- AFN: '؋',
7
- ALL: 'L',
8
- AMD: 'դր.',
9
- ANG: 'ƒ',
10
- AOA: 'Kz',
11
- ARS: '$',
12
- AUD: '$',
13
- AWG: 'ƒ',
14
- AZN: '₼',
15
- BAM: 'КМ',
16
- BBD: '$',
17
- BDT: '৳',
18
- BGN: 'лв.',
19
- BHD: 'ب.د',
20
- BIF: 'Fr',
21
- BMD: '$',
22
- BND: '$',
23
- BOB: 'Bs.',
24
- BRL: 'R$',
25
- BSD: '$',
26
- BTN: 'Nu.',
27
- BWP: 'P',
28
- BYN: 'Br',
29
- BYR: 'Br',
30
- BZD: '$',
31
- CAD: '$',
32
- CDF: 'Fr',
33
- CHF: 'CHF',
34
- CLF: 'UF',
35
- CLP: '$',
36
- CNY: '¥',
37
- COP: '$',
38
- CRC: '₡',
39
- CUC: '$',
40
- CUP: '$',
41
- CVE: '$',
42
- CZK: 'Kč',
43
- DJF: 'Fdj',
44
- DKK: 'kr.',
45
- DOP: '$',
46
- DZD: 'د.ج',
47
- EGP: 'ج.م',
48
- ERN: 'Nfk',
49
- ETB: 'Br',
50
- EUR: '€',
51
- FJD: '$',
52
- FKP: '£',
53
- GBP: '£',
54
- GEL: 'ლ',
55
- GHS: '₵',
56
- GIP: '£',
57
- GMD: 'D',
58
- GNF: 'Fr',
59
- GTQ: 'Q',
60
- GYD: '$',
61
- HKD: '$',
62
- HNL: 'L',
63
- HRK: 'kn',
64
- HTG: 'G',
65
- HUF: 'Ft',
66
- IDR: 'Rp',
67
- ILS: '₪',
68
- INR: '₹',
69
- IQD: 'ع.د',
70
- IRR: '﷼',
71
- ISK: 'kr',
72
- JMD: '$',
73
- JOD: 'د.ا',
74
- JPY: '¥',
75
- KES: 'KSh',
76
- KGS: 'som',
77
- KHR: '៛',
78
- KMF: 'Fr',
79
- KPW: '₩',
80
- KRW: '₩',
81
- KWD: 'د.ك',
82
- KYD: '$',
83
- KZT: '〒',
84
- LAK: '₭',
85
- LBP: 'ل.ل',
86
- LKR: '₨',
87
- LRD: '$',
88
- LSL: 'L',
89
- LTL: 'Lt',
90
- LVL: 'Ls',
91
- LYD: 'ل.د',
92
- MAD: 'د.م.',
93
- MDL: 'L',
94
- MGA: 'Ar',
95
- MKD: 'ден',
96
- MMK: 'K',
97
- MNT: '₮',
98
- MOP: 'P',
99
- MRU: 'UM',
100
- MUR: '₨',
101
- MVR: 'MVR',
102
- MWK: 'MK',
103
- MXN: '$',
104
- MYR: 'RM',
105
- MZN: 'MTn',
106
- NAD: '$',
107
- NGN: '₦',
108
- NIO: 'C$',
109
- NOK: 'kr',
110
- NPR: '₨',
111
- NZD: '$',
112
- OMR: 'ر.ع.',
113
- PAB: 'B/.',
114
- PEN: 'S/.',
115
- PGK: 'K',
116
- PHP: '₱',
117
- PKR: '₨',
118
- PLN: 'zł',
119
- PYG: '₲',
120
- QAR: 'ر.ق',
121
- RON: 'Lei',
122
- RSD: 'РСД',
123
- RUB: '₽',
124
- RWF: 'FRw',
125
- SAR: 'ر.س',
126
- SBD: '$',
127
- SCR: '₨',
128
- SDG: '£',
129
- SEK: 'kr',
130
- SGD: '$',
131
- SHP: '£',
132
- SKK: 'Sk',
133
- SLL: 'Le',
134
- SOS: 'Sh',
135
- SRD: '$',
136
- SSP: '£',
137
- STN: 'Db',
138
- SVC: '₡',
139
- SYP: '£S',
140
- SZL: 'E',
141
- THB: '฿',
142
- TJS: 'ЅМ',
143
- TMT: 'T',
144
- TND: 'د.ت',
145
- TOP: 'T$',
146
- TRY: '₺',
147
- TTD: '$',
148
- TWD: '$',
149
- TZS: 'Sh',
150
- UAH: '₴',
151
- UGX: 'USh',
152
- USD: '$',
153
- UYU: '$',
154
- UZS: '',
155
- VED: 'Bs.D.',
156
- VES: 'Bs.S.',
157
- VND: '₫',
158
- VUV: 'Vt',
159
- WST: 'T',
160
- XAF: 'Fr',
161
- XAG: 'oz t',
162
- XAU: 'oz t',
163
- XBA: '',
164
- XBB: '',
165
- XBC: '',
166
- XBD: '',
167
- XCD: '$',
168
- XDR: 'SDR',
169
- XOF: 'Fr',
170
- XPD: 'oz t',
171
- XPF: 'Fr',
172
- XPT: 'oz t',
173
- xts: '',
174
- YER: '﷼',
175
- ZAR: 'R',
176
- ZMK: 'ZK',
177
- ZMW: 'ZK'
178
- };
179
- const useMoney = (money)=>{
4
+ const useMoney = (amount)=>{
180
5
  const { locale } = useLocale();
181
6
  const { currency } = useCurrency();
182
7
  const options = useMemo(()=>({
@@ -185,43 +10,71 @@ const useMoney = (money)=>{
185
10
  }), [
186
11
  currency
187
12
  ]);
188
- const value = useMemo(()=>new Intl.NumberFormat(locale, options).format(money), [
189
- locale,
190
- options,
191
- money
192
- ]);
193
- const baseParts = new Intl.NumberFormat(locale, options).formatToParts(money);
194
- const nameParts = new Intl.NumberFormat(locale, {
13
+ const defaultFormatter = useLazyFormatter(locale, options);
14
+ const nameFormatter = useLazyFormatter(locale, {
195
15
  ...options,
196
16
  currencyDisplay: 'name'
197
- }).formatToParts(money);
198
- const narrowParts = new Intl.NumberFormat(locale, {
17
+ });
18
+ const narrowSymbolFormatter = useLazyFormatter(locale, {
199
19
  ...options,
200
20
  currencyDisplay: 'narrowSymbol'
201
- }).formatToParts(money);
202
- const moneyValue = useMemo(()=>({
203
- currencyCode: currency,
204
- currencyName: nameParts.find((part)=>part.type === 'currency')?.value ?? // e.g. "US dollars"
205
- currency,
206
- currencyNarrowSymbol: narrowParts.find((part)=>part.type === 'currency')?.value ?? // e.g. "$"
207
- (currency ? NARROW_SYMBOL_MAP[currency] : '') ?? '',
208
- parts: baseParts,
209
- localizedString: value,
210
- amount: baseParts.filter((part)=>[
211
- 'decimal',
212
- 'fraction',
213
- 'group',
214
- 'integer',
215
- 'literal'
216
- ].includes(part.type)).map((part)=>part.value).join('')
21
+ });
22
+ const withoutTrailingZerosFormatter = useLazyFormatter(locale, {
23
+ ...options,
24
+ minimumFractionDigits: 0,
25
+ maximumFractionDigits: 0
26
+ });
27
+ const withoutCurrencyFormatter = useLazyFormatter(locale);
28
+ const withoutTrailingZerosOrCurrencyFormatter = useLazyFormatter(locale, {
29
+ minimumFractionDigits: 0,
30
+ maximumFractionDigits: 0
31
+ });
32
+ const isPartCurrency = (part)=>part.type === 'currency';
33
+ // By wrapping these properties in functions, we only
34
+ // create formatters if they are going to be used.
35
+ const lazyFormatters = useMemo(()=>({
36
+ currencyCode: ()=>currency,
37
+ localizedString: ()=>defaultFormatter().format(amount),
38
+ parts: ()=>defaultFormatter().formatToParts(amount),
39
+ withoutTrailingZeros: ()=>amount % 1 === 0 ? withoutTrailingZerosFormatter().format(amount) : defaultFormatter().format(amount),
40
+ withoutTrailingZerosAndCurrency: ()=>amount % 1 === 0 ? withoutTrailingZerosOrCurrencyFormatter().format(amount) : withoutCurrencyFormatter().format(amount),
41
+ currencyName: ()=>nameFormatter().formatToParts(amount).find(isPartCurrency)?.value ?? currency,
42
+ currencySymbol: ()=>defaultFormatter().formatToParts(amount).find(isPartCurrency)?.value ?? currency,
43
+ currencyNarrowSymbol: ()=>narrowSymbolFormatter().formatToParts(amount).find(isPartCurrency)?.value ?? '',
44
+ amount: ()=>defaultFormatter().formatToParts(amount).filter((part)=>[
45
+ 'decimal',
46
+ 'fraction',
47
+ 'group',
48
+ 'integer',
49
+ 'literal'
50
+ ].includes(part.type)).map((part)=>part.value).join('')
217
51
  }), [
218
- baseParts,
219
- nameParts,
220
- narrowParts,
221
- value,
222
- currency
52
+ currency,
53
+ amount,
54
+ nameFormatter,
55
+ defaultFormatter,
56
+ narrowSymbolFormatter,
57
+ withoutCurrencyFormatter,
58
+ withoutTrailingZerosFormatter,
59
+ withoutTrailingZerosOrCurrencyFormatter
60
+ ]);
61
+ // Call functions automatically when the properties are accessed
62
+ // to keep these functions as an implementation detail.
63
+ return useMemo(()=>new Proxy(lazyFormatters, {
64
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
65
+ get: (target, key)=>Reflect.get(target, key)?.call(null)
66
+ }), [
67
+ lazyFormatters
223
68
  ]);
224
- return moneyValue;
225
69
  };
70
+ function useLazyFormatter(locale, options) {
71
+ return useMemo(()=>{
72
+ let memoized;
73
+ return ()=>memoized ??= new Intl.NumberFormat(locale, options);
74
+ }, [
75
+ locale,
76
+ options
77
+ ]);
78
+ }
226
79
 
227
80
  export { useMoney as default };
package/dist/esm/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  export { default as AddOn } from './components/AddOn.js';
2
2
  export { default as Render } from './components/Render.js';
3
3
  export { default as RenderPreview } from './components/RenderPreview.js';
4
- export { default as RenderLiquid } from './components/Render.liquid.js';
4
+ export { RenderChildren, default as RenderLiquid } from './components/Render.liquid.js';
5
5
  export { AddonProvider, useAddon, useAddons } from './contexts/AddonContext.js';
6
6
  export { BuilderComponentProvider, useBuilderComponent } from './contexts/BuilderComponent.js';
7
7
  export { BuilderProvider, useBuilderStore } from './contexts/BuilderContext.js';
@@ -48,7 +48,7 @@ import * as gtag from './helpers/tracking/gtag.js';
48
48
  export { gtag };
49
49
  import * as tiktokpixel from './helpers/tracking/tiktokpixel.js';
50
50
  export { tiktokpixel };
51
- export { RenderIf, props, styles, template } from './helpers/render.js';
51
+ export { RenderIf, dataStringify, props, styles, template } from './helpers/render.js';
52
52
  export { baseAssetURL, isLocalEnv } from './helpers/convert.js';
53
53
  export { composeSize, composeSizeCss, genSizeClass } from './helpers/size.js';
54
54
  export { composeShadowCss, getStyleShadow, getStyleShadowState, parseValueWithUnit } from './helpers/shadow.js';
@@ -62,18 +62,18 @@ export { useCartNoteUpdate } from './hooks/cart/use-cart-note-update.js';
62
62
  export { useCreateCart } from './hooks/cart/use-create-cart.js';
63
63
  export { useRemoveCartItem } from './hooks/cart/use-remove-cart-item.js';
64
64
  export { useUpdateCartItem } from './hooks/cart/use-update-cart-item.js';
65
- export { useCheckoutUrl, useConnectedShopify, useCurrency, useEditorMode, useIsSampleProduct, useIsStorefrontProduct, useLocale, useMatchMutate, useMobileOnly, usePageType, usePluginEnable, useStoreFront, useSwatches } from './hooks/shop.js';
65
+ export { useCheckoutUrl, useConnectedShopify, useCurrency, useEditorMode, useIsSampleProduct, useIsStorefrontProduct, useLocale, useMatchMutate, useMobileOnly, useMoneyFormat, usePageType, usePluginEnable, useStoreFront, useSwatches } from './hooks/shop.js';
66
66
  export { useCollectionQuery } from './hooks/shop/use-collection-query.js';
67
67
  export { useCollectionsQuery } from './hooks/shop/use-collections-query.js';
68
68
  export { useProductQuery } from './hooks/shop/use-product-query.js';
69
69
  export { useProductsQuery } from './hooks/shop/use-products-query.js';
70
70
  export { useCurrentDevice } from './hooks/use-current-device.js';
71
+ export { useFormatMoney } from './hooks/useFormatMoney.js';
71
72
  export { useLazyVideo } from './hooks/use-lazy-video.js';
72
73
  export { default as useCartId } from './hooks/useCartId.js';
73
74
  export { default as useCartLine } from './hooks/useCartLine.js';
74
75
  export { default as useCartUI } from './hooks/useCartUI.js';
75
76
  export { useCollection } from './hooks/useCollection.js';
76
- export { default as useFormatMoney } from './hooks/useFormatMoney.js';
77
77
  export { useId } from 'react';
78
78
  export { default as useIsomorphicLayoutEffect } from './hooks/useIsomorphicLayoutEffect.js';
79
79
  export { default as useLoadScript } from './hooks/useLoadScript.js';
@@ -25,13 +25,21 @@ type Props$1 = {
25
25
  };
26
26
  declare const RenderPreviewMemo: React.NamedExoticComponent<Props$1>;
27
27
 
28
+ type ExtraFiles = {
29
+ [fileName: string]: string;
30
+ };
28
31
  type Props = {
29
32
  uid: string;
30
33
  builder: Record<string, any>;
31
34
  components: Record<string, any>;
35
+ extraFiles?: ExtraFiles;
32
36
  [key: string]: any;
33
37
  };
34
- declare const Render: ({ uid, builder, components, parentId, ...passProps }: Props) => string | null;
38
+ declare const Render: ({ uid, builder, components, parentId, extraFiles, ...passProps }: Props) => {
39
+ liquid: string;
40
+ extraFiles: ExtraFiles;
41
+ };
42
+ declare const RenderChildren: (props: Props) => string;
35
43
 
36
44
  type AddonContextProps = {
37
45
  components: Record<string, React.ComponentType<any>>;
@@ -7312,6 +7320,8 @@ type ShopContextProps = {
7312
7320
  locale?: string;
7313
7321
  pageType?: PublishedThemePageType;
7314
7322
  currency?: string;
7323
+ moneyFormat?: string;
7324
+ moneyWithCurrencyFormat?: string;
7315
7325
  plugins?: string[];
7316
7326
  storefrontUrl?: string;
7317
7327
  storefrontToken?: string;
@@ -7760,6 +7770,7 @@ type CallbackCondition = () => string;
7760
7770
  declare const RenderIf: (c: boolean | null | undefined, t: string | CallbackCondition, f?: string | CallbackCondition) => string;
7761
7771
  declare const props: (strings: any, ...keys: any[]) => string;
7762
7772
  declare const styles: (strings: any, ...keys: any[]) => string;
7773
+ declare const dataStringify: (obj: object) => string;
7763
7774
  declare const template: (strings: any, ...keys: any[]) => string;
7764
7775
 
7765
7776
  declare const isLocalEnv: boolean;
@@ -7867,6 +7878,10 @@ declare const useCurrency: () => {
7867
7878
  currency: string | undefined;
7868
7879
  changeCurrency: (currency: string) => void;
7869
7880
  };
7881
+ declare const useMoneyFormat: () => {
7882
+ moneyFormat: string | undefined;
7883
+ moneyWithCurrencyFormat: string | undefined;
7884
+ };
7870
7885
  declare const useSwatches: () => {
7871
7886
  swatches: GlobalSwatchesData[] | undefined;
7872
7887
  changeSwatches: (swatches: GlobalSwatchesData[]) => void;
@@ -7903,6 +7918,8 @@ declare const useProductsQuery: (ids?: string[], options?: SWRConfiguration<Prod
7903
7918
 
7904
7919
  declare const useCurrentDevice: () => NameDevices;
7905
7920
 
7921
+ declare const useFormatMoney: (amount: number, withCurrency: boolean) => string;
7922
+
7906
7923
  declare const useLazyVideo: () => void;
7907
7924
 
7908
7925
  declare const useCartId: () => {
@@ -7921,10 +7938,6 @@ declare function useCartUI(): {
7921
7938
 
7922
7939
  declare const useCollection: () => CollectionSelectFragment | undefined;
7923
7940
 
7924
- declare const useFormatMoney: () => {
7925
- formatMoney: (value: number, options?: Intl.NumberFormatOptions & Required<Pick<Intl.NumberFormatOptions, 'currency'>>) => string;
7926
- };
7927
-
7928
7941
  declare const useIsomorphicLayoutEffect: typeof useLayoutEffect;
7929
7942
 
7930
7943
  type LoadScriptParams = Parameters<typeof loadScript>;
@@ -7934,14 +7947,50 @@ type ScriptState = 'loading' | 'done' | 'error';
7934
7947
  */
7935
7948
  declare function useLoadScript(url: LoadScriptParams[0], options?: LoadScriptParams[1]): ScriptState;
7936
7949
 
7937
- declare const useMoney: (money: number) => {
7938
- currencyCode: string | undefined;
7939
- currencyName: string | undefined;
7940
- currencyNarrowSymbol: string;
7950
+ type UseMoneyValue = {
7951
+ /**
7952
+ * The currency code from the `MoneyV2` object.
7953
+ */
7954
+ currencyCode: string;
7955
+ /**
7956
+ * The name for the currency code, returned by `Intl.NumberFormat`.
7957
+ */
7958
+ currencyName?: string;
7959
+ /**
7960
+ * The currency symbol returned by `Intl.NumberFormat`.
7961
+ */
7962
+ currencySymbol?: string;
7963
+ /**
7964
+ * The currency narrow symbol returned by `Intl.NumberFormat`.
7965
+ */
7966
+ currencyNarrowSymbol?: string;
7967
+ /**
7968
+ * The localized amount, without any currency symbols or non-number types from the `Intl.NumberFormat.formatToParts` parts.
7969
+ */
7970
+ amount: string;
7971
+ /**
7972
+ * All parts returned by `Intl.NumberFormat.formatToParts`.
7973
+ */
7941
7974
  parts: Intl.NumberFormatPart[];
7975
+ /**
7976
+ * A string returned by `new Intl.NumberFormat` for the amount and currency code,
7977
+ * using the `locale` value in the [`LocalizationProvider` component](https://shopify.dev/api/hydrogen/components/localization/localizationprovider).
7978
+ */
7942
7979
  localizedString: string;
7943
- amount: string;
7944
- };
7980
+ /**
7981
+ * A string with trailing zeros removed from the fractional part, if any exist. If there are no trailing zeros, then the fractional part remains.
7982
+ * For example, `$640.00` turns into `$640`.
7983
+ * `$640.42` remains `$640.42`.
7984
+ */
7985
+ withoutTrailingZeros: string;
7986
+ /**
7987
+ * A string without currency and without trailing zeros removed from the fractional part, if any exist. If there are no trailing zeros, then the fractional part remains.
7988
+ * For example, `$640.00` turns into `640`.
7989
+ * `$640.42` turns into `640.42`.
7990
+ */
7991
+ withoutTrailingZerosAndCurrency: string;
7992
+ };
7993
+ declare const useMoney: (amount: number) => UseMoneyValue;
7945
7994
 
7946
7995
  declare const usePrevious: <T>(value: T) => T | undefined;
7947
7996
 
@@ -8021,4 +8070,4 @@ type PublishedThemePageSelectFragment = Pick<PublishedThemePage, 'id' | 'name' |
8021
8070
 
8022
8071
  declare const getProductBySlug: (fetcher: FetchFunc, slug?: string) => Promise<ProductSelectFragment>;
8023
8072
 
8024
- export { AddOn, AddonProvider, AddonProviderProps, AlignItemProp, AlignProp, Background, BaseProps, BasePropsWrap, BlockEntity, BoldSubscriptionsWidgetType, Border, BorderStyle, BuilderComponentProvider, BuilderComponentProviderProps, BuilderEntity, BuilderEntityNested, BuilderPreviewProvider, BuilderPreviewProviderProps, BuilderProvider, BuilderProviderProps, BuilderState, Builtin, CartLineProvider, CartLineProviderProps, CollectionDetailFilterDocument, CollectionDetailFilterQueryResponse, CollectionDetailFilterQueryVariables, CollectionDocument, CollectionProvider, CollectionProviderProps, CollectionQueryResponse, CollectionQueryVariables, CollectionSelectFragment, CollectionsDocument, CollectionsQueryResponse, CollectionsQueryVariables, ColorKey, ColorType$1 as ColorType, ColorValueType, Component, ComponentPreset, ComponentSetting, ContainerProp, ControlProp, ControlUI, CornerRadius, CornerRadiusType, CustomComponentConfig, DeepPartial, ExtractState, FetchCollectionArgs, FetchFunc, FetchProductParams, FlexDirectionProp, FontName, GlobalStyleConfig, GlobalStyleResponsiveConfig, GlobalSwatchesData, GraphQLConnection, GroupPropType, HSLAColorType, HSLColorType, HexColorType, InitComponentType, InstantJudgeMeReviewsWidgetType, InstantKlaviyoWidgetType, InstantLooxReviewsWidgetType, JudgeMeReviewsWidgetType, KlaviyoWidgetType, LooxReviewsWidgetType, ModalProvider, ModalProviderProps, NameDevices, NestedKeys, ObjectDeviceGlobalType, ObjectDevices, ObjectLayoutValue, OptionNormalStyle, OptionSpecialStyle, PageViewUpDocument, PageViewUpMutationResponse, PageViewUpMutationVariables, PickyStoryWidgetType, PreviewPageDocument, PreviewPageQueryResponse, PreviewPageQueryVariables, Primitive, ProductInputAnalytic, ProductListProvider, ProductListProviderProps, ProductProvider, ProductProviderProps, ProductReviewsWidgetType, ProductSelectFragment, ProductsDocument, ProductsQueryResponse, ProductsQueryVariables, PublishedThemePageSelectFragment, PublishedThemePagesDocument, PublishedThemePagesQueryResponse, PublishedThemePagesQueryVariables, RGBAColorType, RGBColorType, RenderMemo as Render, RenderIf, Render as RenderLiquid, RenderMode, RenderPreviewMemo as RenderPreview, RequiredCursorEdge, ResponsiveStateProp, RivyoWidgetType, RoundedSize, RyviuWidgetType, SectionData, SectionEntity, SectionProvider, SectionProviderProps, ShadowProps, ShadowStyle, ShadowStyleApplied, ShadowType, ShopProvider, ShopProviderProps, shop as ShopType, SizeProps, SizeSetting, SizeType, SpacingType, StateProp, StateSelector, StateType, StoreConfig, StorePropertyDocument, StorePropertyQueryResponse, StorePropertyQueryVariables, SwatchesOptionType, SwatchesOptionValue, TransformProp, TypographyProps, TypographySetting, TypographyType, VariantSelectFragment, WiserWidgetType, baseAssetURL, calculateFirstProduct, cls, composeAdvanceStyle, composeBackgroundCss, composeBorderCss, composeCornerCss, composeGridLayout, composeRadius, composeShadowCss, composeSize, composeSizeCss, composeSpacing, composeTextColorCss, composeTypographyCss, convertOldLayout, fetchMedias, fetchVariants, flattenConnection, fpixel, genSizeClass, genTypoClass, genVariable, generateCollectionQueryKey, generateProductQueryKey, generateProductsQueryKey, getBorderStyle, getCollection, getCornerCSSFromGlobal, getCustomRadius, getGlobalColorCSSProp, getGlobalColorClass, getGlobalColorResponsiveClass, getGlobalColorResponsiveStyle, getGlobalColorStateClass, getGlobalColorStateClassDynamicBtn, getGlobalColorStateResponsiveClass, getGlobalColorStateResponsiveClassDynamicBtn, getGlobalColorStateResponsiveStyle, getGlobalColorStateStyle, getGlobalColorStyle, getProduct, getProductBySlug, getRadiusCSSFromGlobal, getRadiusStyleActiveState, getResponsiveStateValue, getResponsiveValue, getResponsiveValueByScreen, getSelectedVariant, getShortName, getSingleColorVariable, getSpacingVariable, getStyleBackgroundByDevice, getStyleShadow, getStyleShadowState, globalEvent, gridToArrayRegex, gtag, handleConvertBorderColor, handleConvertBorderStyle, handleConvertBorderWidth, handleConvertClassColor, handleConvertClassColorDynamicBtn, isBrowser, isColor, isDefined, isEmptyChildren, isLocalEnv, loadScript, makeAspectRatio, makeHeight, makeLineClamp, makeStyle, makeStyleResponsive, makeStyleResponsiveState, makeStyleState, makeWidth, normalizeBuilderData, optionLayoutStyle, parseSelectedOption, parseValueWithUnit, prefetchQueries, props, splitStyle, styles, template, tiktokpixel, useAddToCart, useAddon, useAddons, useBuilderComponent, useBuilderPreviewStore, useBuilderStore, useCartData, useCartDiscountCodesUpdate, useCartId, useCartLine, useCartLineStore, useCartNoteUpdate, useCartUI, useCheckAvailableVariantInStock, useCheckoutUrl, useCollection, useCollectionQuery, useCollectionStore, useCollectionsQuery, useConnectedShopify, useCreateCart, useCurrency, useCurrentDevice, useCurrentVariant, useCurrentVariantInStock, useEditorMode, useFeaturedImageGlobal, useFormatMoney, useIsSampleProduct, useIsStorefrontProduct, useIsomorphicLayoutEffect, useLazyVideo, useLoadScript, useLocale, useMatchMutate, useMobileOnly, useModalStore, useMoney, usePageType, usePluginEnable, usePrevious, useProduct, useProductList, useProductListProducts, useProductListSettings, useProductListStore, useProductListStyles, useProductProperties, useProductQuery, useProductStore, useProductsQuery, useQuantity, useRemoveCartItem, useSection, useSectionStore, useSelectedOption, useShopStore, useStoreFront, useSuspenseFetch, useSwatches, useSwatchesOptions, useUniqProductID, useUpdateCartItem, useVariant, useVariantOutStock, useVariants, validateEmail };
8073
+ export { AddOn, AddonProvider, AddonProviderProps, AlignItemProp, AlignProp, Background, BaseProps, BasePropsWrap, BlockEntity, BoldSubscriptionsWidgetType, Border, BorderStyle, BuilderComponentProvider, BuilderComponentProviderProps, BuilderEntity, BuilderEntityNested, BuilderPreviewProvider, BuilderPreviewProviderProps, BuilderProvider, BuilderProviderProps, BuilderState, Builtin, CartLineProvider, CartLineProviderProps, CollectionDetailFilterDocument, CollectionDetailFilterQueryResponse, CollectionDetailFilterQueryVariables, CollectionDocument, CollectionProvider, CollectionProviderProps, CollectionQueryResponse, CollectionQueryVariables, CollectionSelectFragment, CollectionsDocument, CollectionsQueryResponse, CollectionsQueryVariables, ColorKey, ColorType$1 as ColorType, ColorValueType, Component, ComponentPreset, ComponentSetting, ContainerProp, ControlProp, ControlUI, CornerRadius, CornerRadiusType, CustomComponentConfig, DeepPartial, ExtractState, FetchCollectionArgs, FetchFunc, FetchProductParams, FlexDirectionProp, FontName, GlobalStyleConfig, GlobalStyleResponsiveConfig, GlobalSwatchesData, GraphQLConnection, GroupPropType, HSLAColorType, HSLColorType, HexColorType, InitComponentType, InstantJudgeMeReviewsWidgetType, InstantKlaviyoWidgetType, InstantLooxReviewsWidgetType, JudgeMeReviewsWidgetType, KlaviyoWidgetType, LooxReviewsWidgetType, ModalProvider, ModalProviderProps, NameDevices, NestedKeys, ObjectDeviceGlobalType, ObjectDevices, ObjectLayoutValue, OptionNormalStyle, OptionSpecialStyle, PageViewUpDocument, PageViewUpMutationResponse, PageViewUpMutationVariables, PickyStoryWidgetType, PreviewPageDocument, PreviewPageQueryResponse, PreviewPageQueryVariables, Primitive, ProductInputAnalytic, ProductListProvider, ProductListProviderProps, ProductProvider, ProductProviderProps, ProductReviewsWidgetType, ProductSelectFragment, ProductsDocument, ProductsQueryResponse, ProductsQueryVariables, PublishedThemePageSelectFragment, PublishedThemePagesDocument, PublishedThemePagesQueryResponse, PublishedThemePagesQueryVariables, RGBAColorType, RGBColorType, RenderMemo as Render, RenderChildren, RenderIf, Render as RenderLiquid, RenderMode, RenderPreviewMemo as RenderPreview, RequiredCursorEdge, ResponsiveStateProp, RivyoWidgetType, RoundedSize, RyviuWidgetType, SectionData, SectionEntity, SectionProvider, SectionProviderProps, ShadowProps, ShadowStyle, ShadowStyleApplied, ShadowType, ShopProvider, ShopProviderProps, shop as ShopType, SizeProps, SizeSetting, SizeType, SpacingType, StateProp, StateSelector, StateType, StoreConfig, StorePropertyDocument, StorePropertyQueryResponse, StorePropertyQueryVariables, SwatchesOptionType, SwatchesOptionValue, TransformProp, TypographyProps, TypographySetting, TypographyType, VariantSelectFragment, WiserWidgetType, baseAssetURL, calculateFirstProduct, cls, composeAdvanceStyle, composeBackgroundCss, composeBorderCss, composeCornerCss, composeGridLayout, composeRadius, composeShadowCss, composeSize, composeSizeCss, composeSpacing, composeTextColorCss, composeTypographyCss, convertOldLayout, dataStringify, fetchMedias, fetchVariants, flattenConnection, fpixel, genSizeClass, genTypoClass, genVariable, generateCollectionQueryKey, generateProductQueryKey, generateProductsQueryKey, getBorderStyle, getCollection, getCornerCSSFromGlobal, getCustomRadius, getGlobalColorCSSProp, getGlobalColorClass, getGlobalColorResponsiveClass, getGlobalColorResponsiveStyle, getGlobalColorStateClass, getGlobalColorStateClassDynamicBtn, getGlobalColorStateResponsiveClass, getGlobalColorStateResponsiveClassDynamicBtn, getGlobalColorStateResponsiveStyle, getGlobalColorStateStyle, getGlobalColorStyle, getProduct, getProductBySlug, getRadiusCSSFromGlobal, getRadiusStyleActiveState, getResponsiveStateValue, getResponsiveValue, getResponsiveValueByScreen, getSelectedVariant, getShortName, getSingleColorVariable, getSpacingVariable, getStyleBackgroundByDevice, getStyleShadow, getStyleShadowState, globalEvent, gridToArrayRegex, gtag, handleConvertBorderColor, handleConvertBorderStyle, handleConvertBorderWidth, handleConvertClassColor, handleConvertClassColorDynamicBtn, isBrowser, isColor, isDefined, isEmptyChildren, isLocalEnv, loadScript, makeAspectRatio, makeHeight, makeLineClamp, makeStyle, makeStyleResponsive, makeStyleResponsiveState, makeStyleState, makeWidth, normalizeBuilderData, optionLayoutStyle, parseSelectedOption, parseValueWithUnit, prefetchQueries, props, splitStyle, styles, template, tiktokpixel, useAddToCart, useAddon, useAddons, useBuilderComponent, useBuilderPreviewStore, useBuilderStore, useCartData, useCartDiscountCodesUpdate, useCartId, useCartLine, useCartLineStore, useCartNoteUpdate, useCartUI, useCheckAvailableVariantInStock, useCheckoutUrl, useCollection, useCollectionQuery, useCollectionStore, useCollectionsQuery, useConnectedShopify, useCreateCart, useCurrency, useCurrentDevice, useCurrentVariant, useCurrentVariantInStock, useEditorMode, useFeaturedImageGlobal, useFormatMoney, useIsSampleProduct, useIsStorefrontProduct, useIsomorphicLayoutEffect, useLazyVideo, useLoadScript, useLocale, useMatchMutate, useMobileOnly, useModalStore, useMoney, useMoneyFormat, usePageType, usePluginEnable, usePrevious, useProduct, useProductList, useProductListProducts, useProductListSettings, useProductListStore, useProductListStyles, useProductProperties, useProductQuery, useProductStore, useProductsQuery, useQuantity, useRemoveCartItem, useSection, useSectionStore, useSelectedOption, useShopStore, useStoreFront, useSuspenseFetch, useSwatches, useSwatchesOptions, useUniqProductID, useUpdateCartItem, useVariant, useVariantOutStock, useVariants, validateEmail };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gem-sdk/core",
3
- "version": "1.12.0-next.10",
3
+ "version": "1.12.0-next.12",
4
4
  "license": "MIT",
5
5
  "sideEffects": false,
6
6
  "main": "dist/cjs/index.js",