@wix/interact 1.93.0 → 2.0.0-rc.2
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 +2 -23
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/react.js +15 -0
- package/dist/cjs/react.js.map +1 -0
- package/dist/cjs/web.js +2 -0
- package/dist/cjs/web.js.map +1 -0
- package/dist/es/index.js +8 -0
- package/dist/es/index.js.map +1 -0
- package/dist/es/react.js +650 -0
- package/dist/es/react.js.map +1 -0
- package/dist/es/web.js +56 -0
- package/dist/es/web.js.map +1 -0
- package/dist/index-C8QxOkui.mjs +7940 -0
- package/dist/index-C8QxOkui.mjs.map +1 -0
- package/dist/index-DEPRHaUt.js +18 -0
- package/dist/index-DEPRHaUt.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/dist/types/core/Interact.d.ts +17 -7
- package/dist/types/core/Interact.d.ts.map +1 -0
- package/dist/types/core/InteractionController.d.ts +19 -0
- package/dist/types/core/InteractionController.d.ts.map +1 -0
- package/dist/types/core/add.d.ts +4 -3
- package/dist/types/core/add.d.ts.map +1 -0
- package/dist/types/core/css.d.ts +3 -0
- package/dist/types/core/css.d.ts.map +1 -0
- package/dist/types/core/remove.d.ts +3 -1
- package/dist/types/core/remove.d.ts.map +1 -0
- package/dist/types/core/utilities.d.ts +1 -0
- package/dist/types/core/utilities.d.ts.map +1 -0
- package/dist/types/dom/api.d.ts +3 -0
- package/dist/types/dom/api.d.ts.map +1 -0
- package/dist/types/handlers/animationEnd.d.ts +3 -2
- package/dist/types/handlers/animationEnd.d.ts.map +1 -0
- package/dist/types/handlers/click.d.ts +3 -2
- package/dist/types/handlers/click.d.ts.map +1 -0
- package/dist/types/handlers/hover.d.ts +3 -2
- package/dist/types/handlers/hover.d.ts.map +1 -0
- package/dist/types/handlers/index.d.ts +1 -0
- package/dist/types/handlers/index.d.ts.map +1 -0
- package/dist/types/handlers/pointerMove.d.ts +3 -2
- package/dist/types/handlers/pointerMove.d.ts.map +1 -0
- package/dist/types/handlers/utilities.d.ts +1 -0
- package/dist/types/handlers/utilities.d.ts.map +1 -0
- package/dist/types/handlers/viewEnter.d.ts +3 -2
- package/dist/types/handlers/viewEnter.d.ts.map +1 -0
- package/dist/types/handlers/viewProgress.d.ts +4 -3
- package/dist/types/handlers/viewProgress.d.ts.map +1 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/react/Interaction.d.ts +10 -0
- package/dist/types/react/Interaction.d.ts.map +1 -0
- package/dist/types/react/index.d.ts +8 -0
- package/dist/types/react/index.d.ts.map +1 -0
- package/dist/types/react/interactRef.d.ts +3 -0
- package/dist/types/react/interactRef.d.ts.map +1 -0
- package/dist/types/types.d.ts +23 -10
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/utils.d.ts +2 -1
- package/dist/types/utils.d.ts.map +1 -0
- package/dist/types/{InteractElement.d.ts → web/InteractElement.d.ts} +115 -77
- package/dist/types/web/InteractElement.d.ts.map +1 -0
- package/dist/types/web/defineInteractElement.d.ts +2 -0
- package/dist/types/web/defineInteractElement.d.ts.map +1 -0
- package/dist/types/web/index.d.ts +6 -0
- package/dist/types/web/index.d.ts.map +1 -0
- package/docs/README.md +211 -0
- package/docs/advanced/README.md +164 -0
- package/docs/api/README.md +157 -0
- package/docs/api/element-selection.md +607 -0
- package/docs/api/functions.md +638 -0
- package/docs/api/interact-class.md +663 -0
- package/docs/api/interact-element.md +565 -0
- package/docs/api/interaction-controller.md +450 -0
- package/docs/api/types.md +957 -0
- package/docs/examples/README.md +212 -0
- package/docs/examples/click-interactions.md +977 -0
- package/docs/examples/entrance-animations.md +935 -0
- package/docs/examples/hover-effects.md +930 -0
- package/docs/examples/list-patterns.md +737 -0
- package/docs/guides/README.md +49 -0
- package/docs/guides/conditions-and-media-queries.md +1068 -0
- package/docs/guides/configuration-structure.md +726 -0
- package/docs/guides/custom-elements.md +327 -0
- package/docs/guides/effects-and-animations.md +634 -0
- package/docs/guides/getting-started.md +379 -0
- package/docs/guides/lists-and-dynamic-content.md +713 -0
- package/docs/guides/state-management.md +747 -0
- package/docs/guides/understanding-triggers.md +690 -0
- package/docs/integration/README.md +264 -0
- package/docs/integration/react.md +605 -0
- package/package.json +73 -56
- package/rules/Integration.md +255 -0
- package/rules/click-rules.md +533 -0
- package/rules/full-lean.md +346 -0
- package/rules/hover-rules.md +593 -0
- package/rules/pointermove-rules.md +1341 -0
- package/rules/scroll-list-rules.md +900 -0
- package/rules/viewenter-rules.md +1015 -0
- package/rules/viewprogress-rules.md +1044 -0
- package/dist/cjs/InteractElement.js +0 -163
- package/dist/cjs/InteractElement.js.map +0 -1
- package/dist/cjs/__tests__/interact.spec.js +0 -2094
- package/dist/cjs/__tests__/interact.spec.js.map +0 -1
- package/dist/cjs/__tests__/viewEnter.spec.js +0 -207
- package/dist/cjs/__tests__/viewEnter.spec.js.map +0 -1
- package/dist/cjs/core/Interact.js +0 -257
- package/dist/cjs/core/Interact.js.map +0 -1
- package/dist/cjs/core/add.js +0 -250
- package/dist/cjs/core/add.js.map +0 -1
- package/dist/cjs/core/remove.js +0 -35
- package/dist/cjs/core/remove.js.map +0 -1
- package/dist/cjs/core/utilities.js +0 -16
- package/dist/cjs/core/utilities.js.map +0 -1
- package/dist/cjs/external-types.d.js +0 -2
- package/dist/cjs/external-types.d.js.map +0 -1
- package/dist/cjs/handlers/animationEnd.js +0 -37
- package/dist/cjs/handlers/animationEnd.js.map +0 -1
- package/dist/cjs/handlers/click.js +0 -122
- package/dist/cjs/handlers/click.js.map +0 -1
- package/dist/cjs/handlers/hover.js +0 -147
- package/dist/cjs/handlers/hover.js.map +0 -1
- package/dist/cjs/handlers/index.js +0 -32
- package/dist/cjs/handlers/index.js.map +0 -1
- package/dist/cjs/handlers/pointerMove.js +0 -49
- package/dist/cjs/handlers/pointerMove.js.map +0 -1
- package/dist/cjs/handlers/utilities.js +0 -49
- package/dist/cjs/handlers/utilities.js.map +0 -1
- package/dist/cjs/handlers/viewEnter.js +0 -131
- package/dist/cjs/handlers/viewEnter.js.map +0 -1
- package/dist/cjs/handlers/viewProgress.js +0 -79
- package/dist/cjs/handlers/viewProgress.js.map +0 -1
- package/dist/cjs/test-types.d.js +0 -2
- package/dist/cjs/test-types.d.js.map +0 -1
- package/dist/cjs/types.js +0 -2
- package/dist/cjs/types.js.map +0 -1
- package/dist/cjs/utils.js +0 -98
- package/dist/cjs/utils.js.map +0 -1
- package/dist/esm/InteractElement.js +0 -157
- package/dist/esm/InteractElement.js.map +0 -1
- package/dist/esm/__tests__/interact.spec.js +0 -2102
- package/dist/esm/__tests__/interact.spec.js.map +0 -1
- package/dist/esm/__tests__/viewEnter.spec.js +0 -210
- package/dist/esm/__tests__/viewEnter.spec.js.map +0 -1
- package/dist/esm/core/Interact.js +0 -251
- package/dist/esm/core/Interact.js.map +0 -1
- package/dist/esm/core/add.js +0 -245
- package/dist/esm/core/add.js.map +0 -1
- package/dist/esm/core/remove.js +0 -30
- package/dist/esm/core/remove.js.map +0 -1
- package/dist/esm/core/utilities.js +0 -14
- package/dist/esm/core/utilities.js.map +0 -1
- package/dist/esm/external-types.d.js +0 -2
- package/dist/esm/external-types.d.js.map +0 -1
- package/dist/esm/handlers/animationEnd.js +0 -33
- package/dist/esm/handlers/animationEnd.js.map +0 -1
- package/dist/esm/handlers/click.js +0 -122
- package/dist/esm/handlers/click.js.map +0 -1
- package/dist/esm/handlers/hover.js +0 -147
- package/dist/esm/handlers/hover.js.map +0 -1
- package/dist/esm/handlers/index.js +0 -27
- package/dist/esm/handlers/index.js.map +0 -1
- package/dist/esm/handlers/pointerMove.js +0 -48
- package/dist/esm/handlers/pointerMove.js.map +0 -1
- package/dist/esm/handlers/utilities.js +0 -43
- package/dist/esm/handlers/utilities.js.map +0 -1
- package/dist/esm/handlers/viewEnter.js +0 -133
- package/dist/esm/handlers/viewEnter.js.map +0 -1
- package/dist/esm/handlers/viewProgress.js +0 -75
- package/dist/esm/handlers/viewProgress.js.map +0 -1
- package/dist/esm/index.js +0 -5
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/test-types.d.js +0 -2
- package/dist/esm/test-types.d.js.map +0 -1
- package/dist/esm/types.js +0 -2
- package/dist/esm/types.js.map +0 -1
- package/dist/esm/utils.js +0 -92
- package/dist/esm/utils.js.map +0 -1
- package/dist/types/__tests__/interact.spec.d.ts +0 -1
- package/dist/types/__tests__/viewEnter.spec.d.ts +0 -0
|
@@ -0,0 +1,565 @@
|
|
|
1
|
+
# interact-element Custom Element
|
|
2
|
+
|
|
3
|
+
The `interact-element` is a custom HTML element that serves as a wrapper for content that should have interactions applied to it. It automatically manages the connection between DOM elements and the `@wix/interact` system through an internal `InteractionController`.
|
|
4
|
+
|
|
5
|
+
> **Note for React Users**: Consider using the [`Interaction` component](../integration/react.md) from `@wix/interact/react` instead, which provides better React integration with ref forwarding and automatic cleanup.
|
|
6
|
+
|
|
7
|
+
## Import and Setup
|
|
8
|
+
|
|
9
|
+
When using the web entry point, you must ensure the custom element is defined before using it:
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import { Interact } from '@wix/interact/web';
|
|
13
|
+
|
|
14
|
+
// Create your configuration - this automatically defines the custom element
|
|
15
|
+
const interact = Interact.create(config);
|
|
16
|
+
|
|
17
|
+
// Or manually define it
|
|
18
|
+
Interact.defineInteractElement?.();
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Basic Usage
|
|
22
|
+
|
|
23
|
+
```html
|
|
24
|
+
<interact-element data-interact-key="unique-id">
|
|
25
|
+
<div class="content">Your interactive content here</div>
|
|
26
|
+
</interact-element>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { Interact } from '@wix/interact/web';
|
|
31
|
+
|
|
32
|
+
// Configure interactions for the element
|
|
33
|
+
const config = {
|
|
34
|
+
interactions: [{
|
|
35
|
+
trigger: 'viewEnter',
|
|
36
|
+
key: 'unique-id',
|
|
37
|
+
effects: [{ effectId: 'fade-in' }]
|
|
38
|
+
}],
|
|
39
|
+
effects: {
|
|
40
|
+
'fade-in': {
|
|
41
|
+
duration: 1000,
|
|
42
|
+
keyframeEffect: {
|
|
43
|
+
name: 'fade-in',
|
|
44
|
+
keyframes: [
|
|
45
|
+
{ opacity: 0 },
|
|
46
|
+
{ opacity: 1 }
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
Interact.create(config);
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## HTML Usage
|
|
57
|
+
|
|
58
|
+
### Basic Structure
|
|
59
|
+
|
|
60
|
+
```html
|
|
61
|
+
<!-- Minimal structure -->
|
|
62
|
+
<interact-element data-interact-key="my-element">
|
|
63
|
+
<div>Content to animate</div>
|
|
64
|
+
</interact-element>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Required Attributes
|
|
68
|
+
|
|
69
|
+
#### `data-interact-key`
|
|
70
|
+
|
|
71
|
+
**Required:** Yes
|
|
72
|
+
**Type:** `string`
|
|
73
|
+
**Description:** Unique identifier matching the interaction configuration.
|
|
74
|
+
|
|
75
|
+
**Example:**
|
|
76
|
+
```html
|
|
77
|
+
<interact-element data-interact-key="hero">
|
|
78
|
+
<div>Hero content</div>
|
|
79
|
+
</interact-element>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Child Element Requirements
|
|
83
|
+
|
|
84
|
+
The custom element **must** contain at least one child to be the event/animation target element:
|
|
85
|
+
|
|
86
|
+
```html
|
|
87
|
+
<!-- ✅ Correct: Single child element -->
|
|
88
|
+
<interact-element data-interact-key="hero">
|
|
89
|
+
<div class="hero-content">
|
|
90
|
+
<h1>Title</h1>
|
|
91
|
+
<p>Description</p>
|
|
92
|
+
</div>
|
|
93
|
+
</interact-element>
|
|
94
|
+
|
|
95
|
+
<!-- ❌ Incorrect: No child element -->
|
|
96
|
+
<interact-element data-interact-key="empty">
|
|
97
|
+
</interact-element>
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
<!-- ❌ Incorrect: Text node only -->
|
|
101
|
+
<interact-element data-interact-key="text">
|
|
102
|
+
Just text content
|
|
103
|
+
</interact-element>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Properties
|
|
107
|
+
|
|
108
|
+
### `controller: IInteractionController`
|
|
109
|
+
|
|
110
|
+
The internal controller that manages this element's interactions.
|
|
111
|
+
|
|
112
|
+
**Example:**
|
|
113
|
+
```typescript
|
|
114
|
+
const element = document.querySelector('interact-element') as IInteractElement;
|
|
115
|
+
|
|
116
|
+
// Access the controller
|
|
117
|
+
const controller = element.controller;
|
|
118
|
+
console.log('Connected:', controller.connected);
|
|
119
|
+
console.log('Key:', controller.key);
|
|
120
|
+
|
|
121
|
+
// Toggle effects through controller
|
|
122
|
+
controller.toggleEffect('my-effect', 'add');
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### `_internals: ElementInternals | null`
|
|
126
|
+
|
|
127
|
+
The element's internals for CSS custom state management.
|
|
128
|
+
|
|
129
|
+
**Example:**
|
|
130
|
+
```typescript
|
|
131
|
+
const element = document.querySelector('interact-element') as IInteractElement;
|
|
132
|
+
|
|
133
|
+
if (element._internals) {
|
|
134
|
+
// Check active states
|
|
135
|
+
console.log('States:', Array.from(element._internals.states));
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Methods
|
|
140
|
+
|
|
141
|
+
### `connect(key?: string)`
|
|
142
|
+
|
|
143
|
+
Connects the element to the interaction system.
|
|
144
|
+
|
|
145
|
+
**Parameters:**
|
|
146
|
+
- `key?: string` - Optional key override; defaults to `data-interact-key` attribute
|
|
147
|
+
|
|
148
|
+
**Example:**
|
|
149
|
+
```typescript
|
|
150
|
+
const element = document.querySelector('interact-element') as IInteractElement;
|
|
151
|
+
|
|
152
|
+
// Manually connect (usually automatic via connectedCallback)
|
|
153
|
+
element.connect('my-key');
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### `disconnect()`
|
|
157
|
+
|
|
158
|
+
Disconnects the element from the interaction system and cleans up resources.
|
|
159
|
+
|
|
160
|
+
**Example:**
|
|
161
|
+
```typescript
|
|
162
|
+
const element = document.querySelector('interact-element') as IInteractElement;
|
|
163
|
+
|
|
164
|
+
// Manually disconnect
|
|
165
|
+
element.disconnect();
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### `toggleEffect(effectId, method, item?)`
|
|
169
|
+
|
|
170
|
+
Toggles a CSS state effect on the element.
|
|
171
|
+
|
|
172
|
+
**Parameters:**
|
|
173
|
+
- `effectId: string` - The effect identifier
|
|
174
|
+
- `method: 'add' | 'remove' | 'toggle' | 'clear'` - How to change the state
|
|
175
|
+
- `item?: HTMLElement | null` - Optional specific element for list items
|
|
176
|
+
|
|
177
|
+
**Example:**
|
|
178
|
+
```typescript
|
|
179
|
+
const element = document.querySelector('interact-element') as IInteractElement;
|
|
180
|
+
|
|
181
|
+
// Add an effect
|
|
182
|
+
element.toggleEffect('active', 'add');
|
|
183
|
+
|
|
184
|
+
// Toggle an effect
|
|
185
|
+
element.toggleEffect('expanded', 'toggle');
|
|
186
|
+
|
|
187
|
+
// Remove an effect
|
|
188
|
+
element.toggleEffect('active', 'remove');
|
|
189
|
+
|
|
190
|
+
// Clear all effects
|
|
191
|
+
element.toggleEffect('', 'clear');
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### `getActiveEffects(): string[]`
|
|
195
|
+
|
|
196
|
+
Returns an array of currently active effect IDs.
|
|
197
|
+
|
|
198
|
+
**Example:**
|
|
199
|
+
```typescript
|
|
200
|
+
const element = document.querySelector('interact-element') as IInteractElement;
|
|
201
|
+
|
|
202
|
+
const activeEffects = element.getActiveEffects();
|
|
203
|
+
console.log('Active effects:', activeEffects);
|
|
204
|
+
// e.g., ['hover', 'expanded']
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Framework Integration
|
|
208
|
+
|
|
209
|
+
### Vanilla JavaScript
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
import { Interact } from '@wix/interact/web';
|
|
213
|
+
|
|
214
|
+
const config = {
|
|
215
|
+
interactions: [{
|
|
216
|
+
key: 'my-card',
|
|
217
|
+
trigger: 'hover',
|
|
218
|
+
effects: [{ effectId: 'lift' }]
|
|
219
|
+
}],
|
|
220
|
+
effects: {
|
|
221
|
+
lift: {
|
|
222
|
+
duration: 200,
|
|
223
|
+
keyframeEffect: {
|
|
224
|
+
name: 'lift',
|
|
225
|
+
keyframes: [{ transform: 'translateY(-4px)' }]
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
Interact.create(config);
|
|
232
|
+
|
|
233
|
+
// Elements automatically connect when added to DOM
|
|
234
|
+
document.body.innerHTML = `
|
|
235
|
+
<interact-element data-interact-key="my-card">
|
|
236
|
+
<div class="card">Card content</div>
|
|
237
|
+
</interact-element>
|
|
238
|
+
`;
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### React (Using interact-element)
|
|
242
|
+
|
|
243
|
+
> **Recommended**: Use the [`Interaction` component](../integration/react.md) from `@wix/interact/react` instead.
|
|
244
|
+
|
|
245
|
+
```tsx
|
|
246
|
+
import React, { useEffect, useRef } from 'react';
|
|
247
|
+
import { Interact, IInteractElement } from '@wix/interact/web';
|
|
248
|
+
|
|
249
|
+
function InteractiveCard() {
|
|
250
|
+
const ref = useRef<IInteractElement>(null);
|
|
251
|
+
|
|
252
|
+
useEffect(() => {
|
|
253
|
+
Interact.create(config);
|
|
254
|
+
return () => Interact.destroy();
|
|
255
|
+
}, []);
|
|
256
|
+
|
|
257
|
+
const handleClick = () => {
|
|
258
|
+
ref.current?.toggleEffect('clicked', 'toggle');
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
return (
|
|
262
|
+
<interact-element
|
|
263
|
+
ref={ref}
|
|
264
|
+
data-interact-key="card"
|
|
265
|
+
>
|
|
266
|
+
<button onClick={handleClick}>
|
|
267
|
+
Toggle Effect
|
|
268
|
+
</button>
|
|
269
|
+
</interact-element>
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Vue.js
|
|
275
|
+
|
|
276
|
+
```vue
|
|
277
|
+
<template>
|
|
278
|
+
<interact-element
|
|
279
|
+
:data-interact-key="elementKey"
|
|
280
|
+
ref="interactElement"
|
|
281
|
+
>
|
|
282
|
+
<div class="vue-content">
|
|
283
|
+
<h2>{{ title }}</h2>
|
|
284
|
+
<button @click="toggleEffect">Toggle</button>
|
|
285
|
+
</div>
|
|
286
|
+
</interact-element>
|
|
287
|
+
</template>
|
|
288
|
+
|
|
289
|
+
<script setup lang="ts">
|
|
290
|
+
import { ref, onMounted, onUnmounted } from 'vue';
|
|
291
|
+
import { Interact, type IInteractElement } from '@wix/interact/web';
|
|
292
|
+
|
|
293
|
+
const elementKey = ref('vue-component');
|
|
294
|
+
const title = ref('Vue Component');
|
|
295
|
+
const interactElement = ref<IInteractElement>();
|
|
296
|
+
|
|
297
|
+
onMounted(() => {
|
|
298
|
+
Interact.create(config);
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
onUnmounted(() => {
|
|
302
|
+
Interact.destroy();
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
const toggleEffect = () => {
|
|
306
|
+
interactElement.value?.toggleEffect('active', 'toggle');
|
|
307
|
+
};
|
|
308
|
+
</script>
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Angular
|
|
312
|
+
|
|
313
|
+
```typescript
|
|
314
|
+
import { Component, ElementRef, ViewChild, AfterViewInit, OnDestroy } from '@angular/core';
|
|
315
|
+
import { Interact, type IInteractElement } from '@wix/interact/web';
|
|
316
|
+
|
|
317
|
+
@Component({
|
|
318
|
+
selector: 'app-interactive',
|
|
319
|
+
template: `
|
|
320
|
+
<interact-element
|
|
321
|
+
#interactElement
|
|
322
|
+
data-interact-key="angular-component"
|
|
323
|
+
>
|
|
324
|
+
<div class="angular-content">
|
|
325
|
+
<h2>{{ title }}</h2>
|
|
326
|
+
<button (click)="toggleEffect()">Toggle</button>
|
|
327
|
+
</div>
|
|
328
|
+
</interact-element>
|
|
329
|
+
`
|
|
330
|
+
})
|
|
331
|
+
export class InteractiveComponent implements AfterViewInit, OnDestroy {
|
|
332
|
+
@ViewChild('interactElement')
|
|
333
|
+
interactElement!: ElementRef<IInteractElement>;
|
|
334
|
+
|
|
335
|
+
title = 'Angular Component';
|
|
336
|
+
|
|
337
|
+
ngAfterViewInit() {
|
|
338
|
+
Interact.create(config);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
ngOnDestroy() {
|
|
342
|
+
Interact.destroy();
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
toggleEffect() {
|
|
346
|
+
this.interactElement.nativeElement.toggleEffect('active', 'toggle');
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
## State Management
|
|
352
|
+
|
|
353
|
+
### Modern CSS States
|
|
354
|
+
|
|
355
|
+
When `ElementInternals` is supported, effects use modern CSS custom states:
|
|
356
|
+
|
|
357
|
+
```css
|
|
358
|
+
/* Modern syntax */
|
|
359
|
+
interact-element:state(hover-effect) > :first-child {
|
|
360
|
+
transform: scale(1.05);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
interact-element:state(active) > :first-child {
|
|
364
|
+
background-color: blue;
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Legacy Fallback
|
|
369
|
+
|
|
370
|
+
For older browsers, the element falls back to data attributes:
|
|
371
|
+
|
|
372
|
+
```css
|
|
373
|
+
/* Data attribute fallback */
|
|
374
|
+
interact-element[data-interact-effect~="hover-effect"] > :first-child {
|
|
375
|
+
transform: scale(1.05);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
interact-element[data-interact-effect~="active"] > :first-child {
|
|
379
|
+
background-color: blue;
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### Programmatic State Control
|
|
384
|
+
|
|
385
|
+
```typescript
|
|
386
|
+
const element = document.querySelector('interact-element') as IInteractElement;
|
|
387
|
+
|
|
388
|
+
// Add multiple states
|
|
389
|
+
element.toggleEffect('hover', 'add');
|
|
390
|
+
element.toggleEffect('focus', 'add');
|
|
391
|
+
element.toggleEffect('disabled', 'add');
|
|
392
|
+
|
|
393
|
+
// Check current states
|
|
394
|
+
const activeEffects = element.getActiveEffects();
|
|
395
|
+
console.log('Active effects:', activeEffects);
|
|
396
|
+
|
|
397
|
+
// Clear all states
|
|
398
|
+
element.toggleEffect('', 'clear');
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
## List Management with watchChildList
|
|
402
|
+
|
|
403
|
+
The `controller.watchChildList(listContainer: string)` method sets up automatic tracking of list item additions and removals.
|
|
404
|
+
|
|
405
|
+
**Signature:**
|
|
406
|
+
```typescript
|
|
407
|
+
controller.watchChildList(listContainer: string): void
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
**Parameters:**
|
|
411
|
+
- `listContainer: string` - CSS selector for the container to watch
|
|
412
|
+
|
|
413
|
+
**Example:**
|
|
414
|
+
```typescript
|
|
415
|
+
const element = document.querySelector('interact-element') as IInteractElement;
|
|
416
|
+
|
|
417
|
+
// Start watching for child changes in a specific container
|
|
418
|
+
element.controller.watchChildList('.dynamic-list');
|
|
419
|
+
|
|
420
|
+
// Now any DOM mutations will trigger automatic interaction management
|
|
421
|
+
const container = element.querySelector('.dynamic-list');
|
|
422
|
+
|
|
423
|
+
// Adding items - interactions applied automatically
|
|
424
|
+
const newItem = document.createElement('div');
|
|
425
|
+
newItem.className = 'list-item';
|
|
426
|
+
container?.appendChild(newItem); // Automatically gets interactions
|
|
427
|
+
|
|
428
|
+
// Removing items - cleanup happens automatically
|
|
429
|
+
const itemToRemove = container?.querySelector('.item-5');
|
|
430
|
+
itemToRemove?.remove(); // Automatically cleaned up
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
**Automatic Usage:**
|
|
434
|
+
When you use `listContainer` in your configuration, `watchChildList` is called automatically:
|
|
435
|
+
|
|
436
|
+
```typescript
|
|
437
|
+
// This configuration automatically sets up the observer
|
|
438
|
+
{
|
|
439
|
+
key: 'product-list',
|
|
440
|
+
listContainer: '.products', // Automatically calls watchChildList('.products')
|
|
441
|
+
trigger: 'hover',
|
|
442
|
+
effects: [/* ... */]
|
|
443
|
+
}
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
## Lifecycle
|
|
447
|
+
|
|
448
|
+
### Connection Flow
|
|
449
|
+
|
|
450
|
+
1. Element is added to DOM
|
|
451
|
+
2. `connectedCallback()` is called
|
|
452
|
+
3. `connect()` creates or retrieves an `InteractionController`
|
|
453
|
+
4. Controller is stored in `Interact.controllerCache`
|
|
454
|
+
5. Interactions are applied based on configuration
|
|
455
|
+
|
|
456
|
+
### Disconnection Flow
|
|
457
|
+
|
|
458
|
+
1. Element is removed from DOM
|
|
459
|
+
2. `disconnectedCallback()` is called
|
|
460
|
+
3. `disconnect()` cleans up the controller
|
|
461
|
+
4. Event listeners are removed
|
|
462
|
+
5. Controller is removed from cache (if element is fully removed)
|
|
463
|
+
|
|
464
|
+
## Browser Support
|
|
465
|
+
|
|
466
|
+
### Modern Browsers
|
|
467
|
+
- Full feature support including CSS custom states
|
|
468
|
+
- ElementInternals API for state management
|
|
469
|
+
- Adopted stylesheets for dynamic CSS
|
|
470
|
+
|
|
471
|
+
### Legacy Browsers
|
|
472
|
+
- Automatic fallback to data attributes
|
|
473
|
+
- CSS custom property fallbacks
|
|
474
|
+
- Polyfill support for custom elements
|
|
475
|
+
|
|
476
|
+
### Detection
|
|
477
|
+
|
|
478
|
+
```typescript
|
|
479
|
+
function checkSupport() {
|
|
480
|
+
const element = document.createElement('interact-element') as IInteractElement;
|
|
481
|
+
|
|
482
|
+
return {
|
|
483
|
+
customElements: !!window.customElements,
|
|
484
|
+
elementInternals: !!element.attachInternals,
|
|
485
|
+
adoptedStyleSheets: !!document.adoptedStyleSheets,
|
|
486
|
+
cssCustomStates: !!element._internals?.states
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
const support = checkSupport();
|
|
491
|
+
console.log('Browser support:', support);
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
## Debugging
|
|
495
|
+
|
|
496
|
+
### Element Inspection
|
|
497
|
+
|
|
498
|
+
```typescript
|
|
499
|
+
// Debug element state
|
|
500
|
+
function debugElement(key: string) {
|
|
501
|
+
const controller = Interact.getController(key);
|
|
502
|
+
|
|
503
|
+
if (!controller) {
|
|
504
|
+
console.log(`Controller for ${key} not found in cache`);
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
const element = controller.element as IInteractElement;
|
|
509
|
+
|
|
510
|
+
console.log(`Element ${key}:`, {
|
|
511
|
+
connected: controller.connected,
|
|
512
|
+
hasChild: !!element.firstElementChild,
|
|
513
|
+
hasSheet: !!controller.sheet,
|
|
514
|
+
hasInternals: !!element._internals,
|
|
515
|
+
activeEffects: controller.getActiveEffects()
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// Usage
|
|
520
|
+
debugElement('hero');
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
### Common Issues
|
|
524
|
+
|
|
525
|
+
```typescript
|
|
526
|
+
// Check for common problems
|
|
527
|
+
function validateElement(element: IInteractElement) {
|
|
528
|
+
const issues: string[] = [];
|
|
529
|
+
|
|
530
|
+
if (!element.dataset.interactKey) {
|
|
531
|
+
issues.push('Missing data-interact-key attribute');
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
if (!element.firstElementChild) {
|
|
535
|
+
issues.push('Missing child element');
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
if (!element.controller?.connected) {
|
|
539
|
+
issues.push('Controller not connected to interaction system');
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
return issues;
|
|
543
|
+
}
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
## Comparison with Interaction Component
|
|
547
|
+
|
|
548
|
+
| Feature | `<interact-element>` | `<Interaction>` (React) |
|
|
549
|
+
|---------|----------------------|-------------------------|
|
|
550
|
+
| Import | `@wix/interact/web` | `@wix/interact/react` |
|
|
551
|
+
| Type | Web Component | React Component |
|
|
552
|
+
| Ref handling | Manual | Built-in forwarding |
|
|
553
|
+
| TypeScript | Requires casting | Full inference |
|
|
554
|
+
| SSR | Requires care | Better compatibility |
|
|
555
|
+
| Framework | Any | React only |
|
|
556
|
+
|
|
557
|
+
## See Also
|
|
558
|
+
|
|
559
|
+
- [Interact Class](interact-class.md) - Main interaction manager
|
|
560
|
+
- [InteractionController](interaction-controller.md) - Controller API
|
|
561
|
+
- [Functions](functions.md) - `add()` and `remove()` functions
|
|
562
|
+
- [Type Definitions](types.md) - `IInteractElement` interface
|
|
563
|
+
- [React Integration](../integration/react.md) - React components
|
|
564
|
+
- [Configuration Guide](../guides/configuration-structure.md) - Setting up interactions
|
|
565
|
+
- [Getting Started](../guides/getting-started.md) - Basic usage examples
|