@gem-sdk/pages 1.56.0 → 1.57.0-dev.45

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 (46) hide show
  1. package/dist/cjs/components/builder/Body.js +38 -0
  2. package/dist/cjs/components/builder/Footer.js +2 -2
  3. package/dist/cjs/components/builder/Header.js +4 -1
  4. package/dist/cjs/components/builder/InteractionSelectOnPageHeader.js +191 -0
  5. package/dist/cjs/components/builder/SwitchView.js +1 -0
  6. package/dist/cjs/components/builder/Toolbar.js +130 -340
  7. package/dist/cjs/components/builder/Toolbox.js +48 -1
  8. package/dist/cjs/components/builder/toolbar/const.js +7 -0
  9. package/dist/cjs/components/builder/toolbar/utils/findDOMClosest.js +41 -0
  10. package/dist/cjs/components/builder/toolbar/utils/findOverflowParent.js +20 -0
  11. package/dist/cjs/components/builder/toolbar/utils/getChildrenByAttrSelector.js +18 -0
  12. package/dist/cjs/components/builder/toolbar/utils/getDOMElementParents.js +32 -0
  13. package/dist/cjs/components/builder/toolbar/utils/isOverParent.js +16 -0
  14. package/dist/cjs/components/builder/toolbar/utils/isOverToolbarPosition.js +12 -0
  15. package/dist/cjs/components/builder/toolbar/utils/isSection.js +8 -0
  16. package/dist/cjs/components/builder/toolbar/utils/notVisible.js +8 -0
  17. package/dist/cjs/components/builder/toolbar/utils/waitForElementToExist.js +27 -0
  18. package/dist/cjs/components/image-to-layout/DropElement.js +2 -0
  19. package/dist/cjs/libs/api/get-static-page-props-v2.js +2 -1
  20. package/dist/cjs/pages/builder.js +4 -11
  21. package/dist/cjs/pages/static-v2.js +18 -5
  22. package/dist/esm/components/builder/Body.js +34 -0
  23. package/dist/esm/components/builder/Footer.js +2 -2
  24. package/dist/esm/components/builder/Header.js +5 -2
  25. package/dist/esm/components/builder/InteractionSelectOnPageHeader.js +187 -0
  26. package/dist/esm/components/builder/SwitchView.js +1 -0
  27. package/dist/esm/components/builder/Toolbar.js +102 -312
  28. package/dist/esm/components/builder/Toolbox.js +48 -1
  29. package/dist/esm/components/builder/toolbar/const.js +4 -0
  30. package/dist/esm/components/builder/toolbar/utils/findDOMClosest.js +39 -0
  31. package/dist/esm/components/builder/toolbar/utils/findOverflowParent.js +18 -0
  32. package/dist/esm/components/builder/toolbar/utils/getChildrenByAttrSelector.js +16 -0
  33. package/dist/esm/components/builder/toolbar/utils/getDOMElementParents.js +30 -0
  34. package/dist/esm/components/builder/toolbar/utils/isOverParent.js +14 -0
  35. package/dist/esm/components/builder/toolbar/utils/isOverToolbarPosition.js +10 -0
  36. package/dist/esm/components/builder/toolbar/utils/isSection.js +6 -0
  37. package/dist/esm/components/builder/toolbar/utils/notVisible.js +6 -0
  38. package/dist/esm/components/builder/toolbar/utils/waitForElementToExist.js +25 -0
  39. package/dist/esm/components/image-to-layout/DropElement.js +2 -0
  40. package/dist/esm/libs/api/get-static-page-props-v2.js +2 -1
  41. package/dist/esm/pages/builder.js +5 -12
  42. package/dist/esm/pages/static-v2.js +18 -5
  43. package/dist/types/index.d.ts +1 -0
  44. package/package.json +5 -5
  45. package/dist/cjs/components/builder/toolbar/Onboarding.js +0 -110
  46. package/dist/esm/components/builder/toolbar/Onboarding.js +0 -106
@@ -4,51 +4,24 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var react = require('react');
7
- var Onboarding = require('./toolbar/Onboarding.js');
7
+ var getDOMElementParents = require('./toolbar/utils/getDOMElementParents.js');
8
+ var _const = require('./toolbar/const.js');
9
+ var getChildrenByAttrSelector = require('./toolbar/utils/getChildrenByAttrSelector.js');
10
+ var findOverflowParent = require('./toolbar/utils/findOverflowParent.js');
11
+ var waitForElementToExist = require('./toolbar/utils/waitForElementToExist.js');
12
+ var isOverParent = require('./toolbar/utils/isOverParent.js');
13
+ var findDOMClosest = require('./toolbar/utils/findDOMClosest.js');
8
14
 
9
- const TOOLBAR_HOVER_HEIGHT = 24;
10
- const TOOLBAR_ACTIVE_HEIGHT = 32;
11
- const isPopup = (el)=>{
12
- const tag = el.getAttribute('data-component-tag');
13
- return tag === 'Dialog';
14
- };
15
- const isSticky = (el)=>{
16
- const tag = el.getAttribute('data-component-tag');
17
- return tag === 'Sticky';
18
- };
19
- const isOverToolbarPosition = (el, parent1)=>{
20
- const rect = el.getBoundingClientRect();
21
- const rectP = parent1.getBoundingClientRect();
22
- // 32px = toolbar active height
23
- return rect.top - rectP.top < TOOLBAR_ACTIVE_HEIGHT + 1;
24
- };
25
- const findOverflowParent = (element, initEl)=>{
26
- const thisEl = element;
27
- const origEl = initEl || thisEl;
28
- if (!thisEl) return;
29
- if (isSection(thisEl)) return;
30
- if (notVisible(thisEl) && isOverToolbarPosition(initEl, thisEl)) return thisEl;
31
- if (thisEl.parentElement) {
32
- return findOverflowParent(thisEl.parentElement, origEl);
33
- } else {
34
- return;
35
- }
36
- };
37
- const COMPONENTS_TAG_NOT_LOAD_IMAGES = [
38
- 'PostPurchaseProductImages'
39
- ];
40
15
  const Toolbar = ()=>{
41
16
  const currentComponentActive = react.useRef(null);
42
17
  const isDragging = react.useRef(false);
43
18
  const stopWatchReRenderComponent = react.useRef();
44
19
  const isResizeSpacing = react.useRef(false);
45
- const [isOnboarding, setIsOnboarding] = react.useState(false);
46
- const [countShowOnboarding, setCountShowOnboarding] = react.useState(0);
47
- const [onboardingPosition, setOnboardingPosition] = react.useState('bottom');
48
- const timeoutRef = react.useRef(null);
49
- const timeoutOnboarding = 5000;
20
+ const cacheHoverComponents = react.useRef([]);
21
+ const cacheHoverThemeSectionComponents = react.useRef([]);
22
+ const cacheActiveComponents = react.useRef([]);
50
23
  /* Functions */ const changePositionToolbar = ({ state, $toolbar, $component })=>{
51
- const $parentOverflow = findOverflowParent($component, $toolbar);
24
+ const $parentOverflow = findOverflowParent.findOverflowParent($component, $toolbar);
52
25
  const rect = $toolbar.getBoundingClientRect();
53
26
  const rectComponent = $component.getBoundingClientRect();
54
27
  const windowWidth = window.innerWidth;
@@ -63,7 +36,7 @@ const Toolbar = ()=>{
63
36
  $toolbar.setAttribute(`data-toolbar-${state}-overflow`, 'true');
64
37
  }
65
38
  } else {
66
- if (rect.top < TOOLBAR_ACTIVE_HEIGHT + 1) {
39
+ if (rect.top < _const.TOOLBAR_ACTIVE_HEIGHT + 1) {
67
40
  if (rectComponent?.height <= 60) {
68
41
  $toolbar.setAttribute(`data-toolbar-${state}-revert`, 'true');
69
42
  } else {
@@ -88,7 +61,7 @@ const Toolbar = ()=>{
88
61
  const setHoverComponent = react.useCallback(({ $component, componentUid, focus, isPreventSection, isParent })=>{
89
62
  if (!$component && !componentUid) return;
90
63
  if (!$component) {
91
- const $c = document.querySelector(`[data-uid="${componentUid}"]`);
64
+ const $c = document.body.querySelector('#storefront')?.querySelector(`[data-uid="${componentUid}"]`);
92
65
  if (!$c) return;
93
66
  $component = $c;
94
67
  }
@@ -97,11 +70,12 @@ const Toolbar = ()=>{
97
70
  if (!cUid) return;
98
71
  componentUid = cUid;
99
72
  }
100
- const $toolbar = getChildrenByAttrSelector($component, 'data-toolbar');
101
- const $outline = getChildrenByAttrSelector($component, 'data-outline');
102
- const $btnAddTop = getChildrenByAttrSelector($component, 'data-toolbar-add-top');
103
- const $btnAddBottom = getChildrenByAttrSelector($component, 'data-toolbar-add-bottom');
104
- const $themeSectionStatus = getChildrenByAttrSelector($component, 'data-theme-section-status');
73
+ cacheHoverComponents.current.push($component);
74
+ const $toolbar = getChildrenByAttrSelector.getChildrenByAttrSelector($component, 'data-toolbar');
75
+ const $outline = getChildrenByAttrSelector.getChildrenByAttrSelector($component, 'data-outline');
76
+ const $btnAddTop = getChildrenByAttrSelector.getChildrenByAttrSelector($component, 'data-toolbar-add-top');
77
+ const $btnAddBottom = getChildrenByAttrSelector.getChildrenByAttrSelector($component, 'data-toolbar-add-bottom');
78
+ const $themeSectionStatus = getChildrenByAttrSelector.getChildrenByAttrSelector($component, 'data-theme-section-status');
105
79
  if (isPreventSection && $themeSectionStatus) {
106
80
  $themeSectionStatus.setAttribute('data-theme-section-status-active', 'true');
107
81
  }
@@ -125,6 +99,7 @@ const Toolbar = ()=>{
125
99
  $outline.setAttribute('data-outline-parent-hover', 'true');
126
100
  }
127
101
  if (isPreventSection) {
102
+ cacheHoverThemeSectionComponents.current.push($component);
128
103
  $outline.setAttribute('data-outline-overlay-theme-section', 'true');
129
104
  }
130
105
  if (focus) {
@@ -144,11 +119,11 @@ const Toolbar = ()=>{
144
119
  }, []);
145
120
  const setHoverComponentParents = react.useCallback(({ $component, componentUid })=>{
146
121
  if (!$component) {
147
- const $c = document.querySelector(`[data-uid="${componentUid}"]`);
122
+ const $c = document.body.querySelector('#storefront')?.querySelector(`[data-uid="${componentUid}"]`);
148
123
  if (!$c) return;
149
124
  $component = $c;
150
125
  }
151
- const $parents = getDOMElementParents($component, '[data-uid][data-component-type="component"]:not([data-component-no-setting])', 1);
126
+ const $parents = getDOMElementParents.getDOMElementParents($component, '[data-uid][data-component-type="component"]:not([data-component-no-setting])', 1);
152
127
  if ($parents.length) {
153
128
  for (const $parent of $parents){
154
129
  if ($parent) {
@@ -169,7 +144,7 @@ const Toolbar = ()=>{
169
144
  const changePositionToolbarParents = ({ $component, $parents })=>{
170
145
  if (!$component) return;
171
146
  if (!$parents?.length) return;
172
- const $currentToolbar = getChildrenByAttrSelector($component, 'data-toolbar-hover-focus');
147
+ const $currentToolbar = getChildrenByAttrSelector.getChildrenByAttrSelector($component, 'data-toolbar-hover-focus');
173
148
  if ($currentToolbar) {
174
149
  const currentRect = $currentToolbar.getBoundingClientRect();
175
150
  const isRevert = $currentToolbar.getAttribute('data-toolbar-hover-revert') ? true : false;
@@ -179,7 +154,7 @@ const Toolbar = ()=>{
179
154
  if ($parent) {
180
155
  const tag = $parent.getAttribute('data-component-tag');
181
156
  if (tag === 'Section') continue;
182
- const $toolbar = getChildrenByAttrSelector($parent, 'data-toolbar-hover');
157
+ const $toolbar = getChildrenByAttrSelector.getChildrenByAttrSelector($parent, 'data-toolbar-hover');
183
158
  if ($toolbar) {
184
159
  // Ignore with toolbar active
185
160
  const isActive = $toolbar.getAttribute('data-toolbar-active');
@@ -187,7 +162,7 @@ const Toolbar = ()=>{
187
162
  // Start calc
188
163
  const parentRect = $toolbar.getBoundingClientRect();
189
164
  const checkRevert = isRevert || isInside;
190
- if (isOverParent({
165
+ if (isOverParent.isOverParent({
191
166
  current: currentRect,
192
167
  parent: parentRect,
193
168
  index,
@@ -197,9 +172,9 @@ const Toolbar = ()=>{
197
172
  // parentStyle.top
198
173
  const diffTop = currentRect.top - parentRect.top;
199
174
  const diffLeft = currentRect.left - parentRect.left;
200
- let newTop = parseFloat(parentStyle.top) + diffTop - (TOOLBAR_HOVER_HEIGHT - 1) * index; // -1 border bottom
175
+ let newTop = parseFloat(parentStyle.top) + diffTop - (_const.TOOLBAR_HOVER_HEIGHT - 1) * index; // -1 border bottom
201
176
  if (checkRevert) {
202
- newTop = parseFloat(parentStyle.top) - diffTop + (TOOLBAR_HOVER_HEIGHT - 1) * index; // -1 border bottom
177
+ newTop = parseFloat(parentStyle.top) - diffTop + (_const.TOOLBAR_HOVER_HEIGHT - 1) * index; // -1 border bottom
203
178
  }
204
179
  const newLeft = parseFloat(parentStyle.left) + diffLeft;
205
180
  $toolbar.setAttribute('style', `top: ${newTop}px;left: ${newLeft}px;`);
@@ -210,18 +185,23 @@ const Toolbar = ()=>{
210
185
  }
211
186
  }
212
187
  };
213
- const removeHoverOverlayComponent = react.useCallback(()=>{
188
+ const removeHoverThemeSectionComponent = react.useCallback(()=>{
214
189
  const clearAttrs = [
215
- 'data-outline-overlay',
216
190
  'data-outline-overlay-theme-section',
217
191
  'data-theme-section-status-active'
218
192
  ];
219
- const $elms = document.querySelectorAll(clearAttrs.map((attr)=>`[${attr}]`).join(','));
220
- if ($elms) {
221
- clearAttrs.forEach((attr)=>{
222
- $elms.forEach(($el)=>$el.removeAttribute(attr));
223
- });
193
+ const $hoverThemeSectionComponents = cacheHoverThemeSectionComponents.current;
194
+ if ($hoverThemeSectionComponents.length) {
195
+ for (const $hoverThemeSectionComponent of $hoverThemeSectionComponents){
196
+ const $elms = $hoverThemeSectionComponent.querySelectorAll(clearAttrs.map((attr)=>`[${attr}]`).join(','));
197
+ if ($elms) {
198
+ clearAttrs.forEach((attr)=>{
199
+ $elms.forEach(($el)=>$el.removeAttribute(attr));
200
+ });
201
+ }
202
+ }
224
203
  }
204
+ cacheHoverThemeSectionComponents.current = []; // clear
225
205
  }, []);
226
206
  const removeHoverComponent = react.useCallback(()=>{
227
207
  const clearAttrs = [
@@ -235,30 +215,21 @@ const Toolbar = ()=>{
235
215
  'data-outline-parent-hover',
236
216
  'data-toolbar-hover-overflow'
237
217
  ];
238
- const $elms = document.querySelectorAll(clearAttrs.map((attr)=>`[${attr}]`).join(','));
239
- if ($elms) {
240
- clearAttrs.forEach((attr)=>{
241
- $elms.forEach(($el)=>$el.removeAttribute(attr));
242
- });
243
- }
244
- removeHoverOverlayComponent();
245
- }, [
246
- removeHoverOverlayComponent
247
- ]);
248
- const onCloseOnboarding = react.useCallback(()=>{
249
- timeoutRef.current && clearTimeout(timeoutRef.current);
250
- if (countShowOnboarding > 0) {
251
- const eventCreate = new CustomEvent('editor:toolbar:close-onboarding', {
252
- bubbles: true,
253
- detail: {
254
- close: 'close Onboarding'
218
+ const $hoverComponents = cacheHoverComponents.current;
219
+ if ($hoverComponents.length) {
220
+ for (const $hoverComponent of $hoverComponents){
221
+ const $elms = $hoverComponent.querySelectorAll(clearAttrs.map((attr)=>`[${attr}]`).join(','));
222
+ if ($elms) {
223
+ clearAttrs.forEach((attr)=>{
224
+ $elms.forEach(($el)=>$el.removeAttribute(attr));
225
+ });
255
226
  }
256
- });
257
- window.dispatchEvent(eventCreate);
258
- setIsOnboarding(false);
227
+ }
259
228
  }
229
+ removeHoverThemeSectionComponent();
230
+ cacheHoverComponents.current = []; // clear
260
231
  }, [
261
- countShowOnboarding
232
+ removeHoverThemeSectionComponent
262
233
  ]);
263
234
  const removeActiveComponent = react.useCallback(()=>{
264
235
  currentComponentActive.current = null;
@@ -273,48 +244,25 @@ const Toolbar = ()=>{
273
244
  'data-outline-force-hover',
274
245
  'data-toolbar-active-overflow'
275
246
  ];
276
- const $elms = document.querySelectorAll(clearAttrs.map((attr)=>`[${attr}]`).join(','));
277
- if ($elms) {
278
- clearAttrs.forEach((attr)=>{
279
- $elms.forEach(($el)=>$el.removeAttribute(attr));
280
- });
281
- }
282
- setFocusTextEditor(false);
283
- if (stopWatchReRenderComponent.current) stopWatchReRenderComponent.current();
284
- onCloseOnboarding();
285
- }, [
286
- onCloseOnboarding
287
- ]);
288
- const watchComponentReRender = ($el, callback)=>{
289
- // editor:component:render
290
- const onComponentReRender = (e)=>{
291
- const detail = e.detail;
292
- if (detail?.componentUid == currentComponentActive.current?.componentUid) {
293
- callback();
294
- }
295
- };
296
- window.removeEventListener('editor:component:render', onComponentReRender);
297
- window.addEventListener('editor:component:render', onComponentReRender);
298
- const componentTag = $el.getAttribute('data-component-tag');
299
- // hotfix cho sale funnel release, nhưng cần tìm solution cho phần này
300
- if (componentTag && !COMPONENTS_TAG_NOT_LOAD_IMAGES.includes(componentTag)) {
301
- const $images = $el.querySelectorAll('img');
302
- if ($images?.length) {
303
- $images.forEach(($img)=>{
304
- $img.addEventListener('load', ()=>{
305
- callback();
247
+ const $activeComponents = cacheActiveComponents.current;
248
+ if ($activeComponents.length) {
249
+ for (const $activeComponent of $activeComponents){
250
+ const $elms = $activeComponent.querySelectorAll(clearAttrs.map((attr)=>`[${attr}]`).join(','));
251
+ if ($elms) {
252
+ clearAttrs.forEach((attr)=>{
253
+ $elms.forEach(($el)=>$el.removeAttribute(attr));
306
254
  });
307
- });
255
+ }
308
256
  }
309
257
  }
310
- stopWatchReRenderComponent.current = ()=>{
311
- window.removeEventListener('editor:component:render', onComponentReRender);
312
- };
313
- };
258
+ cacheActiveComponents.current = []; // clear
259
+ setFocusTextEditor(false);
260
+ if (stopWatchReRenderComponent.current) stopWatchReRenderComponent.current();
261
+ }, []);
314
262
  const setActiveComponentSpacing = react.useCallback(({ $component })=>{
315
263
  if (!$component) return;
316
264
  const style = getComputedStyle($component);
317
- const $spacing = getChildrenByAttrSelector($component, 'data-spacing');
265
+ const $spacing = getChildrenByAttrSelector.getChildrenByAttrSelector($component, 'data-spacing');
318
266
  const $marginBottom = ($spacing?.querySelector('[data-spacing-margin-bottom]')) || null;
319
267
  if ($marginBottom) {
320
268
  const $bg = $marginBottom.querySelector('[data-spacing-margin-bottom-bg]') || null;
@@ -327,58 +275,6 @@ const Toolbar = ()=>{
327
275
  }
328
276
  }
329
277
  }, []);
330
- const calculateOnboardingPosition = ()=>{
331
- const toolbar = document.querySelector('[data-toolbar-active]');
332
- const toolbarOnboading = document.querySelector('[data-toolbar-onboarding]');
333
- if (toolbar && toolbarOnboading) {
334
- toolbarOnboading?.removeAttribute('data-onboarding-active');
335
- setTimeout(()=>{
336
- const rect = toolbar.getBoundingClientRect();
337
- const rectTop = rect.top || 0;
338
- const rectOnboading = toolbarOnboading?.getBoundingClientRect();
339
- const onboardingHeight = rectOnboading?.height || 0;
340
- const $iframe = parent.document.querySelector('.iframe');
341
- const $iframeWin = $iframe?.contentWindow;
342
- const iframeWinScrollY = $iframeWin?.scrollY || 0;
343
- const iframeHeight = $iframe?.clientHeight || 0;
344
- if (rectTop + onboardingHeight > iframeHeight) {
345
- const oboardingTop = rect.top + iframeWinScrollY - onboardingHeight - 8;
346
- toolbarOnboading?.setAttribute('style', `top: ${oboardingTop}px;left: ${rect.left}px;`);
347
- setOnboardingPosition('top');
348
- if ($iframeWin && oboardingTop < rect.top + iframeWinScrollY) {
349
- setTimeout(()=>{
350
- const toTop = oboardingTop - 20;
351
- $iframeWin.scrollTo({
352
- top: toTop,
353
- behavior: 'smooth'
354
- });
355
- }, 200);
356
- }
357
- } else {
358
- const oboardingTop = rect.top + iframeWinScrollY + rect.height + 8;
359
- toolbarOnboading?.setAttribute('style', `top: ${oboardingTop}px;left: ${rect.left}px;`);
360
- setOnboardingPosition('bottom');
361
- }
362
- setCountShowOnboarding((countShowOnboarding)=>countShowOnboarding + 1);
363
- toolbarOnboading?.setAttribute('data-onboarding-active', 'true');
364
- }, 100);
365
- }
366
- };
367
- const setToolbarOnboarding = react.useCallback(({ $component })=>{
368
- if (!$component) return;
369
- if (isSection($component) || isPopup($component) || isSticky($component)) return;
370
- const toolbarOnboading = document.querySelector('[data-toolbar-onboarding]');
371
- // only show one time
372
- if (countShowOnboarding == 0) {
373
- calculateOnboardingPosition();
374
- } else {
375
- onCloseOnboarding();
376
- toolbarOnboading?.removeAttribute('data-onboarding-active');
377
- }
378
- }, [
379
- countShowOnboarding,
380
- onCloseOnboarding
381
- ]);
382
278
  const getSelectorComponent = ({ componentUid, productId, articleId, marqueeKey })=>{
383
279
  if (articleId) {
384
280
  return `${articleId ? `[data-article-id="${articleId}"][data-uid="${componentUid}"], [data-article-id="${articleId}"] [data-uid="${componentUid}"]` : `[data-uid="${componentUid}"]`}`;
@@ -396,17 +292,18 @@ const Toolbar = ()=>{
396
292
  articleId,
397
293
  marqueeKey
398
294
  });
399
- const $component = await waitForElementToExist(selector, timeAwait);
295
+ const $component = await waitForElementToExist.waitForElementToExist(selector, timeAwait);
400
296
  if (!$component) return;
401
297
  if (!forceReActive && componentUid == currentComponentActive.current?.componentUid && productId == currentComponentActive.current?.productId && articleId == currentComponentActive.current?.articleId && marqueeKey == currentComponentActive.current?.marqueeKey) return;
402
298
  if (componentUid !== currentComponentActive.current?.componentUid || productId !== currentComponentActive.current?.productId || articleId !== currentComponentActive.current?.articleId || forceReActive) removeActiveComponent();
403
299
  if (!forceReActive && componentUid !== currentComponentActive.current?.componentUid || productId !== currentComponentActive.current?.productId || marqueeKey !== currentComponentActive.current?.marqueeKey) {
404
300
  removeActiveComponent();
405
301
  }
406
- const $toolbar = getChildrenByAttrSelector($component, 'data-toolbar');
407
- const $outline = getChildrenByAttrSelector($component, 'data-outline');
408
- const $btnAddTop = getChildrenByAttrSelector($component, 'data-toolbar-add-top');
409
- const $btnAddBottom = getChildrenByAttrSelector($component, 'data-toolbar-add-bottom');
302
+ cacheActiveComponents.current.push($component);
303
+ const $toolbar = getChildrenByAttrSelector.getChildrenByAttrSelector($component, 'data-toolbar');
304
+ const $outline = getChildrenByAttrSelector.getChildrenByAttrSelector($component, 'data-outline');
305
+ const $btnAddTop = getChildrenByAttrSelector.getChildrenByAttrSelector($component, 'data-toolbar-add-top');
306
+ const $btnAddBottom = getChildrenByAttrSelector.getChildrenByAttrSelector($component, 'data-toolbar-add-bottom');
410
307
  if ($toolbar) {
411
308
  currentComponentActive.current = {
412
309
  componentUid,
@@ -431,13 +328,17 @@ const Toolbar = ()=>{
431
328
  if ($btnAddBottom) {
432
329
  $btnAddBottom.setAttribute('data-toolbar-add-active', 'true');
433
330
  }
434
- const isChildOfMarquee = !!$component.closest('[data-component-tag="Marquee"]');
331
+ const { $isChildOfMarquee, $section } = findDOMClosest.findDOMClosest($component, {
332
+ $isChildOfMarquee: '[data-component-tag="Marquee"]',
333
+ $section: '[data-component-tag="Section"]'
334
+ });
435
335
  // Active same element in product list
436
- if (productId || articleId || isChildOfMarquee) {
437
- const $relatedElements = document.querySelectorAll(`[data-uid="${componentUid}"]`);
336
+ if ($section && (productId || articleId || $isChildOfMarquee)) {
337
+ const $relatedElements = $section.querySelectorAll(`[data-uid="${componentUid}"]`);
438
338
  if ($relatedElements?.length) {
439
339
  $relatedElements.forEach(($relatedElement)=>{
440
- const $outline = getChildrenByAttrSelector($relatedElement, 'data-outline');
340
+ cacheActiveComponents.current.push($relatedElement);
341
+ const $outline = getChildrenByAttrSelector.getChildrenByAttrSelector($relatedElement, 'data-outline');
441
342
  if ($outline) {
442
343
  $outline.setAttribute('data-outline-active', 'true');
443
344
  }
@@ -447,35 +348,16 @@ const Toolbar = ()=>{
447
348
  setActiveComponentSpacing({
448
349
  $component
449
350
  });
450
- timeoutRef.current && clearTimeout(timeoutRef.current);
451
- timeoutRef.current = setTimeout(()=>{
452
- if ($component) {
453
- setToolbarOnboarding({
454
- $component
455
- });
456
- }
457
- }, timeoutOnboarding);
458
351
  removeHoverComponent();
459
- // Reactive when component re-render
460
- watchComponentReRender($component, ()=>{
461
- setActiveComponent({
462
- componentUid,
463
- productId,
464
- articleId,
465
- timeAwait: 2000,
466
- forceReActive: true
467
- });
468
- });
469
352
  }, [
470
353
  removeActiveComponent,
471
354
  removeHoverComponent,
472
- setActiveComponentSpacing,
473
- setToolbarOnboarding
355
+ setActiveComponentSpacing
474
356
  ]);
475
357
  const setFocusTextEditor = async (value)=>{
476
358
  if (!value) {
477
- const $components = document.querySelectorAll('[data-outline-editor-inline-focus],[data-toolbar-editor-inline-focus],[data-spacing-hidden]');
478
- if ($components.length) {
359
+ const $components = document.body.querySelector('#storefront')?.querySelectorAll('[data-outline-editor-inline-focus],[data-toolbar-editor-inline-focus],[data-spacing-hidden]');
360
+ if ($components?.length) {
479
361
  $components.forEach(($component)=>{
480
362
  if ($component) {
481
363
  $component.removeAttribute('data-toolbar-editor-inline-focus');
@@ -486,13 +368,14 @@ const Toolbar = ()=>{
486
368
  }
487
369
  } else {
488
370
  if (currentComponentActive.current?.componentUid) {
489
- const componentUid = currentComponentActive.current?.componentUid;
490
- const productId = currentComponentActive.current?.productId;
491
- const $component = await waitForElementToExist(`${productId ? `[data-product-id="${productId}"] ` : ''}[data-uid="${componentUid}"]`, 500);
371
+ const selector = getSelectorComponent({
372
+ ...currentComponentActive.current
373
+ });
374
+ const $component = await waitForElementToExist.waitForElementToExist(selector, 500);
492
375
  if ($component) {
493
- const $toolbar = getChildrenByAttrSelector($component, 'data-toolbar');
494
- const $outline = getChildrenByAttrSelector($component, 'data-outline');
495
- const $spacing = getChildrenByAttrSelector($component, 'data-spacing');
376
+ const $toolbar = getChildrenByAttrSelector.getChildrenByAttrSelector($component, 'data-toolbar');
377
+ const $outline = getChildrenByAttrSelector.getChildrenByAttrSelector($component, 'data-outline');
378
+ const $spacing = getChildrenByAttrSelector.getChildrenByAttrSelector($component, 'data-spacing');
496
379
  if ($toolbar) {
497
380
  if (value) {
498
381
  $toolbar.setAttribute('data-toolbar-editor-inline-focus', 'true');
@@ -517,26 +400,30 @@ const Toolbar = ()=>{
517
400
  const $themeSectionUid = $themeSection?.getAttribute('data-uid');
518
401
  const isActiveThemeSection = $themeSection && $themeSectionUid === currentComponentActive.current?.componentUid;
519
402
  if (!isActiveThemeSection) return;
520
- const $themeSectionStatus = getChildrenByAttrSelector($themeSection, 'data-theme-section-status');
403
+ cacheHoverThemeSectionComponents.current.push($themeSection);
404
+ const $themeSectionStatus = getChildrenByAttrSelector.getChildrenByAttrSelector($themeSection, 'data-theme-section-status');
521
405
  if ($themeSectionStatus) {
522
406
  $themeSectionStatus.setAttribute('data-theme-section-status-active', 'true');
523
407
  }
524
408
  }, []);
525
409
  const setShowParents = async ({ value })=>{
526
- if (!value) {
410
+ if (!value || !currentComponentActive.current) {
527
411
  return;
528
412
  }
529
- const $component = await waitForElementToExist(`${currentComponentActive.current?.productId ? `[data-product-id="${currentComponentActive.current?.productId}"] ` : ''}[data-uid="${currentComponentActive.current?.componentUid}"]`, 500);
413
+ const selector = getSelectorComponent({
414
+ ...currentComponentActive.current
415
+ });
416
+ const $component = await waitForElementToExist.waitForElementToExist(selector, 500);
530
417
  if ($component) {
531
418
  const $parents = $component?.querySelectorAll('[data-toolbar-parent]');
532
419
  if ($parents.length) {
533
420
  const onHover = ($parent)=>{
534
421
  const uid = $parent.getAttribute('data-parent-uid');
535
422
  if (!uid) return;
536
- const $parentComponents = document.querySelectorAll(`[data-uid="${uid}"]`);
537
- if ($parentComponents.length) {
423
+ const $parentComponents = document.body.querySelector('#storefront')?.querySelectorAll(`[data-uid="${uid}"]`);
424
+ if ($parentComponents?.length) {
538
425
  $parentComponents.forEach(($parentComponent)=>{
539
- const $outline = getChildrenByAttrSelector($parentComponent, 'data-outline');
426
+ const $outline = getChildrenByAttrSelector.getChildrenByAttrSelector($parentComponent, 'data-outline');
540
427
  if ($outline) {
541
428
  $outline.setAttribute('data-outline-force-hover', 'true');
542
429
  $outline.setAttribute('data-outline-force-overlay', 'true');
@@ -547,10 +434,10 @@ const Toolbar = ()=>{
547
434
  const outHover = ($parent)=>{
548
435
  const uid = $parent.getAttribute('data-parent-uid');
549
436
  if (!uid) return;
550
- const $parentComponents = document.querySelectorAll(`[data-uid="${uid}"]`);
551
- if ($parentComponents.length) {
437
+ const $parentComponents = document.body.querySelector('#storefront')?.querySelectorAll(`[data-uid="${uid}"]`);
438
+ if ($parentComponents?.length) {
552
439
  $parentComponents.forEach(($parentComponent)=>{
553
- const $outline = getChildrenByAttrSelector($parentComponent, 'data-outline');
440
+ const $outline = getChildrenByAttrSelector.getChildrenByAttrSelector($parentComponent, 'data-outline');
554
441
  if ($outline) {
555
442
  $outline.removeAttribute('data-outline-force-hover');
556
443
  $outline.removeAttribute('data-outline-force-overlay');
@@ -562,12 +449,12 @@ const Toolbar = ()=>{
562
449
  const uid = $parent.getAttribute('data-parent-uid');
563
450
  if (!uid) return;
564
451
  const isElementInsideProduct = async ()=>{
565
- const $component = await waitForElementToExist(`[data-uid="${uid}"]`, 500);
452
+ const $component = await waitForElementToExist.waitForElementToExist(`[data-uid="${uid}"]`, 500);
566
453
  const $product = $component?.closest('[data-product-id]');
567
454
  return !!($product?.getAttribute('data-product-id') || '');
568
455
  };
569
456
  const isElementInsideArticle = async ()=>{
570
- const $component = await waitForElementToExist(`[data-uid="${uid}"]`, 500);
457
+ const $component = await waitForElementToExist.waitForElementToExist(`[data-uid="${uid}"]`, 500);
571
458
  const $article = $component?.closest('[data-article-id]');
572
459
  return !!($article?.getAttribute('data-article-id') || '');
573
460
  };
@@ -584,7 +471,8 @@ const Toolbar = ()=>{
584
471
  detail: {
585
472
  componentUid: uid,
586
473
  productId,
587
- articleId
474
+ articleId,
475
+ elementTag: $parent.getAttribute('data-component-tag') || ''
588
476
  }
589
477
  });
590
478
  outHover($parent);
@@ -602,42 +490,35 @@ const Toolbar = ()=>{
602
490
  if (isDragging.current) return;
603
491
  if (isResizeSpacing.current) return;
604
492
  const $target = e.target;
493
+ // check target
605
494
  if (!$target || typeof $target.closest !== 'function') {
606
- removeHoverOverlayComponent();
495
+ removeHoverThemeSectionComponent();
496
+ removeHoverComponent();
607
497
  return;
608
498
  }
609
- const $toolbarHover = $target.closest('[data-toolbar-hover]');
499
+ const { $toolbarHover, $component, $themeSection, $shopifySection } = findDOMClosest.findDOMClosest($target, {
500
+ $toolbarHover: '[data-toolbar-hover]',
501
+ $component: '[data-toolbar-wrap]',
502
+ $themeSection: '[data-theme-section]',
503
+ $shopifySection: '[data-shopify-section]'
504
+ });
610
505
  if ($toolbarHover) {
611
506
  // Disable feature overlay when hover to toolbar parents
612
507
  return;
613
- // removeHoverOverlayComponent(); // remove overlay old
614
- // // Hover to toolbar is focus
615
- // if ($toolbarHover?.getAttribute('data-toolbar-hover-focus')) return;
616
- // const $component = $target.closest('[data-toolbar-wrap]');
617
- // if (!$component) return;
618
- // const $outline = getChildrenByAttrSelector($component, 'data-outline');
619
- // if (!$outline) return;
620
- // const isThemeSection = $component.getAttribute('data-theme-section');
621
- // const outlineOverlay = isThemeSection
622
- // ? 'data-outline-overlay-theme-section'
623
- // : 'data-outline-overlay';
624
- // $outline.setAttribute(outlineOverlay, 'true');
625
508
  }
626
509
  // Hover to other component
627
- const $component = $target.closest('[data-toolbar-wrap]');
628
510
  const componentUid = $component?.getAttribute('data-uid');
629
511
  if (!$component || !componentUid || componentUid == 'ROOT') {
630
512
  removeHoverComponent();
631
513
  return;
632
514
  }
633
- const $toolbar = getChildrenByAttrSelector($component, 'data-toolbar');
634
- const $outline = getChildrenByAttrSelector($component, 'data-outline');
635
- if ($outline) $outline.removeAttribute('data-outline-overlay');
515
+ const $toolbar = getChildrenByAttrSelector.getChildrenByAttrSelector($component, 'data-toolbar');
636
516
  if (!componentUid) return;
637
517
  if (componentUid == 'ROOT') return;
638
518
  if ($toolbar?.getAttribute('data-toolbar-hover-focus')) return;
639
519
  if (!$toolbar?.getAttribute('data-toolbar-hover-focus')) removeHoverComponent();
640
520
  hoverActiveThemeSection($target);
521
+ const $preventSection = $themeSection || $shopifySection;
641
522
  // Disable event when hover active component
642
523
  if (componentUid == currentComponentActive.current?.componentUid) {
643
524
  if (currentComponentActive.current.productId) {
@@ -650,7 +531,6 @@ const Toolbar = ()=>{
650
531
  }
651
532
  }
652
533
  }
653
- const $preventSection = $target.closest('[data-theme-section]') || $target.closest('[data-shopify-section]');
654
534
  if ($preventSection) {
655
535
  setHoverComponent({
656
536
  $component: $preventSection,
@@ -661,7 +541,6 @@ const Toolbar = ()=>{
661
541
  return;
662
542
  }
663
543
  }
664
- const $preventSection = $target.closest('[data-theme-section]') || $target.closest('[data-shopify-section]');
665
544
  if ($preventSection) {
666
545
  setHoverComponent({
667
546
  $component: $preventSection,
@@ -684,7 +563,7 @@ const Toolbar = ()=>{
684
563
  removeHoverComponent,
685
564
  setHoverComponent,
686
565
  setHoverComponentParents,
687
- removeHoverOverlayComponent,
566
+ removeHoverThemeSectionComponent,
688
567
  currentComponentActive
689
568
  ]);
690
569
  const onActiveComponent = react.useCallback((e)=>{
@@ -749,10 +628,10 @@ const Toolbar = ()=>{
749
628
  ]);
750
629
  const setHoverParentComponent = (uid, type)=>{
751
630
  if (!uid) return;
752
- const $parentComponents = document.querySelectorAll(`[data-uid="${uid}"]`);
753
- if ($parentComponents.length) {
631
+ const $parentComponents = document.body.querySelector('#storefront')?.querySelectorAll(`[data-uid="${uid}"]`);
632
+ if ($parentComponents?.length) {
754
633
  $parentComponents.forEach(($parentComponent)=>{
755
- const $outline = getChildrenByAttrSelector($parentComponent, 'data-outline');
634
+ const $outline = getChildrenByAttrSelector.getChildrenByAttrSelector($parentComponent, 'data-outline');
756
635
  if ($outline) {
757
636
  if (type === 'in') {
758
637
  $outline.setAttribute('data-outline-force-hover', 'true');
@@ -774,19 +653,14 @@ const Toolbar = ()=>{
774
653
  }, [
775
654
  isDragging
776
655
  ]);
777
- const onToolbarOnboarding = react.useCallback((e)=>{
656
+ const onComponentReRender = (e)=>{
778
657
  const detail = e.detail;
779
- if (detail?.isNewUser) {
780
- setIsOnboarding(true);
781
- }
782
- }, []);
783
- const onWindowResize = react.useCallback(()=>{
784
- if (isOnboarding) {
785
- calculateOnboardingPosition();
658
+ if (currentComponentActive.current?.componentUid && detail?.componentUid == currentComponentActive.current?.componentUid) {
659
+ setActiveComponent({
660
+ ...currentComponentActive.current
661
+ });
786
662
  }
787
- }, [
788
- isOnboarding
789
- ]);
663
+ };
790
664
  /* Register event */ react.useEffect(()=>{
791
665
  document.addEventListener('mousemove', onMouseMove);
792
666
  window.addEventListener('editor:active-component', onActiveComponent);
@@ -796,8 +670,7 @@ const Toolbar = ()=>{
796
670
  window.addEventListener('editor:toolbar:show-parents', onShowParents);
797
671
  window.addEventListener('editor:toolbar:resize-spacing', onResizeSpacing);
798
672
  window.addEventListener('editor:hover-component', onHoverComponent);
799
- window.addEventListener('editor:toolbar-onboarding', onToolbarOnboarding);
800
- window.addEventListener('resize', onWindowResize);
673
+ window.addEventListener('editor:component:render', onComponentReRender);
801
674
  return ()=>{
802
675
  document.removeEventListener('mousemove', onMouseMove);
803
676
  window.removeEventListener('editor:active-component', onActiveComponent);
@@ -807,8 +680,7 @@ const Toolbar = ()=>{
807
680
  window.removeEventListener('editor:toolbar:show-parents', onShowParents);
808
681
  window.removeEventListener('editor:toolbar:resize-spacing', onResizeSpacing);
809
682
  window.removeEventListener('editor:hover-component', onHoverComponent);
810
- window.removeEventListener('editor:toolbar-onboarding', onToolbarOnboarding);
811
- window.removeEventListener('resize', onWindowResize);
683
+ window.removeEventListener('editor:component:render', onComponentReRender);
812
684
  };
813
685
  }, [
814
686
  onMouseMove,
@@ -819,91 +691,9 @@ const Toolbar = ()=>{
819
691
  onShowParents,
820
692
  onResizeSpacing,
821
693
  onHoverComponent,
822
- onToolbarOnboarding,
823
- onWindowResize
694
+ onComponentReRender
824
695
  ]);
825
- return isOnboarding && /*#__PURE__*/ jsxRuntime.jsx(Onboarding.default, {
826
- enable: true,
827
- position: onboardingPosition,
828
- onCloseOnboarding: onCloseOnboarding
829
- });
830
- };
831
- const getDOMElementParents = ($el, selector, limit)=>{
832
- // Set up a parent array
833
- const parents = [];
834
- // Push each parent $elms to the array
835
- while($el){
836
- $el = $el.parentElement ?? undefined;
837
- if ($el) {
838
- if ($el.tagName === 'BODY' || $el.getAttribute('data-uid') === 'ROOT') {
839
- break;
840
- }
841
- if (selector) {
842
- if ($el.matches(selector)) {
843
- parents.push($el);
844
- if (limit && parents.length == limit) {
845
- return parents;
846
- }
847
- }
848
- continue;
849
- }
850
- parents.push($el);
851
- if (limit && parents.length == limit) {
852
- return parents;
853
- }
854
- }
855
- }
856
- // Return our parent array
857
- return parents;
858
- };
859
- const getChildrenByAttrSelector = ($el, attrSelector)=>{
860
- const childLen = $el.children.length;
861
- if (childLen) {
862
- for(let i = 0; i < childLen; i++){
863
- const children = $el.children[i];
864
- if (children) {
865
- const is = children.getAttribute(attrSelector);
866
- if (is) {
867
- return children;
868
- }
869
- }
870
- }
871
- }
872
- };
873
- const isOverParent = ({ current, parent: parent1, index, revert })=>{
874
- for(let i = 0; i < index; i++){
875
- let is = current.top - (TOOLBAR_HOVER_HEIGHT - 1) * i >= parent1.top && current.top - (TOOLBAR_HOVER_HEIGHT - 1) * i <= parent1.top + parent1.height || current.top - (TOOLBAR_HOVER_HEIGHT - 1) * i >= parent1.top + parent1.height && current.top - (TOOLBAR_HOVER_HEIGHT - 1) * i <= parent1.top;
876
- if (revert) {
877
- is = current.bottom + (TOOLBAR_HOVER_HEIGHT - 1) * i >= parent1.bottom && current.bottom + (TOOLBAR_HOVER_HEIGHT - 1) * i <= parent1.bottom - parent1.height || current.bottom + (TOOLBAR_HOVER_HEIGHT - 1) * i >= parent1.bottom - parent1.height && current.bottom + (TOOLBAR_HOVER_HEIGHT - 1) * i <= parent1.bottom;
878
- }
879
- if (is) return true;
880
- }
881
- return false;
882
- };
883
- const waitForElementToExist = (selector, timeout = 200)=>{
884
- return new Promise((resolve)=>{
885
- const intervalID = setInterval(()=>{
886
- const el = document.querySelector(selector);
887
- if (el) {
888
- clearInterval(intervalID);
889
- clearTimeout(timeoutID);
890
- resolve(el);
891
- }
892
- }, 50);
893
- const timeoutID = setTimeout(()=>{
894
- clearInterval(intervalID);
895
- clearTimeout(timeoutID);
896
- resolve(null);
897
- }, timeout);
898
- });
899
- };
900
- const notVisible = (el)=>{
901
- const overflow = getComputedStyle(el).overflow;
902
- return overflow !== 'visible';
903
- };
904
- const isSection = (el)=>{
905
- const tag = el.getAttribute('data-component-tag');
906
- return tag === 'Section';
696
+ return /*#__PURE__*/ jsxRuntime.jsx(jsxRuntime.Fragment, {});
907
697
  };
908
698
  var Toolbar$1 = /*#__PURE__*/ react.memo(Toolbar);
909
699