@wix/interact 1.92.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.
Files changed (179) hide show
  1. package/dist/cjs/index.js +2 -23
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/react.js +15 -0
  4. package/dist/cjs/react.js.map +1 -0
  5. package/dist/cjs/web.js +2 -0
  6. package/dist/cjs/web.js.map +1 -0
  7. package/dist/es/index.js +8 -0
  8. package/dist/es/index.js.map +1 -0
  9. package/dist/es/react.js +650 -0
  10. package/dist/es/react.js.map +1 -0
  11. package/dist/es/web.js +56 -0
  12. package/dist/es/web.js.map +1 -0
  13. package/dist/index-C8QxOkui.mjs +7940 -0
  14. package/dist/index-C8QxOkui.mjs.map +1 -0
  15. package/dist/index-DEPRHaUt.js +18 -0
  16. package/dist/index-DEPRHaUt.js.map +1 -0
  17. package/dist/tsconfig.build.tsbuildinfo +1 -0
  18. package/dist/types/core/Interact.d.ts +17 -7
  19. package/dist/types/core/Interact.d.ts.map +1 -0
  20. package/dist/types/core/InteractionController.d.ts +19 -0
  21. package/dist/types/core/InteractionController.d.ts.map +1 -0
  22. package/dist/types/core/add.d.ts +4 -3
  23. package/dist/types/core/add.d.ts.map +1 -0
  24. package/dist/types/core/css.d.ts +3 -0
  25. package/dist/types/core/css.d.ts.map +1 -0
  26. package/dist/types/core/remove.d.ts +3 -1
  27. package/dist/types/core/remove.d.ts.map +1 -0
  28. package/dist/types/core/utilities.d.ts +1 -0
  29. package/dist/types/core/utilities.d.ts.map +1 -0
  30. package/dist/types/dom/api.d.ts +3 -0
  31. package/dist/types/dom/api.d.ts.map +1 -0
  32. package/dist/types/handlers/animationEnd.d.ts +3 -2
  33. package/dist/types/handlers/animationEnd.d.ts.map +1 -0
  34. package/dist/types/handlers/click.d.ts +3 -2
  35. package/dist/types/handlers/click.d.ts.map +1 -0
  36. package/dist/types/handlers/hover.d.ts +3 -2
  37. package/dist/types/handlers/hover.d.ts.map +1 -0
  38. package/dist/types/handlers/index.d.ts +1 -0
  39. package/dist/types/handlers/index.d.ts.map +1 -0
  40. package/dist/types/handlers/pointerMove.d.ts +3 -2
  41. package/dist/types/handlers/pointerMove.d.ts.map +1 -0
  42. package/dist/types/handlers/utilities.d.ts +1 -0
  43. package/dist/types/handlers/utilities.d.ts.map +1 -0
  44. package/dist/types/handlers/viewEnter.d.ts +3 -2
  45. package/dist/types/handlers/viewEnter.d.ts.map +1 -0
  46. package/dist/types/handlers/viewProgress.d.ts +4 -3
  47. package/dist/types/handlers/viewProgress.d.ts.map +1 -0
  48. package/dist/types/index.d.ts +3 -2
  49. package/dist/types/index.d.ts.map +1 -0
  50. package/dist/types/react/Interaction.d.ts +10 -0
  51. package/dist/types/react/Interaction.d.ts.map +1 -0
  52. package/dist/types/react/index.d.ts +8 -0
  53. package/dist/types/react/index.d.ts.map +1 -0
  54. package/dist/types/react/interactRef.d.ts +3 -0
  55. package/dist/types/react/interactRef.d.ts.map +1 -0
  56. package/dist/types/types.d.ts +25 -10
  57. package/dist/types/types.d.ts.map +1 -0
  58. package/dist/types/utils.d.ts +4 -2
  59. package/dist/types/utils.d.ts.map +1 -0
  60. package/dist/types/{InteractElement.d.ts → web/InteractElement.d.ts} +115 -77
  61. package/dist/types/web/InteractElement.d.ts.map +1 -0
  62. package/dist/types/web/defineInteractElement.d.ts +2 -0
  63. package/dist/types/web/defineInteractElement.d.ts.map +1 -0
  64. package/dist/types/web/index.d.ts +6 -0
  65. package/dist/types/web/index.d.ts.map +1 -0
  66. package/docs/README.md +211 -0
  67. package/docs/advanced/README.md +164 -0
  68. package/docs/api/README.md +157 -0
  69. package/docs/api/element-selection.md +607 -0
  70. package/docs/api/functions.md +638 -0
  71. package/docs/api/interact-class.md +663 -0
  72. package/docs/api/interact-element.md +565 -0
  73. package/docs/api/interaction-controller.md +450 -0
  74. package/docs/api/types.md +957 -0
  75. package/docs/examples/README.md +212 -0
  76. package/docs/examples/click-interactions.md +977 -0
  77. package/docs/examples/entrance-animations.md +935 -0
  78. package/docs/examples/hover-effects.md +930 -0
  79. package/docs/examples/list-patterns.md +737 -0
  80. package/docs/guides/README.md +49 -0
  81. package/docs/guides/conditions-and-media-queries.md +1068 -0
  82. package/docs/guides/configuration-structure.md +726 -0
  83. package/docs/guides/custom-elements.md +327 -0
  84. package/docs/guides/effects-and-animations.md +634 -0
  85. package/docs/guides/getting-started.md +379 -0
  86. package/docs/guides/lists-and-dynamic-content.md +713 -0
  87. package/docs/guides/state-management.md +747 -0
  88. package/docs/guides/understanding-triggers.md +690 -0
  89. package/docs/integration/README.md +264 -0
  90. package/docs/integration/react.md +605 -0
  91. package/package.json +73 -56
  92. package/rules/Integration.md +255 -0
  93. package/rules/click-rules.md +533 -0
  94. package/rules/full-lean.md +346 -0
  95. package/rules/hover-rules.md +593 -0
  96. package/rules/pointermove-rules.md +1341 -0
  97. package/rules/scroll-list-rules.md +900 -0
  98. package/rules/viewenter-rules.md +1015 -0
  99. package/rules/viewprogress-rules.md +1044 -0
  100. package/dist/cjs/InteractElement.js +0 -162
  101. package/dist/cjs/InteractElement.js.map +0 -1
  102. package/dist/cjs/__tests__/interact.spec.js +0 -1930
  103. package/dist/cjs/__tests__/interact.spec.js.map +0 -1
  104. package/dist/cjs/__tests__/viewEnter.spec.js +0 -207
  105. package/dist/cjs/__tests__/viewEnter.spec.js.map +0 -1
  106. package/dist/cjs/core/Interact.js +0 -257
  107. package/dist/cjs/core/Interact.js.map +0 -1
  108. package/dist/cjs/core/add.js +0 -246
  109. package/dist/cjs/core/add.js.map +0 -1
  110. package/dist/cjs/core/remove.js +0 -35
  111. package/dist/cjs/core/remove.js.map +0 -1
  112. package/dist/cjs/core/utilities.js +0 -16
  113. package/dist/cjs/core/utilities.js.map +0 -1
  114. package/dist/cjs/external-types.d.js +0 -2
  115. package/dist/cjs/external-types.d.js.map +0 -1
  116. package/dist/cjs/handlers/animationEnd.js +0 -33
  117. package/dist/cjs/handlers/animationEnd.js.map +0 -1
  118. package/dist/cjs/handlers/click.js +0 -116
  119. package/dist/cjs/handlers/click.js.map +0 -1
  120. package/dist/cjs/handlers/hover.js +0 -141
  121. package/dist/cjs/handlers/hover.js.map +0 -1
  122. package/dist/cjs/handlers/index.js +0 -32
  123. package/dist/cjs/handlers/index.js.map +0 -1
  124. package/dist/cjs/handlers/pointerMove.js +0 -49
  125. package/dist/cjs/handlers/pointerMove.js.map +0 -1
  126. package/dist/cjs/handlers/utilities.js +0 -49
  127. package/dist/cjs/handlers/utilities.js.map +0 -1
  128. package/dist/cjs/handlers/viewEnter.js +0 -127
  129. package/dist/cjs/handlers/viewEnter.js.map +0 -1
  130. package/dist/cjs/handlers/viewProgress.js +0 -65
  131. package/dist/cjs/handlers/viewProgress.js.map +0 -1
  132. package/dist/cjs/test-types.d.js +0 -2
  133. package/dist/cjs/test-types.d.js.map +0 -1
  134. package/dist/cjs/types.js +0 -2
  135. package/dist/cjs/types.js.map +0 -1
  136. package/dist/cjs/utils.js +0 -68
  137. package/dist/cjs/utils.js.map +0 -1
  138. package/dist/esm/InteractElement.js +0 -156
  139. package/dist/esm/InteractElement.js.map +0 -1
  140. package/dist/esm/__tests__/interact.spec.js +0 -1937
  141. package/dist/esm/__tests__/interact.spec.js.map +0 -1
  142. package/dist/esm/__tests__/viewEnter.spec.js +0 -210
  143. package/dist/esm/__tests__/viewEnter.spec.js.map +0 -1
  144. package/dist/esm/core/Interact.js +0 -251
  145. package/dist/esm/core/Interact.js.map +0 -1
  146. package/dist/esm/core/add.js +0 -241
  147. package/dist/esm/core/add.js.map +0 -1
  148. package/dist/esm/core/remove.js +0 -30
  149. package/dist/esm/core/remove.js.map +0 -1
  150. package/dist/esm/core/utilities.js +0 -14
  151. package/dist/esm/core/utilities.js.map +0 -1
  152. package/dist/esm/external-types.d.js +0 -2
  153. package/dist/esm/external-types.d.js.map +0 -1
  154. package/dist/esm/handlers/animationEnd.js +0 -29
  155. package/dist/esm/handlers/animationEnd.js.map +0 -1
  156. package/dist/esm/handlers/click.js +0 -116
  157. package/dist/esm/handlers/click.js.map +0 -1
  158. package/dist/esm/handlers/hover.js +0 -141
  159. package/dist/esm/handlers/hover.js.map +0 -1
  160. package/dist/esm/handlers/index.js +0 -27
  161. package/dist/esm/handlers/index.js.map +0 -1
  162. package/dist/esm/handlers/pointerMove.js +0 -48
  163. package/dist/esm/handlers/pointerMove.js.map +0 -1
  164. package/dist/esm/handlers/utilities.js +0 -43
  165. package/dist/esm/handlers/utilities.js.map +0 -1
  166. package/dist/esm/handlers/viewEnter.js +0 -129
  167. package/dist/esm/handlers/viewEnter.js.map +0 -1
  168. package/dist/esm/handlers/viewProgress.js +0 -61
  169. package/dist/esm/handlers/viewProgress.js.map +0 -1
  170. package/dist/esm/index.js +0 -5
  171. package/dist/esm/index.js.map +0 -1
  172. package/dist/esm/test-types.d.js +0 -2
  173. package/dist/esm/test-types.d.js.map +0 -1
  174. package/dist/esm/types.js +0 -2
  175. package/dist/esm/types.js.map +0 -1
  176. package/dist/esm/utils.js +0 -63
  177. package/dist/esm/utils.js.map +0 -1
  178. package/dist/types/__tests__/interact.spec.d.ts +0 -1
  179. package/dist/types/__tests__/viewEnter.spec.d.ts +0 -0
@@ -0,0 +1,605 @@
1
+ # React Integration
2
+
3
+ This guide covers how to use `@wix/interact` with React applications. The library provides a dedicated React entry point with components and utilities designed for seamless React integration.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @wix/interact @wix/motion
9
+ ```
10
+
11
+ ## Import
12
+
13
+ ```typescript
14
+ import { Interact, Interaction, createInteractRef } from '@wix/interact/react';
15
+ ```
16
+
17
+ The `@wix/interact/react` entry point exports:
18
+ - `Interact` - Main interaction manager class
19
+ - `Interaction` - React component for interactive elements
20
+ - `createInteractRef` - Function to create interact-aware refs
21
+ - `add`, `remove` - DOM API functions
22
+ - All types from the main package
23
+
24
+ ## Quick Start
25
+
26
+ ```tsx
27
+ import React, { useEffect } from 'react';
28
+ import { Interact, Interaction } from '@wix/interact/react';
29
+
30
+ const config = {
31
+ interactions: [{
32
+ key: 'my-button',
33
+ trigger: 'hover',
34
+ effects: [{
35
+ keyframeEffect: {
36
+ name: 'scale-up',
37
+ keyframes: [{ transform: 'scale(1.1)' }]
38
+ },
39
+ duration: 200
40
+ }]
41
+ }]
42
+ };
43
+
44
+ function Button() {
45
+ return (
46
+ <Interaction tagName="button" interactKey="my-button">
47
+ Hover me!
48
+ </Interaction>
49
+ );
50
+ }
51
+
52
+ function App() {
53
+ useEffect(() => {
54
+ const instance = Interact.create(config);
55
+ return () => instance.destroy();
56
+ }, []);
57
+
58
+ return (
59
+ <Button />
60
+ );
61
+ }
62
+ ```
63
+
64
+ ---
65
+
66
+ ## The `Interaction` Component
67
+
68
+ The `Interaction` component is a wrapper that automatically manages interaction lifecycle for React components.
69
+
70
+ ### Props
71
+
72
+ | Prop | Type | Required | Description |
73
+ |------|------|----------|-------------|
74
+ | `tagName` | `keyof JSX.IntrinsicElements` | Yes | The HTML element to render (e.g., `'div'`, `'button'`, `'span'`) |
75
+ | `interactKey` | `string` | Yes | Unique identifier matching the interaction configuration |
76
+ | `children` | `React.ReactNode` | No | Child elements to render |
77
+ | `ref` | `React.Ref<any>` | No | Forwarded ref to the underlying DOM element |
78
+ | `...rest` | `JSX.IntrinsicElements[T]` | No | Any valid props for the specified `tagName` |
79
+
80
+ ### Basic Usage
81
+
82
+ ```tsx
83
+ import { Interaction } from '@wix/interact/react';
84
+
85
+ // Render as a div
86
+ <Interaction tagName="div" interactKey="card" className="card">
87
+ <h2>Card Title</h2>
88
+ <p>Card content</p>
89
+ </Interaction>
90
+
91
+ // Render as a button
92
+ <Interaction tagName="button" interactKey="cta-button" onClick={handleClick}>
93
+ Click me
94
+ </Interaction>
95
+
96
+ // Render as an image container
97
+ <Interaction tagName="figure" interactKey="image-hover">
98
+ <img src="photo.jpg" alt="Photo" />
99
+ </Interaction>
100
+ ```
101
+
102
+ ### With Forwarded Refs
103
+
104
+ The `Interaction` component supports ref forwarding, allowing you to access the underlying DOM element:
105
+
106
+ ```tsx
107
+ import React, { useRef, useEffect } from 'react';
108
+ import { Interaction } from '@wix/interact/react';
109
+
110
+ function AnimatedCard() {
111
+ const cardRef = useRef<HTMLDivElement>(null);
112
+
113
+ useEffect(() => {
114
+ if (cardRef.current) {
115
+ console.log('Card element:', cardRef.current);
116
+ }
117
+ }, []);
118
+
119
+ return (
120
+ <Interaction
121
+ tagName="div"
122
+ interactKey="card"
123
+ ref={cardRef}
124
+ className="card"
125
+ >
126
+ <h2>Interactive Card</h2>
127
+ </Interaction>
128
+ );
129
+ }
130
+ ```
131
+
132
+ ### TypeScript Support
133
+
134
+ The component is fully typed and provides type inference for the `tagName` prop:
135
+
136
+ ```tsx
137
+ import { Interaction } from '@wix/interact/react';
138
+
139
+ // TypeScript knows these are valid button props
140
+ <Interaction
141
+ tagName="button"
142
+ interactKey="btn"
143
+ type="submit"
144
+ disabled={false}
145
+ onClick={(e) => console.log(e.currentTarget)} // e is MouseEvent<HTMLButtonElement>
146
+ >
147
+ Submit
148
+ </Interaction>
149
+
150
+ // TypeScript knows these are valid anchor props
151
+ <Interaction
152
+ tagName="a"
153
+ interactKey="link"
154
+ href="/about"
155
+ target="_blank"
156
+ >
157
+ About Us
158
+ </Interaction>
159
+ ```
160
+
161
+ ---
162
+
163
+ ## The `createInteractRef` Function
164
+
165
+ For more control over ref management, use `createInteractRef` to create a ref callback that handles interaction lifecycle.
166
+
167
+ ### Signature
168
+
169
+ ```typescript
170
+ function createInteractRef(interactKey: string): InteractRef
171
+
172
+ type InteractRef = (node: Element | null) => () => void;
173
+ ```
174
+
175
+ ### Basic Usage
176
+
177
+ ```tsx
178
+ import React, { useRef, useCallback, useEffect } from 'react';
179
+ import { Interact, createInteractRef } from '@wix/interact/react';
180
+
181
+ function CustomComponent() {
182
+ const interactRef = useRef(createInteractRef('my-element'));
183
+
184
+ useEffect(() => {
185
+ Interact.create(config);
186
+ }, []);
187
+
188
+ return (
189
+ <div ref={interactRef.current} data-interact-key="my-element">
190
+ <span>Interactive content</span>
191
+ </div>
192
+ );
193
+ }
194
+ ```
195
+
196
+ ### React 18 vs React 19 Compatibility
197
+
198
+ The `createInteractRef` function is designed to work with both React 18 and React 19's different cleanup patterns:
199
+
200
+ ```tsx
201
+ // React 18: Cleanup happens when ref receives null
202
+ // React 19: Cleanup happens via returned cleanup function
203
+
204
+ const interactRef = createInteractRef('my-key');
205
+
206
+ // The ref callback handles both patterns automatically:
207
+ // - When node is null (React 18 unmount), it calls remove()
208
+ // - Returns a cleanup function for React 19+
209
+ ```
210
+
211
+ ### Combining with Other Refs
212
+
213
+ When you need to combine the interact ref with other refs:
214
+
215
+ ```tsx
216
+ import React, { useRef, useCallback } from 'react';
217
+ import { createInteractRef } from '@wix/interact/react';
218
+
219
+ function CombinedRefExample() {
220
+ const localRef = useRef<HTMLDivElement>(null);
221
+ const interactRef = useRef(createInteractRef('combined'));
222
+
223
+ const combinedRef = useCallback((node: HTMLDivElement | null) => {
224
+ // Set local ref
225
+ localRef.current = node;
226
+
227
+ // Call interact ref
228
+ const cleanup = interactRef.current(node);
229
+
230
+ // Return cleanup for React 19+
231
+ return cleanup;
232
+ }, []);
233
+
234
+ return (
235
+ <div ref={combinedRef} data-interact-key="combined">
236
+ Content
237
+ </div>
238
+ );
239
+ }
240
+ ```
241
+
242
+ ---
243
+
244
+ ## Configuration Patterns
245
+
246
+ ### Basic Setup with useEffect
247
+
248
+ ```tsx
249
+ import React, { useEffect } from 'react';
250
+ import { Interact, Interaction, InteractConfig } from '@wix/interact/react';
251
+
252
+ const config: InteractConfig = {
253
+ interactions: [
254
+ {
255
+ key: 'fade-card',
256
+ trigger: 'viewEnter',
257
+ effects: [{
258
+ keyframeEffect: {
259
+ name: 'fade-in',
260
+ keyframes: [
261
+ { opacity: 0, transform: 'translateY(20px)' },
262
+ { opacity: 1, transform: 'translateY(0)' }
263
+ ]
264
+ },
265
+ duration: 600,
266
+ easing: 'ease-out'
267
+ }]
268
+ }
269
+ ]
270
+ };
271
+
272
+ function App() {
273
+ useEffect(() => {
274
+ const instance = Interact.create(config);
275
+
276
+ // Cleanup on unmount
277
+ return () => {
278
+ instance.destroy();
279
+ };
280
+ }, []);
281
+
282
+ return (
283
+ <Interaction tagName="div" interactKey="fade-card" className="card">
284
+ <h2>Animated Card</h2>
285
+ <p>This card fades in when it enters the viewport.</p>
286
+ </Interaction>
287
+ );
288
+ }
289
+ ```
290
+
291
+ ### Custom Hook for Reusability
292
+
293
+ ```tsx
294
+ import { useEffect, useRef } from 'react';
295
+ import { Interact, InteractConfig } from '@wix/interact/react';
296
+
297
+ export function useInteract(config: InteractConfig) {
298
+ const instanceRef = useRef<Interact | null>(null);
299
+
300
+ useEffect(() => {
301
+ instanceRef.current = Interact.create(config);
302
+
303
+ return () => {
304
+ instanceRef.current?.destroy();
305
+ instanceRef.current = null;
306
+ };
307
+ }, [config]);
308
+
309
+ return instanceRef;
310
+ }
311
+
312
+ // Usage
313
+ function MyComponent() {
314
+ useInteract(config);
315
+
316
+ return (
317
+ <Interaction tagName="div" interactKey="my-element">
318
+ Content
319
+ </Interaction>
320
+ );
321
+ }
322
+ ```
323
+
324
+ ### Multiple Instances
325
+
326
+ ```tsx
327
+ import React, { useEffect } from 'react';
328
+ import { Interact, Interaction } from '@wix/interact/react';
329
+
330
+ const heroConfig = {
331
+ interactions: [{
332
+ key: 'hero',
333
+ trigger: 'viewEnter',
334
+ effects: [/* ... */]
335
+ }]
336
+ };
337
+
338
+ const cardsConfig = {
339
+ interactions: [{
340
+ key: 'card',
341
+ trigger: 'hover',
342
+ effects: [/* ... */]
343
+ }]
344
+ };
345
+
346
+ function App() {
347
+ useEffect(() => {
348
+ const heroInstance = Interact.create(heroConfig);
349
+ const cardsInstance = Interact.create(cardsConfig);
350
+
351
+ return () => {
352
+ heroInstance.destroy();
353
+ cardsInstance.destroy();
354
+ };
355
+ }, []);
356
+
357
+ return (
358
+ <>
359
+ <Interaction tagName="section" interactKey="hero">
360
+ <h1>Welcome</h1>
361
+ </Interaction>
362
+
363
+ <Interaction tagName="article" interactKey="card">
364
+ <h2>Card 1</h2>
365
+ </Interaction>
366
+
367
+ <Interaction tagName="article" interactKey="card">
368
+ <h2>Card 2</h2>
369
+ </Interaction>
370
+ </>
371
+ );
372
+ }
373
+ ```
374
+
375
+ ---
376
+
377
+ ## State-Based Interactions
378
+
379
+ ### Click Toggle Effects
380
+
381
+ ```tsx
382
+ import React, { useEffect } from 'react';
383
+ import { Interact, Interaction, InteractConfig } from '@wix/interact/react';
384
+
385
+ const config: InteractConfig = {
386
+ effects: {
387
+ 'expanded': {
388
+ transitionEffect: {
389
+ properties: ['max-height', 'padding'],
390
+ from: { maxHeight: '0px', padding: '0' },
391
+ to: { maxHeight: '200px', padding: '16px' }
392
+ },
393
+ duration: 300
394
+ }
395
+ },
396
+ interactions: [{
397
+ key: 'accordion',
398
+ trigger: 'click',
399
+ selector: '.accordion-header',
400
+ effects: [{ effectId: 'expanded', method: 'toggle' }]
401
+ }]
402
+ };
403
+
404
+ function Accordion() {
405
+ useEffect(() => {
406
+ const instance = Interact.create(config);
407
+ return () => instance.destroy();
408
+ }, []);
409
+
410
+ return (
411
+ <Interaction tagName="div" interactKey="accordion" className="accordion">
412
+ <button className="accordion-header">Toggle</button>
413
+ <div className="accordion-content">
414
+ <p>Expandable content here</p>
415
+ </div>
416
+ </Interaction>
417
+ );
418
+ }
419
+ ```
420
+
421
+ ### Accessing Active Effects
422
+
423
+ ```tsx
424
+ import React, { useRef, useEffect } from 'react';
425
+ import { Interact, Interaction } from '@wix/interact/react';
426
+
427
+ function EffectAwareComponent() {
428
+ const elementRef = useRef<HTMLDivElement>(null);
429
+
430
+ const checkEffects = () => {
431
+ const controller = Interact.getController('my-element');
432
+ if (controller) {
433
+ const activeEffects = controller.getActiveEffects();
434
+ console.log('Active effects:', activeEffects);
435
+ }
436
+ };
437
+
438
+ return (
439
+ <Interaction
440
+ tagName="div"
441
+ interactKey="my-element"
442
+ ref={elementRef}
443
+ onClick={checkEffects}
444
+ >
445
+ Click to check effects
446
+ </Interaction>
447
+ );
448
+ }
449
+ ```
450
+
451
+ ---
452
+
453
+ ## Lists and Dynamic Content
454
+
455
+ ### Animated Lists
456
+
457
+ ```tsx
458
+ import React, { useEffect, useState } from 'react';
459
+ import { Interact, Interaction, InteractConfig } from '@wix/interact/react';
460
+
461
+ const config: InteractConfig = {
462
+ interactions: [{
463
+ key: 'product-list',
464
+ trigger: 'viewEnter',
465
+ listContainer: '.products',
466
+ effects: [{
467
+ keyframeEffect: {
468
+ name: 'slide-up',
469
+ keyframes: [
470
+ { opacity: 0, transform: 'translateY(30px)' },
471
+ { opacity: 1, transform: 'translateY(0)' }
472
+ ]
473
+ },
474
+ duration: 400,
475
+ stagger: 100 // Stagger animation for list items
476
+ }]
477
+ }]
478
+ };
479
+
480
+ function ProductList() {
481
+ const [products, setProducts] = useState([
482
+ { id: 1, name: 'Product A' },
483
+ { id: 2, name: 'Product B' },
484
+ { id: 3, name: 'Product C' }
485
+ ]);
486
+
487
+ useEffect(() => {
488
+ const instance = Interact.create(config);
489
+ return () => instance.destroy();
490
+ }, []);
491
+
492
+ const addProduct = () => {
493
+ setProducts(prev => [...prev, {
494
+ id: Date.now(),
495
+ name: `Product ${prev.length + 1}`
496
+ }]);
497
+ };
498
+
499
+ return (
500
+ <Interaction tagName="div" interactKey="product-list">
501
+ <button onClick={addProduct}>Add Product</button>
502
+ <div className="products">
503
+ {products.map(product => (
504
+ <div key={product.id} className="product-card">
505
+ {product.name}
506
+ </div>
507
+ ))}
508
+ </div>
509
+ </Interaction>
510
+ );
511
+ }
512
+ ```
513
+
514
+ ---
515
+
516
+ ## Server-Side Rendering (SSR)
517
+
518
+ ### Next.js App Router
519
+
520
+ ```tsx
521
+ // app/components/InteractiveCard.tsx
522
+ 'use client';
523
+
524
+ import { useEffect } from 'react';
525
+ import { Interact, Interaction } from '@wix/interact/react';
526
+
527
+ const config = {/* ... */};
528
+
529
+ export function InteractiveCard({ children }: { children: React.ReactNode }) {
530
+ useEffect(() => {
531
+ const instance = Interact.create(config);
532
+ return () => instance.destroy();
533
+ }, []);
534
+
535
+ return (
536
+ <Interaction tagName="div" interactKey="card">
537
+ {children}
538
+ </Interaction>
539
+ );
540
+ }
541
+ ```
542
+
543
+ ### Next.js Pages Router
544
+
545
+ ```tsx
546
+ // pages/index.tsx
547
+ import { useEffect } from 'react';
548
+ import { Interact, Interaction } from '@wix/interact/react';
549
+
550
+ const config = {/* ... */};
551
+
552
+ export default function Home() {
553
+ useEffect(() => {
554
+ // Only runs on client
555
+ const instance = Interact.create(config);
556
+ return () => instance.destroy();
557
+ }, []);
558
+
559
+ return (
560
+ <Interaction tagName="main" interactKey="hero">
561
+ <h1>Welcome</h1>
562
+ </Interaction>
563
+ );
564
+ }
565
+ ```
566
+
567
+ ## Troubleshooting
568
+
569
+ ### React StrictMode
570
+
571
+ React's StrictMode double-invokes effects in development. The library handles this gracefully:
572
+
573
+ ```tsx
574
+ // This works correctly even in StrictMode
575
+ useEffect(() => {
576
+ const instance = Interact.create(config);
577
+ return () => instance.destroy();
578
+ }, []);
579
+ ```
580
+
581
+ ### Memory leaks
582
+
583
+ Always clean up instances:
584
+
585
+ ```tsx
586
+ useEffect(() => {
587
+ const instance = Interact.create(config);
588
+
589
+ // Always return cleanup function
590
+ return () => {
591
+ instance.destroy();
592
+ };
593
+ }, []);
594
+ ```
595
+
596
+ ---
597
+
598
+ ## See Also
599
+
600
+ - [Getting Started](../guides/getting-started.md) - Basic concepts and setup
601
+ - [Interact Class](../api/interact-class.md) - Main class API
602
+ - [InteractionController](../api/interaction-controller.md) - Controller API
603
+ - [Configuration Guide](../guides/configuration-structure.md) - Configuration options
604
+ - [Type Definitions](../api/types.md) - TypeScript types
605
+