@gem-sdk/pages 1.23.0-staging.31 → 1.23.0-staging.322

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.
@@ -1,119 +1,43 @@
1
- import { memo, useRef, useCallback, useEffect } from 'react';
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { memo, useRef, useState, useCallback, useEffect } from 'react';
3
+ import Onboarding from './toolbar/Onboarding.js';
2
4
 
3
5
  const TOOLBAR_HOVER_HEIGHT = 24;
4
6
  const TOOLBAR_ACTIVE_HEIGHT = 32;
5
- const getDOMElementParents = ($el, selector, limit)=>{
6
- // Set up a parent array
7
- const parents = [];
8
- // Push each parent $elms to the array
9
- while($el){
10
- $el = $el.parentElement ?? undefined;
11
- if ($el) {
12
- if ($el.tagName === 'BODY' || $el.getAttribute('data-uid') === 'ROOT') {
13
- break;
14
- }
15
- if (selector) {
16
- if ($el.matches(selector)) {
17
- parents.push($el);
18
- if (limit && parents.length == limit) {
19
- return parents;
20
- }
21
- }
22
- continue;
23
- }
24
- parents.push($el);
25
- if (limit && parents.length == limit) {
26
- return parents;
27
- }
28
- }
29
- }
30
- // Return our parent array
31
- return parents;
32
- };
33
- const getChildrenByAttrSelector = ($el, attrSelector)=>{
34
- const childLen = $el.children.length;
35
- if (childLen) {
36
- for(let i = 0; i < childLen; i++){
37
- const children = $el.children[i];
38
- if (children) {
39
- const is = children.getAttribute(attrSelector);
40
- if (is) {
41
- return children;
42
- }
43
- }
44
- }
45
- }
46
- };
47
- const isOverParent = ({ current, parent, index, revert })=>{
48
- for(let i = 0; i < index; i++){
49
- 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;
50
- if (revert) {
51
- 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;
52
- }
53
- if (is) return true;
54
- }
55
- return false;
56
- };
57
- const waitForElementToExist = (selector, timeout = 200)=>{
58
- return new Promise((resolve)=>{
59
- const intervalID = setInterval(()=>{
60
- const el = document.querySelector(selector);
61
- if (el) {
62
- clearInterval(intervalID);
63
- clearTimeout(timeoutID);
64
- resolve(el);
65
- }
66
- }, 50);
67
- const timeoutID = setTimeout(()=>{
68
- clearInterval(intervalID);
69
- clearTimeout(timeoutID);
70
- resolve(null);
71
- }, timeout);
72
- });
73
- };
74
- const notVisible = (el)=>{
75
- const overflow = getComputedStyle(el).overflow;
76
- return overflow !== 'visible';
77
- };
78
- const isSection = (el)=>{
7
+ const isPopup = (el)=>{
79
8
  const tag = el.getAttribute('data-component-tag');
80
- return tag === 'Section';
9
+ return tag === 'Dialog';
81
10
  };
82
- const isOverToolbarPosition = (el, parent)=>{
83
- const rect = el.getBoundingClientRect();
84
- const rectP = parent.getBoundingClientRect();
85
- // 32px = toolbar active height
86
- return rect.top - rectP.top < TOOLBAR_ACTIVE_HEIGHT + 1;
87
- };
88
- const findOverflowParent = (element, initEl)=>{
89
- const thisEl = element;
90
- const origEl = initEl || thisEl;
91
- if (!thisEl) return;
92
- if (isSection(thisEl)) return;
93
- if (notVisible(thisEl) && isOverToolbarPosition(initEl, thisEl)) return thisEl;
94
- if (thisEl.parentElement) {
95
- return findOverflowParent(thisEl.parentElement, origEl);
96
- } else {
97
- return;
98
- }
11
+ const isSticky = (el)=>{
12
+ const tag = el.getAttribute('data-component-tag');
13
+ return tag === 'Sticky';
99
14
  };
100
15
  const Toolbar = ()=>{
101
16
  const currentComponentActive = useRef(null);
102
17
  const isDragging = useRef(false);
103
- const obsActiveComponent = useRef();
18
+ const stopWatchReRenderComponent = useRef();
104
19
  const isResizeSpacing = useRef(false);
20
+ const [isOnboarding, setIsOnboarding] = useState(false);
21
+ const [countShowOnboarding, setCountShowOnboarding] = useState(0);
22
+ const [onboardingPosition, setOnboardingPosition] = useState('bottom');
23
+ const timeoutRef = useRef(null);
24
+ const timeoutOnboarding = 5000;
105
25
  /* Functions */ const changePositionToolbar = ({ state, $toolbar, $component })=>{
106
26
  const $parentOverflow = findOverflowParent($component, $toolbar);
27
+ const rect = $toolbar.getBoundingClientRect();
28
+ const rectComponent = $component.getBoundingClientRect();
29
+ const windowWidth = window.innerWidth;
107
30
  if ($parentOverflow) {
108
- const rect = $component.getBoundingClientRect();
109
- if (rect?.height <= 60) {
31
+ if (rectComponent?.height <= 60) {
110
32
  $toolbar.setAttribute(`data-toolbar-${state}-revert`, 'true');
111
33
  } else {
112
34
  $toolbar.setAttribute(`data-toolbar-${state}-inside`, 'true');
113
35
  }
36
+ // fix toolbar overflow right side
37
+ if (rectComponent.left + rect.width > windowWidth) {
38
+ $toolbar.setAttribute(`data-toolbar-${state}-overflow`, 'true');
39
+ }
114
40
  } else {
115
- const rect = $toolbar.getBoundingClientRect();
116
- const rectComponent = $component.getBoundingClientRect();
117
41
  if (rect.top < TOOLBAR_ACTIVE_HEIGHT + 1) {
118
42
  if (rectComponent?.height <= 60) {
119
43
  $toolbar.setAttribute(`data-toolbar-${state}-revert`, 'true');
@@ -121,9 +45,22 @@ const Toolbar = ()=>{
121
45
  $toolbar.setAttribute(`data-toolbar-${state}-inside`, 'true');
122
46
  }
123
47
  }
48
+ // fix toolbar overflow right side
49
+ if (rectComponent.left + rect.width > windowWidth) {
50
+ $toolbar.setAttribute(`data-toolbar-${state}-overflow`, 'true');
51
+ }
52
+ }
53
+ // fix Popup overflow right position
54
+ const popupEl = $component?.closest('[aria-label="Dialog body"]');
55
+ if (popupEl) {
56
+ const rectPopupEl = popupEl.getBoundingClientRect();
57
+ const popupElRightPosition = rectPopupEl.left + rectPopupEl.width - 20;
58
+ if (rectComponent.left + rect.width > popupElRightPosition) {
59
+ $toolbar.setAttribute(`data-toolbar-${state}-overflow`, 'true');
60
+ }
124
61
  }
125
62
  };
126
- const setHoverComponent = useCallback(({ $component, componentUid, focus, isThemeSection })=>{
63
+ const setHoverComponent = useCallback(({ $component, componentUid, focus, isThemeSection, isParent })=>{
127
64
  if (!$component && !componentUid) return;
128
65
  if (!$component) {
129
66
  const $c = document.querySelector(`[data-uid="${componentUid}"]`);
@@ -145,7 +82,9 @@ const Toolbar = ()=>{
145
82
  }
146
83
  if ($toolbar) {
147
84
  $toolbar.removeAttribute('style');
148
- $toolbar.setAttribute('data-toolbar-hover', 'true');
85
+ if (!isParent) {
86
+ $toolbar.setAttribute('data-toolbar-hover', 'true');
87
+ }
149
88
  if (focus) {
150
89
  $toolbar.setAttribute('data-toolbar-hover-focus', 'true');
151
90
  }
@@ -157,6 +96,9 @@ const Toolbar = ()=>{
157
96
  }
158
97
  if ($outline) {
159
98
  $outline.setAttribute('data-outline-hover', 'true');
99
+ if (isParent) {
100
+ $outline.setAttribute('data-outline-parent-hover', 'true');
101
+ }
160
102
  if (isThemeSection) {
161
103
  $outline.setAttribute('data-outline-overlay-theme-section', 'true');
162
104
  }
@@ -165,10 +107,14 @@ const Toolbar = ()=>{
165
107
  }
166
108
  }
167
109
  if ($btnAddTop) {
168
- $btnAddTop.setAttribute('data-toolbar-add-hover', 'true');
110
+ if (!isParent) {
111
+ $btnAddTop.setAttribute('data-toolbar-add-hover', 'true');
112
+ }
169
113
  }
170
114
  if ($btnAddBottom) {
171
- $btnAddBottom.setAttribute('data-toolbar-add-hover', 'true');
115
+ if (!isParent) {
116
+ $btnAddBottom.setAttribute('data-toolbar-add-hover', 'true');
117
+ }
172
118
  }
173
119
  }, []);
174
120
  const setHoverComponentParents = useCallback(({ $component, componentUid })=>{
@@ -177,12 +123,13 @@ const Toolbar = ()=>{
177
123
  if (!$c) return;
178
124
  $component = $c;
179
125
  }
180
- const $parents = getDOMElementParents($component, '[data-uid][data-component-type="component"]:not([data-component-no-setting])');
126
+ const $parents = getDOMElementParents($component, '[data-uid][data-component-type="component"]:not([data-component-no-setting])', 1);
181
127
  if ($parents.length) {
182
128
  for (const $parent of $parents){
183
129
  if ($parent) {
184
130
  setHoverComponent({
185
- $component: $parent
131
+ $component: $parent,
132
+ isParent: true
186
133
  });
187
134
  }
188
135
  }
@@ -259,7 +206,9 @@ const Toolbar = ()=>{
259
206
  'data-toolbar-hover-revert',
260
207
  'data-toolbar-hover-inside',
261
208
  'data-outline-hover',
262
- 'data-toolbar-add-hover'
209
+ 'data-toolbar-add-hover',
210
+ 'data-outline-parent-hover',
211
+ 'data-toolbar-hover-overflow'
263
212
  ];
264
213
  const $elms = document.querySelectorAll(clearAttrs.map((attr)=>`[${attr}]`).join(','));
265
214
  if ($elms) {
@@ -271,6 +220,21 @@ const Toolbar = ()=>{
271
220
  }, [
272
221
  removeHoverOverlayComponent
273
222
  ]);
223
+ const onCloseOnboarding = useCallback(()=>{
224
+ timeoutRef.current && clearTimeout(timeoutRef.current);
225
+ if (countShowOnboarding > 0) {
226
+ const eventCreate = new CustomEvent('editor:toolbar:close-onboarding', {
227
+ bubbles: true,
228
+ detail: {
229
+ close: 'close Onboarding'
230
+ }
231
+ });
232
+ window.dispatchEvent(eventCreate);
233
+ setIsOnboarding(false);
234
+ }
235
+ }, [
236
+ countShowOnboarding
237
+ ]);
274
238
  const removeActiveComponent = useCallback(()=>{
275
239
  currentComponentActive.current = null;
276
240
  const clearAttrs = [
@@ -281,7 +245,8 @@ const Toolbar = ()=>{
281
245
  'data-toolbar-active-inside',
282
246
  'data-spacing-margin-bottom-active',
283
247
  'data-toolbar-force-hover',
284
- 'data-outline-force-hover'
248
+ 'data-outline-force-hover',
249
+ 'data-toolbar-active-overflow'
285
250
  ];
286
251
  const $elms = document.querySelectorAll(clearAttrs.map((attr)=>`[${attr}]`).join(','));
287
252
  if ($elms) {
@@ -290,25 +255,32 @@ const Toolbar = ()=>{
290
255
  });
291
256
  }
292
257
  setFocusTextEditor(false);
293
- if (obsActiveComponent.current) obsActiveComponent.current.disconnect();
294
- }, []);
258
+ if (stopWatchReRenderComponent.current) stopWatchReRenderComponent.current();
259
+ onCloseOnboarding();
260
+ }, [
261
+ onCloseOnboarding
262
+ ]);
295
263
  const watchComponentReRender = ($el, callback)=>{
296
- const parent = $el.parentNode;
297
- if (!parent) return;
298
- if (obsActiveComponent.current) obsActiveComponent.current.disconnect();
299
- obsActiveComponent.current = new MutationObserver((mutations)=>{
300
- for (const mutation of mutations){
301
- mutation.removedNodes.forEach((el)=>{
302
- if (el === $el) {
303
- if (obsActiveComponent.current) obsActiveComponent.current.disconnect();
304
- callback();
305
- }
306
- });
264
+ // editor:component:render
265
+ const onComponentReRender = (e)=>{
266
+ const detail = e.detail;
267
+ if (detail?.componentUid == currentComponentActive.current?.componentUid) {
268
+ callback();
307
269
  }
308
- });
309
- obsActiveComponent.current.observe(parent, {
310
- childList: true
311
- });
270
+ };
271
+ window.removeEventListener('editor:component:render', onComponentReRender);
272
+ window.addEventListener('editor:component:render', onComponentReRender);
273
+ const $images = $el.querySelectorAll('img');
274
+ if ($images?.length) {
275
+ $images.forEach(($img)=>{
276
+ $img.addEventListener('load', ()=>{
277
+ callback();
278
+ });
279
+ });
280
+ }
281
+ stopWatchReRenderComponent.current = ()=>{
282
+ window.removeEventListener('editor:component:render', onComponentReRender);
283
+ };
312
284
  };
313
285
  const setActiveComponentSpacing = useCallback(({ $component })=>{
314
286
  if (!$component) return;
@@ -319,43 +291,96 @@ const Toolbar = ()=>{
319
291
  const $bg = $marginBottom.querySelector('[data-spacing-margin-bottom-bg]') || null;
320
292
  const $drag = $marginBottom.querySelector('[data-spacing-margin-bottom-drag]') || null;
321
293
  if ($bg && $drag) {
322
- const value = style.marginBottom;
294
+ let value = style.marginBottom;
295
+ if (parseFloat(value) < 0) {
296
+ value = '0';
297
+ }
323
298
  $bg.style.height = value;
324
299
  $drag.style.top = value;
325
300
  $marginBottom.setAttribute('data-spacing-margin-bottom-active', 'true');
301
+ if (isLayoutElement($component)) {
302
+ $bg.style.left = '0';
303
+ } else {
304
+ const paddingLeft = style.paddingLeft;
305
+ const leftValue = `-${paddingLeft}`;
306
+ const translateCss = `translate(${leftValue}, -100%)`;
307
+ $bg.style.left = leftValue;
308
+ $drag.style.transform = translateCss;
309
+ }
326
310
  }
327
311
  }
328
312
  }, []);
329
- const setActiveComponentForceHoverSection = ($component, value)=>{
330
- const $section = $component.closest('[data-toolbar-wrap][data-component-tag="Section"]');
331
- if ($section) {
332
- if (value) {
333
- const $toolbar = getChildrenByAttrSelector($section, 'data-toolbar');
334
- const $outline = getChildrenByAttrSelector($section, 'data-outline');
335
- if ($toolbar) {
336
- $toolbar.setAttribute('data-toolbar-force-hover', 'true');
337
- }
338
- if ($outline) {
339
- $outline.setAttribute('data-outline-force-hover', 'true');
340
- }
341
- } else {
342
- const $toolbar = getChildrenByAttrSelector($section, 'data-toolbar');
343
- const $outline = getChildrenByAttrSelector($section, 'data-outline');
344
- if ($toolbar) {
345
- $toolbar.removeAttribute('data-toolbar-force-hover');
346
- }
347
- if ($outline) {
348
- $outline.removeAttribute('data-outline-force-hover');
313
+ const calculateOnboardingPosition = ()=>{
314
+ const toolbar = document.querySelector('[data-toolbar-active]');
315
+ const toolbarOnboading = document.querySelector('[data-toolbar-onboarding]');
316
+ if (toolbar && toolbarOnboading) {
317
+ toolbarOnboading?.removeAttribute('data-onboarding-active');
318
+ setTimeout(()=>{
319
+ const rect = toolbar.getBoundingClientRect();
320
+ const rectTop = rect.top || 0;
321
+ const rectOnboading = toolbarOnboading?.getBoundingClientRect();
322
+ const onboardingHeight = rectOnboading?.height || 0;
323
+ const $iframe = parent.document.querySelector('.iframe');
324
+ const $iframeWin = $iframe?.contentWindow;
325
+ const iframeWinScrollY = $iframeWin?.scrollY || 0;
326
+ const iframeHeight = $iframe?.clientHeight || 0;
327
+ if (rectTop + onboardingHeight > iframeHeight) {
328
+ const oboardingTop = rect.top + iframeWinScrollY - onboardingHeight - 8;
329
+ toolbarOnboading?.setAttribute('style', `top: ${oboardingTop}px;left: ${rect.left}px;`);
330
+ setOnboardingPosition('top');
331
+ if ($iframeWin && oboardingTop < rect.top + iframeWinScrollY) {
332
+ setTimeout(()=>{
333
+ const toTop = oboardingTop - 20;
334
+ $iframeWin.scrollTo({
335
+ top: toTop,
336
+ behavior: 'smooth'
337
+ });
338
+ }, 200);
339
+ }
340
+ } else {
341
+ const oboardingTop = rect.top + iframeWinScrollY + rect.height + 8;
342
+ toolbarOnboading?.setAttribute('style', `top: ${oboardingTop}px;left: ${rect.left}px;`);
343
+ setOnboardingPosition('bottom');
349
344
  }
350
- }
345
+ setCountShowOnboarding((countShowOnboarding)=>countShowOnboarding + 1);
346
+ toolbarOnboading?.setAttribute('data-onboarding-active', 'true');
347
+ }, 100);
351
348
  }
352
349
  };
350
+ const setToolbarOnboarding = useCallback(({ $component })=>{
351
+ if (!$component) return;
352
+ if (isSection($component) || isPopup($component) || isSticky($component)) return;
353
+ const toolbarOnboading = document.querySelector('[data-toolbar-onboarding]');
354
+ // only show one time
355
+ if (countShowOnboarding == 0) {
356
+ calculateOnboardingPosition();
357
+ } else {
358
+ onCloseOnboarding();
359
+ toolbarOnboading?.removeAttribute('data-onboarding-active');
360
+ }
361
+ }, [
362
+ countShowOnboarding,
363
+ onCloseOnboarding
364
+ ]);
353
365
  const setActiveComponent = useCallback(async ({ componentUid, productId, timeAwait = 500, forceReActive })=>{
354
366
  if (!componentUid) return;
355
- const $component = await waitForElementToExist(`${productId ? `[data-product-id="${productId}"] ` : ''}[data-uid="${componentUid}"]`, timeAwait);
356
- if (!$component) return;
367
+ let $component = await waitForElementToExist(`${productId ? `[data-product-id="${productId}"] ` : ''}[data-uid="${componentUid}"]`, timeAwait);
368
+ // check element fetch data: product, product list
369
+ if (!$component) {
370
+ const isLoading = document.querySelector(`.gp-loading-placeholder`);
371
+ if (!isLoading) {
372
+ return;
373
+ }
374
+ if (isLoading) {
375
+ // await element onload
376
+ $component = await waitForElementToExist(`${productId ? `[data-product-id="${productId}"] ` : ''}[data-uid="${componentUid}"]`, 15000);
377
+ }
378
+ }
379
+ if (!$component) {
380
+ return;
381
+ }
357
382
  if (!forceReActive && componentUid == currentComponentActive.current?.componentUid && productId == currentComponentActive.current?.productId) return;
358
- if (!forceReActive && componentUid !== currentComponentActive.current?.componentUid || productId !== currentComponentActive.current?.productId) removeActiveComponent();
383
+ if (componentUid !== currentComponentActive.current?.componentUid || productId !== currentComponentActive.current?.productId || forceReActive) removeActiveComponent();
359
384
  const $toolbar = getChildrenByAttrSelector($component, 'data-toolbar');
360
385
  const $outline = getChildrenByAttrSelector($component, 'data-outline');
361
386
  const $btnAddTop = getChildrenByAttrSelector($component, 'data-toolbar-add-top');
@@ -397,7 +422,14 @@ const Toolbar = ()=>{
397
422
  setActiveComponentSpacing({
398
423
  $component
399
424
  });
400
- setActiveComponentForceHoverSection($component, true);
425
+ timeoutRef.current && clearTimeout(timeoutRef.current);
426
+ timeoutRef.current = setTimeout(()=>{
427
+ if ($component) {
428
+ setToolbarOnboarding({
429
+ $component
430
+ });
431
+ }
432
+ }, timeoutOnboarding);
401
433
  removeHoverComponent();
402
434
  // Reactive when component re-render
403
435
  watchComponentReRender($component, ()=>{
@@ -411,7 +443,8 @@ const Toolbar = ()=>{
411
443
  }, [
412
444
  removeActiveComponent,
413
445
  removeHoverComponent,
414
- setActiveComponentSpacing
446
+ setActiveComponentSpacing,
447
+ setToolbarOnboarding
415
448
  ]);
416
449
  const setFocusTextEditor = async (value)=>{
417
450
  if (!value) {
@@ -534,7 +567,7 @@ const Toolbar = ()=>{
534
567
  if (isDragging.current) return;
535
568
  if (isResizeSpacing.current) return;
536
569
  const $target = e.target;
537
- if (!$target) {
570
+ if (!$target || typeof $target.closest !== 'function') {
538
571
  removeHoverOverlayComponent();
539
572
  return;
540
573
  }
@@ -577,6 +610,7 @@ const Toolbar = ()=>{
577
610
  if ($product) {
578
611
  const productId = $product.getAttribute('data-product-id');
579
612
  if (productId == currentComponentActive.current.productId) {
613
+ removeHoverComponent();
580
614
  return;
581
615
  }
582
616
  }
@@ -676,6 +710,46 @@ const Toolbar = ()=>{
676
710
  }, [
677
711
  removeHoverComponent
678
712
  ]);
713
+ const setHoverParentComponent = (uid, type)=>{
714
+ if (!uid) return;
715
+ const $parentComponents = document.querySelectorAll(`[data-uid="${uid}"]`);
716
+ if ($parentComponents.length) {
717
+ $parentComponents.forEach(($parentComponent)=>{
718
+ const $outline = getChildrenByAttrSelector($parentComponent, 'data-outline');
719
+ if ($outline) {
720
+ if (type === 'in') {
721
+ $outline.setAttribute('data-outline-force-hover', 'true');
722
+ $outline.setAttribute('data-outline-force-overlay', 'true');
723
+ } else {
724
+ $outline.removeAttribute('data-outline-force-hover');
725
+ $outline.removeAttribute('data-outline-force-overlay');
726
+ }
727
+ }
728
+ });
729
+ }
730
+ };
731
+ const onHoverComponent = useCallback((e)=>{
732
+ if (isDragging.current) return;
733
+ const detail = e.detail;
734
+ if (detail?.componentUid) {
735
+ setHoverParentComponent(detail?.componentUid, detail?.type);
736
+ }
737
+ }, [
738
+ isDragging
739
+ ]);
740
+ const onToolbarOnboarding = useCallback((e)=>{
741
+ const detail = e.detail;
742
+ if (detail?.isNewUser) {
743
+ setIsOnboarding(true);
744
+ }
745
+ }, []);
746
+ const onWindowResize = useCallback(()=>{
747
+ if (isOnboarding) {
748
+ calculateOnboardingPosition();
749
+ }
750
+ }, [
751
+ isOnboarding
752
+ ]);
679
753
  /* Register event */ useEffect(()=>{
680
754
  document.addEventListener('mousemove', onMouseMove);
681
755
  window.addEventListener('editor:active-component', onActiveComponent);
@@ -684,6 +758,9 @@ const Toolbar = ()=>{
684
758
  window.addEventListener('editor:is-editing-text-editor', onIsEditingTextEditor);
685
759
  window.addEventListener('editor:toolbar:show-parents', onShowParents);
686
760
  window.addEventListener('editor:toolbar:resize-spacing', onResizeSpacing);
761
+ window.addEventListener('editor:hover-component', onHoverComponent);
762
+ window.addEventListener('editor:toolbar-onboarding', onToolbarOnboarding);
763
+ window.addEventListener('resize', onWindowResize);
687
764
  return ()=>{
688
765
  document.removeEventListener('mousemove', onMouseMove);
689
766
  window.removeEventListener('editor:active-component', onActiveComponent);
@@ -692,6 +769,9 @@ const Toolbar = ()=>{
692
769
  window.removeEventListener('editor:is-editing-text-editor', onIsEditingTextEditor);
693
770
  window.removeEventListener('editor:toolbar:show-parents', onShowParents);
694
771
  window.removeEventListener('editor:toolbar:resize-spacing', onResizeSpacing);
772
+ window.removeEventListener('editor:hover-component', onHoverComponent);
773
+ window.removeEventListener('editor:toolbar-onboarding', onToolbarOnboarding);
774
+ window.removeEventListener('resize', onWindowResize);
695
775
  };
696
776
  }, [
697
777
  onMouseMove,
@@ -700,9 +780,115 @@ const Toolbar = ()=>{
700
780
  onIsDragging,
701
781
  onIsEditingTextEditor,
702
782
  onShowParents,
703
- onResizeSpacing
783
+ onResizeSpacing,
784
+ onHoverComponent,
785
+ onToolbarOnboarding,
786
+ onWindowResize
704
787
  ]);
705
- return null;
788
+ return isOnboarding && /*#__PURE__*/ jsx(Onboarding, {
789
+ enable: true,
790
+ position: onboardingPosition,
791
+ onCloseOnboarding: onCloseOnboarding
792
+ });
793
+ };
794
+ const getDOMElementParents = ($el, selector, limit)=>{
795
+ // Set up a parent array
796
+ const parents = [];
797
+ // Push each parent $elms to the array
798
+ while($el){
799
+ $el = $el.parentElement ?? undefined;
800
+ if ($el) {
801
+ if ($el.tagName === 'BODY' || $el.getAttribute('data-uid') === 'ROOT') {
802
+ break;
803
+ }
804
+ if (selector) {
805
+ if ($el.matches(selector)) {
806
+ parents.push($el);
807
+ if (limit && parents.length == limit) {
808
+ return parents;
809
+ }
810
+ }
811
+ continue;
812
+ }
813
+ parents.push($el);
814
+ if (limit && parents.length == limit) {
815
+ return parents;
816
+ }
817
+ }
818
+ }
819
+ // Return our parent array
820
+ return parents;
821
+ };
822
+ const getChildrenByAttrSelector = ($el, attrSelector)=>{
823
+ const childLen = $el.children.length;
824
+ if (childLen) {
825
+ for(let i = 0; i < childLen; i++){
826
+ const children = $el.children[i];
827
+ if (children) {
828
+ const is = children.getAttribute(attrSelector);
829
+ if (is) {
830
+ return children;
831
+ }
832
+ }
833
+ }
834
+ }
835
+ };
836
+ const isOverParent = ({ current, parent: parent1, index, revert })=>{
837
+ for(let i = 0; i < index; i++){
838
+ 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;
839
+ if (revert) {
840
+ 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;
841
+ }
842
+ if (is) return true;
843
+ }
844
+ return false;
845
+ };
846
+ const waitForElementToExist = (selector, timeout = 200)=>{
847
+ return new Promise((resolve)=>{
848
+ const intervalID = setInterval(()=>{
849
+ const el = document.querySelector(selector);
850
+ if (el) {
851
+ clearInterval(intervalID);
852
+ clearTimeout(timeoutID);
853
+ resolve(el);
854
+ }
855
+ }, 50);
856
+ const timeoutID = setTimeout(()=>{
857
+ clearInterval(intervalID);
858
+ clearTimeout(timeoutID);
859
+ resolve(null);
860
+ }, timeout);
861
+ });
862
+ };
863
+ const notVisible = (el)=>{
864
+ const overflow = getComputedStyle(el).overflow;
865
+ return overflow !== 'visible';
866
+ };
867
+ const isSection = (el)=>{
868
+ const tag = el.getAttribute('data-component-tag');
869
+ return tag === 'Section';
870
+ };
871
+ const isLayoutElement = (el)=>{
872
+ const tag = el.getAttribute('data-component-tag');
873
+ return tag === 'Row' || tag === 'Product';
874
+ };
875
+ const isOverToolbarPosition = (el, parent1)=>{
876
+ const rect = el.getBoundingClientRect();
877
+ const rectP = parent1.getBoundingClientRect();
878
+ // 32px = toolbar active height
879
+ return rect.top - rectP.top < TOOLBAR_ACTIVE_HEIGHT + 1;
880
+ };
881
+ const findOverflowParent = (element, initEl)=>{
882
+ const thisEl = element;
883
+ const origEl = initEl || thisEl;
884
+ if (!thisEl) return;
885
+ if (isSection(thisEl)) return;
886
+ if (notVisible(thisEl) && isOverToolbarPosition(initEl, thisEl)) return thisEl;
887
+ if (thisEl.parentElement) {
888
+ return findOverflowParent(thisEl.parentElement, origEl);
889
+ } else {
890
+ return;
891
+ }
706
892
  };
707
893
  var Toolbar$1 = /*#__PURE__*/ memo(Toolbar);
708
894