@gem-sdk/pages 1.23.0-staging.27 → 1.23.0-staging.270
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.
- package/dist/cjs/components/builder/Toolbar.js +435 -211
- package/dist/cjs/components/builder/Toolbox.js +94 -53
- package/dist/cjs/components/builder/toolbar/Onboarding.js +110 -0
- package/dist/cjs/components/image-to-layout/AddSectionImageToLayout.js +1 -7
- package/dist/cjs/libs/api/get-home-page-props-v2.js +3 -1
- package/dist/cjs/libs/api/get-static-page-props-preview.js +3 -1
- package/dist/cjs/libs/google-fonts.js +6 -1
- package/dist/cjs/libs/helpers/gen-fonts.js +15 -4
- package/dist/cjs/pages/builder.js +43 -41
- package/dist/cjs/pages/collection-detail.js +12 -10
- package/dist/cjs/pages/product-detail.js +18 -16
- package/dist/cjs/pages/static-v2.js +14 -12
- package/dist/cjs/pages/static.js +13 -11
- package/dist/esm/components/builder/Toolbar.js +436 -212
- package/dist/esm/components/builder/Toolbox.js +95 -54
- package/dist/esm/components/builder/toolbar/Onboarding.js +106 -0
- package/dist/esm/components/image-to-layout/AddSectionImageToLayout.js +1 -7
- package/dist/esm/libs/api/get-home-page-props-v2.js +4 -2
- package/dist/esm/libs/api/get-static-page-props-preview.js +4 -2
- package/dist/esm/libs/google-fonts.js +6 -1
- package/dist/esm/libs/helpers/gen-fonts.js +15 -4
- package/dist/esm/pages/builder.js +44 -42
- package/dist/esm/pages/collection-detail.js +13 -11
- package/dist/esm/pages/product-detail.js +19 -17
- package/dist/esm/pages/static-v2.js +15 -13
- package/dist/esm/pages/static.js +14 -12
- package/dist/types/index.d.ts +1 -0
- package/package.json +2 -2
|
@@ -2,108 +2,69 @@
|
|
|
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
|
-
|
|
9
|
-
const
|
|
10
|
-
// Set up a parent array
|
|
11
|
-
const parents = [];
|
|
12
|
-
// Push each parent $elms to the array
|
|
13
|
-
while($el){
|
|
14
|
-
$el = $el.parentElement ?? undefined;
|
|
15
|
-
if ($el) {
|
|
16
|
-
if ($el.tagName === 'BODY' || $el.getAttribute('data-uid') === 'ROOT') {
|
|
17
|
-
break;
|
|
18
|
-
}
|
|
19
|
-
if (selector) {
|
|
20
|
-
if ($el.matches(selector)) {
|
|
21
|
-
parents.push($el);
|
|
22
|
-
if (limit && parents.length == limit) {
|
|
23
|
-
return parents;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
continue;
|
|
27
|
-
}
|
|
28
|
-
parents.push($el);
|
|
29
|
-
if (limit && parents.length == limit) {
|
|
30
|
-
return parents;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
// Return our parent array
|
|
35
|
-
return parents;
|
|
36
|
-
};
|
|
37
|
-
const getChildrenByAttrSelector = ($el, attrSelector)=>{
|
|
38
|
-
const childLen = $el.children.length;
|
|
39
|
-
if (childLen) {
|
|
40
|
-
for(let i = 0; i < childLen; i++){
|
|
41
|
-
const children = $el.children[i];
|
|
42
|
-
if (children) {
|
|
43
|
-
const is = children.getAttribute(attrSelector);
|
|
44
|
-
if (is) {
|
|
45
|
-
return children;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
const isOverParent = (current, parent, index)=>{
|
|
52
|
-
for(let i = 0; i < index; i++){
|
|
53
|
-
const is = current.top - (TOOLBAR_HOVER_HEIGHT - 1) * i >= parent.top && current.top - (TOOLBAR_HOVER_HEIGHT - 1) * i <= parent.top + parent.height && current.left >= parent.left && current.left <= parent.left + parent.width;
|
|
54
|
-
if (is) return true;
|
|
55
|
-
}
|
|
56
|
-
return false;
|
|
57
|
-
};
|
|
58
|
-
const waitForElementToExist = (selector, timeout = 200)=>{
|
|
59
|
-
return new Promise((resolve)=>{
|
|
60
|
-
const intervalID = setInterval(()=>{
|
|
61
|
-
const el = document.querySelector(selector);
|
|
62
|
-
if (el) {
|
|
63
|
-
clearInterval(intervalID);
|
|
64
|
-
clearTimeout(timeoutID);
|
|
65
|
-
resolve(el);
|
|
66
|
-
}
|
|
67
|
-
}, 50);
|
|
68
|
-
const timeoutID = setTimeout(()=>{
|
|
69
|
-
clearInterval(intervalID);
|
|
70
|
-
clearTimeout(timeoutID);
|
|
71
|
-
resolve(null);
|
|
72
|
-
}, timeout);
|
|
73
|
-
});
|
|
74
|
-
};
|
|
75
|
-
const notVisible = (el)=>{
|
|
76
|
-
const overflow = getComputedStyle(el).overflow;
|
|
77
|
-
return overflow !== 'visible';
|
|
78
|
-
};
|
|
79
|
-
const isSection = (el)=>{
|
|
10
|
+
const TOOLBAR_ACTIVE_HEIGHT = 32;
|
|
11
|
+
const isPopup = (el)=>{
|
|
80
12
|
const tag = el.getAttribute('data-component-tag');
|
|
81
|
-
return tag === '
|
|
82
|
-
};
|
|
83
|
-
const isOverToolbarPosition = (el, parent)=>{
|
|
84
|
-
const rect = el.getBoundingClientRect();
|
|
85
|
-
const rectP = parent.getBoundingClientRect();
|
|
86
|
-
// 32px = toolbar active height
|
|
87
|
-
return rect.top - rectP.top < 32 + 5;
|
|
13
|
+
return tag === 'Dialog';
|
|
88
14
|
};
|
|
89
|
-
const
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
if (!thisEl) return;
|
|
93
|
-
if (isSection(thisEl)) return;
|
|
94
|
-
if (notVisible(thisEl) && isOverToolbarPosition(initEl, thisEl)) return thisEl;
|
|
95
|
-
if (thisEl.parentElement) {
|
|
96
|
-
return findOverflowParent(thisEl.parentElement, origEl);
|
|
97
|
-
} else {
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
15
|
+
const isSticky = (el)=>{
|
|
16
|
+
const tag = el.getAttribute('data-component-tag');
|
|
17
|
+
return tag === 'Sticky';
|
|
100
18
|
};
|
|
101
19
|
const Toolbar = ()=>{
|
|
102
20
|
const currentComponentActive = react.useRef(null);
|
|
103
21
|
const isDragging = react.useRef(false);
|
|
104
|
-
const
|
|
22
|
+
const stopWatchReRenderComponent = react.useRef();
|
|
105
23
|
const isResizeSpacing = react.useRef(false);
|
|
106
|
-
|
|
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;
|
|
29
|
+
/* Functions */ const changePositionToolbar = ({ state, $toolbar, $component })=>{
|
|
30
|
+
const $parentOverflow = findOverflowParent($component, $toolbar);
|
|
31
|
+
const rect = $toolbar.getBoundingClientRect();
|
|
32
|
+
const rectComponent = $component.getBoundingClientRect();
|
|
33
|
+
const windowWidth = window.innerWidth;
|
|
34
|
+
if ($parentOverflow) {
|
|
35
|
+
if (rectComponent?.height <= 60) {
|
|
36
|
+
$toolbar.setAttribute(`data-toolbar-${state}-revert`, 'true');
|
|
37
|
+
} else {
|
|
38
|
+
$toolbar.setAttribute(`data-toolbar-${state}-inside`, 'true');
|
|
39
|
+
}
|
|
40
|
+
// fix toolbar overflow right side
|
|
41
|
+
if (rectComponent.left + rect.width > windowWidth) {
|
|
42
|
+
$toolbar.setAttribute(`data-toolbar-${state}-overflow`, 'true');
|
|
43
|
+
}
|
|
44
|
+
} else {
|
|
45
|
+
if (rect.top < TOOLBAR_ACTIVE_HEIGHT + 1) {
|
|
46
|
+
if (rectComponent?.height <= 60) {
|
|
47
|
+
$toolbar.setAttribute(`data-toolbar-${state}-revert`, 'true');
|
|
48
|
+
} else {
|
|
49
|
+
$toolbar.setAttribute(`data-toolbar-${state}-inside`, 'true');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// fix toolbar overflow right side
|
|
53
|
+
if (rectComponent.left + rect.width > windowWidth) {
|
|
54
|
+
$toolbar.setAttribute(`data-toolbar-${state}-overflow`, 'true');
|
|
55
|
+
}
|
|
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
|
+
}
|
|
66
|
+
};
|
|
67
|
+
const setHoverComponent = react.useCallback(({ $component, componentUid, focus, isThemeSection, isParent })=>{
|
|
107
68
|
if (!$component && !componentUid) return;
|
|
108
69
|
if (!$component) {
|
|
109
70
|
const $c = document.querySelector(`[data-uid="${componentUid}"]`);
|
|
@@ -125,17 +86,23 @@ const Toolbar = ()=>{
|
|
|
125
86
|
}
|
|
126
87
|
if ($toolbar) {
|
|
127
88
|
$toolbar.removeAttribute('style');
|
|
128
|
-
|
|
89
|
+
if (!isParent) {
|
|
90
|
+
$toolbar.setAttribute('data-toolbar-hover', 'true');
|
|
91
|
+
}
|
|
129
92
|
if (focus) {
|
|
130
93
|
$toolbar.setAttribute('data-toolbar-hover-focus', 'true');
|
|
131
94
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
$
|
|
135
|
-
|
|
95
|
+
changePositionToolbar({
|
|
96
|
+
$toolbar,
|
|
97
|
+
$component,
|
|
98
|
+
state: 'hover'
|
|
99
|
+
});
|
|
136
100
|
}
|
|
137
101
|
if ($outline) {
|
|
138
102
|
$outline.setAttribute('data-outline-hover', 'true');
|
|
103
|
+
if (isParent) {
|
|
104
|
+
$outline.setAttribute('data-outline-parent-hover', 'true');
|
|
105
|
+
}
|
|
139
106
|
if (isThemeSection) {
|
|
140
107
|
$outline.setAttribute('data-outline-overlay-theme-section', 'true');
|
|
141
108
|
}
|
|
@@ -144,10 +111,14 @@ const Toolbar = ()=>{
|
|
|
144
111
|
}
|
|
145
112
|
}
|
|
146
113
|
if ($btnAddTop) {
|
|
147
|
-
|
|
114
|
+
if (!isParent) {
|
|
115
|
+
$btnAddTop.setAttribute('data-toolbar-add-hover', 'true');
|
|
116
|
+
}
|
|
148
117
|
}
|
|
149
118
|
if ($btnAddBottom) {
|
|
150
|
-
|
|
119
|
+
if (!isParent) {
|
|
120
|
+
$btnAddBottom.setAttribute('data-toolbar-add-hover', 'true');
|
|
121
|
+
}
|
|
151
122
|
}
|
|
152
123
|
}, []);
|
|
153
124
|
const setHoverComponentParents = react.useCallback(({ $component, componentUid })=>{
|
|
@@ -156,12 +127,13 @@ const Toolbar = ()=>{
|
|
|
156
127
|
if (!$c) return;
|
|
157
128
|
$component = $c;
|
|
158
129
|
}
|
|
159
|
-
const $parents = getDOMElementParents($component, '[data-uid][data-component-type="component"]:not([data-component-no-setting])');
|
|
130
|
+
const $parents = getDOMElementParents($component, '[data-uid][data-component-type="component"]:not([data-component-no-setting])', 1);
|
|
160
131
|
if ($parents.length) {
|
|
161
132
|
for (const $parent of $parents){
|
|
162
133
|
if ($parent) {
|
|
163
134
|
setHoverComponent({
|
|
164
|
-
$component: $parent
|
|
135
|
+
$component: $parent,
|
|
136
|
+
isParent: true
|
|
165
137
|
});
|
|
166
138
|
}
|
|
167
139
|
}
|
|
@@ -179,6 +151,8 @@ const Toolbar = ()=>{
|
|
|
179
151
|
const $currentToolbar = getChildrenByAttrSelector($component, 'data-toolbar-hover-focus');
|
|
180
152
|
if ($currentToolbar) {
|
|
181
153
|
const currentRect = $currentToolbar.getBoundingClientRect();
|
|
154
|
+
const isRevert = $currentToolbar.getAttribute('data-toolbar-hover-revert') ? true : false;
|
|
155
|
+
const isInside = $currentToolbar.getAttribute('data-toolbar-hover-inside') ? true : false;
|
|
182
156
|
let index = 1;
|
|
183
157
|
for (const $parent of $parents){
|
|
184
158
|
if ($parent) {
|
|
@@ -191,14 +165,19 @@ const Toolbar = ()=>{
|
|
|
191
165
|
if (isActive) continue;
|
|
192
166
|
// Start calc
|
|
193
167
|
const parentRect = $toolbar.getBoundingClientRect();
|
|
194
|
-
|
|
168
|
+
const checkRevert = isRevert || isInside;
|
|
169
|
+
if (isOverParent({
|
|
170
|
+
current: currentRect,
|
|
171
|
+
parent: parentRect,
|
|
172
|
+
index,
|
|
173
|
+
revert: checkRevert
|
|
174
|
+
})) {
|
|
195
175
|
const parentStyle = getComputedStyle($toolbar);
|
|
196
|
-
const isRevert = $toolbar.getAttribute('data-toolbar-hover-revert') ? true : false;
|
|
197
176
|
// parentStyle.top
|
|
198
177
|
const diffTop = currentRect.top - parentRect.top;
|
|
199
178
|
const diffLeft = currentRect.left - parentRect.left;
|
|
200
179
|
let newTop = parseFloat(parentStyle.top) + diffTop - (TOOLBAR_HOVER_HEIGHT - 1) * index; // -1 border bottom
|
|
201
|
-
if (
|
|
180
|
+
if (checkRevert) {
|
|
202
181
|
newTop = parseFloat(parentStyle.top) - diffTop + (TOOLBAR_HOVER_HEIGHT - 1) * index; // -1 border bottom
|
|
203
182
|
}
|
|
204
183
|
const newLeft = parseFloat(parentStyle.left) + diffLeft;
|
|
@@ -229,8 +208,11 @@ const Toolbar = ()=>{
|
|
|
229
208
|
'data-toolbar-hover',
|
|
230
209
|
'data-outline-hover-focus',
|
|
231
210
|
'data-toolbar-hover-revert',
|
|
211
|
+
'data-toolbar-hover-inside',
|
|
232
212
|
'data-outline-hover',
|
|
233
|
-
'data-toolbar-add-hover'
|
|
213
|
+
'data-toolbar-add-hover',
|
|
214
|
+
'data-outline-parent-hover',
|
|
215
|
+
'data-toolbar-hover-overflow'
|
|
234
216
|
];
|
|
235
217
|
const $elms = document.querySelectorAll(clearAttrs.map((attr)=>`[${attr}]`).join(','));
|
|
236
218
|
if ($elms) {
|
|
@@ -242,6 +224,21 @@ const Toolbar = ()=>{
|
|
|
242
224
|
}, [
|
|
243
225
|
removeHoverOverlayComponent
|
|
244
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
|
+
]);
|
|
245
242
|
const removeActiveComponent = react.useCallback(()=>{
|
|
246
243
|
currentComponentActive.current = null;
|
|
247
244
|
const clearAttrs = [
|
|
@@ -249,9 +246,11 @@ const Toolbar = ()=>{
|
|
|
249
246
|
'data-outline-active',
|
|
250
247
|
'data-toolbar-add-active',
|
|
251
248
|
'data-toolbar-active-revert',
|
|
249
|
+
'data-toolbar-active-inside',
|
|
252
250
|
'data-spacing-margin-bottom-active',
|
|
253
251
|
'data-toolbar-force-hover',
|
|
254
|
-
'data-outline-force-hover'
|
|
252
|
+
'data-outline-force-hover',
|
|
253
|
+
'data-toolbar-active-overflow'
|
|
255
254
|
];
|
|
256
255
|
const $elms = document.querySelectorAll(clearAttrs.map((attr)=>`[${attr}]`).join(','));
|
|
257
256
|
if ($elms) {
|
|
@@ -260,25 +259,32 @@ const Toolbar = ()=>{
|
|
|
260
259
|
});
|
|
261
260
|
}
|
|
262
261
|
setFocusTextEditor(false);
|
|
263
|
-
if (
|
|
264
|
-
|
|
262
|
+
if (stopWatchReRenderComponent.current) stopWatchReRenderComponent.current();
|
|
263
|
+
onCloseOnboarding();
|
|
264
|
+
}, [
|
|
265
|
+
onCloseOnboarding
|
|
266
|
+
]);
|
|
265
267
|
const watchComponentReRender = ($el, callback)=>{
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
mutation.removedNodes.forEach((el)=>{
|
|
272
|
-
if (el === $el) {
|
|
273
|
-
if (obsActiveComponent.current) obsActiveComponent.current.disconnect();
|
|
274
|
-
callback();
|
|
275
|
-
}
|
|
276
|
-
});
|
|
268
|
+
// editor:component:render
|
|
269
|
+
const onComponentReRender = (e)=>{
|
|
270
|
+
const detail = e.detail;
|
|
271
|
+
if (detail?.componentUid == currentComponentActive.current?.componentUid) {
|
|
272
|
+
callback();
|
|
277
273
|
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
274
|
+
};
|
|
275
|
+
window.removeEventListener('editor:component:render', onComponentReRender);
|
|
276
|
+
window.addEventListener('editor:component:render', onComponentReRender);
|
|
277
|
+
const $images = $el.querySelectorAll('img');
|
|
278
|
+
if ($images?.length) {
|
|
279
|
+
$images.forEach(($img)=>{
|
|
280
|
+
$img.addEventListener('load', ()=>{
|
|
281
|
+
callback();
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
stopWatchReRenderComponent.current = ()=>{
|
|
286
|
+
window.removeEventListener('editor:component:render', onComponentReRender);
|
|
287
|
+
};
|
|
282
288
|
};
|
|
283
289
|
const setActiveComponentSpacing = react.useCallback(({ $component })=>{
|
|
284
290
|
if (!$component) return;
|
|
@@ -289,43 +295,96 @@ const Toolbar = ()=>{
|
|
|
289
295
|
const $bg = $marginBottom.querySelector('[data-spacing-margin-bottom-bg]') || null;
|
|
290
296
|
const $drag = $marginBottom.querySelector('[data-spacing-margin-bottom-drag]') || null;
|
|
291
297
|
if ($bg && $drag) {
|
|
292
|
-
|
|
298
|
+
let value = style.marginBottom;
|
|
299
|
+
if (parseFloat(value) < 0) {
|
|
300
|
+
value = '0';
|
|
301
|
+
}
|
|
293
302
|
$bg.style.height = value;
|
|
294
303
|
$drag.style.top = value;
|
|
295
304
|
$marginBottom.setAttribute('data-spacing-margin-bottom-active', 'true');
|
|
305
|
+
if (isLayoutElement($component)) {
|
|
306
|
+
$bg.style.left = '0';
|
|
307
|
+
} else {
|
|
308
|
+
const paddingLeft = style.paddingLeft;
|
|
309
|
+
const leftValue = `-${paddingLeft}`;
|
|
310
|
+
const translateCss = `translate(${leftValue}, -100%)`;
|
|
311
|
+
$bg.style.left = leftValue;
|
|
312
|
+
$drag.style.transform = translateCss;
|
|
313
|
+
}
|
|
296
314
|
}
|
|
297
315
|
}
|
|
298
316
|
}, []);
|
|
299
|
-
const
|
|
300
|
-
const
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
const
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
317
|
+
const calculateOnboardingPosition = ()=>{
|
|
318
|
+
const toolbar = document.querySelector('[data-toolbar-active]');
|
|
319
|
+
const toolbarOnboading = document.querySelector('[data-toolbar-onboarding]');
|
|
320
|
+
if (toolbar && toolbarOnboading) {
|
|
321
|
+
toolbarOnboading?.removeAttribute('data-onboarding-active');
|
|
322
|
+
setTimeout(()=>{
|
|
323
|
+
const rect = toolbar.getBoundingClientRect();
|
|
324
|
+
const rectTop = rect.top || 0;
|
|
325
|
+
const rectOnboading = toolbarOnboading?.getBoundingClientRect();
|
|
326
|
+
const onboardingHeight = rectOnboading?.height || 0;
|
|
327
|
+
const $iframe = parent.document.querySelector('.iframe');
|
|
328
|
+
const $iframeWin = $iframe?.contentWindow;
|
|
329
|
+
const iframeWinScrollY = $iframeWin?.scrollY || 0;
|
|
330
|
+
const iframeHeight = $iframe?.clientHeight || 0;
|
|
331
|
+
if (rectTop + onboardingHeight > iframeHeight) {
|
|
332
|
+
const oboardingTop = rect.top + iframeWinScrollY - onboardingHeight - 8;
|
|
333
|
+
toolbarOnboading?.setAttribute('style', `top: ${oboardingTop}px;left: ${rect.left}px;`);
|
|
334
|
+
setOnboardingPosition('top');
|
|
335
|
+
if ($iframeWin && oboardingTop < rect.top + iframeWinScrollY) {
|
|
336
|
+
setTimeout(()=>{
|
|
337
|
+
const toTop = oboardingTop - 20;
|
|
338
|
+
$iframeWin.scrollTo({
|
|
339
|
+
top: toTop,
|
|
340
|
+
behavior: 'smooth'
|
|
341
|
+
});
|
|
342
|
+
}, 200);
|
|
343
|
+
}
|
|
344
|
+
} else {
|
|
345
|
+
const oboardingTop = rect.top + iframeWinScrollY + rect.height + 8;
|
|
346
|
+
toolbarOnboading?.setAttribute('style', `top: ${oboardingTop}px;left: ${rect.left}px;`);
|
|
347
|
+
setOnboardingPosition('bottom');
|
|
319
348
|
}
|
|
320
|
-
|
|
349
|
+
setCountShowOnboarding((countShowOnboarding)=>countShowOnboarding + 1);
|
|
350
|
+
toolbarOnboading?.setAttribute('data-onboarding-active', 'true');
|
|
351
|
+
}, 100);
|
|
321
352
|
}
|
|
322
353
|
};
|
|
354
|
+
const setToolbarOnboarding = react.useCallback(({ $component })=>{
|
|
355
|
+
if (!$component) return;
|
|
356
|
+
if (isSection($component) || isPopup($component) || isSticky($component)) return;
|
|
357
|
+
const toolbarOnboading = document.querySelector('[data-toolbar-onboarding]');
|
|
358
|
+
// only show one time
|
|
359
|
+
if (countShowOnboarding == 0) {
|
|
360
|
+
calculateOnboardingPosition();
|
|
361
|
+
} else {
|
|
362
|
+
onCloseOnboarding();
|
|
363
|
+
toolbarOnboading?.removeAttribute('data-onboarding-active');
|
|
364
|
+
}
|
|
365
|
+
}, [
|
|
366
|
+
countShowOnboarding,
|
|
367
|
+
onCloseOnboarding
|
|
368
|
+
]);
|
|
323
369
|
const setActiveComponent = react.useCallback(async ({ componentUid, productId, timeAwait = 500, forceReActive })=>{
|
|
324
370
|
if (!componentUid) return;
|
|
325
|
-
|
|
326
|
-
|
|
371
|
+
let $component = await waitForElementToExist(`${productId ? `[data-product-id="${productId}"] ` : ''}[data-uid="${componentUid}"]`, timeAwait);
|
|
372
|
+
// check element fetch data: product, product list
|
|
373
|
+
if (!$component) {
|
|
374
|
+
const isLoading = document.querySelector(`.gp-loading-placeholder`);
|
|
375
|
+
if (!isLoading) {
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
if (isLoading) {
|
|
379
|
+
// await element onload
|
|
380
|
+
$component = await waitForElementToExist(`${productId ? `[data-product-id="${productId}"] ` : ''}[data-uid="${componentUid}"]`, 15000);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
if (!$component) {
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
327
386
|
if (!forceReActive && componentUid == currentComponentActive.current?.componentUid && productId == currentComponentActive.current?.productId) return;
|
|
328
|
-
if (
|
|
387
|
+
if (componentUid !== currentComponentActive.current?.componentUid || productId !== currentComponentActive.current?.productId || forceReActive) removeActiveComponent();
|
|
329
388
|
const $toolbar = getChildrenByAttrSelector($component, 'data-toolbar');
|
|
330
389
|
const $outline = getChildrenByAttrSelector($component, 'data-outline');
|
|
331
390
|
const $btnAddTop = getChildrenByAttrSelector($component, 'data-toolbar-add-top');
|
|
@@ -337,10 +396,11 @@ const Toolbar = ()=>{
|
|
|
337
396
|
};
|
|
338
397
|
$toolbar.removeAttribute('style');
|
|
339
398
|
$toolbar.setAttribute('data-toolbar-active', 'true');
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
$
|
|
343
|
-
|
|
399
|
+
changePositionToolbar({
|
|
400
|
+
$toolbar,
|
|
401
|
+
$component,
|
|
402
|
+
state: 'active'
|
|
403
|
+
});
|
|
344
404
|
}
|
|
345
405
|
if ($outline) {
|
|
346
406
|
$outline.setAttribute('data-outline-active', 'true');
|
|
@@ -366,7 +426,14 @@ const Toolbar = ()=>{
|
|
|
366
426
|
setActiveComponentSpacing({
|
|
367
427
|
$component
|
|
368
428
|
});
|
|
369
|
-
|
|
429
|
+
timeoutRef.current && clearTimeout(timeoutRef.current);
|
|
430
|
+
timeoutRef.current = setTimeout(()=>{
|
|
431
|
+
if ($component) {
|
|
432
|
+
setToolbarOnboarding({
|
|
433
|
+
$component
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
}, timeoutOnboarding);
|
|
370
437
|
removeHoverComponent();
|
|
371
438
|
// Reactive when component re-render
|
|
372
439
|
watchComponentReRender($component, ()=>{
|
|
@@ -380,7 +447,8 @@ const Toolbar = ()=>{
|
|
|
380
447
|
}, [
|
|
381
448
|
removeActiveComponent,
|
|
382
449
|
removeHoverComponent,
|
|
383
|
-
setActiveComponentSpacing
|
|
450
|
+
setActiveComponentSpacing,
|
|
451
|
+
setToolbarOnboarding
|
|
384
452
|
]);
|
|
385
453
|
const setFocusTextEditor = async (value)=>{
|
|
386
454
|
if (!value) {
|
|
@@ -503,59 +571,53 @@ const Toolbar = ()=>{
|
|
|
503
571
|
if (isDragging.current) return;
|
|
504
572
|
if (isResizeSpacing.current) return;
|
|
505
573
|
const $target = e.target;
|
|
506
|
-
if (!$target) {
|
|
574
|
+
if (!$target || typeof $target.closest !== 'function') {
|
|
507
575
|
removeHoverOverlayComponent();
|
|
508
576
|
return;
|
|
509
577
|
}
|
|
510
578
|
const $toolbarHover = $target.closest('[data-toolbar-hover]');
|
|
511
579
|
if ($toolbarHover) {
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
580
|
+
// Disable feature overlay when hover to toolbar parents
|
|
581
|
+
return;
|
|
582
|
+
// removeHoverOverlayComponent(); // remove overlay old
|
|
583
|
+
// // Hover to toolbar is focus
|
|
584
|
+
// if ($toolbarHover?.getAttribute('data-toolbar-hover-focus')) return;
|
|
585
|
+
// const $component = $target.closest('[data-toolbar-wrap]');
|
|
586
|
+
// if (!$component) return;
|
|
587
|
+
// const $outline = getChildrenByAttrSelector($component, 'data-outline');
|
|
588
|
+
// if (!$outline) return;
|
|
589
|
+
// const isThemeSection = $component.getAttribute('data-theme-section');
|
|
590
|
+
// const outlineOverlay = isThemeSection
|
|
591
|
+
// ? 'data-outline-overlay-theme-section'
|
|
592
|
+
// : 'data-outline-overlay';
|
|
593
|
+
// $outline.setAttribute(outlineOverlay, 'true');
|
|
594
|
+
}
|
|
595
|
+
// Hover to other component
|
|
596
|
+
const $component = $target.closest('[data-toolbar-wrap]');
|
|
597
|
+
const componentUid = $component?.getAttribute('data-uid');
|
|
598
|
+
if (!$component || !componentUid || componentUid == 'ROOT') {
|
|
599
|
+
removeHoverComponent();
|
|
600
|
+
return;
|
|
601
|
+
}
|
|
602
|
+
const $toolbar = getChildrenByAttrSelector($component, 'data-toolbar');
|
|
603
|
+
const $outline = getChildrenByAttrSelector($component, 'data-outline');
|
|
604
|
+
if ($outline) $outline.removeAttribute('data-outline-overlay');
|
|
605
|
+
if (!componentUid) return;
|
|
606
|
+
if (componentUid == 'ROOT') return;
|
|
607
|
+
if ($toolbar?.getAttribute('data-toolbar-hover-focus')) return;
|
|
608
|
+
if (!$toolbar?.getAttribute('data-toolbar-hover-focus')) removeHoverComponent();
|
|
609
|
+
hoverActiveThemeSection($target);
|
|
610
|
+
// Disable event when hover active component
|
|
611
|
+
if (componentUid == currentComponentActive.current?.componentUid) {
|
|
612
|
+
if (currentComponentActive.current.productId) {
|
|
613
|
+
const $product = $component.closest(`[data-product-id]`);
|
|
614
|
+
if ($product) {
|
|
615
|
+
const productId = $product.getAttribute('data-product-id');
|
|
616
|
+
if (productId == currentComponentActive.current.productId) {
|
|
617
|
+
removeHoverComponent();
|
|
618
|
+
return;
|
|
547
619
|
}
|
|
548
620
|
}
|
|
549
|
-
const $themeSection = $target.closest('[data-theme-section]');
|
|
550
|
-
if ($themeSection) {
|
|
551
|
-
setHoverComponent({
|
|
552
|
-
$component: $themeSection,
|
|
553
|
-
focus: true,
|
|
554
|
-
isThemeSection: true
|
|
555
|
-
});
|
|
556
|
-
} else {
|
|
557
|
-
return;
|
|
558
|
-
}
|
|
559
621
|
}
|
|
560
622
|
const $themeSection = $target.closest('[data-theme-section]');
|
|
561
623
|
if ($themeSection) {
|
|
@@ -565,17 +627,27 @@ const Toolbar = ()=>{
|
|
|
565
627
|
isThemeSection: true
|
|
566
628
|
});
|
|
567
629
|
} else {
|
|
568
|
-
|
|
569
|
-
$component,
|
|
570
|
-
componentUid,
|
|
571
|
-
focus: true
|
|
572
|
-
});
|
|
573
|
-
setHoverComponentParents({
|
|
574
|
-
$component,
|
|
575
|
-
componentUid
|
|
576
|
-
});
|
|
630
|
+
return;
|
|
577
631
|
}
|
|
578
632
|
}
|
|
633
|
+
const $themeSection = $target.closest('[data-theme-section]');
|
|
634
|
+
if ($themeSection) {
|
|
635
|
+
setHoverComponent({
|
|
636
|
+
$component: $themeSection,
|
|
637
|
+
focus: true,
|
|
638
|
+
isThemeSection: true
|
|
639
|
+
});
|
|
640
|
+
} else {
|
|
641
|
+
setHoverComponent({
|
|
642
|
+
$component,
|
|
643
|
+
componentUid,
|
|
644
|
+
focus: true
|
|
645
|
+
});
|
|
646
|
+
setHoverComponentParents({
|
|
647
|
+
$component,
|
|
648
|
+
componentUid
|
|
649
|
+
});
|
|
650
|
+
}
|
|
579
651
|
}, [
|
|
580
652
|
hoverActiveThemeSection,
|
|
581
653
|
removeHoverComponent,
|
|
@@ -642,6 +714,46 @@ const Toolbar = ()=>{
|
|
|
642
714
|
}, [
|
|
643
715
|
removeHoverComponent
|
|
644
716
|
]);
|
|
717
|
+
const setHoverParentComponent = (uid, type)=>{
|
|
718
|
+
if (!uid) return;
|
|
719
|
+
const $parentComponents = document.querySelectorAll(`[data-uid="${uid}"]`);
|
|
720
|
+
if ($parentComponents.length) {
|
|
721
|
+
$parentComponents.forEach(($parentComponent)=>{
|
|
722
|
+
const $outline = getChildrenByAttrSelector($parentComponent, 'data-outline');
|
|
723
|
+
if ($outline) {
|
|
724
|
+
if (type === 'in') {
|
|
725
|
+
$outline.setAttribute('data-outline-force-hover', 'true');
|
|
726
|
+
$outline.setAttribute('data-outline-force-overlay', 'true');
|
|
727
|
+
} else {
|
|
728
|
+
$outline.removeAttribute('data-outline-force-hover');
|
|
729
|
+
$outline.removeAttribute('data-outline-force-overlay');
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
});
|
|
733
|
+
}
|
|
734
|
+
};
|
|
735
|
+
const onHoverComponent = react.useCallback((e)=>{
|
|
736
|
+
if (isDragging.current) return;
|
|
737
|
+
const detail = e.detail;
|
|
738
|
+
if (detail?.componentUid) {
|
|
739
|
+
setHoverParentComponent(detail?.componentUid, detail?.type);
|
|
740
|
+
}
|
|
741
|
+
}, [
|
|
742
|
+
isDragging
|
|
743
|
+
]);
|
|
744
|
+
const onToolbarOnboarding = react.useCallback((e)=>{
|
|
745
|
+
const detail = e.detail;
|
|
746
|
+
if (detail?.isNewUser) {
|
|
747
|
+
setIsOnboarding(true);
|
|
748
|
+
}
|
|
749
|
+
}, []);
|
|
750
|
+
const onWindowResize = react.useCallback(()=>{
|
|
751
|
+
if (isOnboarding) {
|
|
752
|
+
calculateOnboardingPosition();
|
|
753
|
+
}
|
|
754
|
+
}, [
|
|
755
|
+
isOnboarding
|
|
756
|
+
]);
|
|
645
757
|
/* Register event */ react.useEffect(()=>{
|
|
646
758
|
document.addEventListener('mousemove', onMouseMove);
|
|
647
759
|
window.addEventListener('editor:active-component', onActiveComponent);
|
|
@@ -650,6 +762,9 @@ const Toolbar = ()=>{
|
|
|
650
762
|
window.addEventListener('editor:is-editing-text-editor', onIsEditingTextEditor);
|
|
651
763
|
window.addEventListener('editor:toolbar:show-parents', onShowParents);
|
|
652
764
|
window.addEventListener('editor:toolbar:resize-spacing', onResizeSpacing);
|
|
765
|
+
window.addEventListener('editor:hover-component', onHoverComponent);
|
|
766
|
+
window.addEventListener('editor:toolbar-onboarding', onToolbarOnboarding);
|
|
767
|
+
window.addEventListener('resize', onWindowResize);
|
|
653
768
|
return ()=>{
|
|
654
769
|
document.removeEventListener('mousemove', onMouseMove);
|
|
655
770
|
window.removeEventListener('editor:active-component', onActiveComponent);
|
|
@@ -658,6 +773,9 @@ const Toolbar = ()=>{
|
|
|
658
773
|
window.removeEventListener('editor:is-editing-text-editor', onIsEditingTextEditor);
|
|
659
774
|
window.removeEventListener('editor:toolbar:show-parents', onShowParents);
|
|
660
775
|
window.removeEventListener('editor:toolbar:resize-spacing', onResizeSpacing);
|
|
776
|
+
window.removeEventListener('editor:hover-component', onHoverComponent);
|
|
777
|
+
window.removeEventListener('editor:toolbar-onboarding', onToolbarOnboarding);
|
|
778
|
+
window.removeEventListener('resize', onWindowResize);
|
|
661
779
|
};
|
|
662
780
|
}, [
|
|
663
781
|
onMouseMove,
|
|
@@ -666,9 +784,115 @@ const Toolbar = ()=>{
|
|
|
666
784
|
onIsDragging,
|
|
667
785
|
onIsEditingTextEditor,
|
|
668
786
|
onShowParents,
|
|
669
|
-
onResizeSpacing
|
|
787
|
+
onResizeSpacing,
|
|
788
|
+
onHoverComponent,
|
|
789
|
+
onToolbarOnboarding,
|
|
790
|
+
onWindowResize
|
|
670
791
|
]);
|
|
671
|
-
return
|
|
792
|
+
return isOnboarding && /*#__PURE__*/ jsxRuntime.jsx(Onboarding.default, {
|
|
793
|
+
enable: true,
|
|
794
|
+
position: onboardingPosition,
|
|
795
|
+
onCloseOnboarding: onCloseOnboarding
|
|
796
|
+
});
|
|
797
|
+
};
|
|
798
|
+
const getDOMElementParents = ($el, selector, limit)=>{
|
|
799
|
+
// Set up a parent array
|
|
800
|
+
const parents = [];
|
|
801
|
+
// Push each parent $elms to the array
|
|
802
|
+
while($el){
|
|
803
|
+
$el = $el.parentElement ?? undefined;
|
|
804
|
+
if ($el) {
|
|
805
|
+
if ($el.tagName === 'BODY' || $el.getAttribute('data-uid') === 'ROOT') {
|
|
806
|
+
break;
|
|
807
|
+
}
|
|
808
|
+
if (selector) {
|
|
809
|
+
if ($el.matches(selector)) {
|
|
810
|
+
parents.push($el);
|
|
811
|
+
if (limit && parents.length == limit) {
|
|
812
|
+
return parents;
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
continue;
|
|
816
|
+
}
|
|
817
|
+
parents.push($el);
|
|
818
|
+
if (limit && parents.length == limit) {
|
|
819
|
+
return parents;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
// Return our parent array
|
|
824
|
+
return parents;
|
|
825
|
+
};
|
|
826
|
+
const getChildrenByAttrSelector = ($el, attrSelector)=>{
|
|
827
|
+
const childLen = $el.children.length;
|
|
828
|
+
if (childLen) {
|
|
829
|
+
for(let i = 0; i < childLen; i++){
|
|
830
|
+
const children = $el.children[i];
|
|
831
|
+
if (children) {
|
|
832
|
+
const is = children.getAttribute(attrSelector);
|
|
833
|
+
if (is) {
|
|
834
|
+
return children;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
};
|
|
840
|
+
const isOverParent = ({ current, parent: parent1, index, revert })=>{
|
|
841
|
+
for(let i = 0; i < index; i++){
|
|
842
|
+
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;
|
|
843
|
+
if (revert) {
|
|
844
|
+
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;
|
|
845
|
+
}
|
|
846
|
+
if (is) return true;
|
|
847
|
+
}
|
|
848
|
+
return false;
|
|
849
|
+
};
|
|
850
|
+
const waitForElementToExist = (selector, timeout = 200)=>{
|
|
851
|
+
return new Promise((resolve)=>{
|
|
852
|
+
const intervalID = setInterval(()=>{
|
|
853
|
+
const el = document.querySelector(selector);
|
|
854
|
+
if (el) {
|
|
855
|
+
clearInterval(intervalID);
|
|
856
|
+
clearTimeout(timeoutID);
|
|
857
|
+
resolve(el);
|
|
858
|
+
}
|
|
859
|
+
}, 50);
|
|
860
|
+
const timeoutID = setTimeout(()=>{
|
|
861
|
+
clearInterval(intervalID);
|
|
862
|
+
clearTimeout(timeoutID);
|
|
863
|
+
resolve(null);
|
|
864
|
+
}, timeout);
|
|
865
|
+
});
|
|
866
|
+
};
|
|
867
|
+
const notVisible = (el)=>{
|
|
868
|
+
const overflow = getComputedStyle(el).overflow;
|
|
869
|
+
return overflow !== 'visible';
|
|
870
|
+
};
|
|
871
|
+
const isSection = (el)=>{
|
|
872
|
+
const tag = el.getAttribute('data-component-tag');
|
|
873
|
+
return tag === 'Section';
|
|
874
|
+
};
|
|
875
|
+
const isLayoutElement = (el)=>{
|
|
876
|
+
const tag = el.getAttribute('data-component-tag');
|
|
877
|
+
return tag === 'Row' || tag === 'Product';
|
|
878
|
+
};
|
|
879
|
+
const isOverToolbarPosition = (el, parent1)=>{
|
|
880
|
+
const rect = el.getBoundingClientRect();
|
|
881
|
+
const rectP = parent1.getBoundingClientRect();
|
|
882
|
+
// 32px = toolbar active height
|
|
883
|
+
return rect.top - rectP.top < TOOLBAR_ACTIVE_HEIGHT + 1;
|
|
884
|
+
};
|
|
885
|
+
const findOverflowParent = (element, initEl)=>{
|
|
886
|
+
const thisEl = element;
|
|
887
|
+
const origEl = initEl || thisEl;
|
|
888
|
+
if (!thisEl) return;
|
|
889
|
+
if (isSection(thisEl)) return;
|
|
890
|
+
if (notVisible(thisEl) && isOverToolbarPosition(initEl, thisEl)) return thisEl;
|
|
891
|
+
if (thisEl.parentElement) {
|
|
892
|
+
return findOverflowParent(thisEl.parentElement, origEl);
|
|
893
|
+
} else {
|
|
894
|
+
return;
|
|
895
|
+
}
|
|
672
896
|
};
|
|
673
897
|
var Toolbar$1 = /*#__PURE__*/ react.memo(Toolbar);
|
|
674
898
|
|