@elementor/editor-interactions 4.0.0-619 → 4.0.0-manual
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/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +189 -172
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +189 -172
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -11
- package/src/components/interaction-details.tsx +34 -42
- package/src/interactions-controls-registry.ts +4 -4
- package/src/mcp/index.ts +65 -4
- package/src/mcp/resources/interactions-schema-resource.ts +6 -39
- package/src/mcp/tools/manage-element-interaction-tool.ts +44 -111
- package/src/mcp/tools/schema.ts +73 -0
- package/src/utils/prop-value-utils.ts +29 -29
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-interactions",
|
|
3
|
-
"version": "4.0.0-
|
|
3
|
+
"version": "4.0.0-manual",
|
|
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-
|
|
43
|
-
"@elementor/editor-elements": "4.0.0-
|
|
44
|
-
"@elementor/editor-mcp": "4.0.0-
|
|
45
|
-
"@elementor/editor-props": "4.0.0-
|
|
46
|
-
"@elementor/editor-responsive": "4.0.0-
|
|
47
|
-
"@elementor/editor-ui": "4.0.0-
|
|
48
|
-
"@elementor/editor-v1-adapters": "4.0.0-
|
|
42
|
+
"@elementor/editor-controls": "4.0.0-manual",
|
|
43
|
+
"@elementor/editor-elements": "4.0.0-manual",
|
|
44
|
+
"@elementor/editor-mcp": "4.0.0-manual",
|
|
45
|
+
"@elementor/editor-props": "4.0.0-manual",
|
|
46
|
+
"@elementor/editor-responsive": "4.0.0-manual",
|
|
47
|
+
"@elementor/editor-ui": "4.0.0-manual",
|
|
48
|
+
"@elementor/editor-v1-adapters": "4.0.0-manual",
|
|
49
49
|
"@elementor/icons": "^1.68.0",
|
|
50
|
-
"@elementor/schema": "4.0.0-
|
|
51
|
-
"@elementor/session": "4.0.0-
|
|
50
|
+
"@elementor/schema": "4.0.0-manual",
|
|
51
|
+
"@elementor/session": "4.0.0-manual",
|
|
52
52
|
"@elementor/ui": "1.36.17",
|
|
53
|
-
"@elementor/utils": "4.0.0-
|
|
53
|
+
"@elementor/utils": "4.0.0-manual",
|
|
54
54
|
"@wordpress/i18n": "^5.13.0"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
@@ -35,8 +35,8 @@ export const DEFAULT_VALUES = {
|
|
|
35
35
|
replay: false,
|
|
36
36
|
easing: 'easeIn',
|
|
37
37
|
relativeTo: 'viewport',
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
start: 85,
|
|
39
|
+
end: 15,
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
const TRIGGERS_WITHOUT_REPLAY = [ 'load', 'scrollOn', 'hover', 'click' ];
|
|
@@ -51,8 +51,8 @@ type InteractionsControlType =
|
|
|
51
51
|
| 'replay'
|
|
52
52
|
| 'easing'
|
|
53
53
|
| 'relativeTo'
|
|
54
|
-
| '
|
|
55
|
-
| '
|
|
54
|
+
| 'start'
|
|
55
|
+
| 'end'
|
|
56
56
|
| 'customEffects';
|
|
57
57
|
|
|
58
58
|
type InteractionValues = {
|
|
@@ -65,8 +65,8 @@ type InteractionValues = {
|
|
|
65
65
|
replay: boolean;
|
|
66
66
|
easing: string;
|
|
67
67
|
relativeTo: string;
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
start: SizeStringValue;
|
|
69
|
+
end: SizeStringValue;
|
|
70
70
|
customEffects?: PropValue;
|
|
71
71
|
};
|
|
72
72
|
|
|
@@ -80,8 +80,8 @@ const controlVisibilityConfig: ControlVisibilityConfig = {
|
|
|
80
80
|
effectType: ( values ) => values.effect !== 'custom',
|
|
81
81
|
direction: ( values ) => values.effect !== 'custom',
|
|
82
82
|
relativeTo: ( values ) => values.trigger === 'scrollOn',
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
start: ( values ) => values.trigger === 'scrollOn',
|
|
84
|
+
end: ( values ) => values.trigger === 'scrollOn',
|
|
85
85
|
|
|
86
86
|
duration: ( values ) => {
|
|
87
87
|
const isRelativeToVisible = values.trigger === 'scrollOn';
|
|
@@ -114,11 +114,8 @@ export const InteractionDetails = ( { interaction, onChange, onPlayInteraction }
|
|
|
114
114
|
const easing = extractString( interaction.animation.value.config?.value.easing, DEFAULT_VALUES.easing );
|
|
115
115
|
const relativeTo = extractString( interaction.animation.value.config?.value.relativeTo, DEFAULT_VALUES.relativeTo );
|
|
116
116
|
|
|
117
|
-
const
|
|
118
|
-
const
|
|
119
|
-
interaction.animation.value.config?.value.offsetBottom,
|
|
120
|
-
DEFAULT_VALUES.offsetBottom
|
|
121
|
-
);
|
|
117
|
+
const start = extractSize( interaction.animation.value.config?.value.start, DEFAULT_VALUES.start );
|
|
118
|
+
const end = extractSize( interaction.animation.value.config?.value.end, DEFAULT_VALUES.end );
|
|
122
119
|
|
|
123
120
|
const interactionValues = {
|
|
124
121
|
trigger,
|
|
@@ -130,8 +127,8 @@ export const InteractionDetails = ( { interaction, onChange, onPlayInteraction }
|
|
|
130
127
|
easing,
|
|
131
128
|
replay,
|
|
132
129
|
relativeTo,
|
|
133
|
-
|
|
134
|
-
|
|
130
|
+
start,
|
|
131
|
+
end,
|
|
135
132
|
customEffects,
|
|
136
133
|
};
|
|
137
134
|
|
|
@@ -142,11 +139,8 @@ export const InteractionDetails = ( { interaction, onChange, onPlayInteraction }
|
|
|
142
139
|
'relativeTo',
|
|
143
140
|
controlVisibilityConfig.relativeTo( interactionValues )
|
|
144
141
|
);
|
|
145
|
-
const
|
|
146
|
-
const
|
|
147
|
-
'offsetBottom',
|
|
148
|
-
controlVisibilityConfig.offsetBottom( interactionValues )
|
|
149
|
-
);
|
|
142
|
+
const StartControl = useControlComponent( 'start', controlVisibilityConfig.start( interactionValues ) );
|
|
143
|
+
const EndControl = useControlComponent( 'end', controlVisibilityConfig.end( interactionValues ) );
|
|
150
144
|
const CustomEffectControl = useControlComponent(
|
|
151
145
|
'customEffects',
|
|
152
146
|
controlVisibilityConfig.custom( interactionValues )
|
|
@@ -172,8 +166,8 @@ export const InteractionDetails = ( { interaction, onChange, onPlayInteraction }
|
|
|
172
166
|
replay: boolean;
|
|
173
167
|
easing?: string;
|
|
174
168
|
relativeTo: string;
|
|
175
|
-
|
|
176
|
-
|
|
169
|
+
start: SizeStringValue;
|
|
170
|
+
end: SizeStringValue;
|
|
177
171
|
customEffects?: PropValue;
|
|
178
172
|
} >
|
|
179
173
|
): void => {
|
|
@@ -198,8 +192,8 @@ export const InteractionDetails = ( { interaction, onChange, onPlayInteraction }
|
|
|
198
192
|
replay: updates.replay ?? replay,
|
|
199
193
|
easing: updates.easing ?? easing,
|
|
200
194
|
relativeTo: updates.relativeTo ?? relativeTo,
|
|
201
|
-
|
|
202
|
-
|
|
195
|
+
start: updates.start ?? start,
|
|
196
|
+
end: updates.end ?? end,
|
|
203
197
|
customEffects: updates.customEffects ?? customEffects,
|
|
204
198
|
} ),
|
|
205
199
|
};
|
|
@@ -297,32 +291,30 @@ export const InteractionDetails = ( { interaction, onChange, onPlayInteraction }
|
|
|
297
291
|
<>
|
|
298
292
|
<Divider />
|
|
299
293
|
<Grid container spacing={ 1.5 }>
|
|
300
|
-
|
|
301
|
-
<
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
/>
|
|
305
|
-
</Field>
|
|
306
|
-
{ OffsetTopControl && (
|
|
307
|
-
<Field label={ __( 'Offset Top', 'elementor' ) }>
|
|
308
|
-
<OffsetTopControl
|
|
309
|
-
value={ String( parseSizeValue( offsetTop, [ '%' ] ).size ) }
|
|
294
|
+
{ StartControl && (
|
|
295
|
+
<Field label={ __( 'Start', 'elementor' ) }>
|
|
296
|
+
<StartControl
|
|
297
|
+
value={ parseSizeValue( start, [ '%' ] ).size?.toString() ?? '' }
|
|
310
298
|
onChange={ ( v: string ) =>
|
|
311
|
-
updateInteraction( {
|
|
299
|
+
updateInteraction( { start: v as SizeStringValue } )
|
|
312
300
|
}
|
|
313
301
|
/>
|
|
314
302
|
</Field>
|
|
315
303
|
) }
|
|
316
|
-
{
|
|
317
|
-
<Field label={ __( '
|
|
318
|
-
<
|
|
319
|
-
value={
|
|
320
|
-
onChange={ ( v: string ) =>
|
|
321
|
-
updateInteraction( { offsetBottom: v as SizeStringValue } )
|
|
322
|
-
}
|
|
304
|
+
{ EndControl && (
|
|
305
|
+
<Field label={ __( 'End', 'elementor' ) }>
|
|
306
|
+
<EndControl
|
|
307
|
+
value={ parseSizeValue( end, [ '%' ] ).size?.toString() ?? '' }
|
|
308
|
+
onChange={ ( v: string ) => updateInteraction( { end: v as SizeStringValue } ) }
|
|
323
309
|
/>
|
|
324
310
|
</Field>
|
|
325
311
|
) }
|
|
312
|
+
<Field label={ __( 'Relative To', 'elementor' ) }>
|
|
313
|
+
<RelativeToControl
|
|
314
|
+
value={ relativeTo }
|
|
315
|
+
onChange={ ( v ) => updateInteraction( { relativeTo: v } ) }
|
|
316
|
+
/>
|
|
317
|
+
</Field>
|
|
326
318
|
</Grid>
|
|
327
319
|
<Divider />
|
|
328
320
|
</>
|
|
@@ -13,8 +13,8 @@ type InteractionsControlType =
|
|
|
13
13
|
| 'replay'
|
|
14
14
|
| 'easing'
|
|
15
15
|
| 'relativeTo'
|
|
16
|
-
| '
|
|
17
|
-
| '
|
|
16
|
+
| 'start'
|
|
17
|
+
| 'end'
|
|
18
18
|
| 'customEffects';
|
|
19
19
|
|
|
20
20
|
type InteractionsControlPropsMap = {
|
|
@@ -28,8 +28,8 @@ type InteractionsControlPropsMap = {
|
|
|
28
28
|
replay: ReplayFieldProps;
|
|
29
29
|
easing: FieldProps;
|
|
30
30
|
relativeTo: FieldProps;
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
start: FieldProps;
|
|
32
|
+
end: FieldProps;
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
type ControlOptions< T extends InteractionsControlType > = {
|
package/src/mcp/index.ts
CHANGED
|
@@ -1,13 +1,74 @@
|
|
|
1
1
|
import { getMCPByDomain } from '@elementor/editor-mcp';
|
|
2
2
|
|
|
3
|
+
import { MAX_INTERACTIONS_PER_ELEMENT } from './constants';
|
|
3
4
|
import { initInteractionsSchemaResource } from './resources/interactions-schema-resource';
|
|
4
5
|
import { initManageElementInteractionTool } from './tools/manage-element-interaction-tool';
|
|
5
6
|
|
|
6
7
|
export const initMcpInteractions = () => {
|
|
7
8
|
const reg = getMCPByDomain( 'interactions', {
|
|
8
|
-
instructions:
|
|
9
|
-
|
|
9
|
+
instructions: `
|
|
10
|
+
MCP server for managing element interactions and animations. Use this to add, modify, or remove animations and motion effects triggered by user events such as page load or scroll-into-view.
|
|
11
|
+
** IMPORTANT **
|
|
12
|
+
Use the "interactions-schema" resource to get the schema of the interactions.
|
|
13
|
+
Actions:
|
|
14
|
+
- get: Read the current interactions on the element.
|
|
15
|
+
- add: Add a new interaction (max ${ MAX_INTERACTIONS_PER_ELEMENT } per element).
|
|
16
|
+
- update: Update an existing interaction by its interactionId.
|
|
17
|
+
- delete: Remove a specific interaction by its interactionId.
|
|
18
|
+
- clear: Remove all interactions from the element.
|
|
19
|
+
|
|
20
|
+
For add/update, provide: trigger, effect, effectType, direction (required for slide effect), duration, delay, easing.
|
|
21
|
+
Use excludedBreakpoints to disable the animation on specific responsive breakpoints (e.g. ["mobile", "tablet"]).
|
|
22
|
+
Example Get Request:
|
|
23
|
+
{
|
|
24
|
+
"elementId": "123",
|
|
25
|
+
"action": "get",
|
|
26
|
+
"interactionId": "123",
|
|
27
|
+
"animationData": {
|
|
28
|
+
"trigger": "click",
|
|
29
|
+
"effect": "fade",
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
Example Add Request:
|
|
33
|
+
{
|
|
34
|
+
"elementId": "123",
|
|
35
|
+
"action": "add",
|
|
36
|
+
"animationData": {
|
|
37
|
+
"effectType": "in",
|
|
38
|
+
"direction": "top",
|
|
39
|
+
"trigger": "click",
|
|
40
|
+
"effect": "fade",
|
|
41
|
+
"duration": 1000,
|
|
42
|
+
"delay": 0,
|
|
43
|
+
"easing": "easeIn",
|
|
44
|
+
"excludedBreakpoints": ["mobile", "tablet"],
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
Example Update Request:
|
|
48
|
+
{
|
|
49
|
+
"elementId": "123",
|
|
50
|
+
"action": "update",
|
|
51
|
+
"interactionId": "123",
|
|
52
|
+
"animationData": {
|
|
53
|
+
"trigger": "click",
|
|
54
|
+
"effect": "fade",
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
Example Delete Request:
|
|
58
|
+
{
|
|
59
|
+
"elementId": "123",
|
|
60
|
+
"action": "delete",
|
|
61
|
+
"interactionId": "123",
|
|
62
|
+
}
|
|
63
|
+
Example Clear Request:
|
|
64
|
+
{
|
|
65
|
+
"elementId": "123",
|
|
66
|
+
"action": "clear",
|
|
67
|
+
}
|
|
68
|
+
`,
|
|
69
|
+
} );
|
|
70
|
+
reg.waitForReady().then( () => {
|
|
71
|
+
initInteractionsSchemaResource( reg );
|
|
72
|
+
initManageElementInteractionTool( reg );
|
|
10
73
|
} );
|
|
11
|
-
initInteractionsSchemaResource( reg );
|
|
12
|
-
initManageElementInteractionTool( reg );
|
|
13
74
|
};
|
|
@@ -1,60 +1,27 @@
|
|
|
1
1
|
import { type MCPRegistryEntry } from '@elementor/editor-mcp';
|
|
2
|
+
import { isProActive } from '@elementor/utils';
|
|
2
3
|
|
|
3
|
-
import {
|
|
4
|
-
import { BASE_TRIGGERS, TRIGGER_OPTIONS } from '../../components/controls/trigger';
|
|
5
|
-
import { MAX_INTERACTIONS_PER_ELEMENT } from '../constants';
|
|
4
|
+
import { baseSchema, proSchema } from '../tools/schema';
|
|
6
5
|
|
|
7
6
|
export const INTERACTIONS_SCHEMA_URI = 'elementor://interactions/schema';
|
|
8
7
|
|
|
9
|
-
const schema = {
|
|
10
|
-
triggers: BASE_TRIGGERS.map( ( key ) => ( {
|
|
11
|
-
value: key,
|
|
12
|
-
label: TRIGGER_OPTIONS[ key as keyof typeof TRIGGER_OPTIONS ] ?? key,
|
|
13
|
-
} ) ),
|
|
14
|
-
effects: [
|
|
15
|
-
{ value: 'fade', label: 'Fade' },
|
|
16
|
-
{ value: 'slide', label: 'Slide' },
|
|
17
|
-
{ value: 'scale', label: 'Scale' },
|
|
18
|
-
],
|
|
19
|
-
effectTypes: [
|
|
20
|
-
{ value: 'in', label: 'In' },
|
|
21
|
-
{ value: 'out', label: 'Out' },
|
|
22
|
-
],
|
|
23
|
-
directions: [
|
|
24
|
-
{ value: 'top', label: 'Top', note: '' },
|
|
25
|
-
{ value: 'bottom', label: 'Bottom', note: '' },
|
|
26
|
-
{ value: 'left', label: 'Left', note: '' },
|
|
27
|
-
{ value: 'right', label: 'Right', note: '' },
|
|
28
|
-
{ value: '', label: 'None', note: 'Slide animation must have a direction' },
|
|
29
|
-
],
|
|
30
|
-
easings: Object.entries( EASING_OPTIONS ).map( ( [ value, label ] ) => ( { value, label } ) ),
|
|
31
|
-
timing: {
|
|
32
|
-
duration: { min: 0, max: 10000, unit: 'ms', description: 'Animation duration in milliseconds' },
|
|
33
|
-
delay: { min: 0, max: 10000, unit: 'ms', description: 'Animation delay in milliseconds' },
|
|
34
|
-
},
|
|
35
|
-
excludedBreakpoints: {
|
|
36
|
-
type: 'string[]',
|
|
37
|
-
description: 'List of breakpoint IDs on which this interaction is disabled. Omit to enable on all breakpoints.',
|
|
38
|
-
},
|
|
39
|
-
maxInteractionsPerElement: MAX_INTERACTIONS_PER_ELEMENT,
|
|
40
|
-
};
|
|
41
|
-
|
|
42
8
|
export const initInteractionsSchemaResource = ( reg: MCPRegistryEntry ) => {
|
|
43
9
|
const { resource } = reg;
|
|
10
|
+
const schema = isProActive() ? { ...baseSchema, ...proSchema } : baseSchema;
|
|
44
11
|
|
|
45
12
|
resource(
|
|
46
13
|
'interactions-schema',
|
|
47
14
|
INTERACTIONS_SCHEMA_URI,
|
|
48
15
|
{
|
|
49
|
-
description:
|
|
50
|
-
'Schema describing all available options for element interactions (triggers, effects, easings, timing, breakpoints, etc.).',
|
|
16
|
+
description: 'Schema describing all available options for element interactions.',
|
|
51
17
|
},
|
|
52
18
|
async () => {
|
|
53
19
|
return {
|
|
54
20
|
contents: [
|
|
55
21
|
{
|
|
56
22
|
uri: INTERACTIONS_SCHEMA_URI,
|
|
57
|
-
|
|
23
|
+
mimeType: 'application/json',
|
|
24
|
+
text: JSON.stringify( schema ),
|
|
58
25
|
},
|
|
59
26
|
],
|
|
60
27
|
};
|
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
import { updateElementInteractions } from '@elementor/editor-elements';
|
|
2
2
|
import { type MCPRegistryEntry } from '@elementor/editor-mcp';
|
|
3
3
|
import { z } from '@elementor/schema';
|
|
4
|
+
import { isProActive } from '@elementor/utils';
|
|
4
5
|
|
|
5
|
-
import { DEFAULT_VALUES } from '../../components/interaction-details';
|
|
6
6
|
import { interactionsRepository } from '../../interactions-repository';
|
|
7
7
|
import { type ElementInteractions } from '../../types';
|
|
8
|
-
import {
|
|
9
|
-
createInteractionItem,
|
|
10
|
-
extractExcludedBreakpoints,
|
|
11
|
-
extractSize,
|
|
12
|
-
extractString,
|
|
13
|
-
} from '../../utils/prop-value-utils';
|
|
8
|
+
import { createInteractionItem, extractString } from '../../utils/prop-value-utils';
|
|
14
9
|
import { generateTempInteractionId } from '../../utils/temp-id-utils';
|
|
15
10
|
import { MAX_INTERACTIONS_PER_ELEMENT } from '../constants';
|
|
16
11
|
import { INTERACTIONS_SCHEMA_URI } from '../resources/interactions-schema-resource';
|
|
12
|
+
import { baseSchema, proSchema } from './schema';
|
|
17
13
|
|
|
18
14
|
const EMPTY_INTERACTIONS: ElementInteractions = {
|
|
19
15
|
version: 1,
|
|
@@ -22,94 +18,56 @@ const EMPTY_INTERACTIONS: ElementInteractions = {
|
|
|
22
18
|
|
|
23
19
|
export const initManageElementInteractionTool = ( reg: MCPRegistryEntry ) => {
|
|
24
20
|
const { addTool } = reg;
|
|
21
|
+
const extendedSchema = isProActive() ? { ...baseSchema, ...proSchema } : baseSchema;
|
|
22
|
+
const schema = {
|
|
23
|
+
elementId: z.string().describe( 'The ID of the element to read or modify interactions on' ),
|
|
24
|
+
action: z
|
|
25
|
+
.enum( [ 'get', 'add', 'update', 'delete', 'clear' ] )
|
|
26
|
+
.describe( 'Operation to perform. Use "get" first to inspect existing interactions.' ),
|
|
27
|
+
interactionId: z
|
|
28
|
+
.string()
|
|
29
|
+
.optional()
|
|
30
|
+
.describe( 'Interaction ID — required for update and delete. Obtain from a prior "get" call.' ),
|
|
31
|
+
...extendedSchema,
|
|
32
|
+
};
|
|
25
33
|
|
|
26
34
|
addTool( {
|
|
27
35
|
name: 'manage-element-interaction',
|
|
28
|
-
description: `
|
|
29
|
-
|
|
30
|
-
Actions:
|
|
31
|
-
- get: Read the current interactions on the element.
|
|
32
|
-
- add: Add a new interaction (max ${ MAX_INTERACTIONS_PER_ELEMENT } per element).
|
|
33
|
-
- update: Update an existing interaction by its interactionId.
|
|
34
|
-
- delete: Remove a specific interaction by its interactionId.
|
|
35
|
-
- clear: Remove all interactions from the element.
|
|
36
|
-
|
|
37
|
-
For add/update, provide: trigger, effect, effectType, direction (empty string for non-slide effects), duration, delay, easing.
|
|
38
|
-
Use excludedBreakpoints to disable the animation on specific responsive breakpoints (e.g. ["mobile", "tablet"]).`,
|
|
39
|
-
schema: {
|
|
40
|
-
elementId: z.string().describe( 'The ID of the element to read or modify interactions on' ),
|
|
41
|
-
action: z
|
|
42
|
-
.enum( [ 'get', 'add', 'update', 'delete', 'clear' ] )
|
|
43
|
-
.describe( 'Operation to perform. Use "get" first to inspect existing interactions.' ),
|
|
44
|
-
interactionId: z
|
|
45
|
-
.string()
|
|
46
|
-
.optional()
|
|
47
|
-
.describe( 'Interaction ID — required for update and delete. Obtain from a prior "get" call.' ),
|
|
48
|
-
trigger: z.enum( [ 'load', 'scrollIn' ] ).optional().describe( 'Event that triggers the animation' ),
|
|
49
|
-
effect: z.enum( [ 'fade', 'slide', 'scale' ] ).optional().describe( 'Animation effect type' ),
|
|
50
|
-
effectType: z.enum( [ 'in', 'out' ] ).optional().describe( 'Whether the animation plays in or out' ),
|
|
51
|
-
direction: z
|
|
52
|
-
.enum( [ 'top', 'bottom', 'left', 'right', '' ] )
|
|
53
|
-
.optional()
|
|
54
|
-
.describe( 'Direction for slide effect. Use empty string for fade/scale.' ),
|
|
55
|
-
duration: z.number().min( 0 ).max( 10000 ).optional().describe( 'Animation duration in milliseconds' ),
|
|
56
|
-
delay: z.number().min( 0 ).max( 10000 ).optional().describe( 'Animation delay in milliseconds' ),
|
|
57
|
-
easing: z.string().optional().describe( 'Easing function. See interactions schema for options.' ),
|
|
58
|
-
excludedBreakpoints: z
|
|
59
|
-
.array( z.string() )
|
|
60
|
-
.optional()
|
|
61
|
-
.describe(
|
|
62
|
-
'Breakpoint IDs on which this interaction is disabled (e.g. ["mobile", "tablet"]). Omit to enable on all breakpoints.'
|
|
63
|
-
),
|
|
64
|
-
},
|
|
36
|
+
description: `Manage the element interaction.`,
|
|
37
|
+
schema,
|
|
65
38
|
requiredResources: [
|
|
66
39
|
{ uri: INTERACTIONS_SCHEMA_URI, description: 'Interactions schema with all available options' },
|
|
67
40
|
],
|
|
68
41
|
isDestructive: true,
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
42
|
+
outputSchema: {
|
|
43
|
+
success: z.boolean().describe( 'Whether the action was successful' ),
|
|
44
|
+
action: z
|
|
45
|
+
.enum( [ 'get', 'add', 'update', 'delete', 'clear' ] )
|
|
46
|
+
.describe( 'Operation to perform. Use "get" first to inspect existing interactions.' ),
|
|
47
|
+
elementId: z.string().optional().describe( 'The ID of the element to read or modify interactions on' ),
|
|
48
|
+
interactions: z.array( z.any() ).optional().describe( 'The interactions on the element' ),
|
|
49
|
+
count: z.number().optional().describe( 'The number of interactions on the element' ),
|
|
50
|
+
},
|
|
51
|
+
handler: ( input: {
|
|
52
|
+
elementId: string;
|
|
53
|
+
action: 'get' | 'add' | 'update' | 'delete' | 'clear';
|
|
54
|
+
interactionId?: string;
|
|
55
|
+
[ key: string ]: unknown;
|
|
56
|
+
} ) => {
|
|
57
|
+
const { elementId, action, interactionId, ...animationData } = input;
|
|
83
58
|
|
|
84
59
|
const allInteractions = interactionsRepository.all();
|
|
85
60
|
const elementData = allInteractions.find( ( data ) => data.elementId === elementId );
|
|
86
61
|
const currentInteractions: ElementInteractions = elementData?.interactions ?? EMPTY_INTERACTIONS;
|
|
87
62
|
|
|
88
63
|
if ( action === 'get' ) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const animValue = value.animation.value;
|
|
92
|
-
const timingValue = animValue.timing_config.value;
|
|
93
|
-
const configValue = animValue.config.value;
|
|
94
|
-
|
|
95
|
-
return {
|
|
96
|
-
id: extractString( value.interaction_id ),
|
|
97
|
-
trigger: extractString( value.trigger ),
|
|
98
|
-
effect: extractString( animValue.effect ),
|
|
99
|
-
effectType: extractString( animValue.type ),
|
|
100
|
-
direction: extractString( animValue.direction ),
|
|
101
|
-
duration: extractSize( timingValue.duration ),
|
|
102
|
-
delay: extractSize( timingValue.delay ),
|
|
103
|
-
easing: extractString( configValue.easing ),
|
|
104
|
-
excludedBreakpoints: extractExcludedBreakpoints( value.breakpoints ),
|
|
105
|
-
};
|
|
106
|
-
} );
|
|
107
|
-
|
|
108
|
-
return JSON.stringify( {
|
|
64
|
+
return {
|
|
65
|
+
success: true,
|
|
109
66
|
elementId,
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
67
|
+
action,
|
|
68
|
+
interactions: currentInteractions.items,
|
|
69
|
+
count: currentInteractions.items.length,
|
|
70
|
+
};
|
|
113
71
|
}
|
|
114
72
|
|
|
115
73
|
let updatedItems = [ ...currentInteractions.items ];
|
|
@@ -124,15 +82,7 @@ Use excludedBreakpoints to disable the animation on specific responsive breakpoi
|
|
|
124
82
|
|
|
125
83
|
const newItem = createInteractionItem( {
|
|
126
84
|
interactionId: generateTempInteractionId(),
|
|
127
|
-
|
|
128
|
-
effect: effect ?? DEFAULT_VALUES.effect,
|
|
129
|
-
type: effectType ?? DEFAULT_VALUES.type,
|
|
130
|
-
direction: direction ?? DEFAULT_VALUES.direction,
|
|
131
|
-
duration: duration ?? DEFAULT_VALUES.duration,
|
|
132
|
-
delay: delay ?? DEFAULT_VALUES.delay,
|
|
133
|
-
replay: DEFAULT_VALUES.replay,
|
|
134
|
-
easing: easing ?? DEFAULT_VALUES.easing,
|
|
135
|
-
excludedBreakpoints,
|
|
85
|
+
...animationData,
|
|
136
86
|
} );
|
|
137
87
|
|
|
138
88
|
updatedItems = [ ...updatedItems, newItem ];
|
|
@@ -154,26 +104,9 @@ Use excludedBreakpoints to disable the animation on specific responsive breakpoi
|
|
|
154
104
|
);
|
|
155
105
|
}
|
|
156
106
|
|
|
157
|
-
const existingItem = updatedItems[ itemIndex ];
|
|
158
|
-
const existingValue = existingItem.value;
|
|
159
|
-
const existingAnimation = existingValue.animation.value;
|
|
160
|
-
const existingTiming = existingAnimation.timing_config.value;
|
|
161
|
-
const existingConfig = existingAnimation.config.value;
|
|
162
|
-
const existingExcludedBreakpoints = extractExcludedBreakpoints( existingValue.breakpoints );
|
|
163
|
-
|
|
164
107
|
const updatedItem = createInteractionItem( {
|
|
165
108
|
interactionId,
|
|
166
|
-
|
|
167
|
-
effect: effect ?? extractString( existingAnimation.effect ),
|
|
168
|
-
type: effectType ?? extractString( existingAnimation.type ),
|
|
169
|
-
direction: direction !== undefined ? direction : extractString( existingAnimation.direction ),
|
|
170
|
-
duration:
|
|
171
|
-
duration !== undefined ? duration : ( extractSize( existingTiming.duration ) as number ),
|
|
172
|
-
delay: delay !== undefined ? delay : ( extractSize( existingTiming.delay ) as number ),
|
|
173
|
-
replay: existingConfig.replay?.value ?? DEFAULT_VALUES.replay,
|
|
174
|
-
easing: easing ?? extractString( existingConfig.easing ),
|
|
175
|
-
excludedBreakpoints:
|
|
176
|
-
excludedBreakpoints !== undefined ? excludedBreakpoints : existingExcludedBreakpoints,
|
|
109
|
+
...animationData,
|
|
177
110
|
} );
|
|
178
111
|
|
|
179
112
|
updatedItems = [
|
|
@@ -223,12 +156,12 @@ Use excludedBreakpoints to disable the animation on specific responsive breakpoi
|
|
|
223
156
|
);
|
|
224
157
|
}
|
|
225
158
|
|
|
226
|
-
return
|
|
159
|
+
return {
|
|
227
160
|
success: true,
|
|
228
161
|
action,
|
|
229
162
|
elementId,
|
|
230
|
-
|
|
231
|
-
}
|
|
163
|
+
count: updatedItems.length,
|
|
164
|
+
};
|
|
232
165
|
},
|
|
233
166
|
} );
|
|
234
167
|
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { z } from '@elementor/schema';
|
|
2
|
+
|
|
3
|
+
export const baseSchema = {
|
|
4
|
+
trigger: z.enum( [ 'load', 'scrollIn' ] ).optional().describe( 'Event that triggers the animation' ),
|
|
5
|
+
effect: z.enum( [ 'fade', 'slide', 'scale' ] ).optional().describe( 'Animation effect type' ),
|
|
6
|
+
effectType: z.enum( [ 'in', 'out' ] ).optional().describe( 'Whether the animation plays in or out' ),
|
|
7
|
+
direction: z
|
|
8
|
+
.enum( [ 'top', 'bottom', 'left', 'right', '' ] )
|
|
9
|
+
.optional()
|
|
10
|
+
.describe( 'Direction for slide effect. Use empty string for fade/scale.' ),
|
|
11
|
+
duration: z.number().min( 0 ).max( 10000 ).optional().describe( 'Animation duration in milliseconds' ),
|
|
12
|
+
delay: z.number().min( 0 ).max( 10000 ).optional().describe( 'Animation delay in milliseconds' ),
|
|
13
|
+
easing: z.string().optional().describe( 'Easing function. See interactions schema for options.' ),
|
|
14
|
+
excludedBreakpoints: z
|
|
15
|
+
.array( z.string() )
|
|
16
|
+
.optional()
|
|
17
|
+
.describe(
|
|
18
|
+
'Breakpoint IDs on which this interaction is disabled (e.g. ["mobile", "tablet"]). Omit to enable on all breakpoints.'
|
|
19
|
+
),
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const proSchema = {
|
|
23
|
+
trigger: z
|
|
24
|
+
.enum( [ 'load', 'scrollIn', 'scrollOut', 'scrollOn', 'hover', 'click' ] )
|
|
25
|
+
.optional()
|
|
26
|
+
.describe( 'Event that triggers the animation' ),
|
|
27
|
+
effect: z.enum( [ 'fade', 'slide', 'scale', 'custom' ] ).optional().describe( 'Animation effect type' ),
|
|
28
|
+
customEffect: z
|
|
29
|
+
.object( {
|
|
30
|
+
keyframes: z
|
|
31
|
+
.array(
|
|
32
|
+
z.object( {
|
|
33
|
+
stop: z.number().describe( 'The stop of the keyframe in percent, can be either 0 or 100' ),
|
|
34
|
+
value: z.object( {
|
|
35
|
+
opacity: z.number().min( 0 ).max( 1 ).describe( 'The opacity of the keyframe' ),
|
|
36
|
+
scale: z
|
|
37
|
+
.object( {
|
|
38
|
+
x: z.number().min( 0 ).max( 1 ).describe( 'The x scale of the keyframe' ),
|
|
39
|
+
y: z.number().min( 0 ).max( 1 ).describe( 'The y scale of the keyframe' ),
|
|
40
|
+
} )
|
|
41
|
+
.optional()
|
|
42
|
+
.describe( 'The scale of the keyframe' ),
|
|
43
|
+
rotate: z
|
|
44
|
+
.object( {
|
|
45
|
+
x: z.number().min( 0 ).max( 360 ).describe( 'The x rotate of the keyframe' ),
|
|
46
|
+
y: z.number().min( 0 ).max( 360 ).describe( 'The y rotate of the keyframe' ),
|
|
47
|
+
z: z.number().min( 0 ).max( 360 ).describe( 'The z rotate of the keyframe' ),
|
|
48
|
+
} )
|
|
49
|
+
.optional()
|
|
50
|
+
.describe( 'The rotate of the keyframe' ),
|
|
51
|
+
move: z
|
|
52
|
+
.object( {
|
|
53
|
+
x: z.number().min( 0 ).max( 1 ).describe( 'The x move of the keyframe' ),
|
|
54
|
+
y: z.number().min( 0 ).max( 1 ).describe( 'The y move of the keyframe' ),
|
|
55
|
+
z: z.number().min( 0 ).max( 1 ).describe( 'The z move of the keyframe' ),
|
|
56
|
+
} )
|
|
57
|
+
.optional()
|
|
58
|
+
.describe( 'The move of the keyframe' ),
|
|
59
|
+
skew: z
|
|
60
|
+
.object( {
|
|
61
|
+
x: z.number().min( 0 ).max( 360 ).describe( 'The x skew of the keyframe' ),
|
|
62
|
+
y: z.number().min( 0 ).max( 360 ).describe( 'The y skew of the keyframe' ),
|
|
63
|
+
} )
|
|
64
|
+
.optional()
|
|
65
|
+
.describe( 'The skew of the keyframe' ),
|
|
66
|
+
} ),
|
|
67
|
+
} )
|
|
68
|
+
)
|
|
69
|
+
.describe( 'The keyframes of the custom effect' ),
|
|
70
|
+
} )
|
|
71
|
+
.optional()
|
|
72
|
+
.describe( 'The custom effect to use for the animation' ),
|
|
73
|
+
};
|