@elementor/editor-interactions 4.0.0-650 → 4.0.0-660

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elementor/editor-interactions",
3
- "version": "4.0.0-650",
3
+ "version": "4.0.0-660",
4
4
  "private": false,
5
5
  "author": "Elementor Team",
6
6
  "homepage": "https://elementor.com/",
@@ -39,18 +39,18 @@
39
39
  "dev": "tsup --config=../../tsup.dev.ts"
40
40
  },
41
41
  "dependencies": {
42
- "@elementor/editor-controls": "4.0.0-650",
43
- "@elementor/editor-elements": "4.0.0-650",
44
- "@elementor/editor-mcp": "4.0.0-650",
45
- "@elementor/editor-props": "4.0.0-650",
46
- "@elementor/editor-responsive": "4.0.0-650",
47
- "@elementor/editor-ui": "4.0.0-650",
48
- "@elementor/editor-v1-adapters": "4.0.0-650",
42
+ "@elementor/editor-controls": "4.0.0-660",
43
+ "@elementor/editor-elements": "4.0.0-660",
44
+ "@elementor/editor-mcp": "4.0.0-660",
45
+ "@elementor/editor-props": "4.0.0-660",
46
+ "@elementor/editor-responsive": "4.0.0-660",
47
+ "@elementor/editor-ui": "4.0.0-660",
48
+ "@elementor/editor-v1-adapters": "4.0.0-660",
49
49
  "@elementor/icons": "^1.68.0",
50
- "@elementor/schema": "4.0.0-650",
51
- "@elementor/session": "4.0.0-650",
50
+ "@elementor/schema": "4.0.0-660",
51
+ "@elementor/session": "4.0.0-660",
52
52
  "@elementor/ui": "1.36.17",
53
- "@elementor/utils": "4.0.0-650",
53
+ "@elementor/utils": "4.0.0-660",
54
54
  "@wordpress/i18n": "^5.13.0"
55
55
  },
56
56
  "peerDependencies": {
@@ -35,6 +35,8 @@ export const DEFAULT_VALUES = {
35
35
  replay: false,
36
36
  easing: 'easeIn',
37
37
  relativeTo: 'viewport',
38
+ repeat: '',
39
+ times: 1,
38
40
  start: 85,
39
41
  end: 15,
40
42
  };
@@ -53,7 +55,9 @@ type InteractionsControlType =
53
55
  | 'relativeTo'
54
56
  | 'start'
55
57
  | 'end'
56
- | 'customEffects';
58
+ | 'customEffects'
59
+ | 'repeat'
60
+ | 'times';
57
61
 
58
62
  type InteractionValues = {
59
63
  trigger: string;
@@ -68,6 +72,8 @@ type InteractionValues = {
68
72
  start: SizeStringValue;
69
73
  end: SizeStringValue;
70
74
  customEffects?: PropValue;
75
+ repeat: string;
76
+ times: number;
71
77
  };
72
78
 
73
79
  type ControlVisibilityConfig = {
@@ -82,6 +88,8 @@ const controlVisibilityConfig: ControlVisibilityConfig = {
82
88
  relativeTo: ( values ) => values.trigger === 'scrollOn',
83
89
  start: ( values ) => values.trigger === 'scrollOn',
84
90
  end: ( values ) => values.trigger === 'scrollOn',
91
+ repeat: ( values ) => values.trigger !== 'scrollOn',
92
+ times: ( values ) => values.trigger !== 'scrollOn' && values.repeat === 'times',
85
93
 
86
94
  duration: ( values ) => {
87
95
  const isRelativeToVisible = values.trigger === 'scrollOn';
@@ -93,6 +101,14 @@ const controlVisibilityConfig: ControlVisibilityConfig = {
93
101
  },
94
102
  };
95
103
 
104
+ function normalizeTimesValue( value: unknown, fallback: number ): number {
105
+ const numericValue = Number( value );
106
+ if ( ! Number.isFinite( numericValue ) ) {
107
+ return fallback;
108
+ }
109
+ return Math.max( 1, Math.floor( numericValue ) );
110
+ }
111
+
96
112
  function useControlComponent( controlName: InteractionsControlType, isVisible: boolean = true ) {
97
113
  return useMemo( () => {
98
114
  if ( ! isVisible ) {
@@ -113,6 +129,9 @@ export const InteractionDetails = ( { interaction, onChange, onPlayInteraction }
113
129
  const replay = extractBoolean( interaction.animation.value.config?.value.replay, DEFAULT_VALUES.replay );
114
130
  const easing = extractString( interaction.animation.value.config?.value.easing, DEFAULT_VALUES.easing );
115
131
  const relativeTo = extractString( interaction.animation.value.config?.value.relativeTo, DEFAULT_VALUES.relativeTo );
132
+ const configValue = interaction.animation.value.config?.value;
133
+ const repeat = extractString( configValue?.repeat, DEFAULT_VALUES.repeat );
134
+ const times = normalizeTimesValue( configValue?.times?.value, DEFAULT_VALUES.times );
116
135
 
117
136
  const start = extractSize( interaction.animation.value.config?.value.start, DEFAULT_VALUES.start );
118
137
  const end = extractSize( interaction.animation.value.config?.value.end, DEFAULT_VALUES.end );
@@ -127,6 +146,8 @@ export const InteractionDetails = ( { interaction, onChange, onPlayInteraction }
127
146
  easing,
128
147
  replay,
129
148
  relativeTo,
149
+ repeat,
150
+ times,
130
151
  start,
131
152
  end,
132
153
  customEffects,
@@ -151,6 +172,14 @@ export const InteractionDetails = ( { interaction, onChange, onPlayInteraction }
151
172
  controlVisibilityConfig.effectType( interactionValues )
152
173
  );
153
174
  const DirectionControl = useControlComponent( 'direction', controlVisibilityConfig.direction( interactionValues ) );
175
+ const RepeatControl = useControlComponent(
176
+ 'repeat',
177
+ controlVisibilityConfig.repeat( interactionValues )
178
+ ) as ComponentType< FieldProps< string > >;
179
+ const TimesControl = useControlComponent(
180
+ 'times',
181
+ controlVisibilityConfig.times( interactionValues )
182
+ ) as ComponentType< FieldProps< number > >;
154
183
  const EasingControl = useControlComponent( 'easing' );
155
184
 
156
185
  const containerRef = useRef< HTMLDivElement >( null );
@@ -166,6 +195,8 @@ export const InteractionDetails = ( { interaction, onChange, onPlayInteraction }
166
195
  replay: boolean;
167
196
  easing?: string;
168
197
  relativeTo: string;
198
+ repeat: string;
199
+ times?: number;
169
200
  start: SizeStringValue;
170
201
  end: SizeStringValue;
171
202
  customEffects?: PropValue;
@@ -192,6 +223,8 @@ export const InteractionDetails = ( { interaction, onChange, onPlayInteraction }
192
223
  replay: updates.replay ?? replay,
193
224
  easing: updates.easing ?? easing,
194
225
  relativeTo: updates.relativeTo ?? relativeTo,
226
+ repeat: updates.repeat ?? repeat,
227
+ times: updates.times ?? times,
195
228
  start: updates.start ?? start,
196
229
  end: updates.end ?? end,
197
230
  customEffects: updates.customEffects ?? customEffects,
@@ -266,6 +299,25 @@ export const InteractionDetails = ( { interaction, onChange, onPlayInteraction }
266
299
  </Field>
267
300
  ) }
268
301
 
302
+ { RepeatControl && (
303
+ <Field label={ __( 'Repeat', 'elementor' ) }>
304
+ <RepeatControl value={ repeat } onChange={ ( v ) => updateInteraction( { repeat: v } ) } />
305
+ </Field>
306
+ ) }
307
+
308
+ { TimesControl && (
309
+ <Field label={ __( 'Times', 'elementor' ) }>
310
+ <TimesControl
311
+ value={ times }
312
+ onChange={ ( v ) =>
313
+ updateInteraction( {
314
+ times: normalizeTimesValue( v, DEFAULT_VALUES.times ),
315
+ } )
316
+ }
317
+ />
318
+ </Field>
319
+ ) }
320
+
269
321
  { controlVisibilityConfig.duration( interactionValues ) && (
270
322
  <Field label={ __( 'Duration', 'elementor' ) }>
271
323
  <TimeFrameIndicator
@@ -1,7 +1,13 @@
1
1
  import { type ComponentType } from 'react';
2
2
  import { type PropValue } from '@elementor/editor-props';
3
3
 
4
- import { type DirectionFieldProps, type FieldProps, type ReplayFieldProps } from './types';
4
+ import {
5
+ type DirectionFieldProps,
6
+ type FieldProps,
7
+ type RepeatFieldProps,
8
+ type ReplayFieldProps,
9
+ type TimesFieldProps,
10
+ } from './types';
5
11
 
6
12
  type InteractionsControlType =
7
13
  | 'trigger'
@@ -11,6 +17,8 @@ type InteractionsControlType =
11
17
  | 'duration'
12
18
  | 'delay'
13
19
  | 'replay'
20
+ | 'repeat'
21
+ | 'times'
14
22
  | 'easing'
15
23
  | 'relativeTo'
16
24
  | 'start'
@@ -26,6 +34,8 @@ type InteractionsControlPropsMap = {
26
34
  duration: FieldProps;
27
35
  delay: FieldProps;
28
36
  replay: ReplayFieldProps;
37
+ repeat: RepeatFieldProps;
38
+ times: TimesFieldProps;
29
39
  easing: FieldProps;
30
40
  relativeTo: FieldProps;
31
41
  start: FieldProps;
@@ -40,7 +50,9 @@ type ControlOptions< T extends InteractionsControlType > = {
40
50
 
41
51
  type StoredControlOptions = {
42
52
  type: InteractionsControlType;
43
- component: ComponentType< FieldProps | DirectionFieldProps | ReplayFieldProps >;
53
+ component: ComponentType<
54
+ FieldProps | DirectionFieldProps | ReplayFieldProps | RepeatFieldProps | TimesFieldProps
55
+ >;
44
56
  options?: string[];
45
57
  };
46
58
 
package/src/types.ts CHANGED
@@ -50,6 +50,8 @@ export type FieldProps< T = string > = {
50
50
  };
51
51
 
52
52
  export type ReplayFieldProps = FieldProps< boolean >;
53
+ export type RepeatFieldProps = FieldProps< string >;
54
+ export type TimesFieldProps = FieldProps< number >;
53
55
  export type DirectionFieldProps = FieldProps< string > & {
54
56
  interactionType: string;
55
57
  };
@@ -47,24 +47,31 @@ export const createConfig = ( {
47
47
  replay,
48
48
  easing = 'easeIn',
49
49
  relativeTo = '',
50
+ repeat = '',
51
+ times = 1,
50
52
  start = 85,
51
53
  end = 15,
52
54
  }: {
53
55
  replay: boolean;
54
56
  easing?: string;
55
57
  relativeTo?: string;
58
+ repeat?: string;
59
+ times?: number;
56
60
  start?: SizeStringValue;
57
61
  end?: SizeStringValue;
58
- } ): ConfigPropValue => ( {
59
- $$type: 'config',
60
- value: {
61
- replay: createBoolean( replay ),
62
- easing: createString( easing ),
63
- relativeTo: createString( relativeTo ),
64
- start: createSize( start, '%' ),
65
- end: createSize( end, '%' ),
66
- },
67
- } );
62
+ } ): ConfigPropValue =>
63
+ ( {
64
+ $$type: 'config',
65
+ value: {
66
+ replay: createBoolean( replay ),
67
+ easing: createString( easing ),
68
+ relativeTo: createString( relativeTo ),
69
+ repeat: createString( repeat ),
70
+ times: createNumber( times ),
71
+ start: createSize( start, '%' ),
72
+ end: createSize( end, '%' ),
73
+ },
74
+ } ) as ConfigPropValue;
68
75
 
69
76
  const createSize = ( value?: SizeStringValue, defaultUnit?: Unit, defaultValue?: SizeStringValue ) => {
70
77
  if ( ! value ) {
@@ -103,6 +110,8 @@ export const createAnimationPreset = ( {
103
110
  replay = false,
104
111
  easing = 'easeIn',
105
112
  relativeTo,
113
+ repeat,
114
+ times,
106
115
  start,
107
116
  end,
108
117
  customEffects,
@@ -115,6 +124,8 @@ export const createAnimationPreset = ( {
115
124
  replay: boolean;
116
125
  easing?: string;
117
126
  relativeTo?: string;
127
+ repeat?: string;
128
+ times?: number;
118
129
  start?: SizeStringValue;
119
130
  end?: SizeStringValue;
120
131
  customEffects?: PropValue;
@@ -130,6 +141,8 @@ export const createAnimationPreset = ( {
130
141
  replay,
131
142
  easing,
132
143
  relativeTo,
144
+ repeat,
145
+ times,
133
146
  start,
134
147
  end,
135
148
  } ),
@@ -147,6 +160,8 @@ export const createInteractionItem = ( {
147
160
  replay = false,
148
161
  easing = 'easeIn',
149
162
  relativeTo,
163
+ repeat,
164
+ times,
150
165
  start,
151
166
  end,
152
167
  excludedBreakpoints,
@@ -162,6 +177,8 @@ export const createInteractionItem = ( {
162
177
  replay?: boolean;
163
178
  easing?: string;
164
179
  relativeTo?: string;
180
+ repeat?: string;
181
+ times?: number;
165
182
  start?: number;
166
183
  end?: number;
167
184
  excludedBreakpoints?: string[];
@@ -180,6 +197,8 @@ export const createInteractionItem = ( {
180
197
  replay,
181
198
  easing,
182
199
  relativeTo,
200
+ repeat,
201
+ times,
183
202
  start,
184
203
  end,
185
204
  customEffects,