@caddis/cli 0.0.0 → 0.1.0

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 (153) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +150 -1
  3. package/bundles/antigravity-plugin/agents/code-reviewer.md +47 -0
  4. package/bundles/antigravity-plugin/agents/preflight.md +53 -0
  5. package/bundles/antigravity-plugin/guard_agy.py +338 -0
  6. package/bundles/antigravity-plugin/hooks.json +36 -0
  7. package/bundles/antigravity-plugin/mcp_config.json +8 -0
  8. package/bundles/antigravity-plugin/mcp_ping_server.py +55 -0
  9. package/bundles/antigravity-plugin/plugin.json +5 -0
  10. package/bundles/antigravity-plugin/session_end_agy.py +57 -0
  11. package/bundles/antigravity-plugin/skills/_registry.md +115 -0
  12. package/bundles/antigravity-plugin/skills/add-rules/SKILL.md +45 -0
  13. package/bundles/antigravity-plugin/skills/api-design/SKILL.md +249 -0
  14. package/bundles/antigravity-plugin/skills/backend-development/SKILL.md +305 -0
  15. package/bundles/antigravity-plugin/skills/best-practices/SKILL.md +500 -0
  16. package/bundles/antigravity-plugin/skills/best-practices/agents/best-practices-referencer.md +263 -0
  17. package/bundles/antigravity-plugin/skills/best-practices/agents/codebase-context-builder.md +326 -0
  18. package/bundles/antigravity-plugin/skills/best-practices/agents/task-intent-analyzer.md +245 -0
  19. package/bundles/antigravity-plugin/skills/best-practices/references/anti-patterns.md +571 -0
  20. package/bundles/antigravity-plugin/skills/best-practices/references/before-after-examples.md +1114 -0
  21. package/bundles/antigravity-plugin/skills/best-practices/references/best-practices-guide.md +513 -0
  22. package/bundles/antigravity-plugin/skills/best-practices/references/common-workflows.md +692 -0
  23. package/bundles/antigravity-plugin/skills/best-practices/references/prompt-patterns.md +547 -0
  24. package/bundles/antigravity-plugin/skills/brainstorming/SKILL.md +57 -0
  25. package/bundles/antigravity-plugin/skills/ci-cd-pipeline/SKILL.md +315 -0
  26. package/bundles/antigravity-plugin/skills/code-documentation/SKILL.md +271 -0
  27. package/bundles/antigravity-plugin/skills/code-review/SKILL.md +122 -0
  28. package/bundles/antigravity-plugin/skills/codebase-audit/SKILL.md +204 -0
  29. package/bundles/antigravity-plugin/skills/context-curator/SKILL.md +157 -0
  30. package/bundles/antigravity-plugin/skills/cross-review/SKILL.md +40 -0
  31. package/bundles/antigravity-plugin/skills/css-architecture/SKILL.md +305 -0
  32. package/bundles/antigravity-plugin/skills/css-architecture/references/RESPONSIVE-DESIGN.md +604 -0
  33. package/bundles/antigravity-plugin/skills/database-design/SKILL.md +177 -0
  34. package/bundles/antigravity-plugin/skills/db-diagram/SKILL.md +148 -0
  35. package/bundles/antigravity-plugin/skills/db-diagram/scripts/sql_to_graph.py +1212 -0
  36. package/bundles/antigravity-plugin/skills/digress/SKILL.md +61 -0
  37. package/bundles/antigravity-plugin/skills/draw-io/SKILL.md +162 -0
  38. package/bundles/antigravity-plugin/skills/draw-io/references/aws-icons.md +677 -0
  39. package/bundles/antigravity-plugin/skills/draw-io/references/layout-guidelines.md +142 -0
  40. package/bundles/antigravity-plugin/skills/draw-io/references/troubleshooting.md +118 -0
  41. package/bundles/antigravity-plugin/skills/draw-io/references/workflows.md +103 -0
  42. package/bundles/antigravity-plugin/skills/draw-io/scripts/convert-drawio-to-png.sh +25 -0
  43. package/bundles/antigravity-plugin/skills/draw-io/scripts/find_aws_icon.py +79 -0
  44. package/bundles/antigravity-plugin/skills/error-handling/SKILL.md +260 -0
  45. package/bundles/antigravity-plugin/skills/excalidraw-db/SKILL.md +38 -0
  46. package/bundles/antigravity-plugin/skills/fastapi-dev/SKILL.md +300 -0
  47. package/bundles/antigravity-plugin/skills/feature-plan/SKILL.md +198 -0
  48. package/bundles/antigravity-plugin/skills/frontend-design/SKILL.md +193 -0
  49. package/bundles/antigravity-plugin/skills/frontend-design/references/my-tech-stack.md +127 -0
  50. package/bundles/antigravity-plugin/skills/gh-cli/SKILL.md +195 -0
  51. package/bundles/antigravity-plugin/skills/git-commit/SKILL.md +285 -0
  52. package/bundles/antigravity-plugin/skills/golden-plan/SKILL.md +577 -0
  53. package/bundles/antigravity-plugin/skills/handoff/SKILL.md +100 -0
  54. package/bundles/antigravity-plugin/skills/implement/SKILL.md +114 -0
  55. package/bundles/antigravity-plugin/skills/javascript-typescript/SKILL.md +142 -0
  56. package/bundles/antigravity-plugin/skills/kb/SKILL.md +60 -0
  57. package/bundles/antigravity-plugin/skills/mermaid-db/SKILL.md +33 -0
  58. package/bundles/antigravity-plugin/skills/mermaid-diagrams/SKILL.md +236 -0
  59. package/bundles/antigravity-plugin/skills/mermaid-diagrams/references/ENHANCEMENTS.md +264 -0
  60. package/bundles/antigravity-plugin/skills/mermaid-diagrams/references/MERMAID-SUMMARY.md +137 -0
  61. package/bundles/antigravity-plugin/skills/mermaid-diagrams/references/advanced-features.md +556 -0
  62. package/bundles/antigravity-plugin/skills/mermaid-diagrams/references/architecture-diagrams.md +192 -0
  63. package/bundles/antigravity-plugin/skills/mermaid-diagrams/references/c4-diagrams.md +410 -0
  64. package/bundles/antigravity-plugin/skills/mermaid-diagrams/references/class-diagrams.md +361 -0
  65. package/bundles/antigravity-plugin/skills/mermaid-diagrams/references/erd-diagrams.md +510 -0
  66. package/bundles/antigravity-plugin/skills/mermaid-diagrams/references/flowcharts.md +450 -0
  67. package/bundles/antigravity-plugin/skills/mermaid-diagrams/references/sequence-diagrams.md +394 -0
  68. package/bundles/antigravity-plugin/skills/mermaid-diagrams/references/troubleshooting.md +335 -0
  69. package/bundles/antigravity-plugin/skills/mermaid-diagrams/references/workflows.md +418 -0
  70. package/bundles/antigravity-plugin/skills/migrate-dir/SKILL.md +68 -0
  71. package/bundles/antigravity-plugin/skills/mockup/SKILL.md +242 -0
  72. package/bundles/antigravity-plugin/skills/particle-art/SKILL.md +243 -0
  73. package/bundles/antigravity-plugin/skills/particle-art/references/canvas-utils.ts +171 -0
  74. package/bundles/antigravity-plugin/skills/particle-art/references/dot-field.template.tsx +203 -0
  75. package/bundles/antigravity-plugin/skills/particle-art/references/flow-field.template.tsx +263 -0
  76. package/bundles/antigravity-plugin/skills/particle-art/references/node-shape.template.tsx +261 -0
  77. package/bundles/antigravity-plugin/skills/particle-art/references/shape-sampler.ts +281 -0
  78. package/bundles/antigravity-plugin/skills/particle-art/references/stipple-morph.template.tsx +167 -0
  79. package/bundles/antigravity-plugin/skills/particle-art/references/stipple.template.tsx +175 -0
  80. package/bundles/antigravity-plugin/skills/particle-art/references/trail-ghost.template.tsx +266 -0
  81. package/bundles/antigravity-plugin/skills/particle-art/references/usage-examples.md +320 -0
  82. package/bundles/antigravity-plugin/skills/playwright/API_REFERENCE.md +653 -0
  83. package/bundles/antigravity-plugin/skills/playwright/SKILL.md +454 -0
  84. package/bundles/antigravity-plugin/skills/playwright/lib/helpers.js +441 -0
  85. package/bundles/antigravity-plugin/skills/playwright/package.json +26 -0
  86. package/bundles/antigravity-plugin/skills/playwright/run.js +228 -0
  87. package/bundles/antigravity-plugin/skills/prd/SKILL.md +107 -0
  88. package/bundles/antigravity-plugin/skills/preflight/SKILL.md +435 -0
  89. package/bundles/antigravity-plugin/skills/python/SKILL.md +388 -0
  90. package/bundles/antigravity-plugin/skills/react-best-practices/SKILL.md +269 -0
  91. package/bundles/antigravity-plugin/skills/react-dev/README.md +404 -0
  92. package/bundles/antigravity-plugin/skills/react-dev/SKILL.md +459 -0
  93. package/bundles/antigravity-plugin/skills/react-dev/examples/generic-components.md +579 -0
  94. package/bundles/antigravity-plugin/skills/react-dev/examples/server-components.md +579 -0
  95. package/bundles/antigravity-plugin/skills/react-dev/references/event-handlers.md +574 -0
  96. package/bundles/antigravity-plugin/skills/react-dev/references/hooks.md +456 -0
  97. package/bundles/antigravity-plugin/skills/react-dev/references/react-19-patterns.md +638 -0
  98. package/bundles/antigravity-plugin/skills/react-dev/references/react-router.md +1002 -0
  99. package/bundles/antigravity-plugin/skills/react-dev/references/tanstack-router.md +587 -0
  100. package/bundles/antigravity-plugin/skills/refactoring/SKILL.md +486 -0
  101. package/bundles/antigravity-plugin/skills/resume/SKILL.md +36 -0
  102. package/bundles/antigravity-plugin/skills/security-review/SKILL.md +196 -0
  103. package/bundles/antigravity-plugin/skills/setup-project-ai/SKILL.md +61 -0
  104. package/bundles/antigravity-plugin/skills/ship/SKILL.md +107 -0
  105. package/bundles/antigravity-plugin/skills/ship-merge/SKILL.md +103 -0
  106. package/bundles/antigravity-plugin/skills/ship-pr/SKILL.md +102 -0
  107. package/bundles/antigravity-plugin/skills/skill-creator/LICENSE.txt +202 -0
  108. package/bundles/antigravity-plugin/skills/skill-creator/SKILL.md +491 -0
  109. package/bundles/antigravity-plugin/skills/skill-creator/agents/analyzer.md +274 -0
  110. package/bundles/antigravity-plugin/skills/skill-creator/agents/comparator.md +202 -0
  111. package/bundles/antigravity-plugin/skills/skill-creator/agents/grader.md +223 -0
  112. package/bundles/antigravity-plugin/skills/skill-creator/assets/eval_review.html +146 -0
  113. package/bundles/antigravity-plugin/skills/skill-creator/eval-viewer/generate_review.py +471 -0
  114. package/bundles/antigravity-plugin/skills/skill-creator/eval-viewer/viewer.html +1325 -0
  115. package/bundles/antigravity-plugin/skills/skill-creator/references/schemas.md +430 -0
  116. package/bundles/antigravity-plugin/skills/skill-creator/scripts/__init__.py +0 -0
  117. package/bundles/antigravity-plugin/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  118. package/bundles/antigravity-plugin/skills/skill-creator/scripts/generate_report.py +326 -0
  119. package/bundles/antigravity-plugin/skills/skill-creator/scripts/improve_description.py +247 -0
  120. package/bundles/antigravity-plugin/skills/skill-creator/scripts/package_skill.py +136 -0
  121. package/bundles/antigravity-plugin/skills/skill-creator/scripts/quick_validate.py +103 -0
  122. package/bundles/antigravity-plugin/skills/skill-creator/scripts/run_eval.py +310 -0
  123. package/bundles/antigravity-plugin/skills/skill-creator/scripts/run_loop.py +328 -0
  124. package/bundles/antigravity-plugin/skills/skill-creator/scripts/utils.py +47 -0
  125. package/bundles/antigravity-plugin/skills/sql/SKILL.md +321 -0
  126. package/bundles/antigravity-plugin/skills/tdd/SKILL.md +37 -0
  127. package/bundles/antigravity-plugin/skills/tdd-workflow/SKILL.md +188 -0
  128. package/bundles/antigravity-plugin/skills/technical-writing/SKILL.md +286 -0
  129. package/bundles/antigravity-plugin/skills/test-strategy/SKILL.md +155 -0
  130. package/bundles/antigravity-plugin/skills/ui-brief/SKILL.md +84 -0
  131. package/bundles/antigravity-plugin/skills/ui-review/SKILL.md +176 -0
  132. package/bundles/antigravity-plugin/skills/ui-review/references/framework-fixes.md +471 -0
  133. package/bundles/antigravity-plugin/skills/ui-review/references/visual-checklist.md +236 -0
  134. package/bundles/antigravity-plugin/skills/usage-review/SKILL.md +77 -0
  135. package/bundles/antigravity-plugin/skills/use-model/SKILL.md +64 -0
  136. package/bundles/antigravity-plugin/skills/using-git-worktrees/SKILL.md +217 -0
  137. package/bundles/antigravity-plugin/skills/version/SKILL.md +18 -0
  138. package/bundles/antigravity-plugin/skills/warm-editorial-ui/DESIGN_TOKENS.md +487 -0
  139. package/bundles/antigravity-plugin/skills/warm-editorial-ui/IMPLEMENTATION_GUIDE.md +177 -0
  140. package/bundles/antigravity-plugin/skills/warm-editorial-ui/SKILL.md +732 -0
  141. package/bundles/antigravity-plugin/skills/webapp-testing/LICENSE.txt +202 -0
  142. package/bundles/antigravity-plugin/skills/webapp-testing/SKILL.md +97 -0
  143. package/bundles/antigravity-plugin/skills/webapp-testing/examples/console_logging.py +35 -0
  144. package/bundles/antigravity-plugin/skills/webapp-testing/examples/element_discovery.py +40 -0
  145. package/bundles/antigravity-plugin/skills/webapp-testing/examples/static_html_automation.py +33 -0
  146. package/bundles/antigravity-plugin/skills/webapp-testing/scripts/with_server.py +106 -0
  147. package/bundles/antigravity-plugin/skills/windows-deployment/SKILL.md +880 -0
  148. package/bundles/antigravity-plugin/skills/writing-plans/SKILL.md +384 -0
  149. package/bundles/antigravity-plugin/statusline-command-agy.sh +91 -0
  150. package/bundles/antigravity-plugin/warm_start_agy.py +149 -0
  151. package/bundles/manifest.json +6 -0
  152. package/dist/cli.js +5363 -0
  153. package/package.json +61 -4
@@ -0,0 +1,574 @@
1
+ # Event Handler TypeScript Patterns
2
+
3
+ Proper event typing ensures type-safe access to event properties and target elements.
4
+
5
+ ## Mouse Events
6
+
7
+ ```typescript
8
+ // Click events
9
+ function handleClick(event: React.MouseEvent<HTMLButtonElement>) {
10
+ event.preventDefault();
11
+ event.stopPropagation();
12
+
13
+ // Target element typed correctly
14
+ event.currentTarget.disabled = true;
15
+ event.currentTarget.textContent = 'Clicked';
16
+
17
+ // Mouse position
18
+ console.log(event.clientX, event.clientY);
19
+ console.log(event.pageX, event.pageY);
20
+
21
+ // Mouse buttons
22
+ console.log(event.button); // 0 = left, 1 = middle, 2 = right
23
+ console.log(event.buttons); // Bitmask of pressed buttons
24
+
25
+ // Modifier keys
26
+ if (event.ctrlKey || event.metaKey) {
27
+ console.log('Ctrl/Cmd + Click');
28
+ }
29
+ if (event.shiftKey) {
30
+ console.log('Shift + Click');
31
+ }
32
+ if (event.altKey) {
33
+ console.log('Alt + Click');
34
+ }
35
+ }
36
+
37
+ // Mouse movement
38
+ function handleMouseMove(event: React.MouseEvent<HTMLDivElement>) {
39
+ const rect = event.currentTarget.getBoundingClientRect();
40
+ const x = event.clientX - rect.left;
41
+ const y = event.clientY - rect.top;
42
+ console.log(`Position in element: ${x}, ${y}`);
43
+ }
44
+
45
+ // Hover events
46
+ function handleMouseEnter(event: React.MouseEvent<HTMLDivElement>) {
47
+ event.currentTarget.style.backgroundColor = 'lightblue';
48
+ }
49
+
50
+ function handleMouseLeave(event: React.MouseEvent<HTMLDivElement>) {
51
+ event.currentTarget.style.backgroundColor = '';
52
+ }
53
+
54
+ // Double click
55
+ function handleDoubleClick(event: React.MouseEvent<HTMLElement>) {
56
+ console.log('Double clicked');
57
+ }
58
+ ```
59
+
60
+ ## Form Events
61
+
62
+ ```typescript
63
+ // Form submission
64
+ function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
65
+ event.preventDefault();
66
+
67
+ const form = event.currentTarget;
68
+ const formData = new FormData(form);
69
+
70
+ const data = {
71
+ name: formData.get('name') as string,
72
+ email: formData.get('email') as string,
73
+ };
74
+
75
+ console.log(data);
76
+ }
77
+
78
+ // Input change
79
+ function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
80
+ const target = event.target;
81
+
82
+ // For text inputs
83
+ if (target.type === 'text' || target.type === 'email') {
84
+ console.log(target.value); // string
85
+ }
86
+
87
+ // For checkboxes
88
+ if (target.type === 'checkbox') {
89
+ console.log(target.checked); // boolean
90
+ }
91
+
92
+ // For radio buttons
93
+ if (target.type === 'radio') {
94
+ console.log(target.value, target.checked);
95
+ }
96
+
97
+ // For number inputs
98
+ if (target.type === 'number') {
99
+ console.log(target.valueAsNumber); // number
100
+ }
101
+
102
+ // For file inputs
103
+ if (target.type === 'file') {
104
+ const files = target.files; // FileList | null
105
+ if (files && files.length > 0) {
106
+ console.log(files[0].name);
107
+ }
108
+ }
109
+ }
110
+
111
+ // Textarea change
112
+ function handleTextareaChange(event: React.ChangeEvent<HTMLTextAreaElement>) {
113
+ console.log(event.target.value);
114
+ console.log(event.target.selectionStart); // Cursor position
115
+ }
116
+
117
+ // Select change
118
+ function handleSelectChange(event: React.ChangeEvent<HTMLSelectElement>) {
119
+ const value = event.target.value;
120
+ const selectedIndex = event.target.selectedIndex;
121
+ const selectedOption = event.target.options[selectedIndex];
122
+ console.log(value, selectedOption.text);
123
+ }
124
+
125
+ // Input events (fires on every keystroke)
126
+ function handleInput(event: React.FormEvent<HTMLInputElement>) {
127
+ console.log(event.currentTarget.value);
128
+ }
129
+
130
+ // Reset event
131
+ function handleReset(event: React.FormEvent<HTMLFormElement>) {
132
+ event.preventDefault();
133
+ console.log('Form reset');
134
+ }
135
+ ```
136
+
137
+ ## Keyboard Events
138
+
139
+ ```typescript
140
+ function handleKeyDown(event: React.KeyboardEvent<HTMLInputElement>) {
141
+ // Key identification
142
+ console.log(event.key); // 'Enter', 'Escape', 'a', etc.
143
+ console.log(event.code); // 'Enter', 'Escape', 'KeyA', etc.
144
+
145
+ // Common patterns
146
+ if (event.key === 'Enter') {
147
+ event.preventDefault();
148
+ console.log('Enter pressed');
149
+ }
150
+
151
+ if (event.key === 'Escape') {
152
+ event.currentTarget.blur();
153
+ }
154
+
155
+ // Arrow keys
156
+ if (event.key === 'ArrowUp') {
157
+ event.preventDefault();
158
+ // Navigate up
159
+ }
160
+
161
+ // Modifier keys
162
+ if (event.ctrlKey && event.key === 's') {
163
+ event.preventDefault();
164
+ console.log('Ctrl+S - Save');
165
+ }
166
+
167
+ if (event.metaKey && event.key === 'k') {
168
+ event.preventDefault();
169
+ console.log('Cmd+K - Search');
170
+ }
171
+
172
+ // Check multiple modifiers
173
+ if (event.ctrlKey && event.shiftKey && event.key === 'P') {
174
+ event.preventDefault();
175
+ console.log('Ctrl+Shift+P - Command palette');
176
+ }
177
+
178
+ // Key combinations
179
+ if ((event.ctrlKey || event.metaKey) && event.key === 'Enter') {
180
+ console.log('Submit with Ctrl/Cmd+Enter');
181
+ }
182
+ }
183
+
184
+ function handleKeyUp(event: React.KeyboardEvent<HTMLInputElement>) {
185
+ console.log('Key released:', event.key);
186
+ }
187
+
188
+ function handleKeyPress(event: React.KeyboardEvent<HTMLInputElement>) {
189
+ // Deprecated - use keyDown instead
190
+ console.log('Key pressed:', event.key);
191
+ }
192
+ ```
193
+
194
+ ## Focus Events
195
+
196
+ ```typescript
197
+ function handleFocus(event: React.FocusEvent<HTMLInputElement>) {
198
+ // Select all text on focus
199
+ event.target.select();
200
+
201
+ // Add visual indicator
202
+ event.currentTarget.classList.add('focused');
203
+ }
204
+
205
+ function handleBlur(event: React.FocusEvent<HTMLInputElement>) {
206
+ // Validate on blur
207
+ const value = event.target.value;
208
+ if (value === '') {
209
+ event.currentTarget.classList.add('error');
210
+ }
211
+
212
+ // Remove visual indicator
213
+ event.currentTarget.classList.remove('focused');
214
+ }
215
+
216
+ // Focus within
217
+ function handleFocusWithin(event: React.FocusEvent<HTMLDivElement>) {
218
+ // Related target - element receiving focus
219
+ const relatedTarget = event.relatedTarget as HTMLElement | null;
220
+ console.log('Focus moved from:', relatedTarget);
221
+ }
222
+ ```
223
+
224
+ ## Drag and Drop Events
225
+
226
+ ```typescript
227
+ function handleDragStart(event: React.DragEvent<HTMLDivElement>) {
228
+ event.dataTransfer.effectAllowed = 'move';
229
+ event.dataTransfer.setData('text/plain', event.currentTarget.id);
230
+
231
+ // Custom drag image
232
+ const dragImage = document.createElement('div');
233
+ dragImage.textContent = 'Dragging...';
234
+ event.dataTransfer.setDragImage(dragImage, 0, 0);
235
+ }
236
+
237
+ function handleDragOver(event: React.DragEvent<HTMLDivElement>) {
238
+ event.preventDefault();
239
+ event.dataTransfer.dropEffect = 'move';
240
+ event.currentTarget.classList.add('drag-over');
241
+ }
242
+
243
+ function handleDragLeave(event: React.DragEvent<HTMLDivElement>) {
244
+ event.currentTarget.classList.remove('drag-over');
245
+ }
246
+
247
+ function handleDrop(event: React.DragEvent<HTMLDivElement>) {
248
+ event.preventDefault();
249
+ event.currentTarget.classList.remove('drag-over');
250
+
251
+ const data = event.dataTransfer.getData('text/plain');
252
+ console.log('Dropped:', data);
253
+
254
+ // Handle files
255
+ const files = event.dataTransfer.files;
256
+ if (files.length > 0) {
257
+ Array.from(files).forEach((file) => {
258
+ console.log(file.name, file.type, file.size);
259
+ });
260
+ }
261
+ }
262
+
263
+ function handleDragEnd(event: React.DragEvent<HTMLDivElement>) {
264
+ console.log('Drag ended');
265
+ }
266
+ ```
267
+
268
+ ## Clipboard Events
269
+
270
+ ```typescript
271
+ function handleCopy(event: React.ClipboardEvent<HTMLDivElement>) {
272
+ event.preventDefault();
273
+
274
+ // Custom copy behavior
275
+ const selection = window.getSelection();
276
+ if (selection) {
277
+ const text = `Copied from app: ${selection.toString()}`;
278
+ event.clipboardData.setData('text/plain', text);
279
+ }
280
+ }
281
+
282
+ function handleCut(event: React.ClipboardEvent<HTMLInputElement>) {
283
+ console.log('Cut:', event.currentTarget.value);
284
+ }
285
+
286
+ function handlePaste(event: React.ClipboardEvent<HTMLInputElement>) {
287
+ event.preventDefault();
288
+
289
+ const pastedText = event.clipboardData.getData('text/plain');
290
+ console.log('Pasted:', pastedText);
291
+
292
+ // Validate pasted content
293
+ const sanitized = pastedText.replace(/[^a-zA-Z0-9]/g, '');
294
+ event.currentTarget.value = sanitized;
295
+ }
296
+ ```
297
+
298
+ ## Composition Events (IME)
299
+
300
+ ```typescript
301
+ // For international input methods (Chinese, Japanese, etc.)
302
+ function handleCompositionStart(event: React.CompositionEvent<HTMLInputElement>) {
303
+ console.log('Composition started');
304
+ }
305
+
306
+ function handleCompositionUpdate(event: React.CompositionEvent<HTMLInputElement>) {
307
+ console.log('Composing:', event.data);
308
+ }
309
+
310
+ function handleCompositionEnd(event: React.CompositionEvent<HTMLInputElement>) {
311
+ console.log('Composition ended:', event.data);
312
+ }
313
+ ```
314
+
315
+ ## Touch Events
316
+
317
+ ```typescript
318
+ function handleTouchStart(event: React.TouchEvent<HTMLDivElement>) {
319
+ const touch = event.touches[0];
320
+ console.log('Touch start:', touch.clientX, touch.clientY);
321
+ }
322
+
323
+ function handleTouchMove(event: React.TouchEvent<HTMLDivElement>) {
324
+ event.preventDefault(); // Prevent scrolling
325
+
326
+ const touch = event.touches[0];
327
+ console.log('Touch move:', touch.clientX, touch.clientY);
328
+ }
329
+
330
+ function handleTouchEnd(event: React.TouchEvent<HTMLDivElement>) {
331
+ console.log('Touch ended');
332
+ }
333
+
334
+ // Multi-touch
335
+ function handleMultiTouch(event: React.TouchEvent<HTMLDivElement>) {
336
+ if (event.touches.length === 2) {
337
+ const [touch1, touch2] = event.touches;
338
+
339
+ const distance = Math.hypot(
340
+ touch2.clientX - touch1.clientX,
341
+ touch2.clientY - touch1.clientY
342
+ );
343
+
344
+ console.log('Pinch distance:', distance);
345
+ }
346
+ }
347
+ ```
348
+
349
+ ## Wheel Events
350
+
351
+ ```typescript
352
+ function handleWheel(event: React.WheelEvent<HTMLDivElement>) {
353
+ // Prevent default scroll
354
+ event.preventDefault();
355
+
356
+ // Scroll delta
357
+ console.log('Delta X:', event.deltaX);
358
+ console.log('Delta Y:', event.deltaY);
359
+ console.log('Delta Z:', event.deltaZ);
360
+
361
+ // Delta mode (0 = pixels, 1 = lines, 2 = pages)
362
+ console.log('Delta mode:', event.deltaMode);
363
+
364
+ // Zoom with Ctrl+Wheel
365
+ if (event.ctrlKey) {
366
+ const zoomDelta = event.deltaY > 0 ? -0.1 : 0.1;
367
+ console.log('Zoom:', zoomDelta);
368
+ }
369
+ }
370
+ ```
371
+
372
+ ## Generic Event Handlers
373
+
374
+ Reusable handlers with proper typing.
375
+
376
+ ```typescript
377
+ // Generic change handler
378
+ function createChangeHandler<T extends HTMLElement>(
379
+ callback: (value: string) => void
380
+ ) {
381
+ return (event: React.ChangeEvent<T>) => {
382
+ if ('value' in event.target) {
383
+ callback(event.target.value);
384
+ }
385
+ };
386
+ }
387
+
388
+ // Usage
389
+ const handleNameChange = createChangeHandler<HTMLInputElement>((value) => {
390
+ setName(value);
391
+ });
392
+
393
+ const handleBioChange = createChangeHandler<HTMLTextAreaElement>((value) => {
394
+ setBio(value);
395
+ });
396
+
397
+ // Generic click handler with target validation
398
+ function createClickHandler<T extends HTMLElement>(
399
+ selector: string,
400
+ callback: (element: T) => void
401
+ ) {
402
+ return (event: React.MouseEvent<HTMLElement>) => {
403
+ const target = event.target as HTMLElement;
404
+ const match = target.closest(selector);
405
+
406
+ if (match) {
407
+ callback(match as T);
408
+ }
409
+ };
410
+ }
411
+
412
+ // Usage
413
+ const handleItemClick = createClickHandler<HTMLLIElement>('li[data-id]', (item) => {
414
+ const id = item.dataset.id;
415
+ console.log('Clicked item:', id);
416
+ });
417
+ ```
418
+
419
+ ## Event Handler Type Aliases
420
+
421
+ ```typescript
422
+ // Create reusable type aliases
423
+ type InputChangeHandler = React.ChangeEventHandler<HTMLInputElement>;
424
+ type ButtonClickHandler = React.MouseEventHandler<HTMLButtonElement>;
425
+ type FormSubmitHandler = React.FormEventHandler<HTMLFormElement>;
426
+
427
+ // Usage
428
+ const handleChange: InputChangeHandler = (event) => {
429
+ console.log(event.target.value);
430
+ };
431
+
432
+ const handleClick: ButtonClickHandler = (event) => {
433
+ event.currentTarget.disabled = true;
434
+ };
435
+
436
+ const handleSubmit: FormSubmitHandler = (event) => {
437
+ event.preventDefault();
438
+ };
439
+
440
+ // Generic handler type
441
+ type EventHandler<E extends HTMLElement, Evt extends React.SyntheticEvent> = (
442
+ event: Evt & { currentTarget: E }
443
+ ) => void;
444
+
445
+ // Usage
446
+ const handleInput: EventHandler<HTMLInputElement, React.ChangeEvent<HTMLInputElement>> = (
447
+ event
448
+ ) => {
449
+ console.log(event.currentTarget.value);
450
+ };
451
+ ```
452
+
453
+ ## Delegated Event Handlers
454
+
455
+ Type-safe event delegation.
456
+
457
+ ```typescript
458
+ function ListContainer() {
459
+ const handleListClick = (event: React.MouseEvent<HTMLUListElement>) => {
460
+ const target = event.target as HTMLElement;
461
+
462
+ // Find clicked list item
463
+ const listItem = target.closest('li');
464
+ if (!listItem) return;
465
+
466
+ // Type guard for data attributes
467
+ const itemId = listItem.getAttribute('data-id');
468
+ if (itemId) {
469
+ console.log('Clicked item:', itemId);
470
+ }
471
+
472
+ // Handle button within list item
473
+ if (target.matches('button.delete')) {
474
+ event.stopPropagation();
475
+ console.log('Delete clicked');
476
+ }
477
+ };
478
+
479
+ return (
480
+ <ul onClick={handleListClick}>
481
+ <li data-id="1">
482
+ Item 1<button className="delete">Delete</button>
483
+ </li>
484
+ <li data-id="2">
485
+ Item 2<button className="delete">Delete</button>
486
+ </li>
487
+ </ul>
488
+ );
489
+ }
490
+ ```
491
+
492
+ ## Native vs Synthetic Events
493
+
494
+ ```typescript
495
+ function Component() {
496
+ const ref = useRef<HTMLDivElement>(null);
497
+
498
+ useEffect(() => {
499
+ const element = ref.current;
500
+ if (!element) return;
501
+
502
+ // Native event listener
503
+ const handleNativeClick = (event: MouseEvent) => {
504
+ console.log('Native click:', event.target);
505
+ };
506
+
507
+ element.addEventListener('click', handleNativeClick);
508
+
509
+ return () => {
510
+ element.removeEventListener('click', handleNativeClick);
511
+ };
512
+ }, []);
513
+
514
+ // React synthetic event
515
+ const handleReactClick = (event: React.MouseEvent<HTMLDivElement>) => {
516
+ console.log('React click:', event.target);
517
+
518
+ // Access native event
519
+ const nativeEvent = event.nativeEvent;
520
+ console.log('Native event:', nativeEvent);
521
+ };
522
+
523
+ return <div ref={ref} onClick={handleReactClick}>Click me</div>;
524
+ }
525
+ ```
526
+
527
+ ## Custom Events
528
+
529
+ ```typescript
530
+ // Define custom event type
531
+ type CustomEventMap = {
532
+ 'user:login': CustomEvent<{ userId: string }>;
533
+ 'user:logout': CustomEvent;
534
+ };
535
+
536
+ // Typed custom event dispatcher
537
+ function dispatchCustomEvent<K extends keyof CustomEventMap>(
538
+ element: HTMLElement,
539
+ type: K,
540
+ detail?: CustomEventMap[K]['detail']
541
+ ) {
542
+ const event = new CustomEvent(type, { detail, bubbles: true });
543
+ element.dispatchEvent(event);
544
+ }
545
+
546
+ // Component using custom events
547
+ function UserButton() {
548
+ const ref = useRef<HTMLButtonElement>(null);
549
+
550
+ const handleLogin = () => {
551
+ if (ref.current) {
552
+ dispatchCustomEvent(ref.current, 'user:login', { userId: '123' });
553
+ }
554
+ };
555
+
556
+ useEffect(() => {
557
+ const element = ref.current;
558
+ if (!element) return;
559
+
560
+ const handleCustomLogin = (event: Event) => {
561
+ const customEvent = event as CustomEvent<{ userId: string }>;
562
+ console.log('User logged in:', customEvent.detail.userId);
563
+ };
564
+
565
+ element.addEventListener('user:login', handleCustomLogin);
566
+
567
+ return () => {
568
+ element.removeEventListener('user:login', handleCustomLogin);
569
+ };
570
+ }, []);
571
+
572
+ return <button ref={ref} onClick={handleLogin}>Login</button>;
573
+ }
574
+ ```