@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,450 @@
1
+ # InteractionController
2
+
3
+ The `InteractionController` class is the core unit for managing interactions on an element. It handles the connection between DOM elements and the interaction system, manages state, and coordinates with the `Interact` class.
4
+
5
+ ## Overview
6
+
7
+ The `InteractionController` is used internally by:
8
+ - The `interact-element` custom element (web approach)
9
+ - The `Interaction` component and `createInteractRef` (React approach)
10
+ - Direct DOM manipulation via `add()` and `remove()` functions
11
+
12
+ In most cases, you won't need to instantiate this class directly, as it's created automatically by the higher-level APIs.
13
+
14
+ ## Import
15
+
16
+ ```typescript
17
+ // The controller is created internally; you typically access it via:
18
+ import { Interact } from '@wix/interact/web';
19
+
20
+ const controller = Interact.getController('my-element');
21
+ ```
22
+
23
+ ## Interface
24
+
25
+ ```typescript
26
+ interface IInteractionController {
27
+ // Properties
28
+ element: HTMLElement;
29
+ key: string | undefined;
30
+ connected: boolean;
31
+ sheet: CSSStyleSheet | null;
32
+ _observers: WeakMap<HTMLElement, MutationObserver>;
33
+
34
+ // Methods
35
+ connect(key?: string): void;
36
+ disconnect(): void;
37
+ update(): void;
38
+ toggleEffect(effectId: string, method: StateParams['method'], item?: HTMLElement | null, isLegacy?: boolean): void;
39
+ getActiveEffects(): string[];
40
+ renderStyle(cssRules: string[]): void;
41
+ watchChildList(listContainer: string): void;
42
+ _childListChangeHandler(listContainer: string, entries: MutationRecord[]): void;
43
+ }
44
+ ```
45
+
46
+ ## Properties
47
+
48
+ ### `element: HTMLElement`
49
+
50
+ The DOM element this controller manages.
51
+
52
+ **Example:**
53
+ ```typescript
54
+ const controller = Interact.getController('my-element');
55
+ if (controller) {
56
+ console.log('Managing element:', controller.element);
57
+ console.log('Tag name:', controller.element.tagName);
58
+ }
59
+ ```
60
+
61
+ ### `key: string | undefined`
62
+
63
+ The unique identifier for this element's interactions.
64
+
65
+ **Example:**
66
+ ```typescript
67
+ const controller = Interact.getController('hero');
68
+ if (controller) {
69
+ console.log('Key:', controller.key); // 'hero'
70
+ }
71
+ ```
72
+
73
+ ### `connected: boolean`
74
+
75
+ Whether the controller is currently connected to the interaction system.
76
+
77
+ **Example:**
78
+ ```typescript
79
+ const controller = Interact.getController('my-element');
80
+ if (controller?.connected) {
81
+ console.log('Controller is active and listening for events');
82
+ } else {
83
+ console.log('Controller is not connected');
84
+ }
85
+ ```
86
+
87
+ ### `sheet: CSSStyleSheet | null`
88
+
89
+ The adopted stylesheet for dynamic CSS rules generated by interactions.
90
+
91
+ **Example:**
92
+ ```typescript
93
+ const controller = Interact.getController('my-element');
94
+ if (controller?.sheet) {
95
+ console.log('CSS rules count:', controller.sheet.cssRules.length);
96
+ }
97
+ ```
98
+
99
+ ### `_observers: WeakMap<HTMLElement, MutationObserver>`
100
+
101
+ Internal storage for mutation observers watching list containers.
102
+
103
+ ## Methods
104
+
105
+ ### `connect(key?: string)`
106
+
107
+ Connects the controller to the interaction system, setting up all event listeners and effects.
108
+
109
+ **Signature:**
110
+ ```typescript
111
+ connect(key?: string): void
112
+ ```
113
+
114
+ **Parameters:**
115
+ - `key?: string` - Optional key override. If not provided, uses `this.key` or `element.dataset.interactKey`
116
+
117
+ **Example:**
118
+ ```typescript
119
+ const controller = Interact.getController('my-element');
120
+ if (controller && !controller.connected) {
121
+ controller.connect();
122
+ }
123
+ ```
124
+
125
+ **Behavior:**
126
+ 1. Returns early if already connected
127
+ 2. Resolves the key from parameter, instance property, or data attribute
128
+ 3. Logs warning if no key is found
129
+ 4. Calls internal `add()` function to set up interactions
130
+ 5. Sets `connected = true` on success
131
+
132
+ ### `disconnect()`
133
+
134
+ Disconnects the controller from the interaction system, cleaning up all resources.
135
+
136
+ **Signature:**
137
+ ```typescript
138
+ disconnect(): void
139
+ ```
140
+
141
+ **Example:**
142
+ ```typescript
143
+ const controller = Interact.getController('my-element');
144
+ if (controller?.connected) {
145
+ controller.disconnect();
146
+ console.log('Controller disconnected');
147
+ }
148
+ ```
149
+
150
+ **Behavior:**
151
+ 1. Calls internal `remove()` to clean up interactions
152
+ 2. Removes adopted stylesheet from document
153
+ 3. Clears all mutation observers
154
+ 4. Sets `connected = false`
155
+
156
+ ### `update()`
157
+
158
+ Disconnects and reconnects the controller, effectively refreshing all interactions.
159
+
160
+ **Signature:**
161
+ ```typescript
162
+ update(): void
163
+ ```
164
+
165
+ **Example:**
166
+ ```typescript
167
+ const controller = Interact.getController('my-element');
168
+ if (controller) {
169
+ // After changing configuration
170
+ controller.update();
171
+ }
172
+ ```
173
+
174
+ **Use Cases:**
175
+ - After dynamically changing interaction configuration
176
+ - To reset all interaction state
177
+ - After modifying the element's structure
178
+
179
+ ### `toggleEffect(effectId, method, item?, isLegacy?)`
180
+
181
+ Toggles a CSS state effect on the element or a specific list item.
182
+
183
+ **Signature:**
184
+ ```typescript
185
+ toggleEffect(
186
+ effectId: string,
187
+ method: 'add' | 'remove' | 'toggle' | 'clear',
188
+ item?: HTMLElement | null,
189
+ isLegacy?: boolean
190
+ ): void
191
+ ```
192
+
193
+ **Parameters:**
194
+ - `effectId: string` - The effect identifier
195
+ - `method` - How to change the state:
196
+ - `'add'` - Add the effect
197
+ - `'remove'` - Remove the effect
198
+ - `'toggle'` - Toggle the effect on/off
199
+ - `'clear'` - Clear all effects
200
+ - `item?: HTMLElement | null` - Specific element for list item effects; `null` skips the operation
201
+ - `isLegacy?: boolean` - Internal flag for legacy syntax handling
202
+
203
+ **Example:**
204
+ ```typescript
205
+ const controller = Interact.getController('my-element');
206
+ if (controller) {
207
+ // Add an effect
208
+ controller.toggleEffect('active', 'add');
209
+
210
+ // Toggle an effect
211
+ controller.toggleEffect('expanded', 'toggle');
212
+
213
+ // Remove an effect
214
+ controller.toggleEffect('active', 'remove');
215
+
216
+ // Clear all effects
217
+ controller.toggleEffect('', 'clear');
218
+
219
+ // Toggle effect on a specific list item
220
+ const listItem = document.querySelector('.list-item');
221
+ controller.toggleEffect('selected', 'add', listItem);
222
+ }
223
+ ```
224
+
225
+ **Behavior:**
226
+ 1. Returns early if `item === null` (explicit skip)
227
+ 2. If element is an `IInteractElement` with custom states, delegates to it
228
+ 3. Otherwise, manages effects via `data-interact-effect` attribute
229
+ 4. Effects are stored as space-separated values
230
+
231
+ ### `getActiveEffects(): string[]`
232
+
233
+ Returns an array of currently active effect IDs on this element.
234
+
235
+ **Signature:**
236
+ ```typescript
237
+ getActiveEffects(): string[]
238
+ ```
239
+
240
+ **Returns:** `string[]` - Array of active effect identifiers
241
+
242
+ **Example:**
243
+ ```typescript
244
+ const controller = Interact.getController('my-element');
245
+ if (controller) {
246
+ const effects = controller.getActiveEffects();
247
+ console.log('Active effects:', effects);
248
+ // e.g., ['hover', 'expanded', 'selected']
249
+
250
+ // Check for specific effect
251
+ if (effects.includes('expanded')) {
252
+ console.log('Element is expanded');
253
+ }
254
+ }
255
+ ```
256
+
257
+ ### `renderStyle(cssRules: string[])`
258
+
259
+ Renders CSS rules to the controller's adopted stylesheet.
260
+
261
+ **Signature:**
262
+ ```typescript
263
+ renderStyle(cssRules: string[]): void
264
+ ```
265
+
266
+ **Parameters:**
267
+ - `cssRules: string[]` - Array of CSS rule strings to add
268
+
269
+ **Example:**
270
+ ```typescript
271
+ const controller = Interact.getController('my-element');
272
+ if (controller) {
273
+ controller.renderStyle([
274
+ '.my-element { opacity: 1; }',
275
+ '.my-element.hidden { opacity: 0; }'
276
+ ]);
277
+ }
278
+ ```
279
+
280
+ **Behavior:**
281
+ 1. If no stylesheet exists, creates one and adds it to `document.adoptedStyleSheets`
282
+ 2. If stylesheet exists, appends rules at the end
283
+ 3. Logs errors for invalid CSS rules
284
+
285
+ ### `watchChildList(listContainer: string)`
286
+
287
+ Sets up a mutation observer to watch for child additions/removals in a list container.
288
+
289
+ **Signature:**
290
+ ```typescript
291
+ watchChildList(listContainer: string): void
292
+ ```
293
+
294
+ **Parameters:**
295
+ - `listContainer: string` - CSS selector for the container to watch
296
+
297
+ **Example:**
298
+ ```typescript
299
+ const controller = Interact.getController('product-list');
300
+ if (controller) {
301
+ // Start watching for changes in .products container
302
+ controller.watchChildList('.products');
303
+
304
+ // Now any DOM changes are automatically handled
305
+ const container = controller.element.querySelector('.products');
306
+
307
+ // Adding items - interactions applied automatically
308
+ const newItem = document.createElement('div');
309
+ container?.appendChild(newItem);
310
+
311
+ // Removing items - cleanup happens automatically
312
+ container?.querySelector('.old-item')?.remove();
313
+ }
314
+ ```
315
+
316
+ **Behavior:**
317
+ 1. Finds the list container within the controller's element
318
+ 2. Creates a MutationObserver if one doesn't exist for this container
319
+ 3. Observers are stored in WeakMap to prevent duplicates
320
+ 4. Automatically calls `addListItems` for added nodes
321
+ 5. Automatically calls `removeListItems` for removed nodes
322
+
323
+ ### `_childListChangeHandler(listContainer, entries)`
324
+
325
+ Internal handler for mutation observer callbacks. You typically don't call this directly.
326
+
327
+ **Signature:**
328
+ ```typescript
329
+ _childListChangeHandler(listContainer: string, entries: MutationRecord[]): void
330
+ ```
331
+
332
+ ## Usage Patterns
333
+
334
+ ### Accessing Controllers
335
+
336
+ ```typescript
337
+ import { Interact } from '@wix/interact/web';
338
+
339
+ // Get a controller by key
340
+ const controller = Interact.getController('my-element');
341
+
342
+ // Iterate all controllers
343
+ Interact.controllerCache.forEach((controller, key) => {
344
+ console.log(`${key}: connected=${controller.connected}`);
345
+ });
346
+ ```
347
+
348
+ ### Programmatic State Management
349
+
350
+ ```typescript
351
+ const controller = Interact.getController('accordion');
352
+ if (controller) {
353
+ // Check current state
354
+ const isExpanded = controller.getActiveEffects().includes('expanded');
355
+
356
+ // Toggle based on current state
357
+ controller.toggleEffect('expanded', isExpanded ? 'remove' : 'add');
358
+ }
359
+ ```
360
+
361
+ ### Dynamic List Management
362
+
363
+ ```typescript
364
+ const controller = Interact.getController('todo-list');
365
+ if (controller) {
366
+ // Watch for list changes
367
+ controller.watchChildList('.todo-items');
368
+
369
+ // Add new item - interactions apply automatically
370
+ const todoItems = controller.element.querySelector('.todo-items');
371
+ const newTodo = document.createElement('div');
372
+ newTodo.className = 'todo-item';
373
+ newTodo.textContent = 'New task';
374
+ todoItems?.appendChild(newTodo);
375
+ }
376
+ ```
377
+
378
+ ### Refreshing Interactions
379
+
380
+ ```typescript
381
+ // After configuration change
382
+ const instance = Interact.getInstance('my-element');
383
+ if (instance) {
384
+ // Update configuration
385
+ instance.init(newConfig);
386
+
387
+ // Refresh the controller
388
+ const controller = Interact.getController('my-element');
389
+ controller?.update();
390
+ }
391
+ ```
392
+
393
+ ## Lifecycle
394
+
395
+ ### Creation Flow
396
+
397
+ 1. `add(element, key)` is called (or element connects)
398
+ 2. `InteractionController` is instantiated
399
+ 3. `connect()` is called
400
+ 4. Controller is cached in `Interact.controllerCache`
401
+ 5. Interactions are set up via internal `add()` function
402
+
403
+ ### Destruction Flow
404
+
405
+ 1. `remove(key)` is called (or element disconnects)
406
+ 2. `disconnect()` is called on the controller
407
+ 3. All event listeners are removed
408
+ 4. Stylesheet is removed from document
409
+ 5. Observers are cleared
410
+ 6. Controller is removed from cache
411
+
412
+ ## Error Handling
413
+
414
+ ```typescript
415
+ const controller = Interact.getController('my-element');
416
+
417
+ // Safe operations - won't throw
418
+ controller?.toggleEffect('effect', 'add');
419
+ controller?.connect(); // Safe if already connected
420
+ controller?.disconnect(); // Safe if already disconnected
421
+
422
+ // Check connection status
423
+ if (!controller?.connected) {
424
+ console.warn('Controller not connected');
425
+ }
426
+ ```
427
+
428
+ ## TypeScript Support
429
+
430
+ ```typescript
431
+ import { Interact, IInteractionController } from '@wix/interact/web';
432
+
433
+ const controller: IInteractionController | undefined = Interact.getController('my-element');
434
+
435
+ if (controller) {
436
+ // Full type support
437
+ const effects: string[] = controller.getActiveEffects();
438
+ const isConnected: boolean = controller.connected;
439
+ const element: HTMLElement = controller.element;
440
+ }
441
+ ```
442
+
443
+ ## See Also
444
+
445
+ - [Interact Class](interact-class.md) - Main class API
446
+ - [interact-element](interact-element.md) - Custom element that uses controllers
447
+ - [Functions](functions.md) - `add()` and `remove()` functions
448
+ - [React Integration](../integration/react.md) - React approach to interactions
449
+ - [Type Definitions](types.md) - `IInteractionController` interface
450
+