@gem-sdk/core 1.29.5 → 1.30.1

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/index.js CHANGED
@@ -34,6 +34,7 @@ var isBrowser = require('./helpers/is-browser.js');
34
34
  var isSafari = require('./helpers/is-safari.js');
35
35
  var isEmptyChildren = require('./helpers/is-empty-children.js');
36
36
  var filterToolbarPreview = require('./helpers/filter-toolbar-preview.js');
37
+ var animations = require('./helpers/animations.js');
37
38
  var makeStyle = require('./helpers/make-style.js');
38
39
  var normalizeBuilderData = require('./helpers/normalize-builder-data.js');
39
40
  var prefetchQueries = require('./helpers/prefetch-queries.js');
@@ -89,6 +90,7 @@ var useSwatchesOptions = require('./hooks/useSwatchesOptions.js');
89
90
  var useInitialSwatchesOptions = require('./hooks/useInitialSwatchesOptions.js');
90
91
  var shop$1 = require('./types/shop.js');
91
92
  var globalStyle = require('./types/global-style.js');
93
+ var animations$1 = require('./types/animations.js');
92
94
  var getCollection = require('./helpers/queries/get-collection.js');
93
95
  var getProduct = require('./helpers/queries/get-product.js');
94
96
  var getProductBySlug = require('./helpers/queries/get-product-by-slug.js');
@@ -154,6 +156,7 @@ exports.isBrowser = isBrowser.default;
154
156
  exports.isSafari = isSafari.default;
155
157
  exports.isEmptyChildren = isEmptyChildren.isEmptyChildren;
156
158
  exports.filterToolbarPreview = filterToolbarPreview.filterToolbarPreview;
159
+ exports.animations = animations.animations;
157
160
  exports.makeAspectRatio = makeStyle.makeAspectRatio;
158
161
  exports.makeGlobalSizeWidthResponsive = makeStyle.makeGlobalSizeWidthResponsive;
159
162
  exports.makeHeight = makeStyle.makeHeight;
@@ -312,6 +315,30 @@ exports.useInitialSwatchesOptions = useInitialSwatchesOptions.default;
312
315
  exports.ShopType = shop$1;
313
316
  exports.OptionNormalStyle = globalStyle.OptionNormalStyle;
314
317
  exports.OptionSpecialStyle = globalStyle.OptionSpecialStyle;
318
+ Object.defineProperty(exports, 'AnimationDirectionType', {
319
+ enumerable: true,
320
+ get: function () { return animations$1.AnimationDirectionType; }
321
+ });
322
+ Object.defineProperty(exports, 'AnimationEasingType', {
323
+ enumerable: true,
324
+ get: function () { return animations$1.AnimationEasingType; }
325
+ });
326
+ Object.defineProperty(exports, 'AnimationSetting', {
327
+ enumerable: true,
328
+ get: function () { return animations$1.AnimationSetting; }
329
+ });
330
+ Object.defineProperty(exports, 'AnimationTriggerType', {
331
+ enumerable: true,
332
+ get: function () { return animations$1.AnimationTriggerType; }
333
+ });
334
+ Object.defineProperty(exports, 'AnimationType', {
335
+ enumerable: true,
336
+ get: function () { return animations$1.AnimationType; }
337
+ });
338
+ Object.defineProperty(exports, 'AnimationZoomDirectionType', {
339
+ enumerable: true,
340
+ get: function () { return animations$1.AnimationZoomDirectionType; }
341
+ });
315
342
  exports.calculateFirstProduct = getCollection.calculateFirstProduct;
316
343
  exports.getCollection = getCollection.getCollection;
317
344
  exports.fetchMedias = getProduct.fetchMedias;
@@ -0,0 +1,47 @@
1
+ 'use strict';
2
+
3
+ exports.AnimationType = void 0;
4
+ (function(AnimationType) {
5
+ AnimationType["Fade"] = 'fade';
6
+ AnimationType["Slide"] = 'slide';
7
+ AnimationType["Zoom"] = 'zoom';
8
+ AnimationType["Shake"] = 'shake';
9
+ AnimationType["None"] = 'none';
10
+ })(exports.AnimationType || (exports.AnimationType = {}));
11
+ exports.AnimationSetting = void 0;
12
+ (function(AnimationSetting) {
13
+ AnimationSetting["Loop"] = 'loop';
14
+ AnimationSetting["Scale"] = 'scale';
15
+ AnimationSetting["Delay"] = 'delay';
16
+ AnimationSetting["Easing"] = 'easing';
17
+ AnimationSetting["Speed"] = 'speed';
18
+ AnimationSetting["IsFade"] = 'isFade';
19
+ AnimationSetting["Distance"] = 'distance';
20
+ AnimationSetting["Intensity"] = 'intensity';
21
+ AnimationSetting["Direction"] = 'direction';
22
+ AnimationSetting["ZoomDirection"] = 'zoomDirection';
23
+ })(exports.AnimationSetting || (exports.AnimationSetting = {}));
24
+ exports.AnimationDirectionType = void 0;
25
+ (function(AnimationDirectionType) {
26
+ AnimationDirectionType["Left"] = 'left';
27
+ AnimationDirectionType["Right"] = 'right';
28
+ AnimationDirectionType["Up"] = 'up';
29
+ AnimationDirectionType["Down"] = 'down';
30
+ })(exports.AnimationDirectionType || (exports.AnimationDirectionType = {}));
31
+ exports.AnimationTriggerType = void 0;
32
+ (function(AnimationTriggerType) {
33
+ AnimationTriggerType["Appear"] = 'appear';
34
+ AnimationTriggerType["Hover"] = 'hover';
35
+ })(exports.AnimationTriggerType || (exports.AnimationTriggerType = {}));
36
+ exports.AnimationZoomDirectionType = void 0;
37
+ (function(AnimationZoomDirectionType) {
38
+ AnimationZoomDirectionType["In"] = 'in';
39
+ AnimationZoomDirectionType["Out"] = 'out';
40
+ })(exports.AnimationZoomDirectionType || (exports.AnimationZoomDirectionType = {}));
41
+ exports.AnimationEasingType = void 0;
42
+ (function(AnimationEasingType) {
43
+ AnimationEasingType["Ease"] = 'ease';
44
+ AnimationEasingType["EaseIn"] = 'ease-in';
45
+ AnimationEasingType["EaseOut"] = 'ease-out';
46
+ AnimationEasingType["Linear"] = 'linear';
47
+ })(exports.AnimationEasingType || (exports.AnimationEasingType = {}));
@@ -4,6 +4,7 @@ import { composeAdvanceStyle } from '../helpers/compose-advance-style.js';
4
4
  import { disableWrap, excludeApplyStyle } from './constant.js';
5
5
  import RenderCustomCode from './RenderCustomCode.js';
6
6
  import { ComponentToolbarPreview } from './ComponentToolbarPreview.js';
7
+ import useApplyAnimation from '../hooks/animation/useApplyAnimation.js';
7
8
 
8
9
  const ComponentWrapperPreview = ({ children, ...props })=>{
9
10
  useEffect(()=>{
@@ -17,6 +18,9 @@ const ComponentWrapperPreview = ({ children, ...props })=>{
17
18
  }, [
18
19
  props.uid
19
20
  ]);
21
+ useApplyAnimation({
22
+ props
23
+ });
20
24
  if (props.type === 'section') {
21
25
  return null;
22
26
  }
@@ -1,3 +1,4 @@
1
+ import { makeStyleResponsive } from '../helpers/make-style.js';
1
2
  import 'react';
2
3
  import 'react/jsx-runtime';
3
4
  import 'zustand';
@@ -9,7 +10,7 @@ import '../hooks/useCartUI.js';
9
10
  import 'react-transition-group';
10
11
  import '@gem-sdk/core';
11
12
  import { RenderIf, template } from '../helpers/render.js';
12
- import '../helpers/convert.js';
13
+ import { baseAssetURL, isLocalEnv } from '../helpers/convert.js';
13
14
  import { composeAdvanceStyle } from '../helpers/compose-advance-style.js';
14
15
  import { disableWrap, customRenderChildren } from './constant.js';
15
16
 
@@ -166,6 +167,7 @@ const Render = ({ uid, builder, components, parentId, extraFiles = {}, pageConte
166
167
  const { cssCode, jsCode } = RenderCustomCode(item);
167
168
  if (cssCode) liquid += cssCode;
168
169
  if (jsCode) liquid += jsCode;
170
+ liquid = appendAnimation(item, liquid);
169
171
  return {
170
172
  liquid,
171
173
  extraFiles: customProps.extraFiles
@@ -195,13 +197,55 @@ const RenderCustomCode = (item)=>{
195
197
  jsCode
196
198
  };
197
199
  };
200
+ const appendAnimation = (props, liquid)=>{
201
+ const { advanced, tag } = props;
202
+ const { animation } = advanced ?? {};
203
+ const enableAnimation = animation?.desktop?.enabled || animation?.tablet?.enabled || animation?.mobile?.enabled;
204
+ if (!enableAnimation || !animation?.desktop?.triggerConfig) return liquid;
205
+ const getAnimationType = (settings, type)=>{
206
+ return settings?.triggerConfig?.[type]?.animation ?? 'none';
207
+ };
208
+ const getSettingsByDevice = (device)=>{
209
+ if (device === 'desktop') return animation?.desktop;
210
+ else if (device === 'tablet') return animation?.tablet ?? animation?.desktop;
211
+ else if (device === 'mobile') return animation?.mobile ?? animation?.tablet ?? animation?.desktop;
212
+ return animation?.desktop;
213
+ };
214
+ const getInitOpacity = (device)=>+!(getSettingsByDevice(device)?.enabled && ![
215
+ 'shake',
216
+ 'none'
217
+ ].includes(getAnimationType(getSettingsByDevice(device), 'appear')));
218
+ const opacityObject = {
219
+ desktop: getInitOpacity('desktop'),
220
+ tablet: getInitOpacity('tablet'),
221
+ mobile: getInitOpacity('mobile')
222
+ };
223
+ const inheritParentStyle = {
224
+ all: tag === 'Section' ? '' : 'inherit'
225
+ };
226
+ return template`
227
+ ${RenderIf(isLocalEnv, `<script src="{{ 'gp-animation.js' | asset_url }}" defer="defer"></script>`, `<script src="${baseAssetURL}/assets/gp-animation.js" defer="defer"></script>`)}
228
+ <gp-animation
229
+ gp-data='${JSON.stringify({
230
+ config: animation,
231
+ tag
232
+ })}'
233
+ style="${{
234
+ ...inheritParentStyle
235
+ }}"
236
+ >
237
+ <div style="${{
238
+ ...makeStyleResponsive('op', opacityObject)
239
+ }}">${liquid}</div>
240
+ </gp-animation>
241
+ `;
242
+ };
198
243
  const RenderChildren = (props)=>{
199
244
  const data = Render(props);
200
245
  // Append to prop parent
201
246
  for(const key in data.extraFiles){
202
247
  if (Object.prototype.hasOwnProperty.call(data.extraFiles, key)) {
203
- const value = data.extraFiles[key];
204
- props.customProps.extraFiles[key] = value;
248
+ props.customProps.extraFiles[key] = data.extraFiles[key];
205
249
  }
206
250
  }
207
251
  // Fix limit 256kb
@@ -210,7 +254,7 @@ const RenderChildren = (props)=>{
210
254
  if (Math.ceil(size / 1024) >= 180) {
211
255
  const fileName = `gp-section-snippet-${props.uid}`;
212
256
  props.customProps.extraFiles[fileName] = data.liquid;
213
- return `{% render '${fileName}', product: product, variant: variant, product_form_id: product_form_id, productSelectedVariant: productSelectedVariant %}`;
257
+ return `{% render '${fileName}', product: product, variant: variant, product_form_id: product_form_id, productSelectedVariant: productSelectedVariant, form: form %}`;
214
258
  }
215
259
  return data.liquid;
216
260
  };
@@ -227,7 +271,7 @@ const WrapRenderChildren = ({ uid, customProps }, codes)=>{
227
271
  if (Math.ceil(size / 1024) >= 180) {
228
272
  const fileName = `gp-section-snippet-${uid + i}`;
229
273
  customProps.extraFiles[fileName] = code;
230
- liquid += `{% render '${fileName}', product: product, variant: variant, product_form_id: product_form_id, productSelectedVariant: productSelectedVariant %}`;
274
+ liquid += `{% render '${fileName}', product: product, variant: variant, product_form_id: product_form_id, productSelectedVariant: productSelectedVariant, form: form %}`;
231
275
  } else {
232
276
  liquid += code;
233
277
  }
@@ -0,0 +1,211 @@
1
+ const EASING = {
2
+ ease: 'cubic-bezier(0.46,0.03,0.52,0.96)',
3
+ 'ease-in': 'cubic-bezier(0.55,0.08,0.68,0.53)',
4
+ 'ease-out': 'cubic-bezier(0.46,0.03,0.52,0.96)',
5
+ linear: 'linear'
6
+ };
7
+ const animations = ()=>{
8
+ const normalizeOptions = (options)=>{
9
+ const cloneOptions = JSON.parse(JSON.stringify(options));
10
+ const numberMember = [
11
+ 'delay',
12
+ 'speed',
13
+ 'scale',
14
+ 'intensity'
15
+ ];
16
+ numberMember.forEach((keyName)=>{
17
+ if (!cloneOptions?.[keyName]) return;
18
+ if (keyName === 'scale') {
19
+ if (!cloneOptions?.zoomDirection) throw new TypeError(`zoomDirection not found on zoom preset`);
20
+ const [i1, i2] = cloneOptions?.scale?.in ?? [
21
+ 1,
22
+ 1
23
+ ];
24
+ const [o1, o2] = cloneOptions?.scale?.out ?? [
25
+ 1,
26
+ 1
27
+ ];
28
+ cloneOptions[keyName] = {
29
+ in: [
30
+ Number(i1) / 100,
31
+ Number(i2) / 100
32
+ ],
33
+ out: [
34
+ Number(o1) / 100,
35
+ Number(o2) / 100
36
+ ]
37
+ };
38
+ return;
39
+ }
40
+ const num = Number(cloneOptions?.[keyName]);
41
+ if (keyName === 'delay') cloneOptions[keyName] = num * 1000;
42
+ else cloneOptions[keyName] = num;
43
+ if (!isFinite(num)) throw new TypeError(`${keyName} must be a number`);
44
+ });
45
+ return cloneOptions;
46
+ };
47
+ const slide = (target, options)=>{
48
+ const normalizedOptions = normalizeOptions(options);
49
+ const { direction, distance } = normalizedOptions;
50
+ const coordinate = [
51
+ 'left',
52
+ 'right'
53
+ ].includes(direction ?? '') ? 'X' : 'Y';
54
+ const isNeg = [
55
+ 'left',
56
+ 'down'
57
+ ].includes(direction ?? '') ? '-' : '';
58
+ const preset = [
59
+ {
60
+ opacity: 0,
61
+ transform: `translate${coordinate}(${isNeg}${distance ?? 50}%)`
62
+ },
63
+ {
64
+ opacity: 1,
65
+ transform: `translate${coordinate}(0)`
66
+ }
67
+ ];
68
+ return generateAnimationInstance(target, preset, {
69
+ ...generateOptions(normalizedOptions, 500)
70
+ });
71
+ };
72
+ const fade = (target, options)=>{
73
+ const normalizedOptions = normalizeOptions(options);
74
+ const preset = [
75
+ {
76
+ opacity: 0
77
+ },
78
+ {
79
+ opacity: 1
80
+ }
81
+ ];
82
+ return generateAnimationInstance(target, preset, {
83
+ ...generateOptions(normalizedOptions, 500)
84
+ });
85
+ };
86
+ const generateOptions = (options, defaultDuration)=>{
87
+ const convertSpeedToDuration = (speed)=>{
88
+ if (!speed) return defaultDuration;
89
+ return 1.5 / speed * 1000;
90
+ };
91
+ const { loop, delay, speed, easing } = options ?? {};
92
+ const duration = convertSpeedToDuration(speed);
93
+ const actualDelay = delay ?? 0;
94
+ const actualDuration = loop ? duration + actualDelay : duration;
95
+ return {
96
+ iterations: loop ? Infinity : 1,
97
+ duration: actualDuration,
98
+ delay: actualDelay,
99
+ easing: EASING[easing ?? 'linear']
100
+ };
101
+ };
102
+ const zoom = (target, options)=>{
103
+ const normalizedOptions = normalizeOptions(options);
104
+ const { scale, zoomDirection, isFade } = normalizedOptions;
105
+ const [i1, i2] = scale.in;
106
+ const [o1, o2] = scale.out;
107
+ const zoomInPreset = [
108
+ {
109
+ transform: `scale(${i1}, ${i1})`,
110
+ opacity: isFade ? 0 : 1
111
+ },
112
+ {
113
+ transform: `scale(${i2 ?? 1.2}, ${i2 ?? 1.2})`,
114
+ opacity: 1
115
+ }
116
+ ];
117
+ const zoomOutPreset = [
118
+ {
119
+ transform: `scale(${o1}, ${o1})`,
120
+ opacity: isFade ? 0 : 1
121
+ },
122
+ {
123
+ transform: `scale(${o2 ?? 0.8}, ${o2 ?? 0.8})`,
124
+ opacity: 1
125
+ }
126
+ ];
127
+ const zoomPreset = zoomDirection === 'in' ? zoomInPreset : zoomOutPreset;
128
+ return generateAnimationInstance(target, zoomPreset, {
129
+ ...generateOptions(normalizedOptions, 700)
130
+ });
131
+ };
132
+ const generateLoopDelayEffect = (keyframes, delay, duration)=>{
133
+ if (!delay) return keyframes;
134
+ const offset = delay / duration;
135
+ const keyframe = [
136
+ ...keyframes
137
+ ].pop();
138
+ return [
139
+ ...keyframes,
140
+ {
141
+ ...keyframe,
142
+ offset: 1 - offset
143
+ }
144
+ ];
145
+ };
146
+ const shake = (target, options)=>{
147
+ const normalizedOptions = normalizeOptions(options);
148
+ const { intensity } = normalizedOptions ?? {};
149
+ const zeroIntensity = [
150
+ {
151
+ transform: 'translate3d(0, 0, 0)'
152
+ }
153
+ ];
154
+ const unitIntensity = [
155
+ {
156
+ transform: 'translate3d(4px, 0, 0)'
157
+ },
158
+ {
159
+ transform: 'translate3d(-4px, 0, 0)'
160
+ },
161
+ {
162
+ transform: 'translate3d(4px, 0, 0)'
163
+ }
164
+ ];
165
+ let keyframes = [];
166
+ Array.from(Array(intensity ?? 1).keys()).forEach(()=>{
167
+ keyframes = [
168
+ ...keyframes,
169
+ ...unitIntensity
170
+ ];
171
+ });
172
+ const shakePreset = [
173
+ {
174
+ transform: 'translate3d(-1px, 0, 0)'
175
+ },
176
+ {
177
+ transform: 'translate3d(2px, 0, 0)'
178
+ },
179
+ {
180
+ transform: 'translate3d(-4px, 0, 0)'
181
+ },
182
+ ...keyframes,
183
+ {
184
+ transform: 'translate3d(-4px, 0, 0)'
185
+ },
186
+ {
187
+ transform: 'translate3d(2px, 0, 0)'
188
+ },
189
+ {
190
+ transform: 'translate3d(-1px, 0, 0)'
191
+ }
192
+ ];
193
+ return generateAnimationInstance(target, intensity ? shakePreset : zeroIntensity, {
194
+ ...generateOptions(normalizedOptions ?? {}, 820)
195
+ });
196
+ };
197
+ const generateAnimationInstance = (target, effectPreset, options)=>{
198
+ const effect = new KeyframeEffect(target, options.iterations && options.iterations === 1 ? effectPreset : generateLoopDelayEffect(effectPreset, options?.delay ?? 0, (options?.duration) ?? 0), {
199
+ ...options
200
+ });
201
+ return new Animation(effect, document.timeline);
202
+ };
203
+ return {
204
+ zoom,
205
+ shake,
206
+ fade,
207
+ slide
208
+ };
209
+ };
210
+
211
+ export { animations };
@@ -0,0 +1,37 @@
1
+ import { useRef, useCallback } from 'react';
2
+
3
+ const useAnimationActions = ()=>{
4
+ const listAnimations = useRef();
5
+ const setAnimation = useCallback((newListAnimations)=>{
6
+ listAnimations.current = newListAnimations;
7
+ }, [
8
+ listAnimations
9
+ ]);
10
+ const playAnimation = useCallback(()=>{
11
+ if (!listAnimations.current) return;
12
+ for (const animation of listAnimations.current){
13
+ animation.play();
14
+ }
15
+ }, []);
16
+ const cancelAnimation = useCallback(()=>{
17
+ if (!listAnimations.current) return;
18
+ for (const animation of listAnimations.current){
19
+ animation.cancel();
20
+ }
21
+ }, []);
22
+ const setAnimationOnFinish = useCallback((onFinish)=>{
23
+ if (!listAnimations.current) return;
24
+ for (const animation of listAnimations.current){
25
+ animation.onfinish = onFinish;
26
+ }
27
+ }, []);
28
+ return {
29
+ currentAnimation: listAnimations.current,
30
+ setAnimation,
31
+ playAnimation,
32
+ cancelAnimation,
33
+ setAnimationOnFinish
34
+ };
35
+ };
36
+
37
+ export { useAnimationActions };
@@ -0,0 +1,27 @@
1
+ import { useMemo, useCallback } from 'react';
2
+ import { useCurrentDevice } from '../use-current-device.js';
3
+
4
+ const useAnimationConfig = (props)=>{
5
+ const currentDevice = useCurrentDevice();
6
+ const configByDevices = useMemo(()=>props?.advanced?.animation?.[currentDevice], [
7
+ currentDevice,
8
+ props?.advanced?.animation
9
+ ]);
10
+ const getAnimationConfig = useCallback(()=>{
11
+ const { trigger, triggerConfig } = configByDevices;
12
+ const { animation, setting } = triggerConfig[trigger];
13
+ return {
14
+ type: animation,
15
+ setting: setting[animation]
16
+ };
17
+ }, [
18
+ configByDevices
19
+ ]);
20
+ const isEnabledAnimation = configByDevices?.enabled;
21
+ return {
22
+ isEnabledAnimation,
23
+ getAnimationConfig
24
+ };
25
+ };
26
+
27
+ export { useAnimationConfig };
@@ -0,0 +1,29 @@
1
+ import { useCallback } from 'react';
2
+
3
+ const useAnimationPreview = ({ props, playAnimation, cancelAnimation, setAnimationOnFinish, setToolbarActive })=>{
4
+ const previewAnimation = useCallback((e)=>{
5
+ const { uid, isCancel } = e.detail;
6
+ if (props.uid !== uid) return;
7
+ cancelAnimation();
8
+ if (isCancel) {
9
+ setToolbarActive(true);
10
+ return;
11
+ }
12
+ playAnimation();
13
+ setToolbarActive(false);
14
+ setAnimationOnFinish(()=>{
15
+ setToolbarActive(true);
16
+ });
17
+ }, [
18
+ props.uid,
19
+ cancelAnimation,
20
+ playAnimation,
21
+ setToolbarActive,
22
+ setAnimationOnFinish
23
+ ]);
24
+ return {
25
+ previewAnimation
26
+ };
27
+ };
28
+
29
+ export { useAnimationPreview };
@@ -0,0 +1,118 @@
1
+ import { useRef, useCallback } from 'react';
2
+ import { useAnimationConfig } from './useAnimationConfig.js';
3
+
4
+ const SPACING_ACTIVE_ATTRIBUTE = 'data-spacing';
5
+ const TOOLBAR_ACTIVE_ATTRIBUTE = 'data-toolbar-active';
6
+ const OUTLINE_ACTIVE_ATTRIBUTE = 'data-outline-active';
7
+ const TOOLBAR_ADD_SECTION_ACTIVE_ATTRIBUTE = 'data-toolbar-add-active';
8
+ const useAnimationTarget = (props)=>{
9
+ const { isEnabledAnimation } = useAnimationConfig(props);
10
+ const componentTag = props.tag;
11
+ const componentUid = props.uid;
12
+ const targets = useRef(null);
13
+ const targetObjects = useRef([]);
14
+ const setToolbarActive = (isActive)=>{
15
+ if (!targetObjects.current) return;
16
+ for (const item of targetObjects.current){
17
+ if (isActive) {
18
+ item.toolbar?.setAttribute(TOOLBAR_ACTIVE_ATTRIBUTE, 'true');
19
+ item.outline?.setAttribute(OUTLINE_ACTIVE_ATTRIBUTE, 'true');
20
+ item.spacing?.setAttribute(SPACING_ACTIVE_ATTRIBUTE, 'true');
21
+ item.addSectionTop?.setAttribute(TOOLBAR_ADD_SECTION_ACTIVE_ATTRIBUTE, 'true');
22
+ item.addSectionBottom?.setAttribute(TOOLBAR_ADD_SECTION_ACTIVE_ATTRIBUTE, 'true');
23
+ } else {
24
+ item.toolbar?.removeAttribute(TOOLBAR_ACTIVE_ATTRIBUTE);
25
+ item.outline?.removeAttribute(OUTLINE_ACTIVE_ATTRIBUTE);
26
+ item.spacing?.removeAttribute(SPACING_ACTIVE_ATTRIBUTE);
27
+ item.addSectionTop?.removeAttribute(TOOLBAR_ADD_SECTION_ACTIVE_ATTRIBUTE);
28
+ item.addSectionBottom?.removeAttribute(TOOLBAR_ADD_SECTION_ACTIVE_ATTRIBUTE);
29
+ }
30
+ }
31
+ };
32
+ const getSectionProperties = (target)=>{
33
+ const sectionAddTop = target.querySelector('[data-toolbar-add-top]');
34
+ const sectionAddBottom = target.querySelector('[data-toolbar-add-bottom]');
35
+ const sectionChild = Array.from(target.children);
36
+ const sectionToolbar = sectionChild.find((child)=>child.getAttribute('data-toolbar') !== null);
37
+ const sectionOutline = sectionChild.find((child)=>child.getAttribute('data-outline') !== null);
38
+ return {
39
+ sectionToolbar,
40
+ sectionOutline,
41
+ sectionAddTop,
42
+ sectionAddBottom
43
+ };
44
+ };
45
+ const getUpdatedTargetObjects = useCallback((targets)=>{
46
+ return targets.reduce((accumulator, $rootTarget)=>{
47
+ let addSectionTop = null;
48
+ let addSectionBottom = null;
49
+ let target = $rootTarget;
50
+ let toolbar = $rootTarget.querySelector('[data-toolbar][data-toolbar-active]');
51
+ let outline = $rootTarget.querySelector('[data-outline][data-outline-active]');
52
+ const targetChild = Array.from(target.children);
53
+ const spacing = targetChild.find((child)=>child.getAttribute('data-spacing') !== null);
54
+ switch(componentTag){
55
+ case 'Button':
56
+ case 'SubmitButton':
57
+ case 'ProductButton':
58
+ case 'DynamicCheckout':
59
+ target = $rootTarget.querySelector('.gp-button-base');
60
+ break;
61
+ case 'ProductProperties':
62
+ target = $rootTarget.querySelector('input');
63
+ break;
64
+ case 'Icon':
65
+ target = $rootTarget.firstElementChild;
66
+ break;
67
+ case 'ProductTag':
68
+ target = $rootTarget?.children[0]?.children[0];
69
+ break;
70
+ case 'Section':
71
+ {
72
+ target = $rootTarget;
73
+ const { sectionOutline, sectionToolbar, sectionAddTop, sectionAddBottom } = getSectionProperties(target);
74
+ outline = sectionOutline;
75
+ toolbar = sectionToolbar;
76
+ addSectionTop = sectionAddTop;
77
+ addSectionBottom = sectionAddBottom;
78
+ break;
79
+ }
80
+ default:
81
+ target = $rootTarget;
82
+ }
83
+ const newTargetObject = {
84
+ target,
85
+ toolbar,
86
+ outline,
87
+ spacing,
88
+ addSectionTop,
89
+ addSectionBottom
90
+ };
91
+ accumulator.push(newTargetObject);
92
+ return accumulator;
93
+ }, []);
94
+ }, [
95
+ componentTag
96
+ ]);
97
+ const initListOfTargets = useCallback(()=>{
98
+ if (!isEnabledAnimation) return;
99
+ if (!targets.current) {
100
+ targets.current = document.querySelectorAll(`[data-uid="${componentUid}"]`);
101
+ }
102
+ const targetsArray = Array.from(targets.current);
103
+ if (!targetsArray.length) return;
104
+ const updatedTargetObjects = getUpdatedTargetObjects(targetsArray);
105
+ targetObjects.current = updatedTargetObjects;
106
+ }, [
107
+ componentUid,
108
+ getUpdatedTargetObjects,
109
+ isEnabledAnimation
110
+ ]);
111
+ return {
112
+ targetObjects,
113
+ setToolbarActive,
114
+ initListOfTargets
115
+ };
116
+ };
117
+
118
+ export { useAnimationTarget };