@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,977 @@
1
+ # Click Interactions
2
+
3
+ Click interactions provide immediate feedback and trigger actions. This guide covers patterns using the `click` trigger.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Button Feedback](#button-feedback)
8
+ - [Toggle States](#toggle-states)
9
+ - [Progressive Disclosure](#progressive-disclosure)
10
+ - [Action Confirmations](#action-confirmations)
11
+ - [Modal & Dialog Triggers](#modal--dialog-triggers)
12
+ - [Menu Interactions](#menu-interactions)
13
+ - [Real-World Examples](#real-world-examples)
14
+
15
+ ## Button Feedback
16
+
17
+ ### Simple Click Pulse
18
+
19
+ Button pulses when clicked.
20
+
21
+ ```typescript
22
+ import { Interact } from '@wix/interact';
23
+
24
+ const config = {
25
+ interactions: [{
26
+ key: 'pulse-button',
27
+ trigger: 'click',
28
+ effects: [{
29
+ key: 'pulse-button',
30
+ keyframeEffect: {
31
+ name: 'pulse',
32
+ keyframes: [
33
+ { transform: 'scale(1)' },
34
+ { transform: 'scale(0.95)' },
35
+ { transform: 'scale(1)' }
36
+ ]
37
+ },
38
+ duration: 200,
39
+ easing: 'ease-in-out'
40
+ }]
41
+ }]
42
+ };
43
+
44
+ Interact.create(config);
45
+ ```
46
+
47
+ ```html
48
+ <interact-element data-interact-key="pulse-button">
49
+ <button>Click Me</button>
50
+ </interact-element>
51
+ ```
52
+
53
+ ### Ripple Effect
54
+
55
+ Material design-style ripple on click.
56
+
57
+ ```typescript
58
+ {
59
+ key: 'ripple-button',
60
+ trigger: 'click',
61
+ effects: [{
62
+ key: 'ripple-button',
63
+ selector: '.ripple-overlay',
64
+ keyframeEffect: {
65
+ name: 'ripple',
66
+ keyframes: [
67
+ {
68
+ transform: 'scale(0)',
69
+ opacity: '0.5'
70
+ },
71
+ {
72
+ transform: 'scale(2)',
73
+ opacity: '0'
74
+ }
75
+ ]
76
+ },
77
+ duration: 600,
78
+ easing: 'ease-out'
79
+ }]
80
+ }
81
+ ```
82
+
83
+ ```html
84
+ <interact-element data-interact-key="ripple-button">
85
+ <button class="ripple-btn">
86
+ <span class="btn-text">Click Me</span>
87
+ <span class="ripple-overlay"></span>
88
+ </button>
89
+ </interact-element>
90
+ ```
91
+
92
+ ```css
93
+ .ripple-btn {
94
+ position: relative;
95
+ overflow: hidden;
96
+ }
97
+
98
+ .ripple-overlay {
99
+ position: absolute;
100
+ width: 100%;
101
+ height: 100%;
102
+ top: 0;
103
+ left: 0;
104
+ border-radius: 50%;
105
+ background: rgb(255 255 255 / 0.5);
106
+ pointer-events: none;
107
+ }
108
+ ```
109
+
110
+ ### Color Flash
111
+
112
+ Button flashes color on click.
113
+
114
+ ```typescript
115
+ {
116
+ key: 'flash-button',
117
+ trigger: 'click',
118
+ effects: [{
119
+ key: 'flash-button',
120
+ keyframeEffect: {
121
+ name: 'color-flash',
122
+ keyframes: [
123
+ { backgroundColor: '#3b82f6' },
124
+ { backgroundColor: '#10b981' },
125
+ { backgroundColor: '#3b82f6' }
126
+ ]
127
+ },
128
+ duration: 400,
129
+ easing: 'ease-in-out'
130
+ }]
131
+ }
132
+ ```
133
+
134
+ ### Shake on Error
135
+
136
+ Button shakes when action fails.
137
+
138
+ ```typescript
139
+ {
140
+ key: 'shake-button',
141
+ trigger: 'click',
142
+ effects: [{
143
+ key: 'shake-button',
144
+ keyframeEffect: {
145
+ name: 'shake',
146
+ keyframes: [
147
+ { transform: 'translateX(0)' },
148
+ { transform: 'translateX(-10px)' },
149
+ { transform: 'translateX(10px)' },
150
+ { transform: 'translateX(-10px)' },
151
+ { transform: 'translateX(10px)' },
152
+ { transform: 'translateX(0)' }
153
+ ]
154
+ },
155
+ duration: 400,
156
+ easing: 'ease-in-out'
157
+ }]
158
+ }
159
+ ```
160
+
161
+ ## Toggle States
162
+
163
+ ### Simple Toggle
164
+
165
+ Toggle between two states.
166
+
167
+ ```typescript
168
+ {
169
+ key: 'toggle-switch',
170
+ trigger: 'click',
171
+ params: { method: 'toggle' },
172
+ effects: [{
173
+ key: 'toggle-switch',
174
+ transition: {
175
+ duration: 300,
176
+ easing: 'ease-in-out',
177
+ styleProperties: [
178
+ { name: 'backgroundColor', value: '#10b981' },
179
+ { name: 'transform', value: 'translateX(20px)' }
180
+ ]
181
+ },
182
+ effectId: 'toggle-on'
183
+ }]
184
+ }
185
+ ```
186
+
187
+ ```html
188
+ <interact-element data-interact-key="toggle-switch">
189
+ <div class="toggle-container">
190
+ <div class="toggle-knob"></div>
191
+ </div>
192
+ </interact-element>
193
+ ```
194
+
195
+ ```css
196
+ .toggle-container {
197
+ width: 48px;
198
+ height: 24px;
199
+ background: #d1d5db;
200
+ border-radius: 12px;
201
+ position: relative;
202
+ cursor: pointer;
203
+ transition: background-color 0.3s;
204
+ }
205
+
206
+ .toggle-knob {
207
+ width: 20px;
208
+ height: 20px;
209
+ background: white;
210
+ border-radius: 50%;
211
+ position: absolute;
212
+ top: 2px;
213
+ left: 2px;
214
+ transition: transform 0.3s;
215
+ }
216
+
217
+ interact-element:state(toggle-on) .toggle-container {
218
+ background: #10b981;
219
+ }
220
+ ```
221
+
222
+ ### Checkbox Animation
223
+
224
+ Custom checkbox with animation.
225
+
226
+ ```typescript
227
+ {
228
+ key: 'checkbox',
229
+ trigger: 'click',
230
+ params: { method: 'toggle' },
231
+ effects: [{
232
+ key: 'checkbox',
233
+ selector: '.checkmark',
234
+ keyframeEffect: {
235
+ name: 'check-draw',
236
+ keyframes: [
237
+ { transform: 'scale(0) rotate(45deg)', opacity: '0' },
238
+ { transform: 'scale(1) rotate(45deg)', opacity: '1' }
239
+ ]
240
+ },
241
+ duration: 300,
242
+ easing: 'cubic-bezier(0.34, 1.56, 0.64, 1)',
243
+ effectId: 'checked'
244
+ }]
245
+ }
246
+ ```
247
+
248
+ ```html
249
+ <interact-element data-interact-key="checkbox">
250
+ <label class="checkbox-label">
251
+ <input type="checkbox" hidden />
252
+ <div class="checkbox-box">
253
+ <svg class="checkmark" viewBox="0 0 24 24">
254
+ <path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/>
255
+ </svg>
256
+ </div>
257
+ <span>Accept terms</span>
258
+ </label>
259
+ </interact-element>
260
+ ```
261
+
262
+ ### Like Button
263
+
264
+ Heart animation for like button.
265
+
266
+ ```typescript
267
+ {
268
+ key: 'like-button',
269
+ trigger: 'click',
270
+ params: { method: 'toggle' },
271
+ effects: [{
272
+ key: 'like-button',
273
+ selector: '.heart-icon',
274
+ keyframeEffect: {
275
+ name: 'heart-beat',
276
+ keyframes: [
277
+ { transform: 'scale(1)', fill: '#9ca3af' },
278
+ { transform: 'scale(1.3)', fill: '#ef4444' },
279
+ { transform: 'scale(1)', fill: '#ef4444' }
280
+ ]
281
+ },
282
+ duration: 400,
283
+ easing: 'ease-out',
284
+ effectId: 'liked'
285
+ }]
286
+ }
287
+ ```
288
+
289
+ ## Progressive Disclosure
290
+
291
+ ### Expand/Collapse Content
292
+
293
+ Click to reveal hidden content.
294
+
295
+ ```typescript
296
+ {
297
+ key: 'accordion-trigger',
298
+ selector: '.accordion-header',
299
+ trigger: 'click',
300
+ params: { method: 'toggle' },
301
+ effects: [{
302
+ key: 'accordion-trigger',
303
+ selector: '.accordion-content',
304
+ keyframeEffect: {
305
+ name: 'expand',
306
+ keyframes: [
307
+ {
308
+ maxHeight: '0',
309
+ opacity: '0',
310
+ transform: 'translateY(-10px)'
311
+ },
312
+ {
313
+ maxHeight: '500px',
314
+ opacity: '1',
315
+ transform: 'translateY(0)'
316
+ }
317
+ ]
318
+ },
319
+ duration: 400,
320
+ easing: 'ease-out',
321
+ effectId: 'expanded'
322
+ }]
323
+ }
324
+ ```
325
+
326
+ ```html
327
+ <interact-element data-interact-key="accordion-trigger">
328
+ <div class="accordion">
329
+ <div class="accordion-header">
330
+ <h3>Click to expand</h3>
331
+ <span class="icon">▼</span>
332
+ </div>
333
+ <div class="accordion-content">
334
+ <p>This content is revealed when clicked</p>
335
+ </div>
336
+ </div>
337
+ </interact-element>
338
+ ```
339
+
340
+ ### Read More Button
341
+
342
+ Expand text content on click.
343
+
344
+ ```typescript
345
+ {
346
+ key: 'read-more',
347
+ selector: '.read-more-btn',
348
+ trigger: 'click',
349
+ params: { method: 'toggle' },
350
+ effects: [
351
+ // Expand content
352
+ {
353
+ key: 'read-more',
354
+ selector: '.hidden-content',
355
+ keyframeEffect: {
356
+ name: 'reveal-text',
357
+ keyframes: [
358
+ { maxHeight: '0', opacity: '0' },
359
+ { maxHeight: '300px', opacity: '1' }
360
+ ]
361
+ },
362
+ duration: 500,
363
+ easing: 'ease-out',
364
+ effectId: 'revealed'
365
+ },
366
+ // Change button text via CSS
367
+ {
368
+ key: 'read-more',
369
+ selector: '.read-more-btn',
370
+ transition: {
371
+ duration: 300,
372
+ styleProperties: [
373
+ { name: 'transform', value: 'rotate(180deg)' }
374
+ ]
375
+ }
376
+ }
377
+ ]
378
+ }
379
+ ```
380
+
381
+ ### Tab Switching
382
+
383
+ Switch between tabs on click.
384
+
385
+ ```typescript
386
+ const tabsConfig = {
387
+ interactions: [
388
+ {
389
+ key: 'tab-1',
390
+ selector: '.tab-button',
391
+ trigger: 'click',
392
+ effects: [
393
+ {
394
+ key: 'tab-content-1',
395
+ keyframeEffect: {
396
+ name: 'tab-fade-in',
397
+ keyframes: [
398
+ { opacity: '0', transform: 'translateY(10px)' },
399
+ { opacity: '1', transform: 'translateY(0)' }
400
+ ]
401
+ },
402
+ duration: 300,
403
+ easing: 'ease-out'
404
+ }
405
+ ]
406
+ },
407
+ {
408
+ key: 'tab-2',
409
+ selector: '.tab-button',
410
+ trigger: 'click',
411
+ effects: [
412
+ {
413
+ key: 'tab-content-2',
414
+ keyframeEffect: {
415
+ name: 'tab-fade-in',
416
+ keyframes: [
417
+ { opacity: '0', transform: 'translateY(10px)' },
418
+ { opacity: '1', transform: 'translateY(0)' }
419
+ ]
420
+ },
421
+ duration: 300,
422
+ easing: 'ease-out'
423
+ }
424
+ ]
425
+ }
426
+ ]
427
+ };
428
+ ```
429
+
430
+ ## Action Confirmations
431
+
432
+ ### Success Animation
433
+
434
+ Show success state after action.
435
+
436
+ ```typescript
437
+ {
438
+ key: 'submit-btn',
439
+ trigger: 'click',
440
+ effects: [
441
+ // Button color change
442
+ {
443
+ key: 'submit-btn',
444
+ keyframeEffect: {
445
+ name: 'success-flash',
446
+ keyframes: [
447
+ { backgroundColor: '#3b82f6' },
448
+ { backgroundColor: '#10b981' }
449
+ ]
450
+ },
451
+ duration: 400,
452
+ easing: 'ease-out',
453
+ effectId: 'submitted'
454
+ },
455
+ // Show checkmark
456
+ {
457
+ key: 'submit-btn',
458
+ selector: '.checkmark-icon',
459
+ keyframeEffect: {
460
+ name: 'checkmark-appear',
461
+ keyframes: [
462
+ { opacity: '0', transform: 'scale(0)' },
463
+ { opacity: '1', transform: 'scale(1)' }
464
+ ]
465
+ },
466
+ duration: 300,
467
+ delay: 200,
468
+ easing: 'cubic-bezier(0.34, 1.56, 0.64, 1)'
469
+ }
470
+ ]
471
+ }
472
+ ```
473
+
474
+ ### Loading State
475
+
476
+ Show loading spinner on click.
477
+
478
+ ```typescript
479
+ {
480
+ key: 'async-button',
481
+ trigger: 'click',
482
+ effects: [
483
+ // Disable button appearance
484
+ {
485
+ key: 'async-button',
486
+ transition: {
487
+ duration: 200,
488
+ styleProperties: [
489
+ { name: 'opacity', value: '0.6' },
490
+ { name: 'cursor', value: 'wait' }
491
+ ]
492
+ },
493
+ effectId: 'loading'
494
+ },
495
+ // Show spinner
496
+ {
497
+ key: 'async-button',
498
+ selector: '.spinner',
499
+ keyframeEffect: {
500
+ name: 'spinner-appear',
501
+ keyframes: [
502
+ { opacity: '0', transform: 'scale(0)' },
503
+ { opacity: '1', transform: 'scale(1)' }
504
+ ]
505
+ },
506
+ duration: 300,
507
+ easing: 'ease-out'
508
+ }
509
+ ]
510
+ }
511
+ ```
512
+
513
+ ```css
514
+ .spinner {
515
+ display: inline-block;
516
+ width: 16px;
517
+ height: 16px;
518
+ border: 2px solid rgba(255,255,255,0.3);
519
+ border-top-color: white;
520
+ border-radius: 50%;
521
+ animation: spin 1s linear infinite;
522
+ }
523
+
524
+ @keyframes spin {
525
+ to { transform: rotate(360deg); }
526
+ }
527
+ ```
528
+
529
+ ### Copy to Clipboard Feedback
530
+
531
+ Visual feedback when copying text.
532
+
533
+ ```typescript
534
+ {
535
+ key: 'copy-button',
536
+ trigger: 'click',
537
+ effects: [
538
+ {
539
+ key: 'copy-button',
540
+ selector: '.copy-icon',
541
+ keyframeEffect: {
542
+ name: 'copy-bounce',
543
+ keyframes: [
544
+ { transform: 'scale(1)' },
545
+ { transform: 'scale(1.2)' },
546
+ { transform: 'scale(1)' }
547
+ ]
548
+ },
549
+ duration: 300,
550
+ easing: 'ease-out'
551
+ },
552
+ {
553
+ key: 'copy-feedback',
554
+ keyframeEffect: {
555
+ name: 'feedback-appear',
556
+ keyframes: [
557
+ { opacity: '0', transform: 'translateY(10px)' },
558
+ { opacity: '1', transform: 'translateY(0)' }
559
+ ]
560
+ },
561
+ duration: 200,
562
+ easing: 'ease-out',
563
+ effectId: 'copied'
564
+ }
565
+ ]
566
+ }
567
+ ```
568
+
569
+ ## Modal & Dialog Triggers
570
+
571
+ ### Open Modal
572
+
573
+ Click button to show modal with animation.
574
+
575
+ ```typescript
576
+ {
577
+ key: 'open-modal-btn',
578
+ trigger: 'click',
579
+ effects: [
580
+ // Show overlay
581
+ {
582
+ key: 'modal-overlay',
583
+ keyframeEffect: {
584
+ name: 'overlay-fade',
585
+ keyframes: [
586
+ { opacity: '0' },
587
+ { opacity: '1' }
588
+ ]
589
+ },
590
+ duration: 300,
591
+ easing: 'ease-out'
592
+ },
593
+ // Show modal
594
+ {
595
+ key: 'modal-dialog',
596
+ keyframeEffect: {
597
+ name: 'modal-scale',
598
+ keyframes: [
599
+ {
600
+ opacity: '0',
601
+ transform: 'scale(0.9) translateY(-20px)'
602
+ },
603
+ {
604
+ opacity: '1',
605
+ transform: 'scale(1) translateY(0)'
606
+ }
607
+ ]
608
+ },
609
+ duration: 400,
610
+ delay: 100,
611
+ easing: 'cubic-bezier(0.16, 1, 0.3, 1)'
612
+ }
613
+ ]
614
+ }
615
+ ```
616
+
617
+ ### Close Modal
618
+
619
+ Click to close with exit animation.
620
+
621
+ ```typescript
622
+ {
623
+ key: 'close-modal-btn',
624
+ trigger: 'click',
625
+ effects: [
626
+ // Hide modal
627
+ {
628
+ key: 'modal-dialog',
629
+ keyframeEffect: {
630
+ name: 'modal-exit',
631
+ keyframes: [
632
+ {
633
+ opacity: '1',
634
+ transform: 'scale(1)'
635
+ },
636
+ {
637
+ opacity: '0',
638
+ transform: 'scale(0.9)'
639
+ }
640
+ ]
641
+ },
642
+ duration: 300,
643
+ easing: 'ease-in'
644
+ },
645
+ // Hide overlay
646
+ {
647
+ key: 'modal-overlay',
648
+ keyframeEffect: {
649
+ name: 'overlay-exit',
650
+ keyframes: [
651
+ { opacity: '1' },
652
+ { opacity: '0' }
653
+ ]
654
+ },
655
+ duration: 300,
656
+ delay: 100,
657
+ easing: 'ease-in'
658
+ }
659
+ ]
660
+ }
661
+ ```
662
+
663
+ ### Notification Toast
664
+
665
+ Show temporary notification on action.
666
+
667
+ ```typescript
668
+ {
669
+ key: 'show-toast-btn',
670
+ trigger: 'click',
671
+ effects: [{
672
+ key: 'toast-notification',
673
+ keyframeEffect: {
674
+ name: 'toast-slide-in',
675
+ keyframes: [
676
+ {
677
+ opacity: '0',
678
+ transform: 'translateY(100%) scale(0.9)'
679
+ },
680
+ {
681
+ opacity: '1',
682
+ transform: 'translateY(0) scale(1)'
683
+ }
684
+ ]
685
+ },
686
+ duration: 400,
687
+ easing: 'cubic-bezier(0.16, 1, 0.3, 1)'
688
+ }]
689
+ }
690
+ ```
691
+
692
+ ## Menu Interactions
693
+
694
+ ### Mobile Menu Toggle
695
+
696
+ Toggle mobile navigation menu.
697
+
698
+ ```typescript
699
+ {
700
+ key: 'menu-toggle',
701
+ trigger: 'click',
702
+ params: { method: 'toggle' },
703
+ effects: [
704
+ // Hamburger icon animation
705
+ {
706
+ key: 'menu-toggle',
707
+ selector: '.menu-icon',
708
+ keyframeEffect: {
709
+ name: 'icon-transform',
710
+ keyframes: [
711
+ { transform: 'rotate(0deg)' },
712
+ { transform: 'rotate(90deg)' }
713
+ ]
714
+ },
715
+ duration: 300,
716
+ easing: 'ease-out',
717
+ effectId: 'menu-open'
718
+ },
719
+ // Menu slide in
720
+ {
721
+ key: 'mobile-menu',
722
+ keyframeEffect: {
723
+ name: 'menu-slide',
724
+ keyframes: [
725
+ { transform: 'translateX(-100%)' },
726
+ { transform: 'translateX(0)' }
727
+ ]
728
+ },
729
+ duration: 400,
730
+ easing: 'cubic-bezier(0.16, 1, 0.3, 1)'
731
+ },
732
+ // Overlay fade
733
+ {
734
+ key: 'menu-overlay',
735
+ keyframeEffect: {
736
+ name: 'overlay-fade',
737
+ keyframes: [
738
+ { opacity: '0' },
739
+ { opacity: '0.5' }
740
+ ]
741
+ },
742
+ duration: 400,
743
+ easing: 'ease-out'
744
+ }
745
+ ]
746
+ }
747
+ ```
748
+
749
+ ### Dropdown Menu
750
+
751
+ Click to toggle dropdown.
752
+
753
+ ```typescript
754
+ {
755
+ key: 'dropdown-trigger',
756
+ trigger: 'click',
757
+ params: { method: 'toggle' },
758
+ effects: [
759
+ {
760
+ key: 'dropdown-trigger',
761
+ selector: '.dropdown-menu',
762
+ keyframeEffect: {
763
+ name: 'dropdown-appear',
764
+ keyframes: [
765
+ {
766
+ opacity: '0',
767
+ transform: 'translateY(-10px) scale(0.95)'
768
+ },
769
+ {
770
+ opacity: '1',
771
+ transform: 'translateY(0) scale(1)'
772
+ }
773
+ ]
774
+ },
775
+ duration: 200,
776
+ easing: 'ease-out',
777
+ effectId: 'dropdown-open'
778
+ },
779
+ {
780
+ key: 'dropdown-trigger',
781
+ selector: '.arrow-icon',
782
+ keyframeEffect: {
783
+ name: 'arrow-rotate',
784
+ keyframes: [
785
+ { transform: 'rotate(0deg)' },
786
+ { transform: 'rotate(180deg)' }
787
+ ]
788
+ },
789
+ duration: 200,
790
+ easing: 'ease-out'
791
+ }
792
+ ]
793
+ }
794
+ ```
795
+
796
+ ## Real-World Examples
797
+
798
+ ### Add to Cart Button
799
+
800
+ Complete add-to-cart interaction.
801
+
802
+ ```typescript
803
+ const addToCartConfig = {
804
+ interactions: [{
805
+ key: 'add-to-cart',
806
+ trigger: 'click',
807
+ effects: [
808
+ // Button scale feedback
809
+ {
810
+ key: 'add-to-cart',
811
+ keyframeEffect: {
812
+ name: 'button-press',
813
+ keyframes: [
814
+ { transform: 'scale(1)' },
815
+ { transform: 'scale(0.95)' },
816
+ { transform: 'scale(1)' }
817
+ ]
818
+ },
819
+ duration: 200,
820
+ easing: 'ease-out'
821
+ },
822
+ // Change button color
823
+ {
824
+ key: 'add-to-cart',
825
+ keyframeEffect: {
826
+ name: 'success-color',
827
+ keyframes: [
828
+ { backgroundColor: '#3b82f6' },
829
+ { backgroundColor: '#10b981' }
830
+ ]
831
+ },
832
+ duration: 300,
833
+ delay: 200,
834
+ easing: 'ease-out',
835
+ effectId: 'added'
836
+ },
837
+ // Show cart badge update
838
+ {
839
+ key: 'cart-badge',
840
+ keyframeEffect: {
841
+ name: 'badge-pop',
842
+ keyframes: [
843
+ { transform: 'scale(1)' },
844
+ { transform: 'scale(1.5)' },
845
+ { transform: 'scale(1)' }
846
+ ]
847
+ },
848
+ duration: 400,
849
+ delay: 300,
850
+ easing: 'cubic-bezier(0.34, 1.56, 0.64, 1)'
851
+ },
852
+ // Show success message
853
+ {
854
+ key: 'success-toast',
855
+ keyframeEffect: {
856
+ name: 'toast-appear',
857
+ keyframes: [
858
+ { opacity: '0', transform: 'translateY(20px)' },
859
+ { opacity: '1', transform: 'translateY(0)' }
860
+ ]
861
+ },
862
+ duration: 300,
863
+ delay: 400,
864
+ easing: 'ease-out'
865
+ }
866
+ ]
867
+ }]
868
+ };
869
+ ```
870
+
871
+ ```html
872
+ <interact-element data-interact-key="add-to-cart">
873
+ <button class="add-to-cart-btn">
874
+ Add to Cart
875
+ </button>
876
+ </interact-element>
877
+
878
+ <interact-element data-interact-key="cart-badge">
879
+ <div class="cart-icon">
880
+ <span class="badge">2</span>
881
+ </div>
882
+ </interact-element>
883
+
884
+ <interact-element data-interact-key="success-toast">
885
+ <div class="toast">Item added to cart!</div>
886
+ </interact-element>
887
+ ```
888
+
889
+ ### Contact Form Submit
890
+
891
+ Form submission with validation feedback.
892
+
893
+ ```typescript
894
+ const formConfig = {
895
+ interactions: [{
896
+ key: 'submit-form',
897
+ trigger: 'click',
898
+ effects: [
899
+ // Disable button
900
+ {
901
+ key: 'submit-form',
902
+ transition: {
903
+ duration: 200,
904
+ styleProperties: [
905
+ { name: 'opacity', value: '0.6' },
906
+ { name: 'cursor', value: 'not-allowed' }
907
+ ]
908
+ },
909
+ effectId: 'submitting'
910
+ },
911
+ // Show loading spinner
912
+ {
913
+ key: 'submit-form',
914
+ selector: '.spinner',
915
+ keyframeEffect: {
916
+ name: 'spinner-show',
917
+ keyframes: [
918
+ { opacity: '0', transform: 'scale(0)' },
919
+ { opacity: '1', transform: 'scale(1)' }
920
+ ]
921
+ },
922
+ duration: 200,
923
+ easing: 'ease-out'
924
+ },
925
+ // Success message (after delay)
926
+ {
927
+ key: 'form-message',
928
+ keyframeEffect: {
929
+ name: 'message-appear',
930
+ keyframes: [
931
+ {
932
+ opacity: '0',
933
+ transform: 'translateY(-10px) scale(0.95)'
934
+ },
935
+ {
936
+ opacity: '1',
937
+ transform: 'translateY(0) scale(1)'
938
+ }
939
+ ]
940
+ },
941
+ duration: 400,
942
+ delay: 1000, // Wait for form processing
943
+ easing: 'cubic-bezier(0.16, 1, 0.3, 1)'
944
+ }
945
+ ]
946
+ }]
947
+ };
948
+ ```
949
+
950
+ ## Best Practices
951
+
952
+ ### Click Feedback Timing
953
+
954
+ - **Immediate feedback**: 0-100ms (button press)
955
+ - **Action completion**: 300-500ms (toggle, modal)
956
+ - **Network actions**: Show loading state immediately
957
+
958
+ ### User Experience Tips
959
+
960
+ ✅ **Do:**
961
+ - Provide immediate visual feedback
962
+ - Use appropriate timing for action type
963
+ - Show loading states for async actions
964
+ - Provide success/error feedback
965
+ - Make interactive elements obvious (cursor, hover states)
966
+
967
+ ❌ **Avoid:**
968
+ - Delayed click responses (feels laggy)
969
+ - Animations that block user actions
970
+ - Multiple rapid clicks without debouncing
971
+ - Unclear state changes
972
+
973
+ ## See Also
974
+
975
+ - [Hover Effects](./hover-effects.md) - Mouse interaction patterns
976
+ - [State Management](../guides/state-management.md) - Managing toggle states
977
+ - [Understanding Triggers](../guides/understanding-triggers.md) - Click trigger details