ai-progress-controls 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 (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +823 -0
  3. package/dist/ai-progress-controls.es.js +7191 -0
  4. package/dist/ai-progress-controls.es.js.map +1 -0
  5. package/dist/ai-progress-controls.umd.js +2 -0
  6. package/dist/ai-progress-controls.umd.js.map +1 -0
  7. package/dist/index.d.ts +2212 -0
  8. package/package.json +105 -0
  9. package/src/__tests__/setup.ts +93 -0
  10. package/src/core/base/AIControl.ts +230 -0
  11. package/src/core/base/index.ts +3 -0
  12. package/src/core/base/types.ts +77 -0
  13. package/src/core/base/utils.ts +168 -0
  14. package/src/core/batch-progress/BatchProgress.test.ts +458 -0
  15. package/src/core/batch-progress/BatchProgress.ts +760 -0
  16. package/src/core/batch-progress/index.ts +14 -0
  17. package/src/core/batch-progress/styles.ts +480 -0
  18. package/src/core/batch-progress/types.ts +169 -0
  19. package/src/core/model-loader/ModelLoader.test.ts +311 -0
  20. package/src/core/model-loader/ModelLoader.ts +673 -0
  21. package/src/core/model-loader/index.ts +2 -0
  22. package/src/core/model-loader/styles.ts +496 -0
  23. package/src/core/model-loader/types.ts +127 -0
  24. package/src/core/parameter-panel/ParameterPanel.test.ts +856 -0
  25. package/src/core/parameter-panel/ParameterPanel.ts +877 -0
  26. package/src/core/parameter-panel/index.ts +14 -0
  27. package/src/core/parameter-panel/styles.ts +323 -0
  28. package/src/core/parameter-panel/types.ts +278 -0
  29. package/src/core/parameter-slider/ParameterSlider.test.ts +299 -0
  30. package/src/core/parameter-slider/ParameterSlider.ts +653 -0
  31. package/src/core/parameter-slider/index.ts +8 -0
  32. package/src/core/parameter-slider/styles.ts +493 -0
  33. package/src/core/parameter-slider/types.ts +107 -0
  34. package/src/core/queue-progress/QueueProgress.test.ts +344 -0
  35. package/src/core/queue-progress/QueueProgress.ts +563 -0
  36. package/src/core/queue-progress/index.ts +5 -0
  37. package/src/core/queue-progress/styles.ts +469 -0
  38. package/src/core/queue-progress/types.ts +130 -0
  39. package/src/core/retry-progress/RetryProgress.test.ts +397 -0
  40. package/src/core/retry-progress/RetryProgress.ts +957 -0
  41. package/src/core/retry-progress/index.ts +6 -0
  42. package/src/core/retry-progress/styles.ts +530 -0
  43. package/src/core/retry-progress/types.ts +176 -0
  44. package/src/core/stream-progress/StreamProgress.test.ts +531 -0
  45. package/src/core/stream-progress/StreamProgress.ts +517 -0
  46. package/src/core/stream-progress/index.ts +2 -0
  47. package/src/core/stream-progress/styles.ts +349 -0
  48. package/src/core/stream-progress/types.ts +82 -0
  49. package/src/index.ts +19 -0
@@ -0,0 +1,349 @@
1
+ export const styles = `
2
+ <style>
3
+ :host {
4
+ /* CSS variables inherit from document root with fallback defaults */
5
+
6
+ display: block;
7
+ font-family: var(--ai-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif);
8
+ font-size: var(--ai-font-size, 14px);
9
+ }
10
+
11
+ :host([style*="cursor: progress"]) .stream-progress {
12
+ cursor: progress;
13
+ }
14
+
15
+ :host([style*="cursor: not-allowed"]) .stream-progress {
16
+ cursor: not-allowed;
17
+ }
18
+
19
+ :host([style*="cursor: default"]) .stream-progress {
20
+ cursor: default;
21
+ }
22
+
23
+ .stream-progress {
24
+ background: var(--ai-background-color, #ffffff);
25
+ border: 1px solid var(--ai-border-color, #e5e7eb);
26
+ border-radius: var(--ai-border-radius, 8px);
27
+ padding: var(--ai-spacing, 12px);
28
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
29
+ }
30
+
31
+ .stream-progress.streaming {
32
+ border-color: var(--ai-primary-color, #3b82f6);
33
+ }
34
+
35
+ .stream-progress.cancelled {
36
+ border-color: #ef4444;
37
+ opacity: 0.7;
38
+ }
39
+
40
+ .message {
41
+ color: var(--ai-text-color, #1f2937);
42
+ font-weight: 500;
43
+ margin-bottom: calc(var(--ai-spacing, 12px) * 0.75);
44
+ font-size: 13px;
45
+ }
46
+
47
+ .progress-bar {
48
+ width: 100%;
49
+ height: 8px;
50
+ background: #f3f4f6;
51
+ border-radius: 4px;
52
+ overflow: hidden;
53
+ margin-bottom: var(--ai-spacing, 12px);
54
+ }
55
+
56
+ .progress-fill {
57
+ height: 100%;
58
+ background: linear-gradient(90deg, var(--ai-primary-color, #3b82f6), var(--ai-secondary-color, #10b981));
59
+ transition: width 0.3s ease;
60
+ border-radius: 4px;
61
+ }
62
+
63
+ .streaming .progress-fill {
64
+ /* Default pulse animation - will be overridden by animation attribute */
65
+ }
66
+
67
+ @keyframes pulse {
68
+ 0%, 100% {
69
+ opacity: 1;
70
+ }
71
+ 50% {
72
+ opacity: 0.8;
73
+ }
74
+ }
75
+
76
+ .stats {
77
+ display: flex;
78
+ justify-content: space-between;
79
+ align-items: center;
80
+ flex-wrap: wrap;
81
+ gap: calc(var(--ai-spacing, 12px) * 0.75);
82
+ margin-bottom: var(--ai-spacing, 12px);
83
+ }
84
+
85
+ .stat-item {
86
+ display: flex;
87
+ flex-direction: column;
88
+ gap: 2px;
89
+ }
90
+
91
+ .stat-label {
92
+ font-size: 11px;
93
+ color: #6b7280;
94
+ text-transform: uppercase;
95
+ letter-spacing: 0.5px;
96
+ font-weight: 600;
97
+ }
98
+
99
+ .stat-value {
100
+ font-size: 16px;
101
+ color: var(--ai-text-color, #1f2937);
102
+ font-weight: 600;
103
+ font-variant-numeric: tabular-nums;
104
+ }
105
+
106
+ .cancel-button {
107
+ width: 100%;
108
+ padding: 8px 16px;
109
+ background: #ef4444;
110
+ color: white;
111
+ border: none;
112
+ border-radius: calc(var(--ai-border-radius, 8px) * 0.75);
113
+ font-size: 13px;
114
+ font-weight: 600;
115
+ cursor: pointer;
116
+ transition: background 0.2s ease;
117
+ font-family: inherit;
118
+ }
119
+
120
+ .cancel-button:hover {
121
+ background: #dc2626;
122
+ }
123
+
124
+ .cancel-button:active {
125
+ transform: translateY(1px);
126
+ }
127
+
128
+ .cancel-button:focus-visible {
129
+ outline: 2px solid var(--ai-primary-color, #3b82f6);
130
+ outline-offset: 2px;
131
+ }
132
+
133
+ /* Size variants */
134
+ :host([size="compact"]) .stream-progress {
135
+ padding: 8px;
136
+ font-size: 12px;
137
+ }
138
+
139
+ :host([size="compact"]) .progress-bar {
140
+ height: 6px;
141
+ }
142
+
143
+ :host([size="compact"]) .message {
144
+ font-size: 11px;
145
+ margin-bottom: 6px;
146
+ }
147
+
148
+ :host([size="compact"]) .stat-label {
149
+ font-size: 10px;
150
+ }
151
+
152
+ :host([size="compact"]) .stat-value {
153
+ font-size: 14px;
154
+ }
155
+
156
+ :host([size="compact"]) .cancel-button {
157
+ padding: 6px 12px;
158
+ font-size: 11px;
159
+ }
160
+
161
+ :host([size="large"]) .stream-progress {
162
+ padding: 16px;
163
+ font-size: 16px;
164
+ }
165
+
166
+ :host([size="large"]) .progress-bar {
167
+ height: 10px;
168
+ }
169
+
170
+ :host([size="large"]) .message {
171
+ font-size: 15px;
172
+ margin-bottom: 12px;
173
+ }
174
+
175
+ :host([size="large"]) .stat-label {
176
+ font-size: 12px;
177
+ }
178
+
179
+ :host([size="large"]) .stat-value {
180
+ font-size: 18px;
181
+ }
182
+
183
+ :host([size="large"]) .cancel-button {
184
+ padding: 10px 20px;
185
+ font-size: 15px;
186
+ }
187
+
188
+ /* Visual Variants */
189
+
190
+ /* Minimal variant - clean, no shadows */
191
+ :host([variant="minimal"]) .stream-progress {
192
+ box-shadow: none;
193
+ border: 1px solid var(--ai-border-color, #e5e7eb);
194
+ }
195
+
196
+ :host([variant="minimal"]) .progress-bar {
197
+ background: transparent;
198
+ border: 1px solid var(--ai-border-color, #e5e7eb);
199
+ }
200
+
201
+ /* Gradient variant - colorful gradients */
202
+ :host([variant="gradient"]) .progress-fill {
203
+ background: linear-gradient(
204
+ 90deg,
205
+ var(--ai-primary-color, #3b82f6),
206
+ var(--ai-secondary-color, #10b981),
207
+ var(--ai-primary-color, #3b82f6)
208
+ );
209
+ background-size: 200% 100%;
210
+ animation: gradient-shift 3s ease-in-out infinite;
211
+ }
212
+
213
+ @keyframes gradient-shift {
214
+ 0%, 100% { background-position: 0% 50%; }
215
+ 50% { background-position: 100% 50%; }
216
+ }
217
+
218
+ /* Override gradient animation when custom animation is set */
219
+ :host([animation]:not([animation="none"])[variant="gradient"]) .progress-fill {
220
+ animation: none !important;
221
+ }
222
+
223
+ /* Glassmorphic variant - frosted glass effect */
224
+ :host([variant="glassmorphic"]) .stream-progress {
225
+ background: rgba(255, 255, 255, 0.1);
226
+ backdrop-filter: blur(10px);
227
+ -webkit-backdrop-filter: blur(10px);
228
+ border: 1px solid rgba(255, 255, 255, 0.2);
229
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
230
+ }
231
+
232
+ :host([variant="glassmorphic"]) .progress-bar {
233
+ background: rgba(0, 0, 0, 0.1);
234
+ }
235
+
236
+ :host([variant="glassmorphic"]) .progress-fill {
237
+ background: linear-gradient(
238
+ 90deg,
239
+ rgba(59, 130, 246, 0.8),
240
+ rgba(16, 185, 129, 0.8)
241
+ );
242
+ }
243
+
244
+ /* Animation Effects */
245
+
246
+ /* Striped animation - layer stripes on top of existing background */
247
+ :host([animation="striped"]) .streaming .progress-fill,
248
+ :host([animation="striped"]) .progress-fill {
249
+ background-image:
250
+ linear-gradient(
251
+ 45deg,
252
+ rgba(255, 255, 255, 0.2) 25%,
253
+ transparent 25%,
254
+ transparent 50%,
255
+ rgba(255, 255, 255, 0.2) 50%,
256
+ rgba(255, 255, 255, 0.2) 75%,
257
+ transparent 75%,
258
+ transparent
259
+ ),
260
+ linear-gradient(to right, var(--ai-primary-color, #3b82f6), var(--ai-primary-color, #3b82f6)) !important;
261
+ background-size: 2rem 2rem, 100% 100% !important;
262
+ animation: progress-stripes 3s linear infinite !important;
263
+ }
264
+
265
+ @keyframes progress-stripes {
266
+ 0% { background-position: 0 0, 0 0; }
267
+ 100% { background-position: 2rem 0, 0 0; }
268
+ }
269
+
270
+ /* Pulse animation */
271
+ :host([animation="pulse"]) .streaming .progress-fill,
272
+ :host([animation="pulse"]) .progress-fill {
273
+ animation: progress-pulse 4s ease-in-out infinite !important;
274
+ }
275
+
276
+ @keyframes progress-pulse {
277
+ 0%, 100% { opacity: 1; }
278
+ 50% { opacity: 0.3; }
279
+ }
280
+
281
+ /* Glow animation */
282
+ :host([animation="glow"]) .streaming .progress-fill,
283
+ :host([animation="glow"]) .progress-fill {
284
+ animation: progress-glow 4s ease-in-out infinite !important;
285
+ }
286
+
287
+ @keyframes progress-glow {
288
+ 0%, 100% {
289
+ box-shadow: 0 0 5px var(--ai-primary-color, #3b82f6),
290
+ 0 0 10px var(--ai-primary-color, #3b82f6);
291
+ }
292
+ 50% {
293
+ box-shadow: 0 0 20px var(--ai-primary-color, #3b82f6),
294
+ 0 0 35px var(--ai-primary-color, #3b82f6),
295
+ 0 0 50px var(--ai-primary-color, #3b82f6);
296
+ }
297
+ }
298
+
299
+ /* Dark mode support */
300
+ @media (prefers-color-scheme: dark) {
301
+ :host {
302
+ --ai-background-color: #1f2937;
303
+ --ai-text-color: #f9fafb;
304
+ --ai-border-color: #374151;
305
+ }
306
+
307
+ .progress-bar {
308
+ background: #374151;
309
+ }
310
+
311
+ .stat-label {
312
+ color: #9ca3af;
313
+ }
314
+ }
315
+
316
+ /* Reduced motion support */
317
+ @media (prefers-reduced-motion: reduce) {
318
+ .progress-fill {
319
+ transition: none;
320
+ }
321
+
322
+ .streaming .progress-fill {
323
+ animation: none;
324
+ }
325
+
326
+ .cancel-button {
327
+ transition: none;
328
+ }
329
+ }
330
+
331
+ /* Responsive design */
332
+ @media (max-width: 640px) {
333
+ .stats {
334
+ flex-direction: column;
335
+ align-items: flex-start;
336
+ }
337
+
338
+ .stat-item {
339
+ width: 100%;
340
+ }
341
+ }
342
+
343
+ /* Disabled state */
344
+ :host([disabled]) .stream-progress {
345
+ opacity: 0.5;
346
+ pointer-events: none;
347
+ }
348
+ </style>
349
+ `;
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Configuration for StreamProgress component
3
+ */
4
+ export interface StreamProgressConfig {
5
+ /** Maximum tokens allowed */
6
+ maxTokens?: number;
7
+ /** Cost per token (for cost estimation) */
8
+ costPerToken?: number;
9
+ /** Currency symbol */
10
+ currency?: string;
11
+ /** Show tokens per second */
12
+ showRate?: boolean;
13
+ /** Show cost estimation */
14
+ showCost?: boolean;
15
+ /** Show progress bar */
16
+ showProgressBar?: boolean;
17
+ /** Show cancel button */
18
+ showCancelButton?: boolean;
19
+ /** Enable smooth progress animation */
20
+ smoothProgress?: boolean;
21
+ /** Update throttle in milliseconds */
22
+ updateThrottle?: number;
23
+ /** Custom cancel button label */
24
+ cancelLabel?: string;
25
+ /** Enable automatic cursor state changes based on component state */
26
+ cursorFeedback?: boolean;
27
+ /** Component size variant */
28
+ size?: 'compact' | 'default' | 'large';
29
+ /** Visual style variant */
30
+ variant?: 'default' | 'minimal' | 'gradient' | 'glassmorphic';
31
+ /** Animation style */
32
+ animation?: 'none' | 'striped' | 'pulse' | 'glow';
33
+ /** Debug mode */
34
+ debug?: boolean;
35
+ /** Custom CSS class */
36
+ className?: string;
37
+ /** Aria label */
38
+ ariaLabel?: string;
39
+ }
40
+
41
+ /**
42
+ * State for StreamProgress
43
+ */
44
+ export interface StreamProgressState {
45
+ tokensGenerated: number;
46
+ tokensPerSecond: number;
47
+ totalCost: number;
48
+ isStreaming: boolean;
49
+ isPaused: boolean;
50
+ isCancelled: boolean;
51
+ startTime: number;
52
+ lastUpdateTime: number;
53
+ message?: string;
54
+ }
55
+
56
+ /**
57
+ * Event data for progress updates
58
+ */
59
+ export interface StreamProgressUpdate {
60
+ tokensGenerated: number;
61
+ tokensPerSecond?: number;
62
+ message?: string;
63
+ }
64
+
65
+ /**
66
+ * Event data for stream completion
67
+ */
68
+ export interface StreamCompleteEvent {
69
+ tokensGenerated: number;
70
+ duration: number;
71
+ totalCost: number;
72
+ averageRate: number;
73
+ }
74
+
75
+ /**
76
+ * Event data for stream cancellation
77
+ */
78
+ export interface StreamCancelEvent {
79
+ tokensGenerated: number;
80
+ duration: number;
81
+ reason: 'user' | 'error' | 'timeout';
82
+ }
package/src/index.ts ADDED
@@ -0,0 +1,19 @@
1
+ // Core exports
2
+ export * from './core/base';
3
+ export * from './core/stream-progress';
4
+ export * from './core/model-loader';
5
+ export * from './core/parameter-slider';
6
+ export * from './core/parameter-panel';
7
+ export * from './core/queue-progress';
8
+ export * from './core/retry-progress';
9
+ export * from './core/batch-progress';
10
+
11
+ // Re-export main classes for convenience
12
+ export { AIControl } from './core/base/AIControl';
13
+ export { StreamProgress } from './core/stream-progress/StreamProgress';
14
+ export { ModelLoader } from './core/model-loader/ModelLoader';
15
+ export { ParameterSlider } from './core/parameter-slider/ParameterSlider';
16
+ export { ParameterPanel } from './core/parameter-panel/ParameterPanel';
17
+ export { QueueProgress } from './core/queue-progress/QueueProgress';
18
+ export { RetryProgress } from './core/retry-progress/RetryProgress';
19
+ export { BatchProgress } from './core/batch-progress/BatchProgress';