@gem-sdk/pages 1.51.0-staging.56 → 1.51.0-staging.63

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.
@@ -5,6 +5,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var core = require('@gem-sdk/core');
7
7
  var SwitchView = require('./SwitchView.js');
8
+ var InteractionSelectOnPageHeader = require('./InteractionSelectOnPageHeader.js');
8
9
 
9
10
  const defaultMargin = {
10
11
  desktop: '16px',
@@ -21,8 +22,10 @@ const sizeCheck = {
21
22
  const Header = (props)=>{
22
23
  const { pageType, isOriginTemplate } = props;
23
24
  const layoutSetting = core.useShopStore((s)=>s.layoutSettings);
25
+ const isSelectOnPage = core.usePageStore((s)=>s.interactionData?.isSelectOnPage);
24
26
  const activeHeader = layoutSetting?.showHeader || isOriginTemplate;
25
27
  const headerColor = activeHeader ? HEADER_ON_COLOR : HEADER_OFF_COLOR;
28
+ console.log('isSelectOnPage', isSelectOnPage);
26
29
  return /*#__PURE__*/ jsxRuntime.jsxs(jsxRuntime.Fragment, {
27
30
  children: [
28
31
  /*#__PURE__*/ jsxRuntime.jsx(SwitchView.default, {}),
@@ -177,7 +180,8 @@ const Header = (props)=>{
177
180
  })
178
181
  ]
179
182
  })
180
- })
183
+ }),
184
+ isSelectOnPage && /*#__PURE__*/ jsxRuntime.jsx(InteractionSelectOnPageHeader.default, {})
181
185
  ]
182
186
  });
183
187
  };
@@ -0,0 +1,71 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+ var core = require('@gem-sdk/core');
7
+
8
+ const InteractionSelectOnPageHeader = ()=>{
9
+ const selectType = core.usePageStore((s)=>s.interactionData?.selectType);
10
+ const setInteractionSelectType = core.usePageStore((s)=>s.setInteractionSelectType);
11
+ const { closeSelectOnPage } = core.useInteraction();
12
+ return /*#__PURE__*/ jsxRuntime.jsxs(jsxRuntime.Fragment, {
13
+ children: [
14
+ /*#__PURE__*/ jsxRuntime.jsxs("header", {
15
+ className: "gp-flex gp-justify-between gp-items-center gp-h-10 gp-fixed gp-top-0 gp-left-0 gp-w-full gp-z-100 gp-bg-black gp-text-white",
16
+ children: [
17
+ /*#__PURE__*/ jsxRuntime.jsx("div", {
18
+ className: "gp-ml-4 gp-text-xs gp-mt-1",
19
+ children: "Select mode enabled"
20
+ }),
21
+ /*#__PURE__*/ jsxRuntime.jsxs("section", {
22
+ className: "gp-flex gp-bg-[#3C67FF]/[0.15] gp-items-center gp-h-full gp-rounded-b-lg gp-pt-1 gp-gap-1",
23
+ children: [
24
+ /*#__PURE__*/ jsxRuntime.jsx("button", {
25
+ "data-interaction-mode": "element",
26
+ onClick: ()=>setInteractionSelectType('element'),
27
+ className: `gp-h-full gp-w-[444px] gp-items-center gp-justify-center gp-bg-[#333333] gp-text-[12px] gp-leading-5 gp-font-medium gp-flex gp-rounded-t-[8px] ${selectType === 'element' ? 'gp-bg-[#3C67FF] gp-text-[#F9F9F9]' : 'gp-text-[#AAAAAA]'}`,
28
+ style: {
29
+ cursor: "url('https://cdn.shopify.com/s/files/1/0858/3168/0279/files/gempages_502328832959710176-45eb24ff-a9ee-48ac-af8b-eac35e11918d.png?v=1724038301'), auto"
30
+ },
31
+ children: "Choose an element on page"
32
+ }),
33
+ /*#__PURE__*/ jsxRuntime.jsx("button", {
34
+ "data-interaction-mode": "page",
35
+ onClick: ()=>setInteractionSelectType('page'),
36
+ className: `gp-h-full gp-w-[444px] gp-items-center gp-justify-center gp-bg-[#333333] gp-text-[12px] gp-leading-5 gp-font-medium gp-flex gp-rounded-t-[8px] ${selectType === 'page' ? 'gp-bg-[#3C67FF] gp-text-[#F9F9F9]' : 'gp-text-[#AAAAAA]'}`,
37
+ style: {
38
+ cursor: "url('https://cdn.shopify.com/s/files/1/0858/3168/0279/files/gempages_502328832959710176-45eb24ff-a9ee-48ac-af8b-eac35e11918d.png?v=1724038301'), auto"
39
+ },
40
+ children: "Use entire page"
41
+ })
42
+ ]
43
+ }),
44
+ /*#__PURE__*/ jsxRuntime.jsx("button", {
45
+ onClick: closeSelectOnPage,
46
+ className: "gp-h-10 gp-w-10 gp-flex gp-items-center gp-justify-center gp-rounded-bl-lg",
47
+ children: /*#__PURE__*/ jsxRuntime.jsx("svg", {
48
+ width: "12",
49
+ height: "12",
50
+ viewBox: "0 0 12 12",
51
+ fill: "none",
52
+ xmlns: "http://www.w3.org/2000/svg",
53
+ children: /*#__PURE__*/ jsxRuntime.jsx("path", {
54
+ d: "M9.96967 11.0303C10.2626 11.3232 10.7374 11.3232 11.0303 11.0303C11.3232 10.7374 11.3232 10.2626 11.0303 9.96967L7.06066 6L11.0303 2.03033C11.3232 1.73744 11.3232 1.26256 11.0303 0.96967C10.7374 0.676777 10.2626 0.676777 9.96967 0.96967L6 4.93934L2.03033 0.96967C1.73744 0.676777 1.26256 0.676777 0.96967 0.96967C0.676777 1.26256 0.676777 1.73744 0.96967 2.03033L4.93934 6L0.96967 9.96967C0.676777 10.2626 0.676777 10.7374 0.96967 11.0303C1.26256 11.3232 1.73744 11.3232 2.03033 11.0303L6 7.06066L9.96967 11.0303Z",
55
+ fill: "#F9F9F9"
56
+ })
57
+ })
58
+ })
59
+ ]
60
+ }),
61
+ /*#__PURE__*/ jsxRuntime.jsx("div", {
62
+ className: `gp-w-full gp-fixed gp-top-0 gp-left-0 gp-border-[#3C67FF] gp-border-[4px] gp-mt-[40px] ${selectType === 'page' ? 'gp-z-90 gp-bg-[#3c67ff]/[0.25]' : ''}`,
63
+ style: {
64
+ height: 'calc(100% - 40px)'
65
+ }
66
+ })
67
+ ]
68
+ });
69
+ };
70
+
71
+ exports.default = InteractionSelectOnPageHeader;
@@ -178,6 +178,7 @@ const Devices = ()=>{
178
178
  ]
179
179
  })
180
180
  });
181
+ return null;
181
182
  };
182
183
 
183
184
  exports.default = Devices;
@@ -579,12 +579,14 @@ const Toolbar = ()=>{
579
579
  if (await isElementInsideArticle()) {
580
580
  articleId = currentComponentActive.current?.articleId || '';
581
581
  }
582
+ console.log('$parent$parent', $parent);
582
583
  const event = new CustomEvent('editor:toolbar:force-active-component', {
583
584
  bubbles: true,
584
585
  detail: {
585
586
  componentUid: uid,
586
587
  productId,
587
- articleId
588
+ articleId,
589
+ elementTag: $parent.getAttribute('data-component-tag') || ''
588
590
  }
589
591
  });
590
592
  outHover($parent);
@@ -36,6 +36,9 @@ const Toolbox = ()=>{
36
36
  const changeCreateThemeSectionCount = core.useShopStore((s)=>s.changeCreateThemeSectionCount);
37
37
  const changeShopPlan = core.useShopStore((s)=>s.changeShopPlan);
38
38
  const clearModal = core.useModalStore((s)=>s.clearModal);
39
+ const setInteractionIsSelectOnPage = core.usePageStore((s)=>s.setInteractionIsSelectOnPage);
40
+ const setInteractionItem = core.usePageStore((s)=>s.setInteractionItem);
41
+ const setInteractionSelectType = core.usePageStore((s)=>s.setInteractionSelectType);
39
42
  const fonts = react.useMemo(()=>genFonts.getFontsFromDataBuilder(state), [
40
43
  state
41
44
  ]);
@@ -329,6 +332,21 @@ const Toolbox = ()=>{
329
332
  }, [
330
333
  setSalePageProductId
331
334
  ]);
335
+ const onUpdateInteractionIsSelectOnPage = react.useCallback((e)=>{
336
+ const isSelectOnPage = e.detail.value;
337
+ const mode = e.detail.mode;
338
+ setInteractionIsSelectOnPage(isSelectOnPage);
339
+ setInteractionSelectType(mode);
340
+ }, [
341
+ setInteractionIsSelectOnPage,
342
+ setInteractionSelectType
343
+ ]);
344
+ const onUpdateInteractionItem = react.useCallback((e)=>{
345
+ const interactionItem = e.detail;
346
+ setInteractionItem(interactionItem);
347
+ }, [
348
+ setInteractionItem
349
+ ]);
332
350
  react.useEffect(()=>{
333
351
  if (fonts) {
334
352
  setFontsToHead('google-font-element', fonts);
@@ -356,6 +374,8 @@ const Toolbox = ()=>{
356
374
  window.addEventListener('update-item-attribute', onUpdateItemAttribute);
357
375
  window.addEventListener('set-product-offer', onUpdateProductOffers);
358
376
  window.addEventListener('update-sale-page-product-id', onUpdateSalePageProductId);
377
+ window.addEventListener('update-interaction-is-select-on-page', onUpdateInteractionIsSelectOnPage);
378
+ window.addEventListener('update-interaction-item', onUpdateInteractionItem);
359
379
  return ()=>{
360
380
  window.removeEventListener('update-shop-info', onChangeShopInfo);
361
381
  window.removeEventListener('revalidate-query', onRevalidateQuery);
@@ -375,6 +395,8 @@ const Toolbox = ()=>{
375
395
  window.removeEventListener('update-item-attribute', onUpdateItemAttribute);
376
396
  window.removeEventListener('set-product-offer', onUpdateProductOffers);
377
397
  window.removeEventListener('update-sale-page-product-id', onUpdateSalePageProductId);
398
+ window.removeEventListener('update-interaction-is-select-on-page', onUpdateInteractionIsSelectOnPage);
399
+ window.removeEventListener('update-interaction-item', onUpdateInteractionItem);
378
400
  };
379
401
  }, [
380
402
  onAddEntity,
@@ -395,7 +417,9 @@ const Toolbox = ()=>{
395
417
  onUpdateItemName,
396
418
  onUpdateItemAttribute,
397
419
  onUpdateProductOffers,
398
- onUpdateSalePageProductId
420
+ onUpdateSalePageProductId,
421
+ onUpdateInteractionItem,
422
+ onUpdateInteractionIsSelectOnPage
399
423
  ]);
400
424
  return /*#__PURE__*/ jsxRuntime.jsx("div", {
401
425
  className: "toolbox"
@@ -119,6 +119,40 @@ const fetchThemePageDataByTemplateID = async (data, fetcher)=>{
119
119
  productOffers: productOffers
120
120
  };
121
121
  };
122
+ const fetchShopLibraryPageDataByID = async (data, fetcher)=>{
123
+ const variables = {
124
+ shopLibraryPageId: data.shopLibraryPageId
125
+ };
126
+ const [theme, storeProperty, saleFunnelDiscounts] = await Promise.allSettled([
127
+ fetcher([
128
+ core.ShopLibraryPageDocument,
129
+ variables
130
+ ]),
131
+ fetcher([
132
+ core.StorePropertyDocument
133
+ ]),
134
+ fetcher([
135
+ core.SaleFunnelDiscountsDocument,
136
+ {
137
+ where: {
138
+ saleFunnelOfferID: data.currentOfferID
139
+ }
140
+ }
141
+ ])
142
+ ]);
143
+ if (theme.status === 'rejected') {
144
+ throw new Error(theme.reason?.[0]);
145
+ }
146
+ if (saleFunnelDiscounts.status === 'rejected') {
147
+ throw new Error(saleFunnelDiscounts.reason?.[0]);
148
+ }
149
+ return {
150
+ dataBuilder: theme.value.shopLibraryPage,
151
+ pageStyle: undefined,
152
+ storeProperty,
153
+ productOffers: saleFunnelDiscounts.value.saleFunnelDiscounts?.edges?.filter((item)=>item?.node?.objectType === 'PRODUCT' && item?.node?.type === 'ORDER_VALUE') || []
154
+ };
155
+ };
122
156
  const fetchLibraryTemplateDataByID = async (data, fetcher)=>{
123
157
  const variables = {
124
158
  libraryTemplateId: data.libraryTemplateId
@@ -154,7 +188,7 @@ const fetchLibraryTemplateDataByID = async (data, fetcher)=>{
154
188
  };
155
189
  };
156
190
  const getRelevantPageData = async (data)=>{
157
- const { id, currentOfferID, fetcher, isLibraryTemplate, librarySaleFunnelID } = data;
191
+ const { id, currentOfferID, fetcher, isLibraryTemplate, librarySaleFunnelID, isShopLibraryPage } = data;
158
192
  if (librarySaleFunnelID) {
159
193
  return await fetchThemePageDataByTemplateID({
160
194
  libraryTemplateId: id,
@@ -162,6 +196,12 @@ const getRelevantPageData = async (data)=>{
162
196
  librarySaleFunnelID
163
197
  }, fetcher);
164
198
  }
199
+ if (isShopLibraryPage && currentOfferID) {
200
+ return await fetchShopLibraryPageDataByID({
201
+ shopLibraryPageId: id,
202
+ currentOfferID
203
+ }, fetcher);
204
+ }
165
205
  if (isLibraryTemplate && currentOfferID) {
166
206
  return await fetchLibraryTemplateDataByID({
167
207
  libraryTemplateId: id,
@@ -178,19 +218,21 @@ const getRelevantPageData = async (data)=>{
178
218
  themePageId: id
179
219
  }, fetcher);
180
220
  };
181
- const getPostPurchasePropsPreview = (fetcher, librarySaleFunnelID, storeFrontFetcher)=>async (id, currentOfferID, isLibraryTemplate)=>{
221
+ const getPostPurchasePropsPreview = (fetcher, librarySaleFunnelID, storeFrontFetcher)=>async (data)=>{
182
222
  try {
223
+ const { id, currentOfferID, isLibraryTemplate, isShopLibraryPage } = data;
183
224
  const { dataBuilder, storeProperty, productOffers, pageStyle } = await getRelevantPageData({
184
225
  id,
185
226
  currentOfferID,
186
227
  fetcher,
187
228
  isLibraryTemplate,
229
+ isShopLibraryPage,
188
230
  librarySaleFunnelID
189
231
  });
190
232
  if (!dataBuilder) {
191
233
  throw new Error(`No data builder found for slug: /preview/${id}`);
192
234
  }
193
- const pageTemplate = librarySaleFunnelID || isLibraryTemplate && currentOfferID ? normalize.parseBuilderLibraryTemplate(dataBuilder) : normalize.parseBuilderTemplateV2(dataBuilder);
235
+ const pageTemplate = librarySaleFunnelID || isLibraryTemplate && currentOfferID ? normalize.parseBuilderLibraryTemplate(dataBuilder) : isShopLibraryPage ? normalize.parseShopLibraryPageTemplate(dataBuilder) : normalize.parseBuilderTemplateV2(dataBuilder);
194
236
  const gemPagesStoreFrontFetcher = storeFrontFetcher || fetcher;
195
237
  const [elementFontStyle, fontStyle, fallback] = await Promise.all([
196
238
  googleFonts.getFontStyleFromPageTemplate(pageTemplate),
@@ -219,6 +261,7 @@ const getPostPurchasePropsPreview = (fetcher, librarySaleFunnelID, storeFrontFet
219
261
  exports.fetchLibraryTemplateDataByID = fetchLibraryTemplateDataByID;
220
262
  exports.fetchPostPurchasePageDataByID = fetchPostPurchasePageDataByID;
221
263
  exports.fetchSalePageDataByID = fetchSalePageDataByID;
264
+ exports.fetchShopLibraryPageDataByID = fetchShopLibraryPageDataByID;
222
265
  exports.fetchThemePageDataByTemplateID = fetchThemePageDataByTemplateID;
223
266
  exports.getPostPurchasePropsPreview = getPostPurchasePropsPreview;
224
267
  exports.getRelevantPageData = getRelevantPageData;
@@ -139,7 +139,8 @@ const getStaticPagePropsPreview = (fetcher, shopifyFetcher)=>async (slug)=>{
139
139
  facebookPixelId: dataBuilder.themePageAnalytic?.fbPixelID ?? null,
140
140
  tiktokPixelId: dataBuilder.themePageAnalytic?.tiktokPixelID ?? null,
141
141
  customCodeHeader: dataBuilder.themePageCustomCode?.header ?? null,
142
- customCodeBody: dataBuilder.themePageCustomCode?.body ?? null
142
+ customCodeBody: dataBuilder.themePageCustomCode?.body ?? null,
143
+ interaction: dataBuilder?.interaction
143
144
  });
144
145
  } catch (err) {
145
146
  nextjs.captureException(err);
@@ -141,7 +141,8 @@ const getStaticPagePropsV2 = (fetcher, shopifyFetcher)=>async (slug)=>{
141
141
  customCodeHeader: dataBuilder.themePageCustomCode?.header ?? null,
142
142
  customCodeBody: dataBuilder.themePageCustomCode?.body ?? null,
143
143
  pageHandle: dataBuilder.handle ?? null,
144
- customFonts: customFonts$1
144
+ customFonts: customFonts$1,
145
+ interaction: dataBuilder?.interaction
145
146
  });
146
147
  } catch (err) {
147
148
  nextjs.captureException(err);
@@ -88,9 +88,15 @@ const parseBuilderLibraryTemplate = (data)=>{
88
88
  ...data?.sections ?? []
89
89
  ], data?.sectionPosition);
90
90
  };
91
+ const parseShopLibraryPageTemplate = (data)=>{
92
+ return normalizePageSectionResponseV2([
93
+ ...data?.shopLibrarySections ?? []
94
+ ], data?.sectionPosition);
95
+ };
91
96
 
92
97
  exports.normalizeBuilderData = normalizeBuilderData;
93
98
  exports.normalizePageSectionResponseV2 = normalizePageSectionResponseV2;
94
99
  exports.parseBuilderLibraryTemplate = parseBuilderLibraryTemplate;
95
100
  exports.parseBuilderTemplate = parseBuilderTemplate;
96
101
  exports.parseBuilderTemplateV2 = parseBuilderTemplateV2;
102
+ exports.parseShopLibraryPageTemplate = parseShopLibraryPageTemplate;
@@ -9,9 +9,11 @@ var useTrackingView = require('../libs/hooks/use-tracking-view.js');
9
9
  var parseHtml = require('../libs/parse-html.js');
10
10
  var Header = require('../components/builder/Header.js');
11
11
  var FooterForPostPurchase = require('../components/FooterForPostPurchase.js');
12
+ var Script = require('next/script');
12
13
 
13
- const StaticPageV2 = ({ components, builderData, sectionData, seo, themeStyle, fontStyle, elementFontStyle, customCodeHeader, shopToken, pageHandle, customFonts, isPostPurchase, shopName, productOffers, publicStoreFrontData, isPreview })=>{
14
+ const StaticPageV2 = ({ components, builderData, sectionData, seo, themeStyle, fontStyle, elementFontStyle, customCodeHeader, shopToken, pageHandle, customFonts, isPostPurchase, shopName, productOffers, publicStoreFrontData, isPreview, interaction })=>{
14
15
  const router$1 = router.useRouter();
16
+ const baseAssetURL = process.env.NEXT_GP_BASE_ASSET_URL || 'https://d3kbi0je7pp4lw.cloudfront.net';
15
17
  useTrackingView.useTrackingView(shopToken, pageHandle, router$1.isFallback);
16
18
  if (router$1.isFallback) {
17
19
  return /*#__PURE__*/ jsxRuntime.jsx("div", {
@@ -79,17 +81,28 @@ const StaticPageV2 = ({ components, builderData, sectionData, seo, themeStyle, f
79
81
  isPostPurchase && /*#__PURE__*/ jsxRuntime.jsx(Header.default, {
80
82
  pageType: "POST_PURCHASE"
81
83
  }),
84
+ /*#__PURE__*/ jsxRuntime.jsx("div", {
85
+ dangerouslySetInnerHTML: {
86
+ __html: `<div id="gp-interaction" style="display: none;">${JSON.stringify(interaction?.value || [])}</div>`
87
+ }
88
+ }),
82
89
  /*#__PURE__*/ jsxRuntime.jsx(core.SectionProvider, {
83
90
  data: sectionData,
84
- children: builderData?.map((builder)=>/*#__PURE__*/ jsxRuntime.jsx(core.BuilderProvider, {
91
+ children: builderData?.map((builder)=>/*#__PURE__*/ jsxRuntime.jsxs(core.BuilderProvider, {
85
92
  state: builder.data,
86
93
  lazy: builder.lazy,
87
94
  priority: builder.priority,
88
95
  isPostPurchase: isPostPurchase,
89
96
  isPreview: isPreview,
90
- children: /*#__PURE__*/ jsxRuntime.jsx(core.Render, {
91
- uid: builder.uid
92
- })
97
+ children: [
98
+ /*#__PURE__*/ jsxRuntime.jsx(core.Render, {
99
+ uid: builder.uid
100
+ }),
101
+ /*#__PURE__*/ jsxRuntime.jsx(Script, {
102
+ defer: true,
103
+ src: `${baseAssetURL}/assets-v2/gp-flow-action-lip.js`
104
+ })
105
+ ]
93
106
  }, builder.uid))
94
107
  }),
95
108
  isPostPurchase && /*#__PURE__*/ jsxRuntime.jsx(FooterForPostPurchase.default, {
@@ -1,6 +1,7 @@
1
1
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
- import { useShopStore, cls, makeStyleResponsive } from '@gem-sdk/core';
2
+ import { useShopStore, usePageStore, cls, makeStyleResponsive } from '@gem-sdk/core';
3
3
  import Devices from './SwitchView.js';
4
+ import InteractionSelectOnPageHeader from './InteractionSelectOnPageHeader.js';
4
5
 
5
6
  const defaultMargin = {
6
7
  desktop: '16px',
@@ -17,8 +18,10 @@ const sizeCheck = {
17
18
  const Header = (props)=>{
18
19
  const { pageType, isOriginTemplate } = props;
19
20
  const layoutSetting = useShopStore((s)=>s.layoutSettings);
21
+ const isSelectOnPage = usePageStore((s)=>s.interactionData?.isSelectOnPage);
20
22
  const activeHeader = layoutSetting?.showHeader || isOriginTemplate;
21
23
  const headerColor = activeHeader ? HEADER_ON_COLOR : HEADER_OFF_COLOR;
24
+ console.log('isSelectOnPage', isSelectOnPage);
22
25
  return /*#__PURE__*/ jsxs(Fragment, {
23
26
  children: [
24
27
  /*#__PURE__*/ jsx(Devices, {}),
@@ -173,7 +176,8 @@ const Header = (props)=>{
173
176
  })
174
177
  ]
175
178
  })
176
- })
179
+ }),
180
+ isSelectOnPage && /*#__PURE__*/ jsx(InteractionSelectOnPageHeader, {})
177
181
  ]
178
182
  });
179
183
  };
@@ -0,0 +1,67 @@
1
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
+ import { usePageStore, useInteraction } from '@gem-sdk/core';
3
+
4
+ const InteractionSelectOnPageHeader = ()=>{
5
+ const selectType = usePageStore((s)=>s.interactionData?.selectType);
6
+ const setInteractionSelectType = usePageStore((s)=>s.setInteractionSelectType);
7
+ const { closeSelectOnPage } = useInteraction();
8
+ return /*#__PURE__*/ jsxs(Fragment, {
9
+ children: [
10
+ /*#__PURE__*/ jsxs("header", {
11
+ className: "gp-flex gp-justify-between gp-items-center gp-h-10 gp-fixed gp-top-0 gp-left-0 gp-w-full gp-z-100 gp-bg-black gp-text-white",
12
+ children: [
13
+ /*#__PURE__*/ jsx("div", {
14
+ className: "gp-ml-4 gp-text-xs gp-mt-1",
15
+ children: "Select mode enabled"
16
+ }),
17
+ /*#__PURE__*/ jsxs("section", {
18
+ className: "gp-flex gp-bg-[#3C67FF]/[0.15] gp-items-center gp-h-full gp-rounded-b-lg gp-pt-1 gp-gap-1",
19
+ children: [
20
+ /*#__PURE__*/ jsx("button", {
21
+ "data-interaction-mode": "element",
22
+ onClick: ()=>setInteractionSelectType('element'),
23
+ className: `gp-h-full gp-w-[444px] gp-items-center gp-justify-center gp-bg-[#333333] gp-text-[12px] gp-leading-5 gp-font-medium gp-flex gp-rounded-t-[8px] ${selectType === 'element' ? 'gp-bg-[#3C67FF] gp-text-[#F9F9F9]' : 'gp-text-[#AAAAAA]'}`,
24
+ style: {
25
+ cursor: "url('https://cdn.shopify.com/s/files/1/0858/3168/0279/files/gempages_502328832959710176-45eb24ff-a9ee-48ac-af8b-eac35e11918d.png?v=1724038301'), auto"
26
+ },
27
+ children: "Choose an element on page"
28
+ }),
29
+ /*#__PURE__*/ jsx("button", {
30
+ "data-interaction-mode": "page",
31
+ onClick: ()=>setInteractionSelectType('page'),
32
+ className: `gp-h-full gp-w-[444px] gp-items-center gp-justify-center gp-bg-[#333333] gp-text-[12px] gp-leading-5 gp-font-medium gp-flex gp-rounded-t-[8px] ${selectType === 'page' ? 'gp-bg-[#3C67FF] gp-text-[#F9F9F9]' : 'gp-text-[#AAAAAA]'}`,
33
+ style: {
34
+ cursor: "url('https://cdn.shopify.com/s/files/1/0858/3168/0279/files/gempages_502328832959710176-45eb24ff-a9ee-48ac-af8b-eac35e11918d.png?v=1724038301'), auto"
35
+ },
36
+ children: "Use entire page"
37
+ })
38
+ ]
39
+ }),
40
+ /*#__PURE__*/ jsx("button", {
41
+ onClick: closeSelectOnPage,
42
+ className: "gp-h-10 gp-w-10 gp-flex gp-items-center gp-justify-center gp-rounded-bl-lg",
43
+ children: /*#__PURE__*/ jsx("svg", {
44
+ width: "12",
45
+ height: "12",
46
+ viewBox: "0 0 12 12",
47
+ fill: "none",
48
+ xmlns: "http://www.w3.org/2000/svg",
49
+ children: /*#__PURE__*/ jsx("path", {
50
+ d: "M9.96967 11.0303C10.2626 11.3232 10.7374 11.3232 11.0303 11.0303C11.3232 10.7374 11.3232 10.2626 11.0303 9.96967L7.06066 6L11.0303 2.03033C11.3232 1.73744 11.3232 1.26256 11.0303 0.96967C10.7374 0.676777 10.2626 0.676777 9.96967 0.96967L6 4.93934L2.03033 0.96967C1.73744 0.676777 1.26256 0.676777 0.96967 0.96967C0.676777 1.26256 0.676777 1.73744 0.96967 2.03033L4.93934 6L0.96967 9.96967C0.676777 10.2626 0.676777 10.7374 0.96967 11.0303C1.26256 11.3232 1.73744 11.3232 2.03033 11.0303L6 7.06066L9.96967 11.0303Z",
51
+ fill: "#F9F9F9"
52
+ })
53
+ })
54
+ })
55
+ ]
56
+ }),
57
+ /*#__PURE__*/ jsx("div", {
58
+ className: `gp-w-full gp-fixed gp-top-0 gp-left-0 gp-border-[#3C67FF] gp-border-[4px] gp-mt-[40px] ${selectType === 'page' ? 'gp-z-90 gp-bg-[#3c67ff]/[0.25]' : ''}`,
59
+ style: {
60
+ height: 'calc(100% - 40px)'
61
+ }
62
+ })
63
+ ]
64
+ });
65
+ };
66
+
67
+ export { InteractionSelectOnPageHeader as default };
@@ -174,6 +174,7 @@ const Devices = ()=>{
174
174
  ]
175
175
  })
176
176
  });
177
+ return null;
177
178
  };
178
179
 
179
180
  export { Devices as default };
@@ -575,12 +575,14 @@ const Toolbar = ()=>{
575
575
  if (await isElementInsideArticle()) {
576
576
  articleId = currentComponentActive.current?.articleId || '';
577
577
  }
578
+ console.log('$parent$parent', $parent);
578
579
  const event = new CustomEvent('editor:toolbar:force-active-component', {
579
580
  bubbles: true,
580
581
  detail: {
581
582
  componentUid: uid,
582
583
  productId,
583
- articleId
584
+ articleId,
585
+ elementTag: $parent.getAttribute('data-component-tag') || ''
584
586
  }
585
587
  });
586
588
  outHover($parent);
@@ -32,6 +32,9 @@ const Toolbox = ()=>{
32
32
  const changeCreateThemeSectionCount = useShopStore((s)=>s.changeCreateThemeSectionCount);
33
33
  const changeShopPlan = useShopStore((s)=>s.changeShopPlan);
34
34
  const clearModal = useModalStore((s)=>s.clearModal);
35
+ const setInteractionIsSelectOnPage = usePageStore((s)=>s.setInteractionIsSelectOnPage);
36
+ const setInteractionItem = usePageStore((s)=>s.setInteractionItem);
37
+ const setInteractionSelectType = usePageStore((s)=>s.setInteractionSelectType);
35
38
  const fonts = useMemo(()=>getFontsFromDataBuilder(state), [
36
39
  state
37
40
  ]);
@@ -325,6 +328,21 @@ const Toolbox = ()=>{
325
328
  }, [
326
329
  setSalePageProductId
327
330
  ]);
331
+ const onUpdateInteractionIsSelectOnPage = useCallback((e)=>{
332
+ const isSelectOnPage = e.detail.value;
333
+ const mode = e.detail.mode;
334
+ setInteractionIsSelectOnPage(isSelectOnPage);
335
+ setInteractionSelectType(mode);
336
+ }, [
337
+ setInteractionIsSelectOnPage,
338
+ setInteractionSelectType
339
+ ]);
340
+ const onUpdateInteractionItem = useCallback((e)=>{
341
+ const interactionItem = e.detail;
342
+ setInteractionItem(interactionItem);
343
+ }, [
344
+ setInteractionItem
345
+ ]);
328
346
  useEffect(()=>{
329
347
  if (fonts) {
330
348
  setFontsToHead('google-font-element', fonts);
@@ -352,6 +370,8 @@ const Toolbox = ()=>{
352
370
  window.addEventListener('update-item-attribute', onUpdateItemAttribute);
353
371
  window.addEventListener('set-product-offer', onUpdateProductOffers);
354
372
  window.addEventListener('update-sale-page-product-id', onUpdateSalePageProductId);
373
+ window.addEventListener('update-interaction-is-select-on-page', onUpdateInteractionIsSelectOnPage);
374
+ window.addEventListener('update-interaction-item', onUpdateInteractionItem);
355
375
  return ()=>{
356
376
  window.removeEventListener('update-shop-info', onChangeShopInfo);
357
377
  window.removeEventListener('revalidate-query', onRevalidateQuery);
@@ -371,6 +391,8 @@ const Toolbox = ()=>{
371
391
  window.removeEventListener('update-item-attribute', onUpdateItemAttribute);
372
392
  window.removeEventListener('set-product-offer', onUpdateProductOffers);
373
393
  window.removeEventListener('update-sale-page-product-id', onUpdateSalePageProductId);
394
+ window.removeEventListener('update-interaction-is-select-on-page', onUpdateInteractionIsSelectOnPage);
395
+ window.removeEventListener('update-interaction-item', onUpdateInteractionItem);
374
396
  };
375
397
  }, [
376
398
  onAddEntity,
@@ -391,7 +413,9 @@ const Toolbox = ()=>{
391
413
  onUpdateItemName,
392
414
  onUpdateItemAttribute,
393
415
  onUpdateProductOffers,
394
- onUpdateSalePageProductId
416
+ onUpdateSalePageProductId,
417
+ onUpdateInteractionItem,
418
+ onUpdateInteractionIsSelectOnPage
395
419
  ]);
396
420
  return /*#__PURE__*/ jsx("div", {
397
421
  className: "toolbox"
@@ -1,8 +1,8 @@
1
- import { ThemePageDocument, StorePropertyDocument, SaleFunnelDiscountsDocument, LibraryTemplateDocument, LibrarySaleFunnelDocument } from '@gem-sdk/core';
1
+ import { ThemePageDocument, StorePropertyDocument, SaleFunnelDiscountsDocument, LibraryTemplateDocument, LibrarySaleFunnelDocument, ShopLibraryPageDocument } from '@gem-sdk/core';
2
2
  import { captureException } from '@sentry/nextjs';
3
3
  import { getFontStyleFromPageTemplate, getFontFromGlobalStyle } from '../google-fonts.js';
4
4
  import { getFallbackV2 } from '../helpers/get-fallback.js';
5
- import { parseBuilderLibraryTemplate, parseBuilderTemplateV2 } from '../helpers/normalize.js';
5
+ import { parseBuilderLibraryTemplate, parseShopLibraryPageTemplate, parseBuilderTemplateV2 } from '../helpers/normalize.js';
6
6
  import { usePagePreview } from '../hooks/usePagePreview.js';
7
7
  import { serializableJson } from '../helpers/parse-json.js';
8
8
  import { genCSS } from '../helpers/gen-css.js';
@@ -117,6 +117,40 @@ const fetchThemePageDataByTemplateID = async (data, fetcher)=>{
117
117
  productOffers: productOffers
118
118
  };
119
119
  };
120
+ const fetchShopLibraryPageDataByID = async (data, fetcher)=>{
121
+ const variables = {
122
+ shopLibraryPageId: data.shopLibraryPageId
123
+ };
124
+ const [theme, storeProperty, saleFunnelDiscounts] = await Promise.allSettled([
125
+ fetcher([
126
+ ShopLibraryPageDocument,
127
+ variables
128
+ ]),
129
+ fetcher([
130
+ StorePropertyDocument
131
+ ]),
132
+ fetcher([
133
+ SaleFunnelDiscountsDocument,
134
+ {
135
+ where: {
136
+ saleFunnelOfferID: data.currentOfferID
137
+ }
138
+ }
139
+ ])
140
+ ]);
141
+ if (theme.status === 'rejected') {
142
+ throw new Error(theme.reason?.[0]);
143
+ }
144
+ if (saleFunnelDiscounts.status === 'rejected') {
145
+ throw new Error(saleFunnelDiscounts.reason?.[0]);
146
+ }
147
+ return {
148
+ dataBuilder: theme.value.shopLibraryPage,
149
+ pageStyle: undefined,
150
+ storeProperty,
151
+ productOffers: saleFunnelDiscounts.value.saleFunnelDiscounts?.edges?.filter((item)=>item?.node?.objectType === 'PRODUCT' && item?.node?.type === 'ORDER_VALUE') || []
152
+ };
153
+ };
120
154
  const fetchLibraryTemplateDataByID = async (data, fetcher)=>{
121
155
  const variables = {
122
156
  libraryTemplateId: data.libraryTemplateId
@@ -152,7 +186,7 @@ const fetchLibraryTemplateDataByID = async (data, fetcher)=>{
152
186
  };
153
187
  };
154
188
  const getRelevantPageData = async (data)=>{
155
- const { id, currentOfferID, fetcher, isLibraryTemplate, librarySaleFunnelID } = data;
189
+ const { id, currentOfferID, fetcher, isLibraryTemplate, librarySaleFunnelID, isShopLibraryPage } = data;
156
190
  if (librarySaleFunnelID) {
157
191
  return await fetchThemePageDataByTemplateID({
158
192
  libraryTemplateId: id,
@@ -160,6 +194,12 @@ const getRelevantPageData = async (data)=>{
160
194
  librarySaleFunnelID
161
195
  }, fetcher);
162
196
  }
197
+ if (isShopLibraryPage && currentOfferID) {
198
+ return await fetchShopLibraryPageDataByID({
199
+ shopLibraryPageId: id,
200
+ currentOfferID
201
+ }, fetcher);
202
+ }
163
203
  if (isLibraryTemplate && currentOfferID) {
164
204
  return await fetchLibraryTemplateDataByID({
165
205
  libraryTemplateId: id,
@@ -176,19 +216,21 @@ const getRelevantPageData = async (data)=>{
176
216
  themePageId: id
177
217
  }, fetcher);
178
218
  };
179
- const getPostPurchasePropsPreview = (fetcher, librarySaleFunnelID, storeFrontFetcher)=>async (id, currentOfferID, isLibraryTemplate)=>{
219
+ const getPostPurchasePropsPreview = (fetcher, librarySaleFunnelID, storeFrontFetcher)=>async (data)=>{
180
220
  try {
221
+ const { id, currentOfferID, isLibraryTemplate, isShopLibraryPage } = data;
181
222
  const { dataBuilder, storeProperty, productOffers, pageStyle } = await getRelevantPageData({
182
223
  id,
183
224
  currentOfferID,
184
225
  fetcher,
185
226
  isLibraryTemplate,
227
+ isShopLibraryPage,
186
228
  librarySaleFunnelID
187
229
  });
188
230
  if (!dataBuilder) {
189
231
  throw new Error(`No data builder found for slug: /preview/${id}`);
190
232
  }
191
- const pageTemplate = librarySaleFunnelID || isLibraryTemplate && currentOfferID ? parseBuilderLibraryTemplate(dataBuilder) : parseBuilderTemplateV2(dataBuilder);
233
+ const pageTemplate = librarySaleFunnelID || isLibraryTemplate && currentOfferID ? parseBuilderLibraryTemplate(dataBuilder) : isShopLibraryPage ? parseShopLibraryPageTemplate(dataBuilder) : parseBuilderTemplateV2(dataBuilder);
192
234
  const gemPagesStoreFrontFetcher = storeFrontFetcher || fetcher;
193
235
  const [elementFontStyle, fontStyle, fallback] = await Promise.all([
194
236
  getFontStyleFromPageTemplate(pageTemplate),
@@ -214,4 +256,4 @@ const getPostPurchasePropsPreview = (fetcher, librarySaleFunnelID, storeFrontFet
214
256
  }
215
257
  };
216
258
 
217
- export { fetchLibraryTemplateDataByID, fetchPostPurchasePageDataByID, fetchSalePageDataByID, fetchThemePageDataByTemplateID, getPostPurchasePropsPreview, getRelevantPageData };
259
+ export { fetchLibraryTemplateDataByID, fetchPostPurchasePageDataByID, fetchSalePageDataByID, fetchShopLibraryPageDataByID, fetchThemePageDataByTemplateID, getPostPurchasePropsPreview, getRelevantPageData };
@@ -137,7 +137,8 @@ const getStaticPagePropsPreview = (fetcher, shopifyFetcher)=>async (slug)=>{
137
137
  facebookPixelId: dataBuilder.themePageAnalytic?.fbPixelID ?? null,
138
138
  tiktokPixelId: dataBuilder.themePageAnalytic?.tiktokPixelID ?? null,
139
139
  customCodeHeader: dataBuilder.themePageCustomCode?.header ?? null,
140
- customCodeBody: dataBuilder.themePageCustomCode?.body ?? null
140
+ customCodeBody: dataBuilder.themePageCustomCode?.body ?? null,
141
+ interaction: dataBuilder?.interaction
141
142
  });
142
143
  } catch (err) {
143
144
  captureException(err);
@@ -139,7 +139,8 @@ const getStaticPagePropsV2 = (fetcher, shopifyFetcher)=>async (slug)=>{
139
139
  customCodeHeader: dataBuilder.themePageCustomCode?.header ?? null,
140
140
  customCodeBody: dataBuilder.themePageCustomCode?.body ?? null,
141
141
  pageHandle: dataBuilder.handle ?? null,
142
- customFonts
142
+ customFonts,
143
+ interaction: dataBuilder?.interaction
143
144
  });
144
145
  } catch (err) {
145
146
  captureException(err);
@@ -86,5 +86,10 @@ const parseBuilderLibraryTemplate = (data)=>{
86
86
  ...data?.sections ?? []
87
87
  ], data?.sectionPosition);
88
88
  };
89
+ const parseShopLibraryPageTemplate = (data)=>{
90
+ return normalizePageSectionResponseV2([
91
+ ...data?.shopLibrarySections ?? []
92
+ ], data?.sectionPosition);
93
+ };
89
94
 
90
- export { normalizeBuilderData, normalizePageSectionResponseV2, parseBuilderLibraryTemplate, parseBuilderTemplate, parseBuilderTemplateV2 };
95
+ export { normalizeBuilderData, normalizePageSectionResponseV2, parseBuilderLibraryTemplate, parseBuilderTemplate, parseBuilderTemplateV2, parseShopLibraryPageTemplate };
@@ -7,9 +7,11 @@ import { useTrackingView } from '../libs/hooks/use-tracking-view.js';
7
7
  import { parseHtml } from '../libs/parse-html.js';
8
8
  import Header from '../components/builder/Header.js';
9
9
  import FooterForPostPurchase from '../components/FooterForPostPurchase.js';
10
+ import Script from 'next/script';
10
11
 
11
- const StaticPageV2 = ({ components, builderData, sectionData, seo, themeStyle, fontStyle, elementFontStyle, customCodeHeader, shopToken, pageHandle, customFonts, isPostPurchase, shopName, productOffers, publicStoreFrontData, isPreview })=>{
12
+ const StaticPageV2 = ({ components, builderData, sectionData, seo, themeStyle, fontStyle, elementFontStyle, customCodeHeader, shopToken, pageHandle, customFonts, isPostPurchase, shopName, productOffers, publicStoreFrontData, isPreview, interaction })=>{
12
13
  const router = useRouter();
14
+ const baseAssetURL = process.env.NEXT_GP_BASE_ASSET_URL || 'https://d3kbi0je7pp4lw.cloudfront.net';
13
15
  useTrackingView(shopToken, pageHandle, router.isFallback);
14
16
  if (router.isFallback) {
15
17
  return /*#__PURE__*/ jsx("div", {
@@ -77,17 +79,28 @@ const StaticPageV2 = ({ components, builderData, sectionData, seo, themeStyle, f
77
79
  isPostPurchase && /*#__PURE__*/ jsx(Header, {
78
80
  pageType: "POST_PURCHASE"
79
81
  }),
82
+ /*#__PURE__*/ jsx("div", {
83
+ dangerouslySetInnerHTML: {
84
+ __html: `<div id="gp-interaction" style="display: none;">${JSON.stringify(interaction?.value || [])}</div>`
85
+ }
86
+ }),
80
87
  /*#__PURE__*/ jsx(SectionProvider, {
81
88
  data: sectionData,
82
- children: builderData?.map((builder)=>/*#__PURE__*/ jsx(BuilderProvider, {
89
+ children: builderData?.map((builder)=>/*#__PURE__*/ jsxs(BuilderProvider, {
83
90
  state: builder.data,
84
91
  lazy: builder.lazy,
85
92
  priority: builder.priority,
86
93
  isPostPurchase: isPostPurchase,
87
94
  isPreview: isPreview,
88
- children: /*#__PURE__*/ jsx(Render, {
89
- uid: builder.uid
90
- })
95
+ children: [
96
+ /*#__PURE__*/ jsx(Render, {
97
+ uid: builder.uid
98
+ }),
99
+ /*#__PURE__*/ jsx(Script, {
100
+ defer: true,
101
+ src: `${baseAssetURL}/assets-v2/gp-flow-action-lip.js`
102
+ })
103
+ ]
91
104
  }, builder.uid))
92
105
  }),
93
106
  isPostPurchase && /*#__PURE__*/ jsx(FooterForPostPurchase, {
@@ -40,6 +40,7 @@ type PageBuilderProps = {
40
40
  customCodeBody?: string | null;
41
41
  isStorefront?: boolean;
42
42
  customFonts?: string | null;
43
+ interaction?: ShopType.Maybe<Pick<ShopType.PublishedPageInteraction, "id" | "value">>;
43
44
  };
44
45
  type PageBuilderPropsV2 = {
45
46
  builderData?: {
@@ -93,7 +94,12 @@ type StaticPagePropsV2 = PageBuilderPropsV2 & {
93
94
  };
94
95
  declare const StaticPageV2: React.FC<StaticPagePropsV2 & AdditionalPageBuilderProps>;
95
96
 
96
- declare const getPostPurchasePropsPreview: (fetcher: FetchFunc, librarySaleFunnelID?: string, storeFrontFetcher?: FetchFunc) => (id: string, currentOfferID: string, isLibraryTemplate?: boolean) => Promise<Omit<StaticPagePropsV2, 'publicStoreFrontData'>>;
97
+ declare const getPostPurchasePropsPreview: (fetcher: FetchFunc, librarySaleFunnelID?: string, storeFrontFetcher?: FetchFunc) => (data: {
98
+ id: string;
99
+ currentOfferID: string;
100
+ isLibraryTemplate?: boolean;
101
+ isShopLibraryPage?: boolean;
102
+ }) => Promise<Omit<StaticPagePropsV2, 'publicStoreFrontData'>>;
97
103
 
98
104
  declare const getStaticPagePropsPreview: (fetcher: FetchFunc, shopifyFetcher: FetchFunc) => (slug: string) => Promise<PageBuilderPropsV2>;
99
105
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gem-sdk/pages",
3
- "version": "1.51.0-staging.56",
3
+ "version": "1.51.0-staging.63",
4
4
  "license": "MIT",
5
5
  "sideEffects": false,
6
6
  "main": "dist/cjs/index.js",
@@ -26,7 +26,7 @@
26
26
  "next": "latest"
27
27
  },
28
28
  "devDependencies": {
29
- "@gem-sdk/core": "1.51.0-staging.56",
29
+ "@gem-sdk/core": "1.51.0-staging.63",
30
30
  "@gem-sdk/plugin-cookie-bar": "1.50.0",
31
31
  "@gem-sdk/plugin-quick-view": "1.50.0",
32
32
  "@gem-sdk/plugin-sticky-add-to-cart": "1.50.0"