@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,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
|