@gem-sdk/pages 1.23.0-staging.182 → 1.23.0-staging.196

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.
@@ -2,15 +2,30 @@
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 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
+ };
9
19
  const Toolbar = ()=>{
10
20
  const currentComponentActive = react.useRef(null);
11
21
  const isDragging = react.useRef(false);
12
22
  const stopWatchReRenderComponent = react.useRef();
13
23
  const isResizeSpacing = react.useRef(false);
24
+ const [isOnboarding, setIsOnboarding] = react.useState(false);
25
+ const [countShowOnboarding, setCountShowOnboarding] = react.useState(0);
26
+ const [onboardingPosition, setOnboardingPosition] = react.useState('bottom');
27
+ const timeoutRef = react.useRef(null);
28
+ const timeoutOnboarding = 5000;
14
29
  /* Functions */ const changePositionToolbar = ({ state, $toolbar, $component })=>{
15
30
  const $parentOverflow = findOverflowParent($component, $toolbar);
16
31
  const rect = $toolbar.getBoundingClientRect();
@@ -39,6 +54,15 @@ const Toolbar = ()=>{
39
54
  $toolbar.setAttribute(`data-toolbar-${state}-overflow`, 'true');
40
55
  }
41
56
  }
57
+ // fix Popup overflow right position
58
+ const popupEl = $component?.closest('[aria-label="Dialog body"]');
59
+ if (popupEl) {
60
+ const rectPopupEl = popupEl.getBoundingClientRect();
61
+ const popupElRightPosition = rectPopupEl.left + rectPopupEl.width - 20;
62
+ if (rectComponent.left + rect.width > popupElRightPosition) {
63
+ $toolbar.setAttribute(`data-toolbar-${state}-overflow`, 'true');
64
+ }
65
+ }
42
66
  };
43
67
  const setHoverComponent = react.useCallback(({ $component, componentUid, focus, isThemeSection, isParent })=>{
44
68
  if (!$component && !componentUid) return;
@@ -200,6 +224,21 @@ const Toolbar = ()=>{
200
224
  }, [
201
225
  removeHoverOverlayComponent
202
226
  ]);
227
+ const onCloseOnboarding = react.useCallback(()=>{
228
+ timeoutRef.current && clearTimeout(timeoutRef.current);
229
+ if (countShowOnboarding > 0) {
230
+ const eventCreate = new CustomEvent('editor:toolbar:close-onboarding', {
231
+ bubbles: true,
232
+ detail: {
233
+ close: 'close Onboarding'
234
+ }
235
+ });
236
+ window.dispatchEvent(eventCreate);
237
+ setIsOnboarding(false);
238
+ }
239
+ }, [
240
+ countShowOnboarding
241
+ ]);
203
242
  const removeActiveComponent = react.useCallback(()=>{
204
243
  currentComponentActive.current = null;
205
244
  const clearAttrs = [
@@ -221,7 +260,10 @@ const Toolbar = ()=>{
221
260
  }
222
261
  setFocusTextEditor(false);
223
262
  if (stopWatchReRenderComponent.current) stopWatchReRenderComponent.current();
224
- }, []);
263
+ onCloseOnboarding();
264
+ }, [
265
+ onCloseOnboarding
266
+ ]);
225
267
  const watchComponentReRender = ($el, callback)=>{
226
268
  // editor:component:render
227
269
  const onComponentReRender = (e)=>{
@@ -260,6 +302,44 @@ const Toolbar = ()=>{
260
302
  }
261
303
  }
262
304
  }, []);
305
+ const setToolbarOnboarding = react.useCallback(({ $component })=>{
306
+ if (!$component) return;
307
+ if (isSection($component) || isPopup($component) || isSticky($component)) return;
308
+ const toolbar = getChildrenByAttrSelector($component, 'data-toolbar');
309
+ if (toolbar) {
310
+ const toolbarOnboading = document.querySelector('[data-toolbar-onboarding]');
311
+ // only show one time
312
+ if (countShowOnboarding == 0) {
313
+ setTimeout(()=>{
314
+ const rect = toolbar.getBoundingClientRect();
315
+ const rectTop = rect.top || 0;
316
+ const rectOnboading = toolbarOnboading?.getBoundingClientRect();
317
+ const onboardingHeight = rectOnboading?.height || 0;
318
+ const $iframe = parent.document.querySelector('.iframe');
319
+ const $iframeWin = $iframe?.contentWindow;
320
+ const iframeWinScrollY = $iframeWin?.scrollY || 0;
321
+ const iframeHeight = $iframe?.clientHeight || 0;
322
+ if (rectTop + onboardingHeight > iframeHeight) {
323
+ const _top = rect.top + iframeWinScrollY - onboardingHeight - 8;
324
+ toolbarOnboading?.setAttribute('style', `top: ${_top}px;left: ${rect.left}px;`);
325
+ setOnboardingPosition('top');
326
+ } else {
327
+ const _top = rect.top + iframeWinScrollY + rect.height + 8;
328
+ toolbarOnboading?.setAttribute('style', `top: ${_top}px;left: ${rect.left}px;`);
329
+ setOnboardingPosition('bottom');
330
+ }
331
+ setCountShowOnboarding((countShowOnboarding)=>countShowOnboarding + 1);
332
+ toolbarOnboading?.setAttribute('data-onboarding-active', 'true');
333
+ }, 250);
334
+ } else {
335
+ onCloseOnboarding();
336
+ toolbarOnboading?.removeAttribute('data-onboarding-active');
337
+ }
338
+ }
339
+ }, [
340
+ countShowOnboarding,
341
+ onCloseOnboarding
342
+ ]);
263
343
  const setActiveComponent = react.useCallback(async ({ componentUid, productId, timeAwait = 500, forceReActive })=>{
264
344
  if (!componentUid) return;
265
345
  let $component = await waitForElementToExist(`${productId ? `[data-product-id="${productId}"] ` : ''}[data-uid="${componentUid}"]`, timeAwait);
@@ -320,6 +400,14 @@ const Toolbar = ()=>{
320
400
  setActiveComponentSpacing({
321
401
  $component
322
402
  });
403
+ timeoutRef.current && clearTimeout(timeoutRef.current);
404
+ timeoutRef.current = setTimeout(()=>{
405
+ if ($component) {
406
+ setToolbarOnboarding({
407
+ $component
408
+ });
409
+ }
410
+ }, timeoutOnboarding);
323
411
  removeHoverComponent();
324
412
  // Reactive when component re-render
325
413
  watchComponentReRender($component, ()=>{
@@ -333,7 +421,8 @@ const Toolbar = ()=>{
333
421
  }, [
334
422
  removeActiveComponent,
335
423
  removeHoverComponent,
336
- setActiveComponentSpacing
424
+ setActiveComponentSpacing,
425
+ setToolbarOnboarding
337
426
  ]);
338
427
  const setFocusTextEditor = async (value)=>{
339
428
  if (!value) {
@@ -599,6 +688,39 @@ const Toolbar = ()=>{
599
688
  }, [
600
689
  removeHoverComponent
601
690
  ]);
691
+ const setHoverParentComponent = (uid, type)=>{
692
+ if (!uid) return;
693
+ const $parentComponents = document.querySelectorAll(`[data-uid="${uid}"]`);
694
+ if ($parentComponents.length) {
695
+ $parentComponents.forEach(($parentComponent)=>{
696
+ const $outline = getChildrenByAttrSelector($parentComponent, 'data-outline');
697
+ if ($outline) {
698
+ if (type === 'in') {
699
+ $outline.setAttribute('data-outline-force-hover', 'true');
700
+ $outline.setAttribute('data-outline-force-overlay', 'true');
701
+ } else {
702
+ $outline.removeAttribute('data-outline-force-hover');
703
+ $outline.removeAttribute('data-outline-force-overlay');
704
+ }
705
+ }
706
+ });
707
+ }
708
+ };
709
+ const onHoverComponent = react.useCallback((e)=>{
710
+ if (isDragging.current) return;
711
+ const detail = e.detail;
712
+ if (detail?.componentUid) {
713
+ setHoverParentComponent(detail?.componentUid, detail?.type);
714
+ }
715
+ }, [
716
+ isDragging
717
+ ]);
718
+ const onToolbarOnboarding = react.useCallback((e)=>{
719
+ const detail = e.detail;
720
+ if (detail?.isNewUser) {
721
+ setIsOnboarding(true);
722
+ }
723
+ }, []);
602
724
  /* Register event */ react.useEffect(()=>{
603
725
  document.addEventListener('mousemove', onMouseMove);
604
726
  window.addEventListener('editor:active-component', onActiveComponent);
@@ -607,6 +729,8 @@ const Toolbar = ()=>{
607
729
  window.addEventListener('editor:is-editing-text-editor', onIsEditingTextEditor);
608
730
  window.addEventListener('editor:toolbar:show-parents', onShowParents);
609
731
  window.addEventListener('editor:toolbar:resize-spacing', onResizeSpacing);
732
+ window.addEventListener('editor:hover-component', onHoverComponent);
733
+ window.addEventListener('editor:toolbar-onboarding', onToolbarOnboarding);
610
734
  return ()=>{
611
735
  document.removeEventListener('mousemove', onMouseMove);
612
736
  window.removeEventListener('editor:active-component', onActiveComponent);
@@ -615,6 +739,8 @@ const Toolbar = ()=>{
615
739
  window.removeEventListener('editor:is-editing-text-editor', onIsEditingTextEditor);
616
740
  window.removeEventListener('editor:toolbar:show-parents', onShowParents);
617
741
  window.removeEventListener('editor:toolbar:resize-spacing', onResizeSpacing);
742
+ window.removeEventListener('editor:hover-component', onHoverComponent);
743
+ window.removeEventListener('editor:toolbar-onboarding', onToolbarOnboarding);
618
744
  };
619
745
  }, [
620
746
  onMouseMove,
@@ -623,9 +749,15 @@ const Toolbar = ()=>{
623
749
  onIsDragging,
624
750
  onIsEditingTextEditor,
625
751
  onShowParents,
626
- onResizeSpacing
752
+ onResizeSpacing,
753
+ onHoverComponent,
754
+ onToolbarOnboarding
627
755
  ]);
628
- return null;
756
+ return isOnboarding && /*#__PURE__*/ jsxRuntime.jsx(Onboarding.default, {
757
+ enable: true,
758
+ position: onboardingPosition,
759
+ onCloseOnboarding: onCloseOnboarding
760
+ });
629
761
  };
630
762
  const getDOMElementParents = ($el, selector, limit)=>{
631
763
  // Set up a parent array
@@ -669,11 +801,11 @@ const getChildrenByAttrSelector = ($el, attrSelector)=>{
669
801
  }
670
802
  }
671
803
  };
672
- const isOverParent = ({ current, parent, index, revert })=>{
804
+ const isOverParent = ({ current, parent: parent1, index, revert })=>{
673
805
  for(let i = 0; i < index; i++){
674
- 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;
806
+ 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;
675
807
  if (revert) {
676
- 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;
808
+ 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;
677
809
  }
678
810
  if (is) return true;
679
811
  }
@@ -704,9 +836,9 @@ const isSection = (el)=>{
704
836
  const tag = el.getAttribute('data-component-tag');
705
837
  return tag === 'Section';
706
838
  };
707
- const isOverToolbarPosition = (el, parent)=>{
839
+ const isOverToolbarPosition = (el, parent1)=>{
708
840
  const rect = el.getBoundingClientRect();
709
- const rectP = parent.getBoundingClientRect();
841
+ const rectP = parent1.getBoundingClientRect();
710
842
  // 32px = toolbar active height
711
843
  return rect.top - rectP.top < TOOLBAR_ACTIVE_HEIGHT + 1;
712
844
  };
@@ -0,0 +1,109 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+ var react = require('react');
7
+
8
+ const Onboarding = ({ enable, position, onCloseOnboarding })=>{
9
+ const closeOnboarding = ()=>{
10
+ onCloseOnboarding();
11
+ };
12
+ const videoSrc = 'https://ucarecdn.com/de5fd2eb-4525-45a7-ad13-53960dac225e/';
13
+ const Video = ()=>{
14
+ return /*#__PURE__*/ jsxRuntime.jsxs("video", {
15
+ width: "100%",
16
+ className: "w-full",
17
+ loop: true,
18
+ muted: true,
19
+ autoPlay: true,
20
+ playsInline: true,
21
+ children: [
22
+ /*#__PURE__*/ jsxRuntime.jsx("source", {
23
+ src: videoSrc,
24
+ type: "video/mp4"
25
+ }),
26
+ "Sorry, your browser doesn‘t support embedded videos."
27
+ ]
28
+ });
29
+ };
30
+ return /*#__PURE__*/ jsxRuntime.jsx("div", {
31
+ "data-toolbar-onboarding": true,
32
+ "data-toolbar-onboarding-position": position,
33
+ children: enable && /*#__PURE__*/ jsxRuntime.jsxs(jsxRuntime.Fragment, {
34
+ children: [
35
+ /*#__PURE__*/ jsxRuntime.jsx("span", {
36
+ "data-icon": true,
37
+ "data-position": position,
38
+ children: position === 'bottom' ? /*#__PURE__*/ jsxRuntime.jsx("svg", {
39
+ width: "8",
40
+ height: "4",
41
+ viewBox: "0 0 8 4",
42
+ fill: "none",
43
+ xmlns: "http://www.w3.org/2000/svg",
44
+ children: /*#__PURE__*/ jsxRuntime.jsx("path", {
45
+ d: "M-1.74846e-07 4L4 -1.74846e-07L8 4L-1.74846e-07 4Z",
46
+ fill: "white"
47
+ })
48
+ }) : /*#__PURE__*/ jsxRuntime.jsx("svg", {
49
+ width: "8",
50
+ height: "4",
51
+ viewBox: "0 0 8 4",
52
+ fill: "none",
53
+ xmlns: "http://www.w3.org/2000/svg",
54
+ children: /*#__PURE__*/ jsxRuntime.jsx("path", {
55
+ d: "M8 3.33818e-07L4 4L4.76995e-08 7.15256e-07L8 3.33818e-07Z",
56
+ fill: "white"
57
+ })
58
+ })
59
+ }),
60
+ /*#__PURE__*/ jsxRuntime.jsxs("div", {
61
+ "data-onboarding-wrapper": true,
62
+ children: [
63
+ /*#__PURE__*/ jsxRuntime.jsx("button", {
64
+ "data-close": true,
65
+ type: "button",
66
+ onClick: closeOnboarding,
67
+ children: /*#__PURE__*/ jsxRuntime.jsxs("svg", {
68
+ width: "32",
69
+ height: "32",
70
+ viewBox: "0 0 32 32",
71
+ fill: "none",
72
+ xmlns: "http://www.w3.org/2000/svg",
73
+ children: [
74
+ /*#__PURE__*/ jsxRuntime.jsx("path", {
75
+ fillRule: "evenodd",
76
+ clipRule: "evenodd",
77
+ d: "M10.6464 10.6464C10.8417 10.4512 11.1583 10.4512 11.3536 10.6464L21.3536 20.6464C21.5488 20.8417 21.5488 21.1583 21.3536 21.3536C21.1583 21.5488 20.8417 21.5488 20.6464 21.3536L10.6464 11.3536C10.4512 11.1583 10.4512 10.8417 10.6464 10.6464Z",
78
+ fill: "#212121"
79
+ }),
80
+ /*#__PURE__*/ jsxRuntime.jsx("path", {
81
+ fillRule: "evenodd",
82
+ clipRule: "evenodd",
83
+ d: "M21.3536 10.6464C21.5488 10.8417 21.5488 11.1583 21.3536 11.3536L11.3536 21.3536C11.1583 21.5488 10.8417 21.5488 10.6464 21.3536C10.4512 21.1583 10.4512 20.8417 10.6464 20.6464L20.6464 10.6464C20.8417 10.4512 21.1583 10.4512 21.3536 10.6464Z",
84
+ fill: "#212121"
85
+ })
86
+ ]
87
+ })
88
+ }),
89
+ /*#__PURE__*/ jsxRuntime.jsx(Video, {}),
90
+ /*#__PURE__*/ jsxRuntime.jsxs("div", {
91
+ "data-content": true,
92
+ children: [
93
+ /*#__PURE__*/ jsxRuntime.jsx("h3", {
94
+ children: "New way to select parent element"
95
+ }),
96
+ /*#__PURE__*/ jsxRuntime.jsx("p", {
97
+ children: "Select parent from here in case you can‘t find yours at times."
98
+ })
99
+ ]
100
+ })
101
+ ]
102
+ })
103
+ ]
104
+ })
105
+ });
106
+ };
107
+ var Onboarding$1 = /*#__PURE__*/ react.memo(Onboarding);
108
+
109
+ exports.default = Onboarding$1;
@@ -1,12 +1,27 @@
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;
7
+ const isPopup = (el)=>{
8
+ const tag = el.getAttribute('data-component-tag');
9
+ return tag === 'Dialog';
10
+ };
11
+ const isSticky = (el)=>{
12
+ const tag = el.getAttribute('data-component-tag');
13
+ return tag === 'Sticky';
14
+ };
5
15
  const Toolbar = ()=>{
6
16
  const currentComponentActive = useRef(null);
7
17
  const isDragging = useRef(false);
8
18
  const stopWatchReRenderComponent = useRef();
9
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;
10
25
  /* Functions */ const changePositionToolbar = ({ state, $toolbar, $component })=>{
11
26
  const $parentOverflow = findOverflowParent($component, $toolbar);
12
27
  const rect = $toolbar.getBoundingClientRect();
@@ -35,6 +50,15 @@ const Toolbar = ()=>{
35
50
  $toolbar.setAttribute(`data-toolbar-${state}-overflow`, 'true');
36
51
  }
37
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
+ }
61
+ }
38
62
  };
39
63
  const setHoverComponent = useCallback(({ $component, componentUid, focus, isThemeSection, isParent })=>{
40
64
  if (!$component && !componentUid) return;
@@ -196,6 +220,21 @@ const Toolbar = ()=>{
196
220
  }, [
197
221
  removeHoverOverlayComponent
198
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
+ ]);
199
238
  const removeActiveComponent = useCallback(()=>{
200
239
  currentComponentActive.current = null;
201
240
  const clearAttrs = [
@@ -217,7 +256,10 @@ const Toolbar = ()=>{
217
256
  }
218
257
  setFocusTextEditor(false);
219
258
  if (stopWatchReRenderComponent.current) stopWatchReRenderComponent.current();
220
- }, []);
259
+ onCloseOnboarding();
260
+ }, [
261
+ onCloseOnboarding
262
+ ]);
221
263
  const watchComponentReRender = ($el, callback)=>{
222
264
  // editor:component:render
223
265
  const onComponentReRender = (e)=>{
@@ -256,6 +298,44 @@ const Toolbar = ()=>{
256
298
  }
257
299
  }
258
300
  }, []);
301
+ const setToolbarOnboarding = useCallback(({ $component })=>{
302
+ if (!$component) return;
303
+ if (isSection($component) || isPopup($component) || isSticky($component)) return;
304
+ const toolbar = getChildrenByAttrSelector($component, 'data-toolbar');
305
+ if (toolbar) {
306
+ const toolbarOnboading = document.querySelector('[data-toolbar-onboarding]');
307
+ // only show one time
308
+ if (countShowOnboarding == 0) {
309
+ setTimeout(()=>{
310
+ const rect = toolbar.getBoundingClientRect();
311
+ const rectTop = rect.top || 0;
312
+ const rectOnboading = toolbarOnboading?.getBoundingClientRect();
313
+ const onboardingHeight = rectOnboading?.height || 0;
314
+ const $iframe = parent.document.querySelector('.iframe');
315
+ const $iframeWin = $iframe?.contentWindow;
316
+ const iframeWinScrollY = $iframeWin?.scrollY || 0;
317
+ const iframeHeight = $iframe?.clientHeight || 0;
318
+ if (rectTop + onboardingHeight > iframeHeight) {
319
+ const _top = rect.top + iframeWinScrollY - onboardingHeight - 8;
320
+ toolbarOnboading?.setAttribute('style', `top: ${_top}px;left: ${rect.left}px;`);
321
+ setOnboardingPosition('top');
322
+ } else {
323
+ const _top = rect.top + iframeWinScrollY + rect.height + 8;
324
+ toolbarOnboading?.setAttribute('style', `top: ${_top}px;left: ${rect.left}px;`);
325
+ setOnboardingPosition('bottom');
326
+ }
327
+ setCountShowOnboarding((countShowOnboarding)=>countShowOnboarding + 1);
328
+ toolbarOnboading?.setAttribute('data-onboarding-active', 'true');
329
+ }, 250);
330
+ } else {
331
+ onCloseOnboarding();
332
+ toolbarOnboading?.removeAttribute('data-onboarding-active');
333
+ }
334
+ }
335
+ }, [
336
+ countShowOnboarding,
337
+ onCloseOnboarding
338
+ ]);
259
339
  const setActiveComponent = useCallback(async ({ componentUid, productId, timeAwait = 500, forceReActive })=>{
260
340
  if (!componentUid) return;
261
341
  let $component = await waitForElementToExist(`${productId ? `[data-product-id="${productId}"] ` : ''}[data-uid="${componentUid}"]`, timeAwait);
@@ -316,6 +396,14 @@ const Toolbar = ()=>{
316
396
  setActiveComponentSpacing({
317
397
  $component
318
398
  });
399
+ timeoutRef.current && clearTimeout(timeoutRef.current);
400
+ timeoutRef.current = setTimeout(()=>{
401
+ if ($component) {
402
+ setToolbarOnboarding({
403
+ $component
404
+ });
405
+ }
406
+ }, timeoutOnboarding);
319
407
  removeHoverComponent();
320
408
  // Reactive when component re-render
321
409
  watchComponentReRender($component, ()=>{
@@ -329,7 +417,8 @@ const Toolbar = ()=>{
329
417
  }, [
330
418
  removeActiveComponent,
331
419
  removeHoverComponent,
332
- setActiveComponentSpacing
420
+ setActiveComponentSpacing,
421
+ setToolbarOnboarding
333
422
  ]);
334
423
  const setFocusTextEditor = async (value)=>{
335
424
  if (!value) {
@@ -595,6 +684,39 @@ const Toolbar = ()=>{
595
684
  }, [
596
685
  removeHoverComponent
597
686
  ]);
687
+ const setHoverParentComponent = (uid, type)=>{
688
+ if (!uid) return;
689
+ const $parentComponents = document.querySelectorAll(`[data-uid="${uid}"]`);
690
+ if ($parentComponents.length) {
691
+ $parentComponents.forEach(($parentComponent)=>{
692
+ const $outline = getChildrenByAttrSelector($parentComponent, 'data-outline');
693
+ if ($outline) {
694
+ if (type === 'in') {
695
+ $outline.setAttribute('data-outline-force-hover', 'true');
696
+ $outline.setAttribute('data-outline-force-overlay', 'true');
697
+ } else {
698
+ $outline.removeAttribute('data-outline-force-hover');
699
+ $outline.removeAttribute('data-outline-force-overlay');
700
+ }
701
+ }
702
+ });
703
+ }
704
+ };
705
+ const onHoverComponent = useCallback((e)=>{
706
+ if (isDragging.current) return;
707
+ const detail = e.detail;
708
+ if (detail?.componentUid) {
709
+ setHoverParentComponent(detail?.componentUid, detail?.type);
710
+ }
711
+ }, [
712
+ isDragging
713
+ ]);
714
+ const onToolbarOnboarding = useCallback((e)=>{
715
+ const detail = e.detail;
716
+ if (detail?.isNewUser) {
717
+ setIsOnboarding(true);
718
+ }
719
+ }, []);
598
720
  /* Register event */ useEffect(()=>{
599
721
  document.addEventListener('mousemove', onMouseMove);
600
722
  window.addEventListener('editor:active-component', onActiveComponent);
@@ -603,6 +725,8 @@ const Toolbar = ()=>{
603
725
  window.addEventListener('editor:is-editing-text-editor', onIsEditingTextEditor);
604
726
  window.addEventListener('editor:toolbar:show-parents', onShowParents);
605
727
  window.addEventListener('editor:toolbar:resize-spacing', onResizeSpacing);
728
+ window.addEventListener('editor:hover-component', onHoverComponent);
729
+ window.addEventListener('editor:toolbar-onboarding', onToolbarOnboarding);
606
730
  return ()=>{
607
731
  document.removeEventListener('mousemove', onMouseMove);
608
732
  window.removeEventListener('editor:active-component', onActiveComponent);
@@ -611,6 +735,8 @@ const Toolbar = ()=>{
611
735
  window.removeEventListener('editor:is-editing-text-editor', onIsEditingTextEditor);
612
736
  window.removeEventListener('editor:toolbar:show-parents', onShowParents);
613
737
  window.removeEventListener('editor:toolbar:resize-spacing', onResizeSpacing);
738
+ window.removeEventListener('editor:hover-component', onHoverComponent);
739
+ window.removeEventListener('editor:toolbar-onboarding', onToolbarOnboarding);
614
740
  };
615
741
  }, [
616
742
  onMouseMove,
@@ -619,9 +745,15 @@ const Toolbar = ()=>{
619
745
  onIsDragging,
620
746
  onIsEditingTextEditor,
621
747
  onShowParents,
622
- onResizeSpacing
748
+ onResizeSpacing,
749
+ onHoverComponent,
750
+ onToolbarOnboarding
623
751
  ]);
624
- return null;
752
+ return isOnboarding && /*#__PURE__*/ jsx(Onboarding, {
753
+ enable: true,
754
+ position: onboardingPosition,
755
+ onCloseOnboarding: onCloseOnboarding
756
+ });
625
757
  };
626
758
  const getDOMElementParents = ($el, selector, limit)=>{
627
759
  // Set up a parent array
@@ -665,11 +797,11 @@ const getChildrenByAttrSelector = ($el, attrSelector)=>{
665
797
  }
666
798
  }
667
799
  };
668
- const isOverParent = ({ current, parent, index, revert })=>{
800
+ const isOverParent = ({ current, parent: parent1, index, revert })=>{
669
801
  for(let i = 0; i < index; i++){
670
- 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;
802
+ 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;
671
803
  if (revert) {
672
- 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;
804
+ 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;
673
805
  }
674
806
  if (is) return true;
675
807
  }
@@ -700,9 +832,9 @@ const isSection = (el)=>{
700
832
  const tag = el.getAttribute('data-component-tag');
701
833
  return tag === 'Section';
702
834
  };
703
- const isOverToolbarPosition = (el, parent)=>{
835
+ const isOverToolbarPosition = (el, parent1)=>{
704
836
  const rect = el.getBoundingClientRect();
705
- const rectP = parent.getBoundingClientRect();
837
+ const rectP = parent1.getBoundingClientRect();
706
838
  // 32px = toolbar active height
707
839
  return rect.top - rectP.top < TOOLBAR_ACTIVE_HEIGHT + 1;
708
840
  };
@@ -0,0 +1,105 @@
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { memo } from 'react';
3
+
4
+ const Onboarding = ({ enable, position, onCloseOnboarding })=>{
5
+ const closeOnboarding = ()=>{
6
+ onCloseOnboarding();
7
+ };
8
+ const videoSrc = 'https://ucarecdn.com/de5fd2eb-4525-45a7-ad13-53960dac225e/';
9
+ const Video = ()=>{
10
+ return /*#__PURE__*/ jsxs("video", {
11
+ width: "100%",
12
+ className: "w-full",
13
+ loop: true,
14
+ muted: true,
15
+ autoPlay: true,
16
+ playsInline: true,
17
+ children: [
18
+ /*#__PURE__*/ jsx("source", {
19
+ src: videoSrc,
20
+ type: "video/mp4"
21
+ }),
22
+ "Sorry, your browser doesn‘t support embedded videos."
23
+ ]
24
+ });
25
+ };
26
+ return /*#__PURE__*/ jsx("div", {
27
+ "data-toolbar-onboarding": true,
28
+ "data-toolbar-onboarding-position": position,
29
+ children: enable && /*#__PURE__*/ jsxs(Fragment, {
30
+ children: [
31
+ /*#__PURE__*/ jsx("span", {
32
+ "data-icon": true,
33
+ "data-position": position,
34
+ children: position === 'bottom' ? /*#__PURE__*/ jsx("svg", {
35
+ width: "8",
36
+ height: "4",
37
+ viewBox: "0 0 8 4",
38
+ fill: "none",
39
+ xmlns: "http://www.w3.org/2000/svg",
40
+ children: /*#__PURE__*/ jsx("path", {
41
+ d: "M-1.74846e-07 4L4 -1.74846e-07L8 4L-1.74846e-07 4Z",
42
+ fill: "white"
43
+ })
44
+ }) : /*#__PURE__*/ jsx("svg", {
45
+ width: "8",
46
+ height: "4",
47
+ viewBox: "0 0 8 4",
48
+ fill: "none",
49
+ xmlns: "http://www.w3.org/2000/svg",
50
+ children: /*#__PURE__*/ jsx("path", {
51
+ d: "M8 3.33818e-07L4 4L4.76995e-08 7.15256e-07L8 3.33818e-07Z",
52
+ fill: "white"
53
+ })
54
+ })
55
+ }),
56
+ /*#__PURE__*/ jsxs("div", {
57
+ "data-onboarding-wrapper": true,
58
+ children: [
59
+ /*#__PURE__*/ jsx("button", {
60
+ "data-close": true,
61
+ type: "button",
62
+ onClick: closeOnboarding,
63
+ children: /*#__PURE__*/ jsxs("svg", {
64
+ width: "32",
65
+ height: "32",
66
+ viewBox: "0 0 32 32",
67
+ fill: "none",
68
+ xmlns: "http://www.w3.org/2000/svg",
69
+ children: [
70
+ /*#__PURE__*/ jsx("path", {
71
+ fillRule: "evenodd",
72
+ clipRule: "evenodd",
73
+ d: "M10.6464 10.6464C10.8417 10.4512 11.1583 10.4512 11.3536 10.6464L21.3536 20.6464C21.5488 20.8417 21.5488 21.1583 21.3536 21.3536C21.1583 21.5488 20.8417 21.5488 20.6464 21.3536L10.6464 11.3536C10.4512 11.1583 10.4512 10.8417 10.6464 10.6464Z",
74
+ fill: "#212121"
75
+ }),
76
+ /*#__PURE__*/ jsx("path", {
77
+ fillRule: "evenodd",
78
+ clipRule: "evenodd",
79
+ d: "M21.3536 10.6464C21.5488 10.8417 21.5488 11.1583 21.3536 11.3536L11.3536 21.3536C11.1583 21.5488 10.8417 21.5488 10.6464 21.3536C10.4512 21.1583 10.4512 20.8417 10.6464 20.6464L20.6464 10.6464C20.8417 10.4512 21.1583 10.4512 21.3536 10.6464Z",
80
+ fill: "#212121"
81
+ })
82
+ ]
83
+ })
84
+ }),
85
+ /*#__PURE__*/ jsx(Video, {}),
86
+ /*#__PURE__*/ jsxs("div", {
87
+ "data-content": true,
88
+ children: [
89
+ /*#__PURE__*/ jsx("h3", {
90
+ children: "New way to select parent element"
91
+ }),
92
+ /*#__PURE__*/ jsx("p", {
93
+ children: "Select parent from here in case you can‘t find yours at times."
94
+ })
95
+ ]
96
+ })
97
+ ]
98
+ })
99
+ ]
100
+ })
101
+ });
102
+ };
103
+ var Onboarding$1 = /*#__PURE__*/ memo(Onboarding);
104
+
105
+ export { Onboarding$1 as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gem-sdk/pages",
3
- "version": "1.23.0-staging.182",
3
+ "version": "1.23.0-staging.196",
4
4
  "license": "MIT",
5
5
  "sideEffects": false,
6
6
  "main": "dist/cjs/index.js",
@@ -25,7 +25,7 @@
25
25
  "next-seo": "^6.0.0"
26
26
  },
27
27
  "devDependencies": {
28
- "@gem-sdk/core": "1.23.0-staging.173",
28
+ "@gem-sdk/core": "1.23.0-staging.195",
29
29
  "@gem-sdk/plugin-cookie-bar": "1.23.0-staging.26",
30
30
  "@gem-sdk/plugin-quick-view": "1.23.0-staging.26",
31
31
  "@gem-sdk/plugin-sticky-add-to-cart": "1.23.0-staging.26"