@gem-sdk/core 1.29.4 → 1.30.0

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,52 @@ 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 && getAnimationType(getSettingsByDevice(device), 'appear') !== 'none');
215
+ const opacityObject = {
216
+ desktop: getInitOpacity('desktop'),
217
+ tablet: getInitOpacity('tablet'),
218
+ mobile: getInitOpacity('mobile')
219
+ };
220
+ const inheritParentStyle = {
221
+ all: tag === 'Section' ? '' : 'inherit'
222
+ };
223
+ return template`
224
+ ${RenderIf(isLocalEnv, `<script src="{{ 'gp-animation.js' | asset_url }}" defer="defer"></script>`, `<script src="${baseAssetURL}/assets/gp-animation.js" defer="defer"></script>`)}
225
+ <gp-animation
226
+ gp-data='${JSON.stringify({
227
+ config: animation,
228
+ tag
229
+ })}'
230
+ style="${{
231
+ ...inheritParentStyle
232
+ }}"
233
+ >
234
+ <div style="${{
235
+ ...makeStyleResponsive('op', opacityObject)
236
+ }}">${liquid}</div>
237
+ </gp-animation>
238
+ `;
239
+ };
198
240
  const RenderChildren = (props)=>{
199
241
  const data = Render(props);
200
242
  // Append to prop parent
201
243
  for(const key in data.extraFiles){
202
244
  if (Object.prototype.hasOwnProperty.call(data.extraFiles, key)) {
203
- const value = data.extraFiles[key];
204
- props.customProps.extraFiles[key] = value;
245
+ props.customProps.extraFiles[key] = data.extraFiles[key];
205
246
  }
206
247
  }
207
248
  // Fix limit 256kb
@@ -210,7 +251,7 @@ const RenderChildren = (props)=>{
210
251
  if (Math.ceil(size / 1024) >= 180) {
211
252
  const fileName = `gp-section-snippet-${props.uid}`;
212
253
  props.customProps.extraFiles[fileName] = data.liquid;
213
- return `{% render '${fileName}', product: product, variant: variant, product_form_id: product_form_id, productSelectedVariant: productSelectedVariant %}`;
254
+ return `{% render '${fileName}', product: product, variant: variant, product_form_id: product_form_id, productSelectedVariant: productSelectedVariant, form: form %}`;
214
255
  }
215
256
  return data.liquid;
216
257
  };
@@ -227,7 +268,7 @@ const WrapRenderChildren = ({ uid, customProps }, codes)=>{
227
268
  if (Math.ceil(size / 1024) >= 180) {
228
269
  const fileName = `gp-section-snippet-${uid + i}`;
229
270
  customProps.extraFiles[fileName] = code;
230
- liquid += `{% render '${fileName}', product: product, variant: variant, product_form_id: product_form_id, productSelectedVariant: productSelectedVariant %}`;
271
+ liquid += `{% render '${fileName}', product: product, variant: variant, product_form_id: product_form_id, productSelectedVariant: productSelectedVariant, form: form %}`;
231
272
  } else {
232
273
  liquid += code;
233
274
  }
@@ -32,7 +32,8 @@ const disableWrap = [
32
32
  'Product',
33
33
  'ProductImages',
34
34
  'ProductImagesV2',
35
- 'Sticky'
35
+ 'Sticky',
36
+ 'Heading'
36
37
  ];
37
38
  const customRenderChildren = [
38
39
  'Accordion',
@@ -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 };