@gem-sdk/core 1.42.7 → 1.43.0-dev.102

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 (92) hide show
  1. package/dist/cjs/components/ComponentToolbarPreview.js +126 -7
  2. package/dist/cjs/components/ComponentWrapperPreview.js +44 -1
  3. package/dist/cjs/components/Render.liquid.js +3 -0
  4. package/dist/cjs/components/RenderCustomCode.js +3 -0
  5. package/dist/cjs/components/RenderPreview.js +1 -0
  6. package/dist/cjs/components/ai-generator/AIContentGenerator.js +252 -0
  7. package/dist/cjs/components/ai-generator/AIGenContentLoading.js +85 -0
  8. package/dist/cjs/components/ai-generator/components/PickProduct.js +219 -0
  9. package/dist/cjs/components/ai-generator/components/ToneAndVoice.js +77 -0
  10. package/dist/cjs/components/ai-generator/hooks/useCheckingProductInside.js +47 -0
  11. package/dist/cjs/components/ai-generator/hooks/useFlipPopup.js +110 -0
  12. package/dist/cjs/components/ai-generator/hooks/useGettingGenerateRequest.js +37 -0
  13. package/dist/cjs/components/ai-generator/hooks/useListenEventGenerate.js +70 -0
  14. package/dist/cjs/components/ai-generator/icons/AIIcon.js +67 -0
  15. package/dist/cjs/components/ai-generator/icons/CloseIcon.js +19 -0
  16. package/dist/cjs/components/ai-generator/icons/DropdownIcon.js +37 -0
  17. package/dist/cjs/components/ai-generator/icons/SearchIcon.js +21 -0
  18. package/dist/cjs/components/ai-generator/icons/ShowMoreIcon.js +21 -0
  19. package/dist/cjs/components/ai-generator/icons/UpgradeIcon.js +27 -0
  20. package/dist/cjs/components/ai-generator/icons/WarningIcon.js +31 -0
  21. package/dist/cjs/components/constant.js +19 -2
  22. package/dist/cjs/components/resize/Spacing.js +21 -11
  23. package/dist/cjs/components/theme-section/CreateThemeSection.js +3 -0
  24. package/dist/cjs/components/theme-section/ThemeSectionStatus.js +14 -5
  25. package/dist/cjs/contexts/ArticleContext.js +39 -0
  26. package/dist/cjs/contexts/ArticleListContext.js +31 -0
  27. package/dist/cjs/contexts/BuilderPreviewContext.js +17 -10
  28. package/dist/cjs/contexts/SectionContext.js +1 -0
  29. package/dist/cjs/contexts/ShopContext.js +18 -0
  30. package/dist/cjs/graphql/queries/articles.generated.js +55 -0
  31. package/dist/cjs/graphql/queries/blogs.generated.js +63 -0
  32. package/dist/cjs/helpers/align.js +19 -0
  33. package/dist/cjs/helpers/background.js +6 -3
  34. package/dist/cjs/helpers/carousel.js +7 -10
  35. package/dist/cjs/helpers/colors.js +2 -2
  36. package/dist/cjs/helpers/queries/get-products.js +23 -0
  37. package/dist/cjs/helpers/shadow.js +1 -1
  38. package/dist/cjs/helpers/typography.js +43 -8
  39. package/dist/cjs/hooks/articles/useArticlesQuery.js +32 -0
  40. package/dist/cjs/hooks/shop/use-products-query.js +29 -0
  41. package/dist/cjs/hooks/useAnimations.js +3 -0
  42. package/dist/cjs/hooks/useFormatMoney.js +61 -60
  43. package/dist/cjs/hooks/useInitialSwatchesOptions.js +3 -0
  44. package/dist/cjs/hooks/useProduct.js +3 -0
  45. package/dist/cjs/index.js +14 -0
  46. package/dist/esm/components/ComponentToolbarPreview.js +127 -8
  47. package/dist/esm/components/ComponentWrapperPreview.js +44 -1
  48. package/dist/esm/components/Render.liquid.js +3 -0
  49. package/dist/esm/components/RenderCustomCode.js +3 -0
  50. package/dist/esm/components/RenderPreview.js +1 -0
  51. package/dist/esm/components/ai-generator/AIContentGenerator.js +250 -0
  52. package/dist/esm/components/ai-generator/AIGenContentLoading.js +83 -0
  53. package/dist/esm/components/ai-generator/components/PickProduct.js +217 -0
  54. package/dist/esm/components/ai-generator/components/ToneAndVoice.js +75 -0
  55. package/dist/esm/components/ai-generator/hooks/useCheckingProductInside.js +45 -0
  56. package/dist/esm/components/ai-generator/hooks/useFlipPopup.js +108 -0
  57. package/dist/esm/components/ai-generator/hooks/useGettingGenerateRequest.js +35 -0
  58. package/dist/esm/components/ai-generator/hooks/useListenEventGenerate.js +68 -0
  59. package/dist/esm/components/ai-generator/icons/AIIcon.js +65 -0
  60. package/dist/esm/components/ai-generator/icons/CloseIcon.js +17 -0
  61. package/dist/esm/components/ai-generator/icons/DropdownIcon.js +34 -0
  62. package/dist/esm/components/ai-generator/icons/SearchIcon.js +19 -0
  63. package/dist/esm/components/ai-generator/icons/ShowMoreIcon.js +19 -0
  64. package/dist/esm/components/ai-generator/icons/UpgradeIcon.js +25 -0
  65. package/dist/esm/components/ai-generator/icons/WarningIcon.js +29 -0
  66. package/dist/esm/components/constant.js +19 -3
  67. package/dist/esm/components/resize/Spacing.js +21 -11
  68. package/dist/esm/components/theme-section/CreateThemeSection.js +3 -0
  69. package/dist/esm/components/theme-section/ThemeSectionStatus.js +14 -5
  70. package/dist/esm/contexts/ArticleContext.js +36 -0
  71. package/dist/esm/contexts/ArticleListContext.js +27 -0
  72. package/dist/esm/contexts/BuilderPreviewContext.js +17 -10
  73. package/dist/esm/contexts/SectionContext.js +1 -0
  74. package/dist/esm/contexts/ShopContext.js +19 -1
  75. package/dist/esm/graphql/queries/articles.generated.js +53 -0
  76. package/dist/esm/graphql/queries/blogs.generated.js +61 -0
  77. package/dist/esm/helpers/align.js +17 -0
  78. package/dist/esm/helpers/background.js +6 -4
  79. package/dist/esm/helpers/carousel.js +7 -10
  80. package/dist/esm/helpers/colors.js +2 -2
  81. package/dist/esm/helpers/queries/get-products.js +23 -1
  82. package/dist/esm/helpers/shadow.js +1 -1
  83. package/dist/esm/helpers/typography.js +43 -9
  84. package/dist/esm/hooks/articles/useArticlesQuery.js +29 -0
  85. package/dist/esm/hooks/shop/use-products-query.js +30 -2
  86. package/dist/esm/hooks/useAnimations.js +3 -0
  87. package/dist/esm/hooks/useFormatMoney.js +61 -61
  88. package/dist/esm/hooks/useInitialSwatchesOptions.js +3 -0
  89. package/dist/esm/hooks/useProduct.js +3 -0
  90. package/dist/esm/index.js +7 -3
  91. package/dist/types/index.d.ts +263 -51
  92. package/package.json +6 -3
@@ -0,0 +1,61 @@
1
+ const BlogsDocument = `
2
+ query blogs($after: Cursor, $before: Cursor, $first: Int, $last: Int, $orderBy: BlogOrder, $where: BlogWhereInput) {
3
+ blogs(
4
+ after: $after
5
+ before: $before
6
+ first: $first
7
+ last: $last
8
+ orderBy: $orderBy
9
+ where: $where
10
+ ) {
11
+ edges {
12
+ cursor
13
+ node {
14
+ baseID
15
+ description
16
+ descriptionMeta
17
+ handle
18
+ articles {
19
+ edges {
20
+ node {
21
+ id
22
+ title
23
+ handle
24
+ description
25
+ templateSuffix
26
+ titleMeta
27
+ descriptionMeta
28
+ baseID
29
+ tags
30
+ isSample
31
+ platformCreatedAt
32
+ author
33
+ media {
34
+ width
35
+ src
36
+ height
37
+ }
38
+ }
39
+ }
40
+ totalCount
41
+ }
42
+ id
43
+ platform
44
+ tags
45
+ templateSuffix
46
+ title
47
+ titleMeta
48
+ }
49
+ }
50
+ pageInfo {
51
+ endCursor
52
+ hasNextPage
53
+ hasPreviousPage
54
+ startCursor
55
+ }
56
+ totalCount
57
+ }
58
+ }
59
+ `;
60
+
61
+ export { BlogsDocument };
@@ -0,0 +1,17 @@
1
+ const convertTextAlignToJustify = (align)=>{
2
+ const devices = [
3
+ 'desktop',
4
+ 'tablet',
5
+ 'mobile'
6
+ ];
7
+ const result = {};
8
+ devices.forEach((device)=>{
9
+ const deviceType = device === 'desktop' ? '' : `${device}:`;
10
+ result[`${deviceType}gp-justify-start`] = align?.[device] === 'left';
11
+ result[`${deviceType}gp-justify-center`] = align?.[device] === 'center';
12
+ result[`${deviceType}gp-justify-end`] = align?.[device] === 'right';
13
+ });
14
+ return result;
15
+ };
16
+
17
+ export { convertTextAlignToJustify };
@@ -7,7 +7,9 @@ const getStyleBackgroundByDevice = (background, options)=>{
7
7
  return {};
8
8
  }
9
9
  return {
10
- ...getStyleBgColor(background),
10
+ ...!options?.ignoreBackgroundColor ? {
11
+ ...getStyleBgColor(background)
12
+ } : {},
11
13
  ...!options?.ignoreBackgroundImage ? {
12
14
  ...getStyleBgImage(background, options),
13
15
  ...getStyleBgPosition(background),
@@ -201,7 +203,7 @@ const getGradientBgrStyleForButton = (backgroundStyle)=>{
201
203
  });
202
204
  return bgrStyle;
203
205
  };
204
- const getGradientBgrStyleByDevice = (backgroundStyle)=>{
206
+ const getGradientBgrStyleByDevice = (backgroundStyle, ignoreBackgroundImage = false)=>{
205
207
  if (!backgroundStyle) return;
206
208
  const bgrStyle = {};
207
209
  [
@@ -212,11 +214,11 @@ const getGradientBgrStyleByDevice = (backgroundStyle)=>{
212
214
  if (backgroundStyle[device]?.color?.includes(GRADIENT_BGR_KEY)) {
213
215
  Object.assign(bgrStyle, {
214
216
  [`--bgc${device !== 'desktop' ? '-' + device : ''}`]: 'transparent',
215
- [`--bgi${device !== 'desktop' ? '-' + device : ''}`]: `${getBgImageByDevice(backgroundStyle, device) || 'url()'}, ${backgroundStyle[device]?.color}`
217
+ [`--bgi${device !== 'desktop' ? '-' + device : ''}`]: ignoreBackgroundImage ? `${backgroundStyle[device]?.color}` : `${getBgImageByDevice(backgroundStyle, device) || 'url()'}, ${backgroundStyle[device]?.color}`
216
218
  });
217
219
  }
218
220
  });
219
221
  return bgrStyle;
220
222
  };
221
223
 
222
- export { GRADIENT_BGR_KEY, composeBackgroundCss, getBgImageByDevice, getGradientBgrStyleByDevice, getGradientBgrStyleForButton, getStyleBackgroundByDevice, makeFixedBgAttachment };
224
+ export { GRADIENT_BGR_KEY, composeBackgroundCss, getBgImageByDevice, getGradientBgrStyleByDevice, getGradientBgrStyleForButton, getStyleBackgroundByDevice, getStyleBgColor, makeFixedBgAttachment };
@@ -1,23 +1,20 @@
1
1
  import { getResponsiveValueByScreen } from './get-resonsive-value.js';
2
2
 
3
- const getCarouselContainerHeight = (dotStyle, dotSize, dotGapToCarousel)=>{
4
- const getVal = (dotStyle, dotSize, dotGapToCarousel)=>{
5
- if (dotStyle === 'outside') {
6
- return `calc(100% - ${dotSize ?? '0'}px - ${!dotGapToCarousel || dotGapToCarousel === 'Auto' ? '0' : dotGapToCarousel}px)`;
7
- }
8
- return '100%';
3
+ const getCarouselContainerHeight = (dotStyle)=>{
4
+ const getVal = (dotStyle)=>{
5
+ return dotStyle === 'outside' ? 'auto' : '100%';
9
6
  };
10
7
  return {
11
- desktop: getVal(getResponsiveValueByScreen(dotStyle, 'desktop'), getResponsiveValueByScreen(dotSize, 'desktop'), getResponsiveValueByScreen(dotGapToCarousel, 'desktop')),
12
- tablet: getVal(getResponsiveValueByScreen(dotStyle, 'tablet'), getResponsiveValueByScreen(dotSize, 'tablet'), getResponsiveValueByScreen(dotGapToCarousel, 'tablet')),
13
- mobile: getVal(getResponsiveValueByScreen(dotStyle, 'mobile'), getResponsiveValueByScreen(dotSize, 'mobile'), getResponsiveValueByScreen(dotGapToCarousel, 'mobile'))
8
+ desktop: getVal(getResponsiveValueByScreen(dotStyle, 'desktop')),
9
+ tablet: getVal(getResponsiveValueByScreen(dotStyle, 'tablet')),
10
+ mobile: getVal(getResponsiveValueByScreen(dotStyle, 'mobile'))
14
11
  };
15
12
  };
16
13
  const makeContainerWidthOrHeight = (setting)=>{
17
14
  const getStyleName = (vertical)=>{
18
15
  return vertical ? 'w' : 'h';
19
16
  };
20
- const result = getCarouselContainerHeight(setting.dotStyle, setting.dotSize, setting.dotGapToCarousel);
17
+ const result = getCarouselContainerHeight(setting.dotStyle);
21
18
  return {
22
19
  [`--${getStyleName(getResponsiveValueByScreen(setting?.vertical, 'desktop'))}`]: result.desktop,
23
20
  [`--${getStyleName(getResponsiveValueByScreen(setting?.vertical, 'tablet'))}-tablet`]: result.tablet,
@@ -117,7 +117,7 @@ const getGlobalColorStateStyle = (type, data)=>{
117
117
  return Object.fromEntries(Object.entries(data).map(([state, value])=>{
118
118
  if (state === 'active') return [];
119
119
  return [
120
- `-${stateMapping?.[state]}-${type}`,
120
+ `-${stateMapping?.[state] || ''}-${type}`,
121
121
  getSingleColorVariable(value)
122
122
  ];
123
123
  }).filter(isDefined));
@@ -154,7 +154,7 @@ const getSingleColorVariable = (color)=>{
154
154
  };
155
155
  function isColor(color) {
156
156
  if (!color || typeof color !== 'string') return false;
157
- return color?.startsWith('#') || color?.startsWith('rgb') || color?.startsWith('hsl') || color?.startsWith('transparent');
157
+ return color?.startsWith('#') || color?.startsWith('rgb') || color?.startsWith('hsl') || color?.startsWith('transparent') || color?.startsWith('linear-gradient');
158
158
  }
159
159
  const getGlobalColorStyle = (data)=>{
160
160
  if (!data) return {};
@@ -78,6 +78,28 @@ const getProductQueryAll = async (fetcher, arg)=>{
78
78
  const pageData = await fetchProducts(fetcher, variables);
79
79
  return pageData;
80
80
  };
81
+ const getListProductByVariables = async (fetcher, arg)=>{
82
+ const variables = {
83
+ first: arg.first || 8,
84
+ firstMedia: 1,
85
+ firstVariant: 1,
86
+ orderBy: {
87
+ field: 'PLATFORM_CREATED_AT',
88
+ direction: 'DESC'
89
+ },
90
+ orderByMedia: {
91
+ field: 'POSITION',
92
+ direction: 'ASC'
93
+ },
94
+ where: {
95
+ status: 'ACTIVE',
96
+ ...arg.where
97
+ },
98
+ after: arg.after
99
+ };
100
+ const pageData = await fetchProducts(fetcher, variables);
101
+ return pageData;
102
+ };
81
103
  const fetchProducts = async (fetcher, variables)=>{
82
104
  return fetcher([
83
105
  ProductsDocument,
@@ -185,4 +207,4 @@ const mergeMediasToProducts = async ({ fetcher, products, isSample, isStorefront
185
207
  // );
186
208
  // };
187
209
 
188
- export { getProductQueryAll, getProducts };
210
+ export { getListProductByVariables, getProductQueryAll, getProducts };
@@ -25,7 +25,7 @@ const getStyleShadow = (shadowStyle, isActiveState = false)=>{
25
25
  if (typeof value.distance == 'undefined') return {};
26
26
  const { value: distance, unit: unitDistance } = parseValueWithUnit(`${value?.distance}`);
27
27
  return {
28
- [`-${!isActiveState ? stateMapping?.[state] : ''}-${getShortName(styleAppliedFor)}`]: isEnableShadow ? `${Math.cos(parseFloat(`${value?.angle}`) * Math.PI / 180) * parseFloat(`${distance}`)}${unitDistance} ${Math.sin(parseFloat(`${value?.angle}`) * Math.PI / 180) * parseFloat(`${distance}`)}${unitDistance} ${value?.blur} ${styleAppliedFor === 'box-shadow' ? value?.spread + ' ' : ''}${getSingleColorVariable(value?.color)}` : 'none'
28
+ [`-${!isActiveState ? stateMapping?.[state] || '' : ''}-${getShortName(styleAppliedFor)}`]: isEnableShadow ? `${Math.cos(parseFloat(`${value?.angle}`) * Math.PI / 180) * parseFloat(`${distance}`)}${unitDistance} ${Math.sin(parseFloat(`${value?.angle}`) * Math.PI / 180) * parseFloat(`${distance}`)}${unitDistance} ${value?.blur} ${styleAppliedFor === 'box-shadow' ? value?.spread + ' ' : ''}${getSingleColorVariable(value?.color)}` : 'none'
29
29
  };
30
30
  };
31
31
  const getStyleShadowState = (shadow, styleAppliedFor, isEnableShadow)=>{
@@ -8,7 +8,9 @@ const composeTypographyCss = (typography)=>{
8
8
  const typographyCustom = typography?.custom;
9
9
  const { fontFamily, fontSize, fontStyle, fontWeight, lineHeight, letterSpacing } = typographyCustom?.desktop ?? {};
10
10
  return `
11
- ${fontFamily ? `font-family: var(--g-font-${fontFamily}, ${fontFamily});` : ''}
11
+ ${fontFamily ? `fontFamily: ${composeFontFamilyTypographyV2({
12
+ fontFamily
13
+ })};` : ''}
12
14
  ${fontSize ? `font-size: ${fontSize};` : ''}
13
15
  ${fontStyle ? `font-style: ${fontStyle};` : ''}
14
16
  ${fontWeight ? `font-weight: ${fontWeight};` : ''}
@@ -23,11 +25,13 @@ const composeTypographyV2Css = (typography, isImportant)=>{
23
25
  const { bold, italic, underline, transform } = typographyAttrs ?? {};
24
26
  const composeImportant = isImportant ? '!important' : '';
25
27
  return `
26
- ${fontFamily ? `font-family: var(--g-font-${fontFamily}, ${fontFamily}) ${composeImportant};` : ''}
28
+ ${fontFamily ? composeFontFamilyTypographyV2({
29
+ fontFamily
30
+ }) : ''}
27
31
  ${fontSize?.desktop ? `font-size: ${fontSize?.desktop} ${composeImportant};` : ''}
28
32
  ${bold ? `font-weight: bold ${composeImportant};` : fontWeight ? `font-weight: ${fontWeight} ${composeImportant};` : ''}
29
33
  ${letterSpacing ? `letter-spacing: ${letterSpacing} ${composeImportant};` : ''}
30
- ${lineHeight ? `line-height: ${lineHeight} ${composeImportant};` : ''}
34
+ ${lineHeight?.desktop ? `line-height: ${lineHeight?.desktop} ${composeImportant};` : ''}
31
35
  ${italic ? `font-style: italic ${composeImportant};` : ''}
32
36
  ${underline ? `text-decoration-line: underline ${composeImportant};` : ''}
33
37
  ${transform ? `text-transform: ${transform} ${composeImportant};` : ''}
@@ -41,7 +45,9 @@ function getCustomCSSByDevice(typography, device) {
41
45
  [`--size${suffix}`]: typography?.[device]?.fontSize,
42
46
  [`--lh${suffix}`]: typography?.[device]?.lineHeight,
43
47
  [`--fs${suffix}`]: typography?.[device]?.fontStyle,
44
- [`--ff${suffix}`]: fontFamily ? `var(--g-font-${fontFamily}, ${fontFamily})` : undefined,
48
+ [`--ff${suffix}`]: composeFontFamilyTypographyV2({
49
+ fontFamily
50
+ }),
45
51
  [`--weight${suffix}`]: typography?.[device]?.fontWeight,
46
52
  [`--ls${suffix}`]: typography?.[device]?.letterSpacing
47
53
  };
@@ -59,14 +65,42 @@ const composeTypographyV2 = (value, attrs)=>{
59
65
  return removeNullUndefined({
60
66
  ...makeStyle({
61
67
  fs: !attrs?.italic ? value?.fontStyle : undefined,
62
- ff: value?.fontFamily ? `var(--g-font-${value.fontFamily.replace(/ /g, '-')}, '${value.fontFamily}'), ${value.fallbackFontFamily}` : undefined,
68
+ ff: composeFontFamilyTypographyV2(value),
63
69
  weight: !attrs?.bold ? value?.fontWeight : undefined,
64
- ls: value?.letterSpacing,
65
- lh: value?.lineHeight
70
+ ls: value?.letterSpacing
66
71
  }),
67
- ...makeStyleResponsive('size', value?.fontSize)
72
+ ...makeStyleResponsive('size', value?.fontSize),
73
+ ...makeStyleResponsive('lh', value?.lineHeight)
68
74
  });
69
75
  };
76
+ const composeFontFamilyTypographyV2 = (value)=>{
77
+ const fontFamily = value?.fontFamily;
78
+ if (!fontFamily) return;
79
+ if (typeof fontFamily === 'string') {
80
+ return getFontUsedByTypographyV2({
81
+ fontFamily,
82
+ fallbackFontFamily: value?.fallbackFontFamily
83
+ });
84
+ }
85
+ if (typeof fontFamily === 'object' && typeof fontFamily?.value === 'string') {
86
+ switch(fontFamily.type){
87
+ case 'theme':
88
+ return `var(${fontFamily?.value}), var(--g-font-body)`;
89
+ default:
90
+ return getFontUsedByTypographyV2({
91
+ fontFamily: fontFamily.value,
92
+ fallbackFontFamily: value?.fallbackFontFamily
93
+ });
94
+ }
95
+ }
96
+ return;
97
+ };
98
+ const getFontUsedByTypographyV2 = ({ fontFamily, fallbackFontFamily })=>{
99
+ if (fontFamily) {
100
+ return `var(--g-font-${fontFamily?.replace(/ /g, '-')}, '${fontFamily}'), ${fallbackFontFamily}`;
101
+ }
102
+ return;
103
+ };
70
104
  const composeTypographyAttr = (attrs)=>{
71
105
  if (!attrs) return {};
72
106
  return removeNullUndefined({
@@ -113,4 +147,4 @@ const composeTypographyStyle = (typo, typography, disableAttr)=>{
113
147
  };
114
148
  };
115
149
 
116
- export { composeFallbackTypographyStyle, composeTypography, composeTypographyAttr, composeTypographyClassName, composeTypographyCss, composeTypographyStyle, composeTypographyV2, composeTypographyV2Css, genTypoClass };
150
+ export { composeFallbackTypographyStyle, composeFontFamilyTypographyV2, composeTypography, composeTypographyAttr, composeTypographyClassName, composeTypographyCss, composeTypographyStyle, composeTypographyV2, composeTypographyV2Css, genTypoClass };
@@ -0,0 +1,29 @@
1
+ import { ArticlesDocument } from '../../graphql/queries/articles.generated.js';
2
+ import { useFetchHandle } from '../useFetchHandle.js';
3
+ import useSWR from 'swr';
4
+ import { BlogsDocument } from '../../graphql/queries/blogs.generated.js';
5
+
6
+ const useArticlesQuery = (variables, options)=>{
7
+ const fetcher = useFetchHandle();
8
+ const fetchArticles = ()=>fetcher([
9
+ ArticlesDocument,
10
+ variables ?? {}
11
+ ]);
12
+ return useSWR(variables ? [
13
+ 'query/articles',
14
+ variables
15
+ ] : null, fetchArticles, options);
16
+ };
17
+ const useBlogsQuery = (variables, options)=>{
18
+ const fetcher = useFetchHandle();
19
+ const fetchBlogs = ()=>fetcher([
20
+ BlogsDocument,
21
+ variables ?? {}
22
+ ]);
23
+ return useSWR(variables ? [
24
+ 'query/blogs',
25
+ variables
26
+ ] : null, fetchBlogs, options);
27
+ };
28
+
29
+ export { useArticlesQuery, useBlogsQuery };
@@ -1,5 +1,6 @@
1
1
  import useSWR from 'swr';
2
- import { getProducts, getProductQueryAll } from '../../helpers/queries/get-products.js';
2
+ import useSWRInfinite from 'swr/infinite';
3
+ import { getProducts, getProductQueryAll, getListProductByVariables } from '../../helpers/queries/get-products.js';
3
4
  import { generateProductsQueryKey } from '../../helpers/query.js';
4
5
  import { useIsSampleProduct, useIsStorefrontProduct } from '../shop.js';
5
6
  import { useFetchHandle } from '../useFetchHandle.js';
@@ -18,6 +19,33 @@ const useProductsQuery = (ids, options, params)=>{
18
19
  return getProducts(params?.fetcher || fetcher, arg);
19
20
  }, options);
20
21
  };
22
+ const getKey = (variable)=>{
23
+ return (pageIndex, previousPageData)=>{
24
+ if (!variable || previousPageData && !previousPageData.products?.pageInfo?.hasNextPage) {
25
+ return null;
26
+ }
27
+ if (pageIndex === 0) {
28
+ return [
29
+ 'query/products',
30
+ variable
31
+ ];
32
+ }
33
+ return [
34
+ 'query/products',
35
+ {
36
+ ...variable,
37
+ after: previousPageData.products?.pageInfo?.endCursor
38
+ }
39
+ ];
40
+ };
41
+ };
42
+ const useListProductQuery = (variable, options)=>{
43
+ const fetcher = useFetchHandle();
44
+ const data = useSWRInfinite(getKey(variable), async ([, arg])=>{
45
+ return getListProductByVariables(fetcher, arg);
46
+ }, options);
47
+ return data;
48
+ };
21
49
  const useProductsQueryAll = (variable, options)=>{
22
50
  const fetcher = useFetchHandle();
23
51
  return useSWR(variable ? [
@@ -28,4 +56,4 @@ const useProductsQueryAll = (variable, options)=>{
28
56
  }, options);
29
57
  };
30
58
 
31
- export { useProductsQuery, useProductsQueryAll };
59
+ export { useListProductQuery, useProductsQuery, useProductsQueryAll };
@@ -5,10 +5,13 @@ import 'zustand';
5
5
  import 'swr';
6
6
  import '@gem-sdk/adapter-shopify';
7
7
  import 'swr/mutation';
8
+ import 'swr/infinite';
8
9
  import 'vanilla-lazyload';
9
10
  import './useCartUI.js';
10
11
  import 'react-transition-group';
11
12
  import '@gem-sdk/core';
13
+ import 'classnames';
14
+ import 'dayjs';
12
15
  import '../helpers/convert.js';
13
16
 
14
17
  const useAnimations = ()=>{
@@ -3,69 +3,69 @@ import { useMoneyFormat } from './shop.js';
3
3
  const shopifyPriceRounding = (amount, precision)=>{
4
4
  return parseFloat(`${amount}`).toFixed(Number(precision) + 1).slice(0, -1);
5
5
  };
6
+ const formatMoney = function(cents, format) {
7
+ let value = '';
8
+ const placeholderRegex = /\{\{\s*(\w+)\s*\}\}/;
9
+ const formatString = format || '${{amount}}';
10
+ /**
11
+ * check default
12
+ * @param opt opt
13
+ * @param def def
14
+ * @returns any
15
+ */ function defaultOption(opt, def) {
16
+ return typeof opt == 'undefined' ? def : opt;
17
+ }
18
+ /**
19
+ * formatWithDelimiters
20
+ * @param number number
21
+ * @param precision precision
22
+ * @param thousands thousands
23
+ * @param decimal decimal
24
+ * @returns any
25
+ */ // eslint-disable-next-line max-params
26
+ function formatWithDelimiters(number, precision, thousands, decimal) {
27
+ precision = defaultOption(precision, 2);
28
+ thousands = defaultOption(thousands, ',');
29
+ decimal = defaultOption(decimal, '.');
30
+ if (isNaN(number) || number == null) {
31
+ return 0;
32
+ }
33
+ // 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
34
+ number = shopifyPriceRounding(number, Number(precision));
35
+ const parts = number.split('.'), dollars = parts[0]?.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + thousands), cents = parts[1] ? decimal + parts[1] : '';
36
+ return dollars + cents;
37
+ }
38
+ switch(formatString.match(placeholderRegex)[1]){
39
+ case 'amount':
40
+ value = formatWithDelimiters(cents, 2);
41
+ break;
42
+ case 'amount_no_decimals':
43
+ value = formatWithDelimiters(cents, 0);
44
+ break;
45
+ case 'amount_with_comma_separator':
46
+ value = formatWithDelimiters(cents, 2, '.', ',');
47
+ break;
48
+ case 'amount_no_decimals_with_comma_separator':
49
+ value = formatWithDelimiters(cents, 0, '.', ',');
50
+ break;
51
+ case 'amount_with_apostrophe_separator':
52
+ value = formatWithDelimiters(cents, 2, "'", '.');
53
+ break;
54
+ case 'amount_no_decimals_with_space_separator':
55
+ value = formatWithDelimiters(cents, 0, ' ');
56
+ break;
57
+ case 'amount_with_space_separator':
58
+ value = formatWithDelimiters(cents, 2, ' ', ',');
59
+ break;
60
+ case 'amount_with_period_and_space_separator':
61
+ value = formatWithDelimiters(cents, 2, ' ', '.');
62
+ break;
63
+ }
64
+ return formatString.replace(placeholderRegex, value);
65
+ };
6
66
  const useFormatMoney = (amount, withCurrency)=>{
7
67
  const { moneyFormat, moneyWithCurrencyFormat } = useMoneyFormat();
8
- const formatMoney = function(cents, format) {
9
- let value = '';
10
- const placeholderRegex = /\{\{\s*(\w+)\s*\}\}/;
11
- const formatString = format || '${{amount}}';
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 = shopifyPriceRounding(number, Number(precision));
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
- case 'amount_with_apostrophe_separator':
54
- value = formatWithDelimiters(cents, 2, "'", '.');
55
- break;
56
- case 'amount_no_decimals_with_space_separator':
57
- value = formatWithDelimiters(cents, 0, ' ');
58
- break;
59
- case 'amount_with_space_separator':
60
- value = formatWithDelimiters(cents, 2, ' ', ',');
61
- break;
62
- case 'amount_with_period_and_space_separator':
63
- value = formatWithDelimiters(cents, 2, ' ', '.');
64
- break;
65
- }
66
- return formatString.replace(placeholderRegex, value);
67
- };
68
68
  return withCurrency ? formatMoney(`${amount}`, moneyWithCurrencyFormat || moneyFormat) : formatMoney(`${amount}`, moneyFormat);
69
69
  };
70
70
 
71
- export { shopifyPriceRounding, useFormatMoney };
71
+ export { formatMoney, shopifyPriceRounding, useFormatMoney };
@@ -9,10 +9,13 @@ import 'react/jsx-runtime';
9
9
  import 'zustand';
10
10
  import '@gem-sdk/adapter-shopify';
11
11
  import 'swr/mutation';
12
+ import 'swr/infinite';
12
13
  import 'vanilla-lazyload';
13
14
  import './useCartUI.js';
14
15
  import 'react-transition-group';
15
16
  import '@gem-sdk/core';
17
+ import 'classnames';
18
+ import 'dayjs';
16
19
  import isBrowser from '../helpers/is-browser.js';
17
20
  import '../helpers/convert.js';
18
21
 
@@ -6,11 +6,14 @@ import 'swr';
6
6
  import { usePageStore } from '../contexts/PageContext.js';
7
7
  import '@gem-sdk/adapter-shopify';
8
8
  import 'swr/mutation';
9
+ import 'swr/infinite';
9
10
  import 'vanilla-lazyload';
10
11
  import './useCartUI.js';
11
12
  import { checkInStock } from '../helpers/variant.js';
12
13
  import 'react-transition-group';
13
14
  import '@gem-sdk/core';
15
+ import 'classnames';
16
+ import 'dayjs';
14
17
  import { flattenConnection } from '../helpers/flatten-connection.js';
15
18
  import '../helpers/convert.js';
16
19
  import { getSelectedVariant } from '../helpers/product.js';
package/dist/esm/index.js CHANGED
@@ -14,6 +14,8 @@ export { ShopProvider, useShopStore } from './contexts/ShopContext.js';
14
14
  export { PageProvider, usePageStore } from './contexts/PageContext.js';
15
15
  export { CollectionProvider, useCollectionStore } from './contexts/CollectionContext.js';
16
16
  export { ModalProvider, useModalStore } from './contexts/ModalContext.js';
17
+ export { ArticleListProvider, useArticleListStore } from './contexts/ArticleListContext.js';
18
+ export { ArticleProvider, useArticleStore } from './contexts/ArticleContext.js';
17
19
  export { PageViewUpDocument } from './graphql/mutations/page-view-up.generated.js';
18
20
  export { CollectionDetailFilterDocument } from './graphql/queries/collection-detail-filter.generated.js';
19
21
  export { CollectionDocument } from './graphql/queries/collection.generated.js';
@@ -50,7 +52,7 @@ import * as gtag from './helpers/tracking/gtag.js';
50
52
  export { gtag };
51
53
  import * as tiktokpixel from './helpers/tracking/tiktokpixel.js';
52
54
  export { tiktokpixel };
53
- export { GRADIENT_BGR_KEY, composeBackgroundCss, getBgImageByDevice, getGradientBgrStyleByDevice, getGradientBgrStyleForButton, getStyleBackgroundByDevice, makeFixedBgAttachment } from './helpers/background.js';
55
+ export { GRADIENT_BGR_KEY, composeBackgroundCss, getBgImageByDevice, getGradientBgrStyleByDevice, getGradientBgrStyleForButton, getStyleBackgroundByDevice, getStyleBgColor, makeFixedBgAttachment } from './helpers/background.js';
54
56
  export { composeTextColorCss, getGlobalColorCSSProp, getGlobalColorClass, getGlobalColorResponsiveClass, getGlobalColorResponsiveStyle, getGlobalColorStateClass, getGlobalColorStateClassDynamicBtn, getGlobalColorStateResponsiveClass, getGlobalColorStateResponsiveClassDynamicBtn, getGlobalColorStateResponsiveStyle, getGlobalColorStateStyle, getGlobalColorStyle, getSingleColorVariable, isColor } from './helpers/colors.js';
55
57
  export { composeAdvanceStyle, composeAdvanceStyleForPostPurchase, filterAttrInStyle, filterCornerInStyle, removeAttrInStyle, removePaddingYInStyle, splitStyle } from './helpers/compose-advance-style.js';
56
58
  export { baseAssetURL, isLocalEnv } from './helpers/convert.js';
@@ -59,13 +61,14 @@ export { composePositionLineHeight, composePostionIconList } from './helpers/ico
59
61
  export { isDefined } from './helpers/is-defined.js';
60
62
  export { composeGridLayout, convertOldLayout, gridToArrayRegex, optionLayoutStyle } from './helpers/layout.js';
61
63
  export { makeAspectRatio, makeGlobalSizeHeightResponsive, makeGlobalSizeWidthResponsive, makeHeight, makeLineClamp, makeStyle, makeStyleKey, makeStyleResponsive, makeStyleResponsiveByScreen, makeStyleResponsiveState, makeStyleState, makeWidth, removeNullUndefined } from './helpers/make-style.js';
64
+ export { convertTextAlignToJustify } from './helpers/align.js';
62
65
  export { checkAvailableVariantInStock, getSelectedVariant, parseSelectedOption } from './helpers/product.js';
63
66
  export { generateCollectionQueryKey, generateProductQueryKey, generateProductsQueryKey } from './helpers/query.js';
64
67
  export { composeCornerCss, composeRadius, composeRadiusResponsive, getCornerCSSFromGlobal, getCustomRadius, getRadiusCSSFromGlobal, getRadiusStyleActiveState } from './helpers/radius.js';
65
68
  export { RenderIf, composeMemo, dataStringify, props, removeUndefinedValuesFromObject, styles, template } from './helpers/render.js';
66
69
  export { composeShadowCss, getStyleShadow, getStyleShadowState, parseValueWithUnit } from './helpers/shadow.js';
67
70
  export { composeSize, composeSizeCss, genSizeClass, getAspectRatioGlobalSize, getGlobalSizeGap, getHeightByShapeGlobalSize, getPaddingGlobalSize, getWidthByShapeGlobalSize, getWidthHeightGlobalSize, makeGlobalSize, makeGlobalSizeIcon, makeStyleWithDefault } from './helpers/size.js';
68
- export { composeFallbackTypographyStyle, composeTypography, composeTypographyAttr, composeTypographyClassName, composeTypographyCss, composeTypographyStyle, composeTypographyV2, composeTypographyV2Css, genTypoClass } from './helpers/typography.js';
71
+ export { composeFallbackTypographyStyle, composeFontFamilyTypographyV2, composeTypography, composeTypographyAttr, composeTypographyClassName, composeTypographyCss, composeTypographyStyle, composeTypographyV2, composeTypographyV2Css, genTypoClass } from './helpers/typography.js';
69
72
  export { useAddToCart } from './hooks/cart/use-add-to-cart.js';
70
73
  export { useCartData } from './hooks/cart/use-cart-data.js';
71
74
  export { useCartDiscountCodesUpdate } from './hooks/cart/use-cart-discount-codes-update.js';
@@ -79,7 +82,7 @@ export { useCollectionsQuery } from './hooks/shop/use-collections-query.js';
79
82
  export { useProductQuery } from './hooks/shop/use-product-query.js';
80
83
  export { useProductsQuery, useProductsQueryAll } from './hooks/shop/use-products-query.js';
81
84
  export { useCurrentDevice } from './hooks/use-current-device.js';
82
- export { shopifyPriceRounding, useFormatMoney } from './hooks/useFormatMoney.js';
85
+ export { formatMoney, shopifyPriceRounding, useFormatMoney } from './hooks/useFormatMoney.js';
83
86
  export { useLazyVideo } from './hooks/use-lazy-video.js';
84
87
  export { default as useCartId } from './hooks/useCartId.js';
85
88
  export { default as useCartLine } from './hooks/useCartLine.js';
@@ -90,6 +93,7 @@ export { default as useIsomorphicLayoutEffect } from './hooks/useIsomorphicLayou
90
93
  export { default as useLoadScript } from './hooks/useLoadScript.js';
91
94
  export { default as useMoney } from './hooks/useMoney.js';
92
95
  export { usePrevious } from './hooks/usePrevious.js';
96
+ export { useArticlesQuery, useBlogsQuery } from './hooks/articles/useArticlesQuery.js';
93
97
  export { useCheckAvailableVariantInStock, useCurrentVariant, useCurrentVariantInStock, useFeaturedImageGlobal, useIsSyncProduct, useProduct, useProductOfferDiscount, useProductProperties, useQuantity, useSelectedOption, useUniqProductID, useVariant, useVariantOutStock, useVariants } from './hooks/useProduct.js';
94
98
  export { useProductList, useProductListProducts, useProductListSettings, useProductListStyles } from './hooks/useProductList.js';
95
99
  export { default as useSuspenseFetch } from './hooks/useSuspenseFetch.js';