kayforms 0.1.1

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 (81) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +337 -0
  3. package/examples/react-demo/README.md +337 -0
  4. package/examples/react-demo/eslint.config.js +22 -0
  5. package/examples/react-demo/index.html +13 -0
  6. package/examples/react-demo/package.json +33 -0
  7. package/examples/react-demo/public/apple-touch-icon.png +0 -0
  8. package/examples/react-demo/public/favicon-96x96.png +0 -0
  9. package/examples/react-demo/public/favicon.ico +0 -0
  10. package/examples/react-demo/public/favicon.svg +17 -0
  11. package/examples/react-demo/public/icons.svg +24 -0
  12. package/examples/react-demo/public/site.webmanifest +21 -0
  13. package/examples/react-demo/public/web-app-manifest-192x192.png +0 -0
  14. package/examples/react-demo/public/web-app-manifest-512x512.png +0 -0
  15. package/examples/react-demo/src/App.css +184 -0
  16. package/examples/react-demo/src/App.tsx +825 -0
  17. package/examples/react-demo/src/assets/hero.png +0 -0
  18. package/examples/react-demo/src/assets/react.svg +1 -0
  19. package/examples/react-demo/src/assets/vite.svg +1 -0
  20. package/examples/react-demo/src/index.css +627 -0
  21. package/examples/react-demo/src/main.tsx +10 -0
  22. package/examples/react-demo/tsconfig.app.json +25 -0
  23. package/examples/react-demo/tsconfig.json +7 -0
  24. package/examples/react-demo/tsconfig.node.json +24 -0
  25. package/examples/react-demo/vite.config.ts +7 -0
  26. package/kayforms.jpg +0 -0
  27. package/package.json +26 -0
  28. package/packages/angular/package.json +43 -0
  29. package/packages/angular/src/index.ts +198 -0
  30. package/packages/angular/tsconfig.json +8 -0
  31. package/packages/angular/tsup.config.ts +17 -0
  32. package/packages/core/README.md +337 -0
  33. package/packages/core/package.json +37 -0
  34. package/packages/core/src/batch.ts +106 -0
  35. package/packages/core/src/devtools.ts +329 -0
  36. package/packages/core/src/field.ts +167 -0
  37. package/packages/core/src/form.ts +448 -0
  38. package/packages/core/src/index.ts +71 -0
  39. package/packages/core/src/registry.ts +126 -0
  40. package/packages/core/src/signal.ts +399 -0
  41. package/packages/core/src/time-travel.ts +275 -0
  42. package/packages/core/src/validation.ts +243 -0
  43. package/packages/core/tsconfig.json +8 -0
  44. package/packages/core/tsup.config.ts +16 -0
  45. package/packages/devtools/extension/background.js +35 -0
  46. package/packages/devtools/extension/content-script.js +10 -0
  47. package/packages/devtools/extension/devtools.html +9 -0
  48. package/packages/devtools/extension/devtools.js +8 -0
  49. package/packages/devtools/extension/manifest.json +19 -0
  50. package/packages/devtools/extension/panel.css +505 -0
  51. package/packages/devtools/extension/panel.html +108 -0
  52. package/packages/devtools/extension/panel.js +354 -0
  53. package/packages/devtools/package.json +38 -0
  54. package/packages/devtools/src/index.ts +95 -0
  55. package/packages/devtools/src/panel.ts +226 -0
  56. package/packages/devtools/src/styles.ts +422 -0
  57. package/packages/devtools/src/timeline.ts +283 -0
  58. package/packages/devtools/tsconfig.json +8 -0
  59. package/packages/devtools/tsup.config.ts +17 -0
  60. package/packages/react/package.json +46 -0
  61. package/packages/react/src/index.ts +279 -0
  62. package/packages/react/tsconfig.json +8 -0
  63. package/packages/react/tsup.config.ts +17 -0
  64. package/packages/solid/package.json +42 -0
  65. package/packages/solid/src/index.ts +206 -0
  66. package/packages/solid/tsconfig.json +8 -0
  67. package/packages/solid/tsup.config.ts +17 -0
  68. package/packages/svelte/package.json +42 -0
  69. package/packages/svelte/src/index.ts +199 -0
  70. package/packages/svelte/tsconfig.json +8 -0
  71. package/packages/svelte/tsup.config.ts +17 -0
  72. package/packages/vanilla/package.json +38 -0
  73. package/packages/vanilla/src/index.ts +254 -0
  74. package/packages/vanilla/tsconfig.json +8 -0
  75. package/packages/vanilla/tsup.config.ts +17 -0
  76. package/packages/vue/package.json +42 -0
  77. package/packages/vue/src/index.ts +217 -0
  78. package/packages/vue/tsconfig.json +8 -0
  79. package/packages/vue/tsup.config.ts +17 -0
  80. package/pnpm-workspace.yaml +3 -0
  81. package/tsconfig.base.json +21 -0
@@ -0,0 +1,505 @@
1
+ /* ============================================================================
2
+ KayForms DevTools Premium Style System
3
+ ============================================================================ */
4
+
5
+ :root {
6
+ --font-sans: 'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
7
+ --font-mono: 'JetBrains Mono', 'Fira Code', monospace;
8
+
9
+ /* Colors */
10
+ --bg-primary: #0a0e17;
11
+ --bg-secondary: #111827;
12
+ --bg-tertiary: #1f2937;
13
+ --bg-glass: rgba(17, 24, 39, 0.7);
14
+ --border-color: rgba(255, 255, 255, 0.08);
15
+ --border-neon: rgba(99, 102, 241, 0.2);
16
+
17
+ --text-primary: #f3f4f6;
18
+ --text-secondary: #9ca3af;
19
+ --text-muted: #6b7280;
20
+
21
+ /* Accents */
22
+ --accent-purple: #818cf8;
23
+ --accent-neon: #6366f1;
24
+ --accent-glow: rgba(99, 102, 241, 0.4);
25
+
26
+ --success: #10b981;
27
+ --success-glow: rgba(16, 185, 129, 0.2);
28
+ --danger: #ef4444;
29
+ --danger-glow: rgba(239, 68, 68, 0.2);
30
+ --warning: #f59e0b;
31
+ }
32
+
33
+ * {
34
+ box-sizing: border-box;
35
+ margin: 0;
36
+ padding: 0;
37
+ }
38
+
39
+ body {
40
+ background-color: var(--bg-primary);
41
+ color: var(--text-primary);
42
+ font-family: var(--font-sans);
43
+ height: 100vh;
44
+ overflow: hidden;
45
+ display: flex;
46
+ flex-direction: column;
47
+ }
48
+
49
+ .panel-container {
50
+ display: flex;
51
+ flex-direction: column;
52
+ height: 100%;
53
+ padding: 16px;
54
+ gap: 16px;
55
+ }
56
+
57
+ /* Header */
58
+ .panel-header {
59
+ display: flex;
60
+ justify-content: space-between;
61
+ align-items: center;
62
+ padding-bottom: 12px;
63
+ border-bottom: 1px solid var(--border-color);
64
+ }
65
+
66
+ .header-left {
67
+ display: flex;
68
+ align-items: center;
69
+ gap: 12px;
70
+ }
71
+
72
+ .logo {
73
+ background: linear-gradient(135deg, #6366f1, #a855f7);
74
+ color: white;
75
+ width: 32px;
76
+ height: 32px;
77
+ border-radius: 8px;
78
+ display: flex;
79
+ align-items: center;
80
+ justify-content: center;
81
+ font-weight: 700;
82
+ font-size: 18px;
83
+ box-shadow: 0 0 15px var(--accent-glow);
84
+ animation: float 3s ease-in-out infinite;
85
+ }
86
+
87
+ .brand h1 {
88
+ font-size: 16px;
89
+ font-weight: 600;
90
+ letter-spacing: 0.5px;
91
+ }
92
+
93
+ .subtitle {
94
+ font-size: 11px;
95
+ color: var(--text-secondary);
96
+ }
97
+
98
+ .header-right {
99
+ display: flex;
100
+ align-items: center;
101
+ gap: 10px;
102
+ }
103
+
104
+ .control-group {
105
+ display: flex;
106
+ align-items: center;
107
+ gap: 8px;
108
+ }
109
+
110
+ .control-group label {
111
+ font-size: 12px;
112
+ color: var(--text-secondary);
113
+ }
114
+
115
+ select {
116
+ background-color: var(--bg-secondary);
117
+ border: 1px solid var(--border-color);
118
+ color: var(--text-primary);
119
+ padding: 6px 12px;
120
+ border-radius: 6px;
121
+ outline: none;
122
+ font-family: var(--font-sans);
123
+ font-size: 13px;
124
+ cursor: pointer;
125
+ transition: all 0.2s ease;
126
+ }
127
+
128
+ select:focus {
129
+ border-color: var(--accent-purple);
130
+ box-shadow: 0 0 0 2px var(--border-neon);
131
+ }
132
+
133
+ /* Buttons */
134
+ .btn {
135
+ display: flex;
136
+ align-items: center;
137
+ gap: 6px;
138
+ padding: 6px 14px;
139
+ border-radius: 6px;
140
+ font-size: 13px;
141
+ font-weight: 500;
142
+ cursor: pointer;
143
+ border: 1px solid transparent;
144
+ font-family: var(--font-sans);
145
+ transition: all 0.2s ease;
146
+ }
147
+
148
+ .btn-secondary {
149
+ background-color: var(--bg-secondary);
150
+ color: var(--text-primary);
151
+ border-color: var(--border-color);
152
+ }
153
+
154
+ .btn-secondary:hover {
155
+ background-color: var(--bg-tertiary);
156
+ border-color: var(--text-muted);
157
+ }
158
+
159
+ .btn-icon {
160
+ background-color: var(--bg-secondary);
161
+ color: var(--text-primary);
162
+ border: 1px solid var(--border-color);
163
+ width: 36px;
164
+ height: 36px;
165
+ display: flex;
166
+ align-items: center;
167
+ justify-content: center;
168
+ border-radius: 8px;
169
+ font-size: 16px;
170
+ }
171
+
172
+ .btn-icon:hover:not(:disabled) {
173
+ background-color: var(--bg-tertiary);
174
+ transform: scale(1.05);
175
+ }
176
+
177
+ .btn-accent {
178
+ background: linear-gradient(135deg, #6366f1, #818cf8);
179
+ border: none;
180
+ box-shadow: 0 4px 10px rgba(99, 102, 241, 0.2);
181
+ }
182
+
183
+ .btn-accent:hover:not(:disabled) {
184
+ box-shadow: 0 0 15px var(--accent-glow);
185
+ }
186
+
187
+ .btn-danger:hover:not(:disabled) {
188
+ background-color: var(--danger);
189
+ border-color: var(--danger);
190
+ box-shadow: 0 0 12px var(--danger-glow);
191
+ }
192
+
193
+ .btn:disabled {
194
+ opacity: 0.5;
195
+ cursor: not-allowed;
196
+ }
197
+
198
+ /* Controls Card */
199
+ .controls-card {
200
+ background: var(--bg-glass);
201
+ backdrop-filter: blur(12px);
202
+ -webkit-backdrop-filter: blur(12px);
203
+ border: 1px solid var(--border-neon);
204
+ border-radius: 12px;
205
+ padding: 16px;
206
+ display: flex;
207
+ align-items: center;
208
+ gap: 16px;
209
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
210
+ }
211
+
212
+ .playback-controls {
213
+ display: flex;
214
+ gap: 8px;
215
+ }
216
+
217
+ .slider-container {
218
+ flex-grow: 1;
219
+ position: relative;
220
+ display: flex;
221
+ flex-direction: column;
222
+ justify-content: center;
223
+ }
224
+
225
+ input[type="range"] {
226
+ -webkit-appearance: none;
227
+ width: 100%;
228
+ height: 6px;
229
+ border-radius: 3px;
230
+ background: var(--bg-secondary);
231
+ outline: none;
232
+ }
233
+
234
+ input[type="range"]::-webkit-slider-runnable-track {
235
+ background: linear-gradient(to right, #6366f1, #a855f7);
236
+ height: 6px;
237
+ border-radius: 3px;
238
+ }
239
+
240
+ input[type="range"]::-webkit-slider-thumb {
241
+ -webkit-appearance: none;
242
+ width: 16px;
243
+ height: 16px;
244
+ border-radius: 50%;
245
+ background: #ffffff;
246
+ cursor: pointer;
247
+ box-shadow: 0 0 10px var(--accent-glow);
248
+ margin-top: -5px;
249
+ transition: transform 0.1s ease;
250
+ }
251
+
252
+ input[type="range"]::-webkit-slider-thumb:hover {
253
+ transform: scale(1.25);
254
+ }
255
+
256
+ .step-counter {
257
+ font-family: var(--font-mono);
258
+ font-size: 14px;
259
+ display: flex;
260
+ align-items: center;
261
+ gap: 4px;
262
+ background-color: var(--bg-secondary);
263
+ padding: 6px 12px;
264
+ border-radius: 6px;
265
+ border: 1px solid var(--border-color);
266
+ }
267
+
268
+ .current-step {
269
+ color: var(--accent-purple);
270
+ font-weight: 600;
271
+ }
272
+
273
+ .step-separator {
274
+ color: var(--text-muted);
275
+ }
276
+
277
+ /* Split View */
278
+ .split-view {
279
+ display: flex;
280
+ flex: 1;
281
+ gap: 16px;
282
+ overflow: hidden;
283
+ }
284
+
285
+ .timeline-pane, .inspector-pane {
286
+ background: var(--bg-glass);
287
+ backdrop-filter: blur(8px);
288
+ border: 1px solid var(--border-color);
289
+ border-radius: 12px;
290
+ display: flex;
291
+ flex-direction: column;
292
+ overflow: hidden;
293
+ }
294
+
295
+ .timeline-pane {
296
+ width: 40%;
297
+ }
298
+
299
+ .inspector-pane {
300
+ width: 60%;
301
+ }
302
+
303
+ .pane-header {
304
+ display: flex;
305
+ justify-content: space-between;
306
+ align-items: center;
307
+ padding: 12px 16px;
308
+ border-bottom: 1px solid var(--border-color);
309
+ background-color: rgba(255, 255, 255, 0.02);
310
+ }
311
+
312
+ .pane-header h2 {
313
+ font-size: 14px;
314
+ font-weight: 600;
315
+ text-transform: uppercase;
316
+ letter-spacing: 0.5px;
317
+ color: var(--text-secondary);
318
+ }
319
+
320
+ .badge {
321
+ font-size: 11px;
322
+ padding: 3px 8px;
323
+ border-radius: 12px;
324
+ background-color: var(--bg-tertiary);
325
+ font-weight: 500;
326
+ border: 1px solid var(--border-color);
327
+ }
328
+
329
+ .badge-success {
330
+ background-color: var(--success-glow);
331
+ color: var(--success);
332
+ border-color: rgba(16, 185, 129, 0.3);
333
+ }
334
+
335
+ .badge-danger {
336
+ background-color: var(--danger-glow);
337
+ color: var(--danger);
338
+ border-color: rgba(239, 68, 68, 0.3);
339
+ }
340
+
341
+ /* Timeline List */
342
+ .timeline-list {
343
+ flex: 1;
344
+ overflow-y: auto;
345
+ padding: 8px;
346
+ display: flex;
347
+ flex-direction: column;
348
+ gap: 6px;
349
+ }
350
+
351
+ .empty-state {
352
+ padding: 32px;
353
+ text-align: center;
354
+ font-size: 13px;
355
+ color: var(--text-muted);
356
+ line-height: 1.5;
357
+ }
358
+
359
+ .entry-card {
360
+ display: flex;
361
+ align-items: center;
362
+ padding: 10px 12px;
363
+ border-radius: 8px;
364
+ background-color: rgba(255, 255, 255, 0.02);
365
+ border: 1px solid transparent;
366
+ cursor: pointer;
367
+ transition: all 0.2s ease;
368
+ }
369
+
370
+ .entry-card:hover {
371
+ background-color: rgba(255, 255, 255, 0.04);
372
+ border-color: var(--border-color);
373
+ }
374
+
375
+ .entry-card.active {
376
+ background-color: rgba(99, 102, 241, 0.08);
377
+ border-color: rgba(99, 102, 241, 0.3);
378
+ }
379
+
380
+ .entry-card.future {
381
+ opacity: 0.55;
382
+ }
383
+
384
+ .entry-index {
385
+ font-family: var(--font-mono);
386
+ font-size: 11px;
387
+ color: var(--text-muted);
388
+ width: 24px;
389
+ }
390
+
391
+ .entry-dot {
392
+ width: 8px;
393
+ height: 8px;
394
+ border-radius: 50%;
395
+ margin-right: 12px;
396
+ background-color: var(--accent-purple);
397
+ box-shadow: 0 0 8px var(--accent-purple);
398
+ }
399
+
400
+ .entry-dot.changed-field {
401
+ background-color: var(--warning);
402
+ box-shadow: 0 0 8px var(--warning);
403
+ }
404
+
405
+ .entry-dot.validation-error {
406
+ background-color: var(--danger);
407
+ box-shadow: 0 0 8px var(--danger);
408
+ }
409
+
410
+ .entry-details {
411
+ flex: 1;
412
+ display: flex;
413
+ flex-direction: column;
414
+ gap: 2px;
415
+ }
416
+
417
+ .entry-row {
418
+ display: flex;
419
+ justify-content: space-between;
420
+ align-items: center;
421
+ }
422
+
423
+ .entry-action {
424
+ font-weight: 500;
425
+ font-size: 13px;
426
+ }
427
+
428
+ .entry-time {
429
+ font-family: var(--font-mono);
430
+ font-size: 11px;
431
+ color: var(--text-muted);
432
+ }
433
+
434
+ .entry-path {
435
+ font-family: var(--font-mono);
436
+ font-size: 11px;
437
+ color: var(--warning);
438
+ }
439
+
440
+ /* Inspector content */
441
+ .inspector-content {
442
+ flex: 1;
443
+ display: flex;
444
+ flex-direction: column;
445
+ overflow-y: auto;
446
+ padding: 16px;
447
+ gap: 16px;
448
+ }
449
+
450
+ .inspector-section {
451
+ display: flex;
452
+ flex-direction: column;
453
+ gap: 8px;
454
+ }
455
+
456
+ .section-title {
457
+ font-size: 12px;
458
+ font-weight: 600;
459
+ text-transform: uppercase;
460
+ color: var(--text-secondary);
461
+ letter-spacing: 0.5px;
462
+ }
463
+
464
+ .json-viewer {
465
+ background-color: var(--bg-secondary);
466
+ border: 1px solid var(--border-color);
467
+ border-radius: 8px;
468
+ padding: 12px;
469
+ font-family: var(--font-mono);
470
+ font-size: 12px;
471
+ color: #a78bfa;
472
+ overflow-x: auto;
473
+ line-height: 1.5;
474
+ white-space: pre-wrap;
475
+ }
476
+
477
+ #json-errors {
478
+ color: #f87171;
479
+ }
480
+
481
+ /* Keyframes & Animations */
482
+ @keyframes float {
483
+ 0% { transform: translateY(0px); }
484
+ 50% { transform: translateY(-3px); }
485
+ 100% { transform: translateY(0px); }
486
+ }
487
+
488
+ /* Scrollbar Customization */
489
+ ::-webkit-scrollbar {
490
+ width: 6px;
491
+ height: 6px;
492
+ }
493
+
494
+ ::-webkit-scrollbar-track {
495
+ background: transparent;
496
+ }
497
+
498
+ ::-webkit-scrollbar-thumb {
499
+ background: var(--border-color);
500
+ border-radius: 3px;
501
+ }
502
+
503
+ ::-webkit-scrollbar-thumb:hover {
504
+ background: var(--text-muted);
505
+ }
@@ -0,0 +1,108 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>KayForms Time-Travel Debugger</title>
6
+ <link rel="preconnect" href="https://fonts.googleapis.com">
7
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
8
+ <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
9
+ <link rel="stylesheet" href="panel.css">
10
+ </head>
11
+ <body>
12
+ <div class="panel-container">
13
+ <!-- Top Header -->
14
+ <header class="panel-header">
15
+ <div class="header-left">
16
+ <div class="logo">K</div>
17
+ <div class="brand">
18
+ <h1>KayForms</h1>
19
+ <span class="subtitle">Time-Travel Debugger</span>
20
+ </div>
21
+ </div>
22
+
23
+ <div class="header-right">
24
+ <!-- Form selector -->
25
+ <div class="control-group">
26
+ <label for="form-select">Form ID:</label>
27
+ <select id="form-select">
28
+ <option value="">-- No Active Forms --</option>
29
+ </select>
30
+ </div>
31
+
32
+ <!-- JSON actions -->
33
+ <button id="btn-export" title="Export History as JSON" class="btn btn-secondary">
34
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M17 8l-5-5-5 5M12 3v12"/></svg>
35
+ Export
36
+ </button>
37
+ <button id="btn-import" title="Import History from JSON" class="btn btn-secondary">
38
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3"/></svg>
39
+ Import
40
+ </button>
41
+ <input type="file" id="import-file" accept=".json" style="display: none;">
42
+ </div>
43
+ </header>
44
+
45
+ <!-- Scrubber and Controls Card -->
46
+ <section class="controls-card">
47
+ <div class="playback-controls">
48
+ <button id="btn-rewind" title="Rewind to start" class="btn btn-icon">
49
+
50
+ </button>
51
+ <button id="btn-play-pause" title="Play history" class="btn btn-icon btn-accent">
52
+
53
+ </button>
54
+ <button id="btn-clear" title="Clear form history" class="btn btn-icon btn-danger">
55
+ 🗑
56
+ </button>
57
+ </div>
58
+
59
+ <div class="slider-container">
60
+ <input type="range" id="time-slider" min="0" max="0" value="0" disabled>
61
+ <div class="slider-ticks" id="slider-ticks"></div>
62
+ </div>
63
+
64
+ <div class="step-counter">
65
+ <span class="current-step" id="current-step-label">0</span>
66
+ <span class="step-separator">/</span>
67
+ <span class="total-steps" id="total-steps-label">0</span>
68
+ </div>
69
+ </section>
70
+
71
+ <!-- Workspace split view -->
72
+ <div class="split-view">
73
+ <!-- Left side: Timeline Entries -->
74
+ <aside class="timeline-pane">
75
+ <div class="pane-header">
76
+ <h2>Timeline</h2>
77
+ <span class="badge" id="entries-count-badge">0 entries</span>
78
+ </div>
79
+ <div class="timeline-list" id="timeline-list">
80
+ <div class="empty-state">No form state changes recorded yet. Interacted fields will show up here.</div>
81
+ </div>
82
+ </aside>
83
+
84
+ <!-- Right side: State Inspector -->
85
+ <main class="inspector-pane">
86
+ <div class="pane-header">
87
+ <h2>State Snapshot</h2>
88
+ <span class="badge badge-success" id="valid-badge">Valid</span>
89
+ </div>
90
+
91
+ <div class="inspector-content">
92
+ <div class="inspector-section">
93
+ <h3 class="section-title">Values</h3>
94
+ <pre class="json-viewer" id="json-values">{}</pre>
95
+ </div>
96
+
97
+ <div class="inspector-section">
98
+ <h3 class="section-title">Validation Errors</h3>
99
+ <pre class="json-viewer" id="json-errors">{}</pre>
100
+ </div>
101
+ </div>
102
+ </main>
103
+ </div>
104
+ </div>
105
+
106
+ <script src="panel.js"></script>
107
+ </body>
108
+ </html>