@gem-sdk/core 1.12.0-next.4 → 1.12.0-next.41

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.
@@ -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 = parseFloat(`${number}`).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';
@@ -29,7 +29,7 @@ export { getShortName } from './helpers/get-shortname.js';
29
29
  export { default as globalEvent } from './helpers/GlobalEvent.js';
30
30
  export { default as isBrowser } from './helpers/is-browser.js';
31
31
  export { isEmptyChildren } from './helpers/is-empty-children.js';
32
- export { makeAspectRatio, makeHeight, makeLineClamp, makeStyle, makeStyleResponsive, makeStyleResponsiveState, makeStyleState, makeWidth } from './helpers/make-style.js';
32
+ export { makeAspectRatio, makeHeight, makeLineClamp, makeStyle, makeStyleResponsive, makeStyleResponsiveState, makeStyleState, makeWidth, removeNullUndefined } from './helpers/make-style.js';
33
33
  export { normalizeBuilderData } from './helpers/normalize-builder-data.js';
34
34
  export { prefetchQueries } from './helpers/prefetch-queries.js';
35
35
  export { composeSpacing, getSpacingVariable } from './helpers/spacing.js';
@@ -39,7 +39,7 @@ export { genVariable } from './helpers/css-variable.js';
39
39
  export { composeGridLayout, convertOldLayout, gridToArrayRegex, optionLayoutStyle } from './helpers/layout.js';
40
40
  export { isDefined } from './helpers/is-defined.js';
41
41
  export { composeTextColorCss, getGlobalColorCSSProp, getGlobalColorClass, getGlobalColorResponsiveClass, getGlobalColorResponsiveStyle, getGlobalColorStateClass, getGlobalColorStateClassDynamicBtn, getGlobalColorStateResponsiveClass, getGlobalColorStateResponsiveClassDynamicBtn, getGlobalColorStateResponsiveStyle, getGlobalColorStateStyle, getGlobalColorStyle, getSingleColorVariable, isColor } from './helpers/colors.js';
42
- export { composeTypographyCss, genTypoClass } from './helpers/typography.js';
42
+ export { composeTypography, composeTypographyAttr, composeTypographyClassName, composeTypographyCss, composeTypographyStyle, composeTypographyV2, genTypoClass } from './helpers/typography.js';
43
43
  export { composeCornerCss, composeRadius, getCornerCSSFromGlobal, getCustomRadius, getRadiusCSSFromGlobal, getRadiusStyleActiveState } from './helpers/radius.js';
44
44
  export { getSelectedVariant, parseSelectedOption } from './helpers/product.js';
45
45
  import * as fpixel from './helpers/tracking/fpixel.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, composeMemo, 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';