@gem-sdk/pages 1.23.0-staging.43 → 1.23.0-staging.456

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 (70) hide show
  1. package/dist/cjs/components/ErrorFallback.js +3 -3
  2. package/dist/cjs/components/Footer.js +101 -79
  3. package/dist/cjs/components/FooterForPostPurchase.js +34 -0
  4. package/dist/cjs/components/Header.js +144 -69
  5. package/dist/cjs/components/builder/PopupManager.js +5 -5
  6. package/dist/cjs/components/builder/Toolbar.js +318 -148
  7. package/dist/cjs/components/builder/Toolbox.js +128 -53
  8. package/dist/cjs/components/builder/toolbar/Onboarding.js +110 -0
  9. package/dist/cjs/components/image-to-layout/AddSectionImageToLayout.js +37 -22
  10. package/dist/cjs/components/image-to-layout/DropElement.js +128 -87
  11. package/dist/cjs/components/image-to-layout/ImageToLayout.js +6 -12
  12. package/dist/cjs/index.js +5 -0
  13. package/dist/cjs/layouts/main.js +1 -1
  14. package/dist/cjs/libs/api/get-home-page-props-v2.js +3 -1
  15. package/dist/cjs/libs/api/get-post-purchase-props-preview.js +166 -0
  16. package/dist/cjs/libs/api/get-static-page-props-preview.js +3 -1
  17. package/dist/cjs/libs/api/get-static-page-props-v2.js +7 -3
  18. package/dist/cjs/libs/custom-fonts.js +62 -0
  19. package/dist/cjs/libs/fetcher.js +33 -0
  20. package/dist/cjs/libs/google-fonts.js +11 -13
  21. package/dist/cjs/libs/helpers/gen-css.js +6 -0
  22. package/dist/cjs/libs/helpers/gen-fonts.js +15 -4
  23. package/dist/cjs/libs/helpers/get-fallback.js +2 -3
  24. package/dist/cjs/libs/helpers/normalize.js +7 -1
  25. package/dist/cjs/libs/hooks/usePagePreview.js +92 -0
  26. package/dist/cjs/pages/404.js +3 -3
  27. package/dist/cjs/pages/500.js +8 -8
  28. package/dist/cjs/pages/builder.js +49 -40
  29. package/dist/cjs/pages/collection-detail.js +12 -10
  30. package/dist/cjs/pages/product-detail.js +18 -16
  31. package/dist/cjs/pages/static-v2.js +42 -19
  32. package/dist/cjs/pages/static.js +18 -16
  33. package/dist/esm/components/ErrorFallback.js +3 -3
  34. package/dist/esm/components/Footer.js +102 -80
  35. package/dist/esm/components/FooterForPostPurchase.js +30 -0
  36. package/dist/esm/components/Header.js +145 -70
  37. package/dist/esm/components/builder/PopupManager.js +5 -5
  38. package/dist/esm/components/builder/Toolbar.js +319 -149
  39. package/dist/esm/components/builder/Toolbox.js +129 -54
  40. package/dist/esm/components/builder/toolbar/Onboarding.js +106 -0
  41. package/dist/esm/components/image-to-layout/AddSectionImageToLayout.js +37 -22
  42. package/dist/esm/components/image-to-layout/DropElement.js +128 -87
  43. package/dist/esm/components/image-to-layout/ImageToLayout.js +6 -12
  44. package/dist/esm/index.js +3 -1
  45. package/dist/esm/layouts/main.js +1 -1
  46. package/dist/esm/libs/api/get-home-page-props-v2.js +4 -2
  47. package/dist/esm/libs/api/get-post-purchase-props-preview.js +161 -0
  48. package/dist/esm/libs/api/get-static-page-props-preview.js +4 -2
  49. package/dist/esm/libs/api/get-static-page-props-v2.js +7 -3
  50. package/dist/esm/libs/custom-fonts.js +57 -0
  51. package/dist/esm/libs/fetcher.js +33 -1
  52. package/dist/esm/libs/google-fonts.js +11 -13
  53. package/dist/esm/libs/helpers/gen-css.js +6 -0
  54. package/dist/esm/libs/helpers/gen-fonts.js +15 -4
  55. package/dist/esm/libs/helpers/get-fallback.js +2 -3
  56. package/dist/esm/libs/helpers/normalize.js +7 -2
  57. package/dist/esm/libs/hooks/usePagePreview.js +90 -0
  58. package/dist/esm/pages/404.js +3 -3
  59. package/dist/esm/pages/500.js +8 -8
  60. package/dist/esm/pages/builder.js +50 -41
  61. package/dist/esm/pages/collection-detail.js +13 -11
  62. package/dist/esm/pages/product-detail.js +19 -17
  63. package/dist/esm/pages/static-v2.js +43 -20
  64. package/dist/esm/pages/static.js +19 -17
  65. package/dist/types/index.d.ts +34 -8
  66. package/package.json +8 -10
  67. package/dist/cjs/components/image-to-layout/ImageToLayoutInput.js +0 -193
  68. package/dist/cjs/components/image-to-layout/PagesSuggestion.js +0 -80
  69. package/dist/esm/components/image-to-layout/ImageToLayoutInput.js +0 -191
  70. package/dist/esm/components/image-to-layout/PagesSuggestion.js +0 -78
@@ -2,36 +2,171 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ var jsxRuntime = require('react/jsx-runtime');
5
6
  var react = require('react');
7
+ var Onboarding = require('./toolbar/Onboarding.js');
6
8
 
7
9
  const TOOLBAR_HOVER_HEIGHT = 24;
8
10
  const TOOLBAR_ACTIVE_HEIGHT = 32;
11
+ const getDOMElementParents = ($el, selector, limit)=>{
12
+ // Set up a parent array
13
+ const parents = [];
14
+ // Push each parent $elms to the array
15
+ while($el){
16
+ $el = $el.parentElement ?? undefined;
17
+ if ($el) {
18
+ if ($el.tagName === 'BODY' || $el.getAttribute('data-uid') === 'ROOT') {
19
+ break;
20
+ }
21
+ if (selector) {
22
+ if ($el.matches(selector)) {
23
+ parents.push($el);
24
+ if (limit && parents.length == limit) {
25
+ return parents;
26
+ }
27
+ }
28
+ continue;
29
+ }
30
+ parents.push($el);
31
+ if (limit && parents.length == limit) {
32
+ return parents;
33
+ }
34
+ }
35
+ }
36
+ // Return our parent array
37
+ return parents;
38
+ };
39
+ const getChildrenByAttrSelector = ($el, attrSelector)=>{
40
+ const childLen = $el.children.length;
41
+ if (childLen) {
42
+ for(let i = 0; i < childLen; i++){
43
+ const children = $el.children[i];
44
+ if (children) {
45
+ const is = children.getAttribute(attrSelector);
46
+ if (is) {
47
+ return children;
48
+ }
49
+ }
50
+ }
51
+ }
52
+ };
53
+ const isOverParent = ({ current, parent: parent1, index, revert })=>{
54
+ for(let i = 0; i < index; i++){
55
+ 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;
56
+ if (revert) {
57
+ 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;
58
+ }
59
+ if (is) return true;
60
+ }
61
+ return false;
62
+ };
63
+ const waitForElementToExist = (selector, timeout = 200)=>{
64
+ return new Promise((resolve)=>{
65
+ const intervalID = setInterval(()=>{
66
+ const el = document.querySelector(selector);
67
+ if (el) {
68
+ clearInterval(intervalID);
69
+ clearTimeout(timeoutID);
70
+ resolve(el);
71
+ }
72
+ }, 50);
73
+ const timeoutID = setTimeout(()=>{
74
+ clearInterval(intervalID);
75
+ clearTimeout(timeoutID);
76
+ resolve(null);
77
+ }, timeout);
78
+ });
79
+ };
80
+ const notVisible = (el)=>{
81
+ const overflow = getComputedStyle(el).overflow;
82
+ return overflow !== 'visible';
83
+ };
84
+ const isSection = (el)=>{
85
+ const tag = el.getAttribute('data-component-tag');
86
+ return tag === 'Section';
87
+ };
88
+ const isLayoutElement = (el)=>{
89
+ const tag = el.getAttribute('data-component-tag');
90
+ return tag === 'Row' || tag === 'Product';
91
+ };
92
+ const isPopup = (el)=>{
93
+ const tag = el.getAttribute('data-component-tag');
94
+ return tag === 'Dialog';
95
+ };
96
+ const isSticky = (el)=>{
97
+ const tag = el.getAttribute('data-component-tag');
98
+ return tag === 'Sticky';
99
+ };
100
+ const isOverToolbarPosition = (el, parent1)=>{
101
+ const rect = el.getBoundingClientRect();
102
+ const rectP = parent1.getBoundingClientRect();
103
+ // 32px = toolbar active height
104
+ return rect.top - rectP.top < TOOLBAR_ACTIVE_HEIGHT + 1;
105
+ };
106
+ const findOverflowParent = (element, initEl)=>{
107
+ const thisEl = element;
108
+ const origEl = initEl || thisEl;
109
+ if (!thisEl) return;
110
+ if (isSection(thisEl)) return;
111
+ if (notVisible(thisEl) && isOverToolbarPosition(initEl, thisEl)) return thisEl;
112
+ if (thisEl.parentElement) {
113
+ return findOverflowParent(thisEl.parentElement, origEl);
114
+ } else {
115
+ return;
116
+ }
117
+ };
118
+ const COMPONENTS_TAG_NOT_LOAD_IMAGES = [
119
+ 'PostPurchaseProductImages'
120
+ ];
9
121
  const Toolbar = ()=>{
10
122
  const currentComponentActive = react.useRef(null);
11
123
  const isDragging = react.useRef(false);
12
124
  const stopWatchReRenderComponent = react.useRef();
13
125
  const isResizeSpacing = react.useRef(false);
126
+ const [isOnboarding, setIsOnboarding] = react.useState(false);
127
+ const [countShowOnboarding, setCountShowOnboarding] = react.useState(0);
128
+ const [onboardingPosition, setOnboardingPosition] = react.useState('bottom');
129
+ const timeoutRef = react.useRef(null);
130
+ const timeoutOnboarding = 5000;
14
131
  /* Functions */ const changePositionToolbar = ({ state, $toolbar, $component })=>{
15
132
  const $parentOverflow = findOverflowParent($component, $toolbar);
133
+ const rect = $toolbar.getBoundingClientRect();
134
+ const rectComponent = $component.getBoundingClientRect();
135
+ const windowWidth = window.innerWidth;
16
136
  if ($parentOverflow) {
17
- const rect = $component.getBoundingClientRect();
18
- if (rect?.height <= 60) {
137
+ if (rectComponent?.height <= 60) {
19
138
  $toolbar.setAttribute(`data-toolbar-${state}-revert`, 'true');
20
139
  } else {
21
140
  $toolbar.setAttribute(`data-toolbar-${state}-inside`, 'true');
22
141
  }
142
+ // fix toolbar overflow right side
143
+ if (rectComponent.left + rect.width > windowWidth) {
144
+ $toolbar.setAttribute(`data-toolbar-${state}-overflow`, 'true');
145
+ }
23
146
  } else {
24
- const rectComponent = $component.getBoundingClientRect();
25
- if (rectComponent.top < TOOLBAR_ACTIVE_HEIGHT + 1) {
147
+ if (rect.top < TOOLBAR_ACTIVE_HEIGHT + 1) {
26
148
  if (rectComponent?.height <= 60) {
27
149
  $toolbar.setAttribute(`data-toolbar-${state}-revert`, 'true');
28
150
  } else {
29
151
  $toolbar.setAttribute(`data-toolbar-${state}-inside`, 'true');
30
152
  }
31
153
  }
154
+ // fix toolbar overflow right side
155
+ if (rectComponent.left + rect.width > windowWidth) {
156
+ $toolbar.setAttribute(`data-toolbar-${state}-overflow`, 'true');
157
+ }
158
+ }
159
+ // fix Popup overflow right position
160
+ const popupEl = $component?.closest('[aria-label="Dialog body"]');
161
+ if (popupEl) {
162
+ const rectPopupEl = popupEl.getBoundingClientRect();
163
+ const popupElRightPosition = rectPopupEl.left + rectPopupEl.width - 20;
164
+ if (rectComponent.left + rect.width > popupElRightPosition) {
165
+ $toolbar.setAttribute(`data-toolbar-${state}-overflow`, 'true');
166
+ }
32
167
  }
33
168
  };
34
- const setHoverComponent = react.useCallback(({ $component, componentUid, focus, isThemeSection })=>{
169
+ const setHoverComponent = react.useCallback(({ $component, componentUid, focus, isThemeSection, isParent })=>{
35
170
  if (!$component && !componentUid) return;
36
171
  if (!$component) {
37
172
  const $c = document.querySelector(`[data-uid="${componentUid}"]`);
@@ -53,7 +188,9 @@ const Toolbar = ()=>{
53
188
  }
54
189
  if ($toolbar) {
55
190
  $toolbar.removeAttribute('style');
56
- $toolbar.setAttribute('data-toolbar-hover', 'true');
191
+ if (!isParent) {
192
+ $toolbar.setAttribute('data-toolbar-hover', 'true');
193
+ }
57
194
  if (focus) {
58
195
  $toolbar.setAttribute('data-toolbar-hover-focus', 'true');
59
196
  }
@@ -65,6 +202,9 @@ const Toolbar = ()=>{
65
202
  }
66
203
  if ($outline) {
67
204
  $outline.setAttribute('data-outline-hover', 'true');
205
+ if (isParent) {
206
+ $outline.setAttribute('data-outline-parent-hover', 'true');
207
+ }
68
208
  if (isThemeSection) {
69
209
  $outline.setAttribute('data-outline-overlay-theme-section', 'true');
70
210
  }
@@ -73,10 +213,14 @@ const Toolbar = ()=>{
73
213
  }
74
214
  }
75
215
  if ($btnAddTop) {
76
- $btnAddTop.setAttribute('data-toolbar-add-hover', 'true');
216
+ if (!isParent) {
217
+ $btnAddTop.setAttribute('data-toolbar-add-hover', 'true');
218
+ }
77
219
  }
78
220
  if ($btnAddBottom) {
79
- $btnAddBottom.setAttribute('data-toolbar-add-hover', 'true');
221
+ if (!isParent) {
222
+ $btnAddBottom.setAttribute('data-toolbar-add-hover', 'true');
223
+ }
80
224
  }
81
225
  }, []);
82
226
  const setHoverComponentParents = react.useCallback(({ $component, componentUid })=>{
@@ -85,12 +229,13 @@ const Toolbar = ()=>{
85
229
  if (!$c) return;
86
230
  $component = $c;
87
231
  }
88
- const $parents = getDOMElementParents($component, '[data-uid][data-component-type="component"]:not([data-component-no-setting])');
232
+ const $parents = getDOMElementParents($component, '[data-uid][data-component-type="component"]:not([data-component-no-setting])', 1);
89
233
  if ($parents.length) {
90
234
  for (const $parent of $parents){
91
235
  if ($parent) {
92
236
  setHoverComponent({
93
- $component: $parent
237
+ $component: $parent,
238
+ isParent: true
94
239
  });
95
240
  }
96
241
  }
@@ -167,7 +312,9 @@ const Toolbar = ()=>{
167
312
  'data-toolbar-hover-revert',
168
313
  'data-toolbar-hover-inside',
169
314
  'data-outline-hover',
170
- 'data-toolbar-add-hover'
315
+ 'data-toolbar-add-hover',
316
+ 'data-outline-parent-hover',
317
+ 'data-toolbar-hover-overflow'
171
318
  ];
172
319
  const $elms = document.querySelectorAll(clearAttrs.map((attr)=>`[${attr}]`).join(','));
173
320
  if ($elms) {
@@ -179,6 +326,21 @@ const Toolbar = ()=>{
179
326
  }, [
180
327
  removeHoverOverlayComponent
181
328
  ]);
329
+ const onCloseOnboarding = react.useCallback(()=>{
330
+ timeoutRef.current && clearTimeout(timeoutRef.current);
331
+ if (countShowOnboarding > 0) {
332
+ const eventCreate = new CustomEvent('editor:toolbar:close-onboarding', {
333
+ bubbles: true,
334
+ detail: {
335
+ close: 'close Onboarding'
336
+ }
337
+ });
338
+ window.dispatchEvent(eventCreate);
339
+ setIsOnboarding(false);
340
+ }
341
+ }, [
342
+ countShowOnboarding
343
+ ]);
182
344
  const removeActiveComponent = react.useCallback(()=>{
183
345
  currentComponentActive.current = null;
184
346
  const clearAttrs = [
@@ -189,7 +351,8 @@ const Toolbar = ()=>{
189
351
  'data-toolbar-active-inside',
190
352
  'data-spacing-margin-bottom-active',
191
353
  'data-toolbar-force-hover',
192
- 'data-outline-force-hover'
354
+ 'data-outline-force-hover',
355
+ 'data-toolbar-active-overflow'
193
356
  ];
194
357
  const $elms = document.querySelectorAll(clearAttrs.map((attr)=>`[${attr}]`).join(','));
195
358
  if ($elms) {
@@ -199,7 +362,10 @@ const Toolbar = ()=>{
199
362
  }
200
363
  setFocusTextEditor(false);
201
364
  if (stopWatchReRenderComponent.current) stopWatchReRenderComponent.current();
202
- }, []);
365
+ onCloseOnboarding();
366
+ }, [
367
+ onCloseOnboarding
368
+ ]);
203
369
  const watchComponentReRender = ($el, callback)=>{
204
370
  // editor:component:render
205
371
  const onComponentReRender = (e)=>{
@@ -210,13 +376,17 @@ const Toolbar = ()=>{
210
376
  };
211
377
  window.removeEventListener('editor:component:render', onComponentReRender);
212
378
  window.addEventListener('editor:component:render', onComponentReRender);
213
- const $images = $el.querySelectorAll('img');
214
- if ($images?.length) {
215
- $images.forEach(($img)=>{
216
- $img.addEventListener('load', ()=>{
217
- callback();
379
+ const componentTag = $el.getAttribute('data-component-tag');
380
+ // hotfix cho sale funnel release, nhưng cần tìm solution cho phần này
381
+ if (componentTag && !COMPONENTS_TAG_NOT_LOAD_IMAGES.includes(componentTag)) {
382
+ const $images = $el.querySelectorAll('img');
383
+ if ($images?.length) {
384
+ $images.forEach(($img)=>{
385
+ $img.addEventListener('load', ()=>{
386
+ callback();
387
+ });
218
388
  });
219
- });
389
+ }
220
390
  }
221
391
  stopWatchReRenderComponent.current = ()=>{
222
392
  window.removeEventListener('editor:component:render', onComponentReRender);
@@ -231,45 +401,80 @@ const Toolbar = ()=>{
231
401
  const $bg = $marginBottom.querySelector('[data-spacing-margin-bottom-bg]') || null;
232
402
  const $drag = $marginBottom.querySelector('[data-spacing-margin-bottom-drag]') || null;
233
403
  if ($bg && $drag) {
234
- const value = style.marginBottom;
404
+ let value = style.marginBottom;
405
+ if (parseFloat(value) < 0) {
406
+ value = '0';
407
+ }
235
408
  $bg.style.height = value;
236
409
  $drag.style.top = value;
237
410
  $marginBottom.setAttribute('data-spacing-margin-bottom-active', 'true');
411
+ if (isLayoutElement($component)) {
412
+ $bg.style.left = '0';
413
+ } else {
414
+ const paddingLeft = style.paddingLeft;
415
+ const leftValue = `-${paddingLeft}`;
416
+ const translateCss = `translate(${leftValue}, -100%)`;
417
+ $bg.style.left = leftValue;
418
+ $drag.style.transform = translateCss;
419
+ }
238
420
  }
239
421
  }
240
422
  }, []);
241
- const setActiveComponentForceHoverSection = react.useCallback(($component, value)=>{
242
- const $section = $component.closest('[data-toolbar-wrap][data-component-tag="Section"]');
243
- if ($section) {
244
- if (value) {
245
- const $toolbar = getChildrenByAttrSelector($section, 'data-toolbar');
246
- const $outline = getChildrenByAttrSelector($section, 'data-outline');
247
- if ($toolbar) {
248
- $toolbar.setAttribute('data-toolbar-force-hover', 'true');
249
- changePositionToolbar({
250
- $toolbar,
251
- $component,
252
- state: 'hover'
253
- });
254
- }
255
- if ($outline) {
256
- $outline.setAttribute('data-outline-force-hover', 'true');
257
- }
258
- } else {
259
- const $toolbar = getChildrenByAttrSelector($section, 'data-toolbar');
260
- const $outline = getChildrenByAttrSelector($section, 'data-outline');
261
- if ($toolbar) {
262
- $toolbar.removeAttribute('data-toolbar-force-hover');
263
- }
264
- if ($outline) {
265
- $outline.removeAttribute('data-outline-force-hover');
423
+ const calculateOnboardingPosition = ()=>{
424
+ const toolbar = document.querySelector('[data-toolbar-active]');
425
+ const toolbarOnboading = document.querySelector('[data-toolbar-onboarding]');
426
+ if (toolbar && toolbarOnboading) {
427
+ toolbarOnboading?.removeAttribute('data-onboarding-active');
428
+ setTimeout(()=>{
429
+ const rect = toolbar.getBoundingClientRect();
430
+ const rectTop = rect.top || 0;
431
+ const rectOnboading = toolbarOnboading?.getBoundingClientRect();
432
+ const onboardingHeight = rectOnboading?.height || 0;
433
+ const $iframe = parent.document.querySelector('.iframe');
434
+ const $iframeWin = $iframe?.contentWindow;
435
+ const iframeWinScrollY = $iframeWin?.scrollY || 0;
436
+ const iframeHeight = $iframe?.clientHeight || 0;
437
+ if (rectTop + onboardingHeight > iframeHeight) {
438
+ const oboardingTop = rect.top + iframeWinScrollY - onboardingHeight - 8;
439
+ toolbarOnboading?.setAttribute('style', `top: ${oboardingTop}px;left: ${rect.left}px;`);
440
+ setOnboardingPosition('top');
441
+ if ($iframeWin && oboardingTop < rect.top + iframeWinScrollY) {
442
+ setTimeout(()=>{
443
+ const toTop = oboardingTop - 20;
444
+ $iframeWin.scrollTo({
445
+ top: toTop,
446
+ behavior: 'smooth'
447
+ });
448
+ }, 200);
449
+ }
450
+ } else {
451
+ const oboardingTop = rect.top + iframeWinScrollY + rect.height + 8;
452
+ toolbarOnboading?.setAttribute('style', `top: ${oboardingTop}px;left: ${rect.left}px;`);
453
+ setOnboardingPosition('bottom');
266
454
  }
267
- }
455
+ setCountShowOnboarding((countShowOnboarding)=>countShowOnboarding + 1);
456
+ toolbarOnboading?.setAttribute('data-onboarding-active', 'true');
457
+ }, 100);
268
458
  }
269
- }, []);
459
+ };
460
+ const setToolbarOnboarding = react.useCallback(({ $component })=>{
461
+ if (!$component) return;
462
+ if (isSection($component) || isPopup($component) || isSticky($component)) return;
463
+ const toolbarOnboading = document.querySelector('[data-toolbar-onboarding]');
464
+ // only show one time
465
+ if (countShowOnboarding == 0) {
466
+ calculateOnboardingPosition();
467
+ } else {
468
+ onCloseOnboarding();
469
+ toolbarOnboading?.removeAttribute('data-onboarding-active');
470
+ }
471
+ }, [
472
+ countShowOnboarding,
473
+ onCloseOnboarding
474
+ ]);
270
475
  const setActiveComponent = react.useCallback(async ({ componentUid, productId, timeAwait = 500, forceReActive })=>{
271
476
  if (!componentUid) return;
272
- let $component = await waitForElementToExist(`${productId ? `[data-product-id="${productId}"] ` : ''}[data-uid="${componentUid}"]`, timeAwait);
477
+ let $component = await waitForElementToExist(`${productId ? `[data-product-id="${productId}"][data-uid="${componentUid}"], [data-product-id="${productId}"] [data-uid="${componentUid}"]` : `[data-uid="${componentUid}"]`}`, timeAwait);
273
478
  // check element fetch data: product, product list
274
479
  if (!$component) {
275
480
  const isLoading = document.querySelector(`.gp-loading-placeholder`);
@@ -327,7 +532,14 @@ const Toolbar = ()=>{
327
532
  setActiveComponentSpacing({
328
533
  $component
329
534
  });
330
- setActiveComponentForceHoverSection($component, true);
535
+ timeoutRef.current && clearTimeout(timeoutRef.current);
536
+ timeoutRef.current = setTimeout(()=>{
537
+ if ($component) {
538
+ setToolbarOnboarding({
539
+ $component
540
+ });
541
+ }
542
+ }, timeoutOnboarding);
331
543
  removeHoverComponent();
332
544
  // Reactive when component re-render
333
545
  watchComponentReRender($component, ()=>{
@@ -341,8 +553,8 @@ const Toolbar = ()=>{
341
553
  }, [
342
554
  removeActiveComponent,
343
555
  removeHoverComponent,
344
- setActiveComponentForceHoverSection,
345
- setActiveComponentSpacing
556
+ setActiveComponentSpacing,
557
+ setToolbarOnboarding
346
558
  ]);
347
559
  const setFocusTextEditor = async (value)=>{
348
560
  if (!value) {
@@ -465,7 +677,7 @@ const Toolbar = ()=>{
465
677
  if (isDragging.current) return;
466
678
  if (isResizeSpacing.current) return;
467
679
  const $target = e.target;
468
- if (!$target) {
680
+ if (!$target || typeof $target.closest !== 'function') {
469
681
  removeHoverOverlayComponent();
470
682
  return;
471
683
  }
@@ -608,6 +820,46 @@ const Toolbar = ()=>{
608
820
  }, [
609
821
  removeHoverComponent
610
822
  ]);
823
+ const setHoverParentComponent = (uid, type)=>{
824
+ if (!uid) return;
825
+ const $parentComponents = document.querySelectorAll(`[data-uid="${uid}"]`);
826
+ if ($parentComponents.length) {
827
+ $parentComponents.forEach(($parentComponent)=>{
828
+ const $outline = getChildrenByAttrSelector($parentComponent, 'data-outline');
829
+ if ($outline) {
830
+ if (type === 'in') {
831
+ $outline.setAttribute('data-outline-force-hover', 'true');
832
+ $outline.setAttribute('data-outline-force-overlay', 'true');
833
+ } else {
834
+ $outline.removeAttribute('data-outline-force-hover');
835
+ $outline.removeAttribute('data-outline-force-overlay');
836
+ }
837
+ }
838
+ });
839
+ }
840
+ };
841
+ const onHoverComponent = react.useCallback((e)=>{
842
+ if (isDragging.current) return;
843
+ const detail = e.detail;
844
+ if (detail?.componentUid) {
845
+ setHoverParentComponent(detail?.componentUid, detail?.type);
846
+ }
847
+ }, [
848
+ isDragging
849
+ ]);
850
+ const onToolbarOnboarding = react.useCallback((e)=>{
851
+ const detail = e.detail;
852
+ if (detail?.isNewUser) {
853
+ setIsOnboarding(true);
854
+ }
855
+ }, []);
856
+ const onWindowResize = react.useCallback(()=>{
857
+ if (isOnboarding) {
858
+ calculateOnboardingPosition();
859
+ }
860
+ }, [
861
+ isOnboarding
862
+ ]);
611
863
  /* Register event */ react.useEffect(()=>{
612
864
  document.addEventListener('mousemove', onMouseMove);
613
865
  window.addEventListener('editor:active-component', onActiveComponent);
@@ -616,6 +868,9 @@ const Toolbar = ()=>{
616
868
  window.addEventListener('editor:is-editing-text-editor', onIsEditingTextEditor);
617
869
  window.addEventListener('editor:toolbar:show-parents', onShowParents);
618
870
  window.addEventListener('editor:toolbar:resize-spacing', onResizeSpacing);
871
+ window.addEventListener('editor:hover-component', onHoverComponent);
872
+ window.addEventListener('editor:toolbar-onboarding', onToolbarOnboarding);
873
+ window.addEventListener('resize', onWindowResize);
619
874
  return ()=>{
620
875
  document.removeEventListener('mousemove', onMouseMove);
621
876
  window.removeEventListener('editor:active-component', onActiveComponent);
@@ -624,6 +879,9 @@ const Toolbar = ()=>{
624
879
  window.removeEventListener('editor:is-editing-text-editor', onIsEditingTextEditor);
625
880
  window.removeEventListener('editor:toolbar:show-parents', onShowParents);
626
881
  window.removeEventListener('editor:toolbar:resize-spacing', onResizeSpacing);
882
+ window.removeEventListener('editor:hover-component', onHoverComponent);
883
+ window.removeEventListener('editor:toolbar-onboarding', onToolbarOnboarding);
884
+ window.removeEventListener('resize', onWindowResize);
627
885
  };
628
886
  }, [
629
887
  onMouseMove,
@@ -632,105 +890,17 @@ const Toolbar = ()=>{
632
890
  onIsDragging,
633
891
  onIsEditingTextEditor,
634
892
  onShowParents,
635
- onResizeSpacing
893
+ onResizeSpacing,
894
+ onHoverComponent,
895
+ onToolbarOnboarding,
896
+ onWindowResize
636
897
  ]);
637
- return null;
638
- };
639
- const getDOMElementParents = ($el, selector, limit)=>{
640
- // Set up a parent array
641
- const parents = [];
642
- // Push each parent $elms to the array
643
- while($el){
644
- $el = $el.parentElement ?? undefined;
645
- if ($el) {
646
- if ($el.tagName === 'BODY' || $el.getAttribute('data-uid') === 'ROOT') {
647
- break;
648
- }
649
- if (selector) {
650
- if ($el.matches(selector)) {
651
- parents.push($el);
652
- if (limit && parents.length == limit) {
653
- return parents;
654
- }
655
- }
656
- continue;
657
- }
658
- parents.push($el);
659
- if (limit && parents.length == limit) {
660
- return parents;
661
- }
662
- }
663
- }
664
- // Return our parent array
665
- return parents;
666
- };
667
- const getChildrenByAttrSelector = ($el, attrSelector)=>{
668
- const childLen = $el.children.length;
669
- if (childLen) {
670
- for(let i = 0; i < childLen; i++){
671
- const children = $el.children[i];
672
- if (children) {
673
- const is = children.getAttribute(attrSelector);
674
- if (is) {
675
- return children;
676
- }
677
- }
678
- }
679
- }
680
- };
681
- const isOverParent = ({ current, parent, index, revert })=>{
682
- for(let i = 0; i < index; i++){
683
- let is = current.top - (TOOLBAR_HOVER_HEIGHT - 1) * i >= parent.top && current.top - (TOOLBAR_HOVER_HEIGHT - 1) * i <= parent.top + parent.height || current.top - (TOOLBAR_HOVER_HEIGHT - 1) * i >= parent.top + parent.height && current.top - (TOOLBAR_HOVER_HEIGHT - 1) * i <= parent.top;
684
- if (revert) {
685
- is = current.bottom + (TOOLBAR_HOVER_HEIGHT - 1) * i >= parent.bottom && current.bottom + (TOOLBAR_HOVER_HEIGHT - 1) * i <= parent.bottom - parent.height || current.bottom + (TOOLBAR_HOVER_HEIGHT - 1) * i >= parent.bottom - parent.height && current.bottom + (TOOLBAR_HOVER_HEIGHT - 1) * i <= parent.bottom;
686
- }
687
- if (is) return true;
688
- }
689
- return false;
690
- };
691
- const waitForElementToExist = (selector, timeout = 200)=>{
692
- return new Promise((resolve)=>{
693
- const intervalID = setInterval(()=>{
694
- const el = document.querySelector(selector);
695
- if (el) {
696
- clearInterval(intervalID);
697
- clearTimeout(timeoutID);
698
- resolve(el);
699
- }
700
- }, 50);
701
- const timeoutID = setTimeout(()=>{
702
- clearInterval(intervalID);
703
- clearTimeout(timeoutID);
704
- resolve(null);
705
- }, timeout);
898
+ return isOnboarding && /*#__PURE__*/ jsxRuntime.jsx(Onboarding.default, {
899
+ enable: true,
900
+ position: onboardingPosition,
901
+ onCloseOnboarding: onCloseOnboarding
706
902
  });
707
903
  };
708
- const notVisible = (el)=>{
709
- const overflow = getComputedStyle(el).overflow;
710
- return overflow !== 'visible';
711
- };
712
- const isSection = (el)=>{
713
- const tag = el.getAttribute('data-component-tag');
714
- return tag === 'Section';
715
- };
716
- const isOverToolbarPosition = (el, parent)=>{
717
- const rect = el.getBoundingClientRect();
718
- const rectP = parent.getBoundingClientRect();
719
- // 32px = toolbar active height
720
- return rect.top - rectP.top < TOOLBAR_ACTIVE_HEIGHT + 1;
721
- };
722
- const findOverflowParent = (element, initEl)=>{
723
- const thisEl = element;
724
- const origEl = initEl || thisEl;
725
- if (!thisEl) return;
726
- if (isSection(thisEl)) return;
727
- if (notVisible(thisEl) && isOverToolbarPosition(initEl, thisEl)) return thisEl;
728
- if (thisEl.parentElement) {
729
- return findOverflowParent(thisEl.parentElement, origEl);
730
- } else {
731
- return;
732
- }
733
- };
734
904
  var Toolbar$1 = /*#__PURE__*/ react.memo(Toolbar);
735
905
 
736
906
  exports.default = Toolbar$1;