@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,85 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var react = require('react');
5
+ var AIIcon = require('./icons/AIIcon.js');
6
+
7
+ function getRandomArbitrary(min, max) {
8
+ const randomNum = Math.random();
9
+ return randomNum * (max - min) + min;
10
+ }
11
+ const AIGenContentLoading = ({ ...props })=>{
12
+ const [isGenerating, setIsGenerating] = react.useState(false);
13
+ const [time, setTime] = react.useState(0);
14
+ const interval = react.useRef(null);
15
+ const onGenerateContentStatus = react.useCallback((e)=>{
16
+ const detail = e.detail;
17
+ if (detail?.generatingUid !== props.uid) {
18
+ return;
19
+ }
20
+ if (detail.status === 'loading') {
21
+ setIsGenerating(true);
22
+ return;
23
+ }
24
+ if (detail.status === 'success') {
25
+ setIsGenerating(false);
26
+ return;
27
+ }
28
+ }, [
29
+ props.uid
30
+ ]);
31
+ react.useEffect(()=>{
32
+ if (isGenerating) {
33
+ handleFakeLoading();
34
+ } else {
35
+ setTime(0);
36
+ }
37
+ return ()=>{
38
+ interval.current && clearInterval(interval.current);
39
+ };
40
+ }, [
41
+ isGenerating
42
+ ]);
43
+ const handleFakeLoading = ()=>{
44
+ setTime(0);
45
+ interval.current = setInterval(()=>{
46
+ setTime((time)=>{
47
+ const randomNum = getRandomArbitrary(0, 6);
48
+ return time >= 580 ? time : time + randomNum;
49
+ });
50
+ }, 50);
51
+ };
52
+ react.useEffect(()=>{
53
+ window.addEventListener('editor:ai-generate-content-status', onGenerateContentStatus);
54
+ return ()=>{
55
+ window.removeEventListener('editor:ai-generate-content-status', onGenerateContentStatus);
56
+ };
57
+ }, [
58
+ onGenerateContentStatus
59
+ ]);
60
+ return isGenerating ? /*#__PURE__*/ jsxRuntime.jsxs("div", {
61
+ className: "gp-absolute gp-top-0 gp-left-0 gp-w-full gp-h-full gp-bg-white gp-bg-opacity-70 gp-flex gp-justify-center gp-items-center gp-z-100 gp-gap-2",
62
+ children: [
63
+ /*#__PURE__*/ jsxRuntime.jsx("div", {
64
+ className: "gp-absolute gp-left-0 gp-top-0 gp-z-2 gp-flex gp-h-full gp-w-full",
65
+ children: /*#__PURE__*/ jsxRuntime.jsxs("div", {
66
+ className: `gp-relative gp-h-[2px] gp-w-full gp-overflow-hidden gp-rounded-md`,
67
+ children: [
68
+ /*#__PURE__*/ jsxRuntime.jsx("div", {
69
+ className: "gp-absolute gp-h-full gp-w-full gp-rounded-md gp-bg-[#F4F4F4]"
70
+ }),
71
+ /*#__PURE__*/ jsxRuntime.jsx("div", {
72
+ className: "gps-image-to-layout-progress-bar gp-absolute gp-h-full gp-rounded-md gp-transition-all",
73
+ style: {
74
+ width: `${time / 600 * 100}%`
75
+ }
76
+ })
77
+ ]
78
+ })
79
+ }),
80
+ /*#__PURE__*/ jsxRuntime.jsx(AIIcon.AIIcon, {})
81
+ ]
82
+ }) : null;
83
+ };
84
+
85
+ exports.AIGenContentLoading = AIGenContentLoading;
@@ -0,0 +1,219 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var react = require('react');
5
+ var SearchIcon = require('../icons/SearchIcon.js');
6
+ var useProductsQuery = require('../../../hooks/shop/use-products-query.js');
7
+ var classNames = require('classnames');
8
+ require('zustand');
9
+ require('swr');
10
+ require('@gem-sdk/adapter-shopify');
11
+ require('swr/mutation');
12
+ var useProductQuery = require('../../../hooks/shop/use-product-query.js');
13
+ require('vanilla-lazyload');
14
+ require('../../../hooks/useCartUI.js');
15
+ require('react-transition-group');
16
+ require('@gem-sdk/core');
17
+ require('dayjs');
18
+ require('../../../helpers/convert.js');
19
+
20
+ const PickProduct = (props)=>{
21
+ const LIMIT_PRODUCTS = 8;
22
+ const [productVariables, setProductVariables] = react.useState(!props.productId ? {
23
+ first: LIMIT_PRODUCTS
24
+ } : undefined);
25
+ const { data: productList, isLoading: isLoadingGetProducts, isValidating: isValidatingGetProducts, size: productsSize, setSize: setProductsSize } = useProductsQuery.useListProductQuery(productVariables, {
26
+ revalidateFirstPage: false
27
+ });
28
+ const { data: sectionProduct } = useProductQuery.useProductQuery(props.productId);
29
+ const [activeProduct, setActiveProduct] = react.useState();
30
+ const [isShowChooseProduct, setIsShowChooseProduct] = react.useState(false);
31
+ const debounceSearch = react.useRef(null);
32
+ const debounceScroll = react.useRef(null);
33
+ const toggleChooseProduct = ()=>{
34
+ if (props.productId) return;
35
+ setIsShowChooseProduct(!isShowChooseProduct);
36
+ };
37
+ const chooseProduct = (product)=>{
38
+ setActiveProduct(product);
39
+ setIsShowChooseProduct(false);
40
+ };
41
+ const searchProduct = (e)=>{
42
+ debounceSearch.current && clearTimeout(debounceSearch.current);
43
+ debounceSearch.current = setTimeout(()=>{
44
+ const searchValue = e.target.value ?? '';
45
+ if (searchValue) {
46
+ setProductVariables({
47
+ first: LIMIT_PRODUCTS,
48
+ where: {
49
+ titleContainsFold: searchValue
50
+ }
51
+ });
52
+ return;
53
+ }
54
+ setProductVariables({
55
+ first: LIMIT_PRODUCTS
56
+ });
57
+ }, 200);
58
+ };
59
+ const handleOpenProductElementSettings = ()=>{
60
+ props.openProductSetting();
61
+ };
62
+ const handleLoadMore = (e)=>{
63
+ const target = e.target;
64
+ if (target.scrollHeight - target.scrollTop === target.clientHeight) {
65
+ debounceScroll.current && clearTimeout(debounceScroll.current);
66
+ debounceScroll.current = setTimeout(()=>{
67
+ setProductsSize(productsSize + 1);
68
+ }, 50);
69
+ }
70
+ };
71
+ const products = react.useMemo(()=>{
72
+ return productList?.reduce((acc, curr)=>{
73
+ return [
74
+ ...acc,
75
+ ...curr.products?.edges ?? []
76
+ ];
77
+ }, []) ?? [];
78
+ }, [
79
+ productList
80
+ ]);
81
+ react.useEffect(()=>{
82
+ if (products.length && !activeProduct && !props.productId) {
83
+ const firstProduct = products[0]?.node;
84
+ if (!firstProduct) return;
85
+ setActiveProduct({
86
+ id: firstProduct?.id,
87
+ name: firstProduct?.title,
88
+ image: firstProduct.featuredImage?.src
89
+ });
90
+ }
91
+ }, [
92
+ products,
93
+ activeProduct,
94
+ props.productId
95
+ ]);
96
+ react.useEffect(()=>{
97
+ if (activeProduct && activeProduct.name) {
98
+ props.changeProductName(activeProduct.name);
99
+ }
100
+ }, [
101
+ activeProduct,
102
+ props
103
+ ]);
104
+ react.useEffect(()=>{
105
+ if (sectionProduct) {
106
+ setActiveProduct({
107
+ id: sectionProduct.id,
108
+ name: sectionProduct.title,
109
+ image: sectionProduct.featuredImage?.src
110
+ });
111
+ }
112
+ }, [
113
+ sectionProduct
114
+ ]);
115
+ return /*#__PURE__*/ jsxRuntime.jsxs("div", {
116
+ className: "gp-flex gp-flex-col gp-gap-2",
117
+ children: [
118
+ /*#__PURE__*/ jsxRuntime.jsx("p", {
119
+ className: "gp-py-2 gp-text-xs",
120
+ children: "Product"
121
+ }),
122
+ /*#__PURE__*/ jsxRuntime.jsxs("div", {
123
+ className: "gp-relative",
124
+ children: [
125
+ !isLoadingGetProducts || activeProduct ? /*#__PURE__*/ jsxRuntime.jsxs("button", {
126
+ className: classNames({
127
+ 'gp-cursor-default': props.productId
128
+ }, 'gp-flex gp-gap-2 gp-items-center gp-w-full gp-p-2 gp-rounded-lg gp-bg-[#333333] gp-text-xs'),
129
+ onClick: toggleChooseProduct,
130
+ children: [
131
+ /*#__PURE__*/ jsxRuntime.jsx("img", {
132
+ className: "gp-rounded-lg gp-w-10 gp-h-10",
133
+ src: activeProduct?.image,
134
+ alt: "product_image"
135
+ }),
136
+ /*#__PURE__*/ jsxRuntime.jsx("span", {
137
+ className: "gp-truncate gp-max-w-[210px]",
138
+ children: activeProduct?.name
139
+ })
140
+ ]
141
+ }) : /*#__PURE__*/ jsxRuntime.jsx("div", {
142
+ children: /*#__PURE__*/ jsxRuntime.jsx("span", {
143
+ className: "gp-text-xs",
144
+ children: "Getting products..."
145
+ })
146
+ }),
147
+ props.productId && /*#__PURE__*/ jsxRuntime.jsx("div", {
148
+ className: "gp-mt-2 gp-text-xs",
149
+ children: /*#__PURE__*/ jsxRuntime.jsxs("p", {
150
+ children: [
151
+ "You can manage it in",
152
+ ' ',
153
+ /*#__PURE__*/ jsxRuntime.jsx("button", {
154
+ className: "gp-text-[#8AA4FF] gp-cursor-pointer hover:gp-underline",
155
+ onClick: handleOpenProductElementSettings,
156
+ children: "Product element"
157
+ })
158
+ ]
159
+ })
160
+ }),
161
+ isShowChooseProduct && /*#__PURE__*/ jsxRuntime.jsxs("div", {
162
+ className: "gp-absolute gp-w-full gp-top-16 gp-left-0 gp-rounded-lg gp-bg-[#333333] gp-p-2 gp-flex gp-flex-col gp-gap-2 gp-z-10",
163
+ children: [
164
+ /*#__PURE__*/ jsxRuntime.jsxs("div", {
165
+ className: "gp-flex gp-items-center gp-gap-2 gp-p-2",
166
+ children: [
167
+ /*#__PURE__*/ jsxRuntime.jsx(SearchIcon.SearchIcon, {}),
168
+ /*#__PURE__*/ jsxRuntime.jsx("input", {
169
+ className: "gp-bg-transparent gp-w-full focus-visible:!gp-outline-none gp-text-xs",
170
+ placeholder: "Search product...",
171
+ onChange: searchProduct
172
+ })
173
+ ]
174
+ }),
175
+ /*#__PURE__*/ jsxRuntime.jsxs("div", {
176
+ className: "gp-max-h-[168px] gp-overflow-auto scrollbar:gp-w-1 scrollbar-thumb:gp-bg-[#999] scrollbar-thumb:gp-rounded-xl",
177
+ onScroll: handleLoadMore,
178
+ children: [
179
+ products?.map((item)=>{
180
+ return /*#__PURE__*/ jsxRuntime.jsxs("button", {
181
+ className: "gp-flex gp-p-2 hover:gp-bg-[#3B3B3B] gp-rounded-lg gp-cursor-pointer gp-gap-2 gp-items-center",
182
+ onClick: ()=>{
183
+ chooseProduct({
184
+ id: item.node?.id,
185
+ name: item.node?.title,
186
+ image: item.node?.featuredImage?.src
187
+ });
188
+ },
189
+ children: [
190
+ /*#__PURE__*/ jsxRuntime.jsx("img", {
191
+ className: "gp-rounded-lg gp-w-10 gp-h-10",
192
+ src: item.node?.featuredImage?.src,
193
+ alt: "product_image"
194
+ }),
195
+ /*#__PURE__*/ jsxRuntime.jsx("span", {
196
+ className: "gp-truncate gp-max-w-[210px] gp-text-xs",
197
+ children: item.node?.title
198
+ })
199
+ ]
200
+ }, item.node?.id);
201
+ }),
202
+ isLoadingGetProducts || isValidatingGetProducts && /*#__PURE__*/ jsxRuntime.jsx("div", {
203
+ className: "gp-p-2",
204
+ children: /*#__PURE__*/ jsxRuntime.jsx("span", {
205
+ className: "gp-text-xs",
206
+ children: "Getting products..."
207
+ })
208
+ })
209
+ ]
210
+ })
211
+ ]
212
+ })
213
+ ]
214
+ })
215
+ ]
216
+ });
217
+ };
218
+
219
+ exports.PickProduct = PickProduct;
@@ -0,0 +1,77 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var react = require('react');
5
+ var DropdownIcon = require('../icons/DropdownIcon.js');
6
+ var classNames = require('classnames');
7
+
8
+ const ToneAndVoice = (props)=>{
9
+ const listToneAndVoice = [
10
+ 'Persuasive',
11
+ 'Friendly',
12
+ 'Professional',
13
+ 'Casual'
14
+ ];
15
+ const [tone, setTone] = react.useState(listToneAndVoice[0]);
16
+ const [isShow, setIsShow] = react.useState(false);
17
+ const toggle = ()=>{
18
+ setIsShow(!isShow);
19
+ };
20
+ const setValue = (value)=>{
21
+ setTone(value);
22
+ setIsShow(false);
23
+ };
24
+ react.useEffect(()=>{
25
+ tone && props.changeToneAndVoice(tone);
26
+ }, [
27
+ tone,
28
+ props
29
+ ]);
30
+ return /*#__PURE__*/ jsxRuntime.jsx("div", {
31
+ children: /*#__PURE__*/ jsxRuntime.jsxs("div", {
32
+ className: "gp-flex gp-flex-col gp-gap-2",
33
+ children: [
34
+ /*#__PURE__*/ jsxRuntime.jsx("p", {
35
+ className: "gp-py-2 gp-text-xs",
36
+ children: "Tone and Voice"
37
+ }),
38
+ /*#__PURE__*/ jsxRuntime.jsxs("div", {
39
+ className: "gp-relative",
40
+ children: [
41
+ /*#__PURE__*/ jsxRuntime.jsxs("button", {
42
+ className: "gp-flex gp-justify-between gp-items-center gp-w-full gp-p-2 gp-rounded-lg gp-bg-[#333333] gp-text-xs",
43
+ onClick: toggle,
44
+ children: [
45
+ tone,
46
+ /*#__PURE__*/ jsxRuntime.jsx(DropdownIcon.DropdownIcon, {})
47
+ ]
48
+ }),
49
+ isShow ? /*#__PURE__*/ jsxRuntime.jsx("div", {
50
+ className: "gp-absolute gp-w-full gp-top-10 gp-left-0 gp-rounded-lg gp-bg-[#333333] gp-p-2 gp-flex gp-flex-col gp-gap-2 gp-z-10",
51
+ children: listToneAndVoice.map((item)=>{
52
+ return /*#__PURE__*/ jsxRuntime.jsxs("button", {
53
+ className: "gp-flex gp-p-2 hover:gp-bg-[#3B3B3B] gp-rounded-lg gp-cursor-pointer gp-gap-3 gp-items-center",
54
+ onClick: ()=>setValue(item),
55
+ children: [
56
+ /*#__PURE__*/ jsxRuntime.jsx("div", {
57
+ className: classNames({
58
+ 'gp-invisible': tone !== item
59
+ }),
60
+ children: /*#__PURE__*/ jsxRuntime.jsx(DropdownIcon.TickIcon, {})
61
+ }),
62
+ /*#__PURE__*/ jsxRuntime.jsx("span", {
63
+ className: "gp-text-xs",
64
+ children: item
65
+ })
66
+ ]
67
+ }, item);
68
+ })
69
+ }) : null
70
+ ]
71
+ })
72
+ ]
73
+ })
74
+ });
75
+ };
76
+
77
+ exports.ToneAndVoice = ToneAndVoice;
@@ -0,0 +1,47 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+
5
+ const useCheckingProductInside = (genTool, options)=>{
6
+ const [productElement, setProductElement] = react.useState({});
7
+ const checkSectionHasProduct = react.useCallback(()=>{
8
+ if (!genTool.current) {
9
+ setProductElement({
10
+ productId: '',
11
+ uid: ''
12
+ });
13
+ return;
14
+ }
15
+ const sectionEl = genTool.current?.closest('[data-component-tag="Section"]');
16
+ const productEl = sectionEl?.querySelector('[data-product-id]:not([data-product-id=""])');
17
+ const productId = productEl?.getAttribute('data-product-id');
18
+ const productElUid = productEl?.getAttribute('data-uid');
19
+ const productListOutSideProduct = productEl?.closest('[data-component-tag="ProductList"]');
20
+ if (productListOutSideProduct || !productId) {
21
+ setProductElement({
22
+ productId: '',
23
+ uid: ''
24
+ });
25
+ return;
26
+ }
27
+ setProductElement({
28
+ productId: productId ? 'gid://shopify/Product/' + productId : '',
29
+ uid: productElUid ?? ''
30
+ });
31
+ }, [
32
+ genTool
33
+ ]);
34
+ react.useEffect(()=>{
35
+ if (!options?.isEnabled) return;
36
+ checkSectionHasProduct();
37
+ }, [
38
+ options?.isEnabled,
39
+ checkSectionHasProduct
40
+ ]);
41
+ return {
42
+ productElement,
43
+ checkSectionHasProduct
44
+ };
45
+ };
46
+
47
+ exports.useCheckingProductInside = useCheckingProductInside;
@@ -0,0 +1,110 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+
5
+ const useFlipPopup = (isShowPopup, dom)=>{
6
+ const { genTool, genPopup, genPopupHeader, genButtonWrapper } = dom;
7
+ const [popupPositionY, setPopupPositionY] = react.useState('top');
8
+ const [popupPositionX, setPopupPositionX] = react.useState('left');
9
+ const [bodyMaxHeight, setBodyMaxHeight] = react.useState(null);
10
+ const [isValidating, setIsValidating] = react.useState(true);
11
+ const calculateMaxHeight = react.useCallback((currentPopupPositionY)=>{
12
+ const parentOverflow = genTool.current?.closest("[class~='gp-overflow-hidden']");
13
+ if (!parentOverflow || !genTool.current) {
14
+ return {
15
+ positionY: currentPopupPositionY,
16
+ maxHeight: null
17
+ };
18
+ }
19
+ const parentOverflowPos = parentOverflow.getBoundingClientRect();
20
+ const genToolPos = genTool.current.getBoundingClientRect();
21
+ const genToolHeaderHeight = genPopupHeader.current?.getBoundingClientRect().height || 0;
22
+ const genButtonHeight = genButtonWrapper.current?.getBoundingClientRect().height || 0;
23
+ const DISTANCE = 8;
24
+ const maxHeightForPositionTop = Math.max(parentOverflowPos.bottom - genToolPos.bottom - genToolHeaderHeight - genButtonHeight - DISTANCE, 0);
25
+ const maxHeightForPositionBottom = Math.max(genToolPos.top - parentOverflowPos.top - genToolHeaderHeight - genButtonHeight - DISTANCE, 0);
26
+ if (maxHeightForPositionBottom > maxHeightForPositionTop) {
27
+ return {
28
+ positionY: 'bottom',
29
+ maxHeight: maxHeightForPositionBottom
30
+ };
31
+ }
32
+ return {
33
+ positionY: 'top',
34
+ maxHeight: maxHeightForPositionTop
35
+ };
36
+ }, [
37
+ genTool,
38
+ genPopupHeader,
39
+ genButtonWrapper
40
+ ]);
41
+ const handleChangePopupPositionY = react.useCallback((posY)=>{
42
+ const { positionY: calcPosY, maxHeight } = calculateMaxHeight(posY);
43
+ setPopupPositionY(calcPosY);
44
+ setBodyMaxHeight(maxHeight);
45
+ }, [
46
+ calculateMaxHeight
47
+ ]);
48
+ const calculatePopupPositionY = react.useCallback(()=>{
49
+ if (!genTool.current || !genPopup.current) return;
50
+ const viewHeight = window.innerHeight;
51
+ const scrollHeight = document.documentElement.scrollHeight;
52
+ const scrollTop = document.documentElement.scrollTop;
53
+ const toolPos = genTool.current?.getBoundingClientRect();
54
+ const genPopupHeight = genPopup.current?.getBoundingClientRect().height;
55
+ const MIN_DISTANCE = 50;
56
+ if (scrollTop + toolPos.top + genPopupHeight >= scrollHeight - MIN_DISTANCE) {
57
+ handleChangePopupPositionY('bottom');
58
+ return;
59
+ }
60
+ if (toolPos.bottom + genPopupHeight > viewHeight) {
61
+ if (toolPos.top - genPopupHeight < 0) {
62
+ handleChangePopupPositionY('top');
63
+ return;
64
+ }
65
+ handleChangePopupPositionY('bottom');
66
+ return;
67
+ }
68
+ handleChangePopupPositionY('top');
69
+ }, [
70
+ genPopup,
71
+ genTool,
72
+ handleChangePopupPositionY
73
+ ]);
74
+ const calculatePopupPositionX = react.useCallback(()=>{
75
+ if (!genTool.current || !genPopup.current) return;
76
+ const viewWidth = window.innerWidth;
77
+ const toolPos = genTool.current?.getBoundingClientRect();
78
+ const genPopupWidth = genPopup.current?.getBoundingClientRect().width;
79
+ if (toolPos.left + genPopupWidth > viewWidth) {
80
+ setPopupPositionX('right');
81
+ return;
82
+ }
83
+ setPopupPositionX('left');
84
+ }, [
85
+ genPopup,
86
+ genTool
87
+ ]);
88
+ react.useEffect(()=>{
89
+ if (!isShowPopup) {
90
+ setIsValidating(true);
91
+ return;
92
+ }
93
+ setIsValidating(true);
94
+ calculatePopupPositionY();
95
+ calculatePopupPositionX();
96
+ setIsValidating(false);
97
+ }, [
98
+ isShowPopup,
99
+ calculatePopupPositionX,
100
+ calculatePopupPositionY
101
+ ]);
102
+ return {
103
+ isValidating,
104
+ bodyMaxHeight,
105
+ popupPositionY,
106
+ popupPositionX
107
+ };
108
+ };
109
+
110
+ exports.useFlipPopup = useFlipPopup;
@@ -0,0 +1,37 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+
5
+ const useGettingGenerateRequest = ()=>{
6
+ const [prompt, setPrompt] = react.useState('');
7
+ const [productName, setProductName] = react.useState('');
8
+ const [tone, setTone] = react.useState('');
9
+ const changePrompt = (value)=>{
10
+ const limit = 200;
11
+ setPrompt(value.slice(0, limit));
12
+ };
13
+ const changeProductName = (value)=>{
14
+ setProductName(value);
15
+ };
16
+ const changeTone = (value)=>{
17
+ setTone(value);
18
+ };
19
+ const getRequestBody = ()=>{
20
+ return {
21
+ prompt,
22
+ productName,
23
+ tone
24
+ };
25
+ };
26
+ return {
27
+ prompt,
28
+ changePrompt,
29
+ productName,
30
+ changeProductName,
31
+ tone,
32
+ changeTone,
33
+ getRequestBody
34
+ };
35
+ };
36
+
37
+ exports.useGettingGenerateRequest = useGettingGenerateRequest;
@@ -0,0 +1,70 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+
5
+ const useListenEventGenerate = (componentInfo)=>{
6
+ const { uid: componentUid, tag: componentTag } = componentInfo;
7
+ const [isGenerating, setIsGenerating] = react.useState(false);
8
+ const onGenerate = (body)=>{
9
+ const eventCreate = new CustomEvent('editor:toolbar:ai-generate-content', {
10
+ bubbles: true,
11
+ detail: {
12
+ componentUid: componentUid,
13
+ componentTag: componentTag,
14
+ genRequest: body
15
+ }
16
+ });
17
+ window.dispatchEvent(eventCreate);
18
+ setIsGenerating(true);
19
+ onNotifyStatus('loading');
20
+ };
21
+ const onNotifyStatus = (status)=>{
22
+ const eventNotifyStatus = new CustomEvent('editor:ai-generate-content-status', {
23
+ bubbles: true,
24
+ detail: {
25
+ status: status,
26
+ generatingUid: componentUid
27
+ }
28
+ });
29
+ window.dispatchEvent(eventNotifyStatus);
30
+ };
31
+ const onGenerateContentStatus = react.useCallback((e)=>{
32
+ const detail = e.detail;
33
+ if (detail?.generatingUid === componentUid && detail.status === 'success') {
34
+ setIsGenerating(false);
35
+ }
36
+ }, [
37
+ componentUid
38
+ ]);
39
+ const onOpenProductElementSettings = (productElementUid)=>{
40
+ const eventCreate = new CustomEvent('editor:toolbar:open-product-element', {
41
+ bubbles: true,
42
+ detail: {
43
+ productElementUid: productElementUid
44
+ }
45
+ });
46
+ window.dispatchEvent(eventCreate);
47
+ };
48
+ const goToPricing = ()=>{
49
+ const eventCreate = new CustomEvent('editor:toolbar:ai-gen-content-go-to-pricing', {
50
+ bubbles: true
51
+ });
52
+ window.dispatchEvent(eventCreate);
53
+ };
54
+ react.useEffect(()=>{
55
+ window.addEventListener('editor:ai-generate-content-status', onGenerateContentStatus);
56
+ return ()=>{
57
+ window.removeEventListener('editor:ai-generate-content-status', onGenerateContentStatus);
58
+ };
59
+ }, [
60
+ onGenerateContentStatus
61
+ ]);
62
+ return {
63
+ isGenerating,
64
+ onGenerate,
65
+ onOpenProductElementSettings,
66
+ goToPricing
67
+ };
68
+ };
69
+
70
+ exports.useListenEventGenerate = useListenEventGenerate;