@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.
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 +23 -10
  57. package/dist/types/types.d.ts.map +1 -0
  58. package/dist/types/utils.d.ts +2 -1
  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 -163
  101. package/dist/cjs/InteractElement.js.map +0 -1
  102. package/dist/cjs/__tests__/interact.spec.js +0 -2094
  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 -250
  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 -37
  117. package/dist/cjs/handlers/animationEnd.js.map +0 -1
  118. package/dist/cjs/handlers/click.js +0 -122
  119. package/dist/cjs/handlers/click.js.map +0 -1
  120. package/dist/cjs/handlers/hover.js +0 -147
  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 -131
  129. package/dist/cjs/handlers/viewEnter.js.map +0 -1
  130. package/dist/cjs/handlers/viewProgress.js +0 -79
  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 -98
  137. package/dist/cjs/utils.js.map +0 -1
  138. package/dist/esm/InteractElement.js +0 -157
  139. package/dist/esm/InteractElement.js.map +0 -1
  140. package/dist/esm/__tests__/interact.spec.js +0 -2102
  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 -245
  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 -33
  155. package/dist/esm/handlers/animationEnd.js.map +0 -1
  156. package/dist/esm/handlers/click.js +0 -122
  157. package/dist/esm/handlers/click.js.map +0 -1
  158. package/dist/esm/handlers/hover.js +0 -147
  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 -133
  167. package/dist/esm/handlers/viewEnter.js.map +0 -1
  168. package/dist/esm/handlers/viewProgress.js +0 -75
  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 -92
  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,607 @@
1
+ # Element Selection Priority
2
+
3
+ Understanding how `@wix/interact` selects elements is crucial for building reliable interactions. This guide explains the selection priority order, common patterns, and troubleshooting tips.
4
+
5
+ ## Selection Priority Overview
6
+
7
+ When `@wix/interact` needs to determine which element to use (either as a trigger source or effect target), it follows a specific priority order:
8
+
9
+ ```
10
+ ┌─────────────────────────────────────┐
11
+ │ Is listContainer specified? │
12
+ └──────────┬──────────────────────────┘
13
+
14
+ ┌──────┴──────┐
15
+ │ YES │ NO
16
+ ▼ ▼
17
+ ┌───────────┐ ┌──────────────────────┐
18
+ │ Find all │ │ Is selector │
19
+ │ children │ │ specified? │
20
+ │ of list │ └──────┬───────────────┘
21
+ │ container │ │
22
+ └─────┬─────┘ ┌─────┴──────┐
23
+ │ │ YES │ NO
24
+ │ ▼ ▼
25
+ │ ┌─────────┐ ┌─────────────┐
26
+ │ │ Query │ │ Use first │
27
+ │ │ selector│ │ child │
28
+ │ │ within │ │ element │
29
+ │ │ element │ │ │
30
+ │ └─────────┘ └─────────────┘
31
+
32
+
33
+ ┌─────────────┐
34
+ │ Is selector |
35
+ │ specified? |
36
+ └────────┬────┘
37
+ ┌────┴───────────────┐
38
+ │ YES │ NO
39
+ ▼ ▼
40
+ ┌─────────────┐ ┌───────────────┐
41
+ | Query | │ Use each item │
42
+ | selector | │ as-is │
43
+ | within each | └───────────────┘
44
+ | item |
45
+ └─────────────┘
46
+ ```
47
+
48
+ ## Priority Levels
49
+
50
+ ### Priority 1: listContainer (Highest)
51
+
52
+ When `listContainer` is specified, it takes precedence over all other selectors.
53
+
54
+ **Behavior:**
55
+ - Finds the container element using the CSS selector
56
+ - Targets all direct children of that container
57
+ - If `selector` is also specified, applies it on each child or within each child
58
+
59
+ **Example:**
60
+ ```typescript
61
+ {
62
+ key: 'gallery',
63
+ listContainer: '.gallery-grid', // Priority 1: Find this container
64
+ selector: '.gallery-item img', // Then: Find img within each child
65
+ trigger: 'hover',
66
+ effects: [/* ... */]
67
+ }
68
+ ```
69
+
70
+ ```html
71
+ <interact-element data-interact-key="gallery">
72
+ <div class="gallery-grid"> <!-- listContainer targets this -->
73
+ <div class="gallery-item"> <!-- Each child is processed -->
74
+ <img src="1.jpg" /> <!-- selector finds this -->
75
+ </div>
76
+ <div class="gallery-item"> <!-- Each child is processed -->
77
+ <img src="2.jpg" /> <!-- selector finds this -->
78
+ </div>
79
+ </div>
80
+ </interact-element>
81
+ ```
82
+
83
+ **Result:** Hover interactions apply to each `img` element within each gallery item.
84
+
85
+ ### Priority 2: selector (Medium)
86
+
87
+ When only `selector` is specified (no `listContainer`), it selects a single element within the `interact-element`.
88
+
89
+ **Behavior:**
90
+ - Queries for the first matching element within the custom element
91
+ - Uses `querySelector()` internally
92
+
93
+ **Example:**
94
+ ```typescript
95
+ {
96
+ key: 'card',
97
+ selector: '.card-image', // Priority 2: Find this specific element
98
+ trigger: 'hover',
99
+ effects: [/* ... */]
100
+ }
101
+ ```
102
+
103
+ ```html
104
+ <interact-element data-interact-key="card">
105
+ <div class="card">
106
+ <div class="card-header">Title</div>
107
+ <div class="card-image"> <!-- selector targets this -->
108
+ <img src="photo.jpg" />
109
+ </div>
110
+ <div class="card-footer">Footer</div>
111
+ </div>
112
+ </interact-element>
113
+ ```
114
+
115
+ **Result:** Hover interaction applies only to `.card-image`.
116
+
117
+ ### Priority 3: First Child (Fallback)
118
+
119
+ When neither `listContainer` nor `selector` is specified, the system uses the first child element.
120
+
121
+ **Behavior:**
122
+ - Uses `firstElementChild` of the `interact-element`
123
+
124
+ **Example:**
125
+ ```typescript
126
+ {
127
+ key: 'button',
128
+ // No selector or listContainer specified
129
+ trigger: 'click',
130
+ effects: [/* ... */]
131
+ }
132
+ ```
133
+
134
+ ```html
135
+ <interact-element data-interact-key="button">
136
+ <button class="primary-btn">Click Me</button> <!-- First child is used -->
137
+ </interact-element>
138
+ ```
139
+
140
+ **Result:** Click interaction applies to the `<button>` element.
141
+
142
+ ## Selection Scenarios
143
+
144
+ ### Scenario 1: Simple Element (No Selectors)
145
+
146
+ **Configuration:**
147
+ ```typescript
148
+ {
149
+ key: 'hero',
150
+ trigger: 'viewEnter',
151
+ effects: [{
152
+ key: 'hero',
153
+ keyframeEffect: {
154
+ name: 'fade',
155
+ keyframes: [
156
+ { opacity: '0' },
157
+ { opacity: '1' }
158
+ ]
159
+ },
160
+ duration: 800
161
+ }]
162
+ }
163
+ ```
164
+
165
+ **HTML:**
166
+ ```html
167
+ <interact-element data-interact-key="hero">
168
+ <section class="hero-section">
169
+ <h1>Welcome</h1>
170
+ <p>Subtitle</p>
171
+ </section>
172
+ </interact-element>
173
+ ```
174
+
175
+ **Result:** The `<section>` element (first child) gets the fade effect.
176
+
177
+ ### Scenario 2: Using selector
178
+
179
+ **Configuration:**
180
+ ```typescript
181
+ {
182
+ key: 'card',
183
+ selector: '.card-content', // Target specific element
184
+ trigger: 'hover',
185
+ effects: [{
186
+ key: 'card',
187
+ selector: '.card-image img', // Different target for effect
188
+ keyframeEffect: {
189
+ name: 'zoom',
190
+ keyframes: [
191
+ { transform: 'scale(1)' },
192
+ { transform: 'scale(1.1)' }
193
+ ]
194
+ },
195
+ duration: 300
196
+ }]
197
+ }
198
+ ```
199
+
200
+ **HTML:**
201
+ ```html
202
+ <interact-element data-interact-key="card">
203
+ <div class="card">
204
+ <div class="card-image">
205
+ <img src="product.jpg" /> <!-- Effect applies here -->
206
+ </div>
207
+ <div class="card-content"> <!-- Trigger listens here -->
208
+ <h3>Product Name</h3>
209
+ </div>
210
+ </div>
211
+ </interact-element>
212
+ ```
213
+
214
+ **Result:** Hovering `.card-content` triggers zoom on `.card-image img`.
215
+
216
+ ### Scenario 3: Using listContainer
217
+
218
+ **Configuration:**
219
+ ```typescript
220
+ {
221
+ key: 'products',
222
+ listContainer: '.product-grid', // Container with multiple items
223
+ trigger: 'viewEnter',
224
+ effects: [{
225
+ key: 'products',
226
+ listContainer: '.product-grid',
227
+ keyframeEffect: {
228
+ name: 'slide-up',
229
+ keyframes: [
230
+ { opacity: '0', transform: 'translateY(20px)' },
231
+ { opacity: '1', transform: 'translateY(0)' }
232
+ ]
233
+ },
234
+ duration: 600
235
+ }]
236
+ }
237
+ ```
238
+
239
+ **HTML:**
240
+ ```html
241
+ <interact-element data-interact-key="products">
242
+ <div class="product-grid">
243
+ <div class="product-card">Product 1</div> <!-- Effect applies -->
244
+ <div class="product-card">Product 2</div> <!-- Effect applies -->
245
+ <div class="product-card">Product 3</div> <!-- Effect applies -->
246
+ </div>
247
+ </interact-element>
248
+ ```
249
+
250
+ **Result:** Each product card gets the slide-up animation independently.
251
+
252
+ ### Scenario 4: listContainer + selector
253
+
254
+ **Configuration:**
255
+ ```typescript
256
+ {
257
+ key: 'gallery',
258
+ listContainer: '.gallery-grid',
259
+ selector: '.gallery-item', // Trigger on item container
260
+ trigger: 'hover',
261
+ effects: [{
262
+ key: 'gallery',
263
+ listContainer: '.gallery-grid',
264
+ selector: '.gallery-item img', // Effect on image
265
+ keyframeEffect: {
266
+ name: 'zoom',
267
+ keyframes: [
268
+ { transform: 'scale(1)' },
269
+ { transform: 'scale(1.05)' }
270
+ ]
271
+ },
272
+ duration: 300
273
+ }]
274
+ }
275
+ ```
276
+
277
+ **HTML:**
278
+ ```html
279
+ <interact-element data-interact-key="gallery">
280
+ <div class="gallery-grid">
281
+ <div class="gallery-item"> <!-- Hover trigger -->
282
+ <img src="photo1.jpg" /> <!-- Zoom effect -->
283
+ <div class="overlay">View</div>
284
+ </div>
285
+ <div class="gallery-item"> <!-- Hover trigger -->
286
+ <img src="photo2.jpg" /> <!-- Zoom effect -->
287
+ <div class="overlay">View</div>
288
+ </div>
289
+ </div>
290
+ </interact-element>
291
+ ```
292
+
293
+ **Result:** Hovering each `.gallery-item` triggers zoom on its `img`.
294
+
295
+ ## Selector Inheritance
296
+
297
+ **Important:** `selector` and `listContainer` are **NOT** inherited from Interaction to Effect.
298
+
299
+ ```typescript
300
+ // ❌ This does NOT work - Effect selector is independent
301
+ {
302
+ key: 'card',
303
+ selector: '.card-content', // Interaction selector
304
+ trigger: 'hover',
305
+ effects: [{
306
+ key: 'card',
307
+ // Missing selector - will use first child of card, not .card-content
308
+ duration: 300
309
+ }]
310
+ }
311
+
312
+ // ✅ Correct - Explicitly specify selectors
313
+ {
314
+ key: 'card',
315
+ selector: '.card-content', // Interaction selector
316
+ trigger: 'hover',
317
+ effects: [{
318
+ key: 'card',
319
+ selector: '.card-image', // Effect selector (independent)
320
+ duration: 300
321
+ }]
322
+ }
323
+ ```
324
+
325
+ **Rule:** Always specify `selector` and `listContainer` on both `Interaction` and `Effect` if you need them for both.
326
+
327
+ ## Common Patterns
328
+
329
+ ### Pattern 1: Self-Targeting
330
+ Element triggers effect on itself.
331
+
332
+ ```typescript
333
+ {
334
+ key: 'button',
335
+ trigger: 'hover',
336
+ effects: [{
337
+ key: 'button', // Same key = self-targeting
338
+ namedEffect: { type: 'Scale' },
339
+ duration: 200
340
+ }]
341
+ }
342
+ ```
343
+
344
+ ### Pattern 2: Cross-Element Targeting
345
+ One element triggers effect on another.
346
+
347
+ ```typescript
348
+ {
349
+ key: 'menu-button',
350
+ trigger: 'click',
351
+ effects: [{
352
+ key: 'sidebar', // Different key = cross-targeting
353
+ namedEffect: { type: 'SlideIn' },
354
+ duration: 300
355
+ }]
356
+ }
357
+ ```
358
+
359
+ ### Pattern 3: Multiple Targets
360
+ One trigger affects multiple elements.
361
+
362
+ ```typescript
363
+ {
364
+ key: 'master',
365
+ trigger: 'click',
366
+ effects: [
367
+ { key: 'element-1', /* ... */ },
368
+ { key: 'element-2', /* ... */ },
369
+ { key: 'element-3', /* ... */ }
370
+ ]
371
+ }
372
+ ```
373
+
374
+ ### Pattern 4: Specific Within Generic
375
+ Use selector to target specific elements.
376
+
377
+ ```typescript
378
+ {
379
+ key: 'card',
380
+ selector: '.card',
381
+ trigger: 'hover',
382
+ effects: [
383
+ { key: 'card', selector: '.card-image', /* zoom */ },
384
+ { key: 'card', selector: '.card-title', /* color change */ },
385
+ { key: 'card', selector: '.card-button', /* reveal */ }
386
+ ]
387
+ }
388
+ ```
389
+
390
+ ### Pattern 5: List with Specific Targets
391
+ Combine listContainer with selector for complex lists.
392
+
393
+ ```typescript
394
+ {
395
+ key: 'products',
396
+ listContainer: '.products',
397
+ selector: '.product-card',
398
+ trigger: 'hover',
399
+ effects: [{
400
+ key: 'products',
401
+ listContainer: '.products',
402
+ selector: '.product-image', // Specific target in each item
403
+ keyframeEffect: {
404
+ name: 'zoom',
405
+ keyframes: [
406
+ { transform: 'scale(1)' },
407
+ { transform: 'scale(1.1)' }
408
+ ]
409
+ },
410
+ duration: 300
411
+ }]
412
+ }
413
+ ```
414
+
415
+ ## Troubleshooting
416
+
417
+ ### Problem: Effect Not Applying
418
+
419
+ **Check 1: Verify Selector Matches**
420
+ ```javascript
421
+ const element = document.querySelector('[data-interact-key="my-key"]');
422
+ const target = element.querySelector('.my-selector');
423
+ console.log('Target found:', !!target);
424
+ ```
425
+
426
+ **Check 2: Inspect Element Structure**
427
+ ```javascript
428
+ function debugSelection(key, selector) {
429
+ const element = Interact.getElement(key);
430
+ console.log({
431
+ element,
432
+ firstChild: element?.firstElementChild,
433
+ selectorMatch: element?.querySelector(selector)
434
+ });
435
+ }
436
+
437
+ debugSelection('my-key', '.my-selector');
438
+ ```
439
+
440
+ ### Problem: Wrong Element Selected
441
+
442
+ **Symptom:** Effect applies to unexpected element
443
+
444
+ **Solution:** Be specific with selectors
445
+
446
+ ```typescript
447
+ // ❌ Too generic
448
+ selector: '.item'
449
+
450
+ // ✅ More specific
451
+ selector: '.product-grid > .item'
452
+ ```
453
+
454
+ ### Problem: listContainer Not Working
455
+
456
+ **Check Container Exists:**
457
+ ```javascript
458
+ const element = document.querySelector('[data-interact-key="my-list"]');
459
+ const container = element?.querySelector('.list-container');
460
+ console.log({
461
+ containerExists: !!container,
462
+ childCount: container?.children.length
463
+ });
464
+ ```
465
+
466
+ **Verify Configuration:**
467
+ ```typescript
468
+ // Both interaction and effect need listContainer
469
+ {
470
+ key: 'list',
471
+ listContainer: '.items', // On interaction
472
+ trigger: 'hover',
473
+ effects: [{
474
+ key: 'list',
475
+ listContainer: '.items', // ALSO on effect
476
+ duration: 300
477
+ }]
478
+ }
479
+ ```
480
+
481
+ ## Best Practices
482
+
483
+ ### 1. Use Descriptive Selectors
484
+ ```typescript
485
+ // ✅ Good: Clear intent
486
+ selector: '.product-card .primary-image'
487
+
488
+ // ❌ Avoid: Ambiguous
489
+ selector: '.image'
490
+ ```
491
+
492
+ ### 2. Keep Selectors Specific but Flexible
493
+ ```typescript
494
+ // ✅ Good: Works with structure changes
495
+ selector: '.card-image img'
496
+
497
+ // ❌ Avoid: Too rigid
498
+ selector: 'div > div.card > div.image > img:first-child'
499
+ ```
500
+
501
+ ### 3. Use listContainer for Repeating Elements
502
+ ```typescript
503
+ // ✅ Good: Scales automatically
504
+ {
505
+ listContainer: '.products',
506
+ trigger: 'hover'
507
+ }
508
+
509
+ // ❌ Avoid: Manual management
510
+ {
511
+ key: 'product-1',
512
+ trigger: 'hover'
513
+ },
514
+ {
515
+ key: 'product-2',
516
+ trigger: 'hover'
517
+ }
518
+ // ... repeating for every item
519
+ ```
520
+
521
+ ### 4. Document Complex Selections
522
+ ```typescript
523
+ {
524
+ key: 'gallery',
525
+ // Select all images within gallery items
526
+ // Structure: grid > item > image-wrapper > img
527
+ listContainer: '.gallery-grid',
528
+ selector: '.gallery-item .image-wrapper img',
529
+ trigger: 'hover',
530
+ effects: [/* ... */]
531
+ }
532
+ ```
533
+
534
+ ## Visual Reference
535
+
536
+ ### Simple Selection (No Selectors)
537
+ ```
538
+ <interact-element>
539
+ <div> ← Selected (first child)
540
+ <span>Not considered</span>
541
+ </div>
542
+ </interact-element>
543
+ ```
544
+
545
+ ### With Selector
546
+ ```
547
+ <interact-element>
548
+ <div>
549
+ <span class="target"> ← Selected (matches selector)
550
+ <span class="other">Not selected</span>
551
+ </div>
552
+ </interact-element>
553
+ ```
554
+
555
+ ### With listContainer
556
+ ```
557
+ <interact-element>
558
+ <div class="container"> ← Container found
559
+ <div> ← Selected (child 1)
560
+ <div> ← Selected (child 2)
561
+ <div> ← Selected (child 3)
562
+ </div>
563
+ </interact-element>
564
+ ```
565
+
566
+ ### With listContainer + selector
567
+ ```
568
+ <interact-element>
569
+ <div class="container"> ← Container found
570
+ <div>
571
+ <img> ← Selected (matches selector in child 1)
572
+ </div>
573
+ <div>
574
+ <img> ← Selected (matches selector in child 2)
575
+ </div>
576
+ </div>
577
+ </interact-element>
578
+ ```
579
+
580
+ ## Quick Decision Guide
581
+
582
+ **Use First Child when:**
583
+ - Single element per interaction
584
+ - Simple structure
585
+ - Element is direct child
586
+
587
+ **Use selector when:**
588
+ - Need specific element within structure
589
+ - Multiple potential targets
590
+ - Element is nested
591
+
592
+ **Use listContainer when:**
593
+ - Repeating elements (lists, grids)
594
+ - Dynamic content (items added/removed)
595
+ - Same interaction for multiple items
596
+
597
+ **Use listContainer + selector when:**
598
+ - Repeating complex structures
599
+ - Need specific element in each item
600
+ - Need to filter items
601
+ - Galleries, product grids, card lists
602
+
603
+ ## See Also
604
+
605
+ - [Configuration Structure](../guides/configuration-structure.md) - Organizing interactions
606
+ - [Lists and Dynamic Content](../guides/lists-and-dynamic-content.md) - Working with lists
607
+ - [API Reference](./README.md) - Complete API documentation