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.
- package/LICENSE +21 -0
- package/README.md +823 -0
- package/dist/ai-progress-controls.es.js +7191 -0
- package/dist/ai-progress-controls.es.js.map +1 -0
- package/dist/ai-progress-controls.umd.js +2 -0
- package/dist/ai-progress-controls.umd.js.map +1 -0
- package/dist/index.d.ts +2212 -0
- package/package.json +105 -0
- package/src/__tests__/setup.ts +93 -0
- package/src/core/base/AIControl.ts +230 -0
- package/src/core/base/index.ts +3 -0
- package/src/core/base/types.ts +77 -0
- package/src/core/base/utils.ts +168 -0
- package/src/core/batch-progress/BatchProgress.test.ts +458 -0
- package/src/core/batch-progress/BatchProgress.ts +760 -0
- package/src/core/batch-progress/index.ts +14 -0
- package/src/core/batch-progress/styles.ts +480 -0
- package/src/core/batch-progress/types.ts +169 -0
- package/src/core/model-loader/ModelLoader.test.ts +311 -0
- package/src/core/model-loader/ModelLoader.ts +673 -0
- package/src/core/model-loader/index.ts +2 -0
- package/src/core/model-loader/styles.ts +496 -0
- package/src/core/model-loader/types.ts +127 -0
- package/src/core/parameter-panel/ParameterPanel.test.ts +856 -0
- package/src/core/parameter-panel/ParameterPanel.ts +877 -0
- package/src/core/parameter-panel/index.ts +14 -0
- package/src/core/parameter-panel/styles.ts +323 -0
- package/src/core/parameter-panel/types.ts +278 -0
- package/src/core/parameter-slider/ParameterSlider.test.ts +299 -0
- package/src/core/parameter-slider/ParameterSlider.ts +653 -0
- package/src/core/parameter-slider/index.ts +8 -0
- package/src/core/parameter-slider/styles.ts +493 -0
- package/src/core/parameter-slider/types.ts +107 -0
- package/src/core/queue-progress/QueueProgress.test.ts +344 -0
- package/src/core/queue-progress/QueueProgress.ts +563 -0
- package/src/core/queue-progress/index.ts +5 -0
- package/src/core/queue-progress/styles.ts +469 -0
- package/src/core/queue-progress/types.ts +130 -0
- package/src/core/retry-progress/RetryProgress.test.ts +397 -0
- package/src/core/retry-progress/RetryProgress.ts +957 -0
- package/src/core/retry-progress/index.ts +6 -0
- package/src/core/retry-progress/styles.ts +530 -0
- package/src/core/retry-progress/types.ts +176 -0
- package/src/core/stream-progress/StreamProgress.test.ts +531 -0
- package/src/core/stream-progress/StreamProgress.ts +517 -0
- package/src/core/stream-progress/index.ts +2 -0
- package/src/core/stream-progress/styles.ts +349 -0
- package/src/core/stream-progress/types.ts +82 -0
- package/src/index.ts +19 -0
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
export const styles = `
|
|
2
|
+
<style>
|
|
3
|
+
:host {
|
|
4
|
+
/* CSS variables inherit from document root with fallback defaults */
|
|
5
|
+
display: block;
|
|
6
|
+
font-family: var(--ai-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif);
|
|
7
|
+
font-size: var(--ai-font-size, 14px);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
:host([style*="cursor: progress"]) .model-loader {
|
|
11
|
+
cursor: progress;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
:host([style*="cursor: not-allowed"]) .model-loader {
|
|
15
|
+
cursor: not-allowed;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
:host([style*="cursor: default"]) .model-loader {
|
|
19
|
+
cursor: default;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.model-loader {
|
|
23
|
+
background: var(--ai-background-color, #ffffff);
|
|
24
|
+
border: 1px solid var(--ai-border-color, #e5e7eb);
|
|
25
|
+
border-radius: var(--ai-border-radius, 8px);
|
|
26
|
+
padding: var(--ai-spacing, 12px);
|
|
27
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.model-loader.loading {
|
|
31
|
+
border-color: var(--ai-primary-color, #3b82f6);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.model-loader.error {
|
|
35
|
+
border-color: #ef4444;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.model-loader.completed {
|
|
39
|
+
border-color: var(--ai-secondary-color, #10b981);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.header {
|
|
43
|
+
display: flex;
|
|
44
|
+
align-items: center;
|
|
45
|
+
justify-content: space-between;
|
|
46
|
+
margin-bottom: var(--ai-spacing, 12px);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.model-name {
|
|
50
|
+
font-size: 15px;
|
|
51
|
+
font-weight: 600;
|
|
52
|
+
color: var(--ai-text-color, #1f2937);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.status-badge {
|
|
56
|
+
padding: 4px 10px;
|
|
57
|
+
border-radius: 12px;
|
|
58
|
+
font-size: 11px;
|
|
59
|
+
font-weight: 600;
|
|
60
|
+
text-transform: uppercase;
|
|
61
|
+
letter-spacing: 0.5px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.status-badge.loading {
|
|
65
|
+
background: #dbeafe;
|
|
66
|
+
color: #1e40af;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.status-badge.completed {
|
|
70
|
+
background: #d1fae5;
|
|
71
|
+
color: #065f46;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.status-badge.error {
|
|
75
|
+
background: #fee2e2;
|
|
76
|
+
color: #991b1b;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.stages {
|
|
80
|
+
display: flex;
|
|
81
|
+
flex-direction: column;
|
|
82
|
+
gap: var(--ai-spacing, 12px);
|
|
83
|
+
margin-bottom: var(--ai-spacing, 12px);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.stage {
|
|
87
|
+
display: flex;
|
|
88
|
+
flex-direction: column;
|
|
89
|
+
gap: 6px;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.stage-header {
|
|
93
|
+
display: flex;
|
|
94
|
+
align-items: center;
|
|
95
|
+
justify-content: space-between;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.stage-info {
|
|
99
|
+
display: flex;
|
|
100
|
+
align-items: center;
|
|
101
|
+
gap: 8px;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.stage-icon {
|
|
105
|
+
width: 24px;
|
|
106
|
+
height: 24px;
|
|
107
|
+
border-radius: 50%;
|
|
108
|
+
display: flex;
|
|
109
|
+
align-items: center;
|
|
110
|
+
justify-content: center;
|
|
111
|
+
font-size: 12px;
|
|
112
|
+
font-weight: bold;
|
|
113
|
+
flex-shrink: 0;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.stage-icon.pending {
|
|
117
|
+
background: #f3f4f6;
|
|
118
|
+
color: #9ca3af;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.stage-icon.in-progress {
|
|
122
|
+
background: #dbeafe;
|
|
123
|
+
color: #1e40af;
|
|
124
|
+
animation: pulse 2s ease-in-out infinite;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.stage-icon.completed {
|
|
128
|
+
background: #d1fae5;
|
|
129
|
+
color: #065f46;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.stage-icon.error {
|
|
133
|
+
background: #fee2e2;
|
|
134
|
+
color: #991b1b;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
@keyframes pulse {
|
|
138
|
+
0%, 100% {
|
|
139
|
+
opacity: 1;
|
|
140
|
+
}
|
|
141
|
+
50% {
|
|
142
|
+
opacity: 0.7;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.stage-name {
|
|
147
|
+
font-size: 13px;
|
|
148
|
+
font-weight: 600;
|
|
149
|
+
color: var(--ai-text-color, #1f2937);
|
|
150
|
+
text-transform: capitalize;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.stage-progress-text {
|
|
154
|
+
font-size: 12px;
|
|
155
|
+
color: #6b7280;
|
|
156
|
+
font-weight: 600;
|
|
157
|
+
font-variant-numeric: tabular-nums;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.stage-message {
|
|
161
|
+
font-size: 12px;
|
|
162
|
+
color: #6b7280;
|
|
163
|
+
padding-left: 32px;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.progress-bar {
|
|
167
|
+
width: 100%;
|
|
168
|
+
height: 6px;
|
|
169
|
+
background: #f3f4f6;
|
|
170
|
+
border-radius: 3px;
|
|
171
|
+
overflow: hidden;
|
|
172
|
+
margin-left: 32px;
|
|
173
|
+
width: calc(100% - 32px);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.progress-fill {
|
|
177
|
+
height: 100%;
|
|
178
|
+
background: linear-gradient(90deg, var(--ai-primary-color, #3b82f6), var(--ai-secondary-color, #10b981));
|
|
179
|
+
transition: width 0.3s ease;
|
|
180
|
+
border-radius: 3px;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.progress-fill.error {
|
|
184
|
+
background: #ef4444;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.stage.in-progress .progress-fill {
|
|
188
|
+
animation: shimmer 2s ease-in-out infinite;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
@keyframes shimmer {
|
|
192
|
+
0% {
|
|
193
|
+
opacity: 1;
|
|
194
|
+
}
|
|
195
|
+
50% {
|
|
196
|
+
opacity: 0.7;
|
|
197
|
+
}
|
|
198
|
+
100% {
|
|
199
|
+
opacity: 1;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/* Override default animation when animation attribute is set */
|
|
204
|
+
:host([animation]) .stage.in-progress .progress-fill {
|
|
205
|
+
animation: none !important;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.stats {
|
|
209
|
+
display: grid;
|
|
210
|
+
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
|
|
211
|
+
gap: var(--ai-spacing, 12px);
|
|
212
|
+
padding-top: var(--ai-spacing, 12px);
|
|
213
|
+
border-top: 1px solid var(--ai-border-color, #e5e7eb);
|
|
214
|
+
margin-top: var(--ai-spacing, 12px);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.stat-item {
|
|
218
|
+
display: flex;
|
|
219
|
+
flex-direction: column;
|
|
220
|
+
gap: 4px;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.stat-label {
|
|
224
|
+
font-size: 11px;
|
|
225
|
+
color: #6b7280;
|
|
226
|
+
text-transform: uppercase;
|
|
227
|
+
letter-spacing: 0.5px;
|
|
228
|
+
font-weight: 600;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.stat-value {
|
|
232
|
+
font-size: 15px;
|
|
233
|
+
color: var(--ai-text-color, #1f2937);
|
|
234
|
+
font-weight: 600;
|
|
235
|
+
font-variant-numeric: tabular-nums;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.error-message {
|
|
239
|
+
background: #fef2f2;
|
|
240
|
+
border: 1px solid #fecaca;
|
|
241
|
+
border-radius: 6px;
|
|
242
|
+
padding: 12px;
|
|
243
|
+
margin-top: var(--ai-spacing, 12px);
|
|
244
|
+
display: flex;
|
|
245
|
+
align-items: flex-start;
|
|
246
|
+
gap: 8px;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.error-icon {
|
|
250
|
+
color: #dc2626;
|
|
251
|
+
font-size: 18px;
|
|
252
|
+
flex-shrink: 0;
|
|
253
|
+
margin-top: 2px;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.error-text {
|
|
257
|
+
color: #991b1b;
|
|
258
|
+
font-size: 13px;
|
|
259
|
+
line-height: 1.5;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.retry-button {
|
|
263
|
+
width: 100%;
|
|
264
|
+
padding: 10px 16px;
|
|
265
|
+
background: var(--ai-primary-color, #3b82f6);
|
|
266
|
+
color: white;
|
|
267
|
+
border: none;
|
|
268
|
+
border-radius: calc(var(--ai-border-radius, 8px) * 0.75);
|
|
269
|
+
font-size: 13px;
|
|
270
|
+
font-weight: 600;
|
|
271
|
+
cursor: pointer;
|
|
272
|
+
transition: background 0.2s ease;
|
|
273
|
+
font-family: inherit;
|
|
274
|
+
margin-top: var(--ai-spacing, 12px);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.retry-button:hover {
|
|
278
|
+
background: #2563eb;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.retry-button:active {
|
|
282
|
+
transform: translateY(1px);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
.retry-button:focus-visible {
|
|
286
|
+
outline: 2px solid var(--ai-primary-color, #3b82f6);
|
|
287
|
+
outline-offset: 2px;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/* Visual Variants */
|
|
291
|
+
|
|
292
|
+
/* Minimal variant - clean, no shadows */
|
|
293
|
+
:host([variant="minimal"]) .model-loader {
|
|
294
|
+
box-shadow: none;
|
|
295
|
+
border: 1px solid var(--ai-border-color, #e5e7eb);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
:host([variant="minimal"]) .progress-bar {
|
|
299
|
+
background: transparent;
|
|
300
|
+
border: 1px solid var(--ai-border-color, #e5e7eb);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/* Gradient variant - colorful gradients */
|
|
304
|
+
:host([variant="gradient"]) .progress-fill {
|
|
305
|
+
background: linear-gradient(
|
|
306
|
+
90deg,
|
|
307
|
+
var(--ai-primary-color, #3b82f6),
|
|
308
|
+
var(--ai-secondary-color, #10b981),
|
|
309
|
+
var(--ai-primary-color, #3b82f6)
|
|
310
|
+
);
|
|
311
|
+
background-size: 200% 100%;
|
|
312
|
+
animation: gradient-shift 3s ease-in-out infinite;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
@keyframes gradient-shift {
|
|
316
|
+
0%, 100% { background-position: 0% 50%; }
|
|
317
|
+
50% { background-position: 100% 50%; }
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/* Override default animation when animation attribute is set */
|
|
321
|
+
:host([animation][variant="gradient"]) .progress-fill {
|
|
322
|
+
animation: none !important;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/* Glassmorphic variant - frosted glass effect */
|
|
326
|
+
:host([variant="glassmorphic"]) .model-loader {
|
|
327
|
+
background: rgba(255, 255, 255, 0.1);
|
|
328
|
+
backdrop-filter: blur(10px);
|
|
329
|
+
-webkit-backdrop-filter: blur(10px);
|
|
330
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
331
|
+
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
:host([variant="glassmorphic"]) .progress-bar {
|
|
335
|
+
background: rgba(0, 0, 0, 0.1);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
:host([variant="glassmorphic"]) .progress-fill {
|
|
339
|
+
background: linear-gradient(
|
|
340
|
+
90deg,
|
|
341
|
+
rgba(59, 130, 246, 0.8),
|
|
342
|
+
rgba(16, 185, 129, 0.8)
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/* Animation Effects */
|
|
347
|
+
|
|
348
|
+
/* Striped animation */
|
|
349
|
+
:host([animation="striped"]) .progress-fill {
|
|
350
|
+
background-image:
|
|
351
|
+
linear-gradient(
|
|
352
|
+
45deg,
|
|
353
|
+
rgba(255, 255, 255, 0.2) 25%,
|
|
354
|
+
transparent 25%,
|
|
355
|
+
transparent 50%,
|
|
356
|
+
rgba(255, 255, 255, 0.2) 50%,
|
|
357
|
+
rgba(255, 255, 255, 0.2) 75%,
|
|
358
|
+
transparent 75%,
|
|
359
|
+
transparent
|
|
360
|
+
),
|
|
361
|
+
linear-gradient(to right, var(--ai-primary-color, #3b82f6), var(--ai-primary-color, #3b82f6)) !important;
|
|
362
|
+
background-size: 2rem 2rem, 100% 100% !important;
|
|
363
|
+
animation: progress-stripes 3s linear infinite !important;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
@keyframes progress-stripes {
|
|
367
|
+
0% { background-position: 0 0, 0 0; }
|
|
368
|
+
100% { background-position: 2rem 0, 0 0; }
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/* Pulse animation */
|
|
372
|
+
:host([animation="pulse"]) .progress-fill {
|
|
373
|
+
animation: progress-pulse 4s ease-in-out infinite !important;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
@keyframes progress-pulse {
|
|
377
|
+
0%, 100% { opacity: 1; }
|
|
378
|
+
50% { opacity: 0.3; }
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/* Glow animation */
|
|
382
|
+
:host([animation="glow"]) .progress-fill {
|
|
383
|
+
animation: progress-glow 4s ease-in-out infinite !important;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
@keyframes progress-glow {
|
|
387
|
+
0%, 100% {
|
|
388
|
+
box-shadow: 0 0 5px var(--ai-primary-color, #3b82f6),
|
|
389
|
+
0 0 10px var(--ai-primary-color, #3b82f6);
|
|
390
|
+
}
|
|
391
|
+
50% {
|
|
392
|
+
box-shadow: 0 0 20px var(--ai-primary-color, #3b82f6),
|
|
393
|
+
0 0 35px var(--ai-primary-color, #3b82f6),
|
|
394
|
+
0 0 50px var(--ai-primary-color, #3b82f6);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/* Dark mode support - variables can be overridden at document level */
|
|
399
|
+
@media (prefers-color-scheme: dark) {
|
|
400
|
+
.progress-bar {
|
|
401
|
+
background: #374151;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
.stat-label,
|
|
405
|
+
.stage-message,
|
|
406
|
+
.stage-progress-text {
|
|
407
|
+
color: #9ca3af;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
.error-message {
|
|
411
|
+
background: #450a0a;
|
|
412
|
+
border-color: #7f1d1d;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/* Reduced motion support */
|
|
417
|
+
@media (prefers-reduced-motion: reduce) {
|
|
418
|
+
.progress-fill,
|
|
419
|
+
.stage-icon.in-progress,
|
|
420
|
+
.stage.in-progress .progress-fill {
|
|
421
|
+
animation: none;
|
|
422
|
+
transition: none;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
.retry-button {
|
|
426
|
+
transition: none;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/* Size variants */
|
|
431
|
+
:host([size="compact"]) .model-loader {
|
|
432
|
+
padding: 8px;
|
|
433
|
+
font-size: 12px;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
:host([size="compact"]) .progress-bar {
|
|
437
|
+
height: 6px;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
:host([size="compact"]) .model-name {
|
|
441
|
+
font-size: 13px;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
:host([size="compact"]) .status-badge {
|
|
445
|
+
padding: 3px 8px;
|
|
446
|
+
font-size: 10px;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
:host([size="compact"]) .stage-name {
|
|
450
|
+
font-size: 11px;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
:host([size="compact"]) .stat-value {
|
|
454
|
+
font-size: 14px;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
:host([size="large"]) .model-loader {
|
|
458
|
+
padding: 16px;
|
|
459
|
+
font-size: 16px;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
:host([size="large"]) .progress-bar {
|
|
463
|
+
height: 10px;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
:host([size="large"]) .model-name {
|
|
467
|
+
font-size: 17px;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
:host([size="large"]) .status-badge {
|
|
471
|
+
padding: 5px 12px;
|
|
472
|
+
font-size: 12px;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
:host([size="large"]) .stage-name {
|
|
476
|
+
font-size: 15px;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
:host([size="large"]) .stat-value {
|
|
480
|
+
font-size: 18px;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/* Responsive design */
|
|
484
|
+
@media (max-width: 640px) {
|
|
485
|
+
.stats {
|
|
486
|
+
grid-template-columns: 1fr;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/* Disabled state */
|
|
491
|
+
:host([disabled]) .model-loader {
|
|
492
|
+
opacity: 0.5;
|
|
493
|
+
pointer-events: none;
|
|
494
|
+
}
|
|
495
|
+
</style>
|
|
496
|
+
`;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loading stages for model initialization
|
|
3
|
+
*/
|
|
4
|
+
export type ModelStage = 'download' | 'load' | 'initialize' | 'ready';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Status of each stage
|
|
8
|
+
*/
|
|
9
|
+
export type StageStatus = 'pending' | 'in-progress' | 'completed' | 'error';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Configuration for ModelLoader component
|
|
13
|
+
*/
|
|
14
|
+
export interface ModelLoaderConfig {
|
|
15
|
+
/** Stages to show (default: all) */
|
|
16
|
+
stages?: ModelStage[];
|
|
17
|
+
|
|
18
|
+
/** Model name to display */
|
|
19
|
+
modelName?: string;
|
|
20
|
+
|
|
21
|
+
/** Show bytes downloaded/total */
|
|
22
|
+
showBytes?: boolean;
|
|
23
|
+
|
|
24
|
+
/** Show memory usage */
|
|
25
|
+
showMemoryUsage?: boolean;
|
|
26
|
+
|
|
27
|
+
/** Show estimated time remaining */
|
|
28
|
+
showETA?: boolean;
|
|
29
|
+
|
|
30
|
+
/** Show retry button on error */
|
|
31
|
+
showRetryButton?: boolean;
|
|
32
|
+
|
|
33
|
+
/** Enable smooth progress animation */
|
|
34
|
+
smoothProgress?: boolean;
|
|
35
|
+
|
|
36
|
+
/** Update throttle in milliseconds */
|
|
37
|
+
updateThrottle?: number;
|
|
38
|
+
|
|
39
|
+
/** Custom retry button label */
|
|
40
|
+
retryLabel?: string;
|
|
41
|
+
|
|
42
|
+
/** Enable automatic cursor state changes based on component state */
|
|
43
|
+
cursorFeedback?: boolean;
|
|
44
|
+
|
|
45
|
+
/** Component size variant */
|
|
46
|
+
size?: 'compact' | 'default' | 'large';
|
|
47
|
+
|
|
48
|
+
/** Visual style variant */
|
|
49
|
+
variant?: 'default' | 'minimal' | 'gradient' | 'glassmorphic';
|
|
50
|
+
|
|
51
|
+
/** Animation style */
|
|
52
|
+
animation?: 'none' | 'striped' | 'pulse' | 'glow';
|
|
53
|
+
|
|
54
|
+
/** Debug mode */
|
|
55
|
+
debug?: boolean;
|
|
56
|
+
|
|
57
|
+
/** Custom CSS class */
|
|
58
|
+
className?: string;
|
|
59
|
+
|
|
60
|
+
/** Aria label */
|
|
61
|
+
ariaLabel?: string;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* State for each stage
|
|
66
|
+
*/
|
|
67
|
+
export interface StageState {
|
|
68
|
+
status: StageStatus;
|
|
69
|
+
progress: number; // 0-100
|
|
70
|
+
message?: string;
|
|
71
|
+
bytesLoaded?: number;
|
|
72
|
+
totalBytes?: number;
|
|
73
|
+
startTime?: number;
|
|
74
|
+
endTime?: number;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Overall ModelLoader state
|
|
79
|
+
*/
|
|
80
|
+
export interface ModelLoaderState {
|
|
81
|
+
currentStage: ModelStage;
|
|
82
|
+
stages: Record<ModelStage, StageState>;
|
|
83
|
+
isLoading: boolean;
|
|
84
|
+
hasError: boolean;
|
|
85
|
+
errorMessage?: string;
|
|
86
|
+
memoryUsage?: number; // in MB
|
|
87
|
+
startTime: number;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Update data for a stage
|
|
92
|
+
*/
|
|
93
|
+
export interface StageUpdate {
|
|
94
|
+
stage: ModelStage;
|
|
95
|
+
progress?: number; // 0-100
|
|
96
|
+
bytesLoaded?: number;
|
|
97
|
+
totalBytes?: number;
|
|
98
|
+
message?: string;
|
|
99
|
+
memoryUsage?: number;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Event data for stage change
|
|
104
|
+
*/
|
|
105
|
+
export interface StageChangeEvent {
|
|
106
|
+
previousStage: ModelStage;
|
|
107
|
+
currentStage: ModelStage;
|
|
108
|
+
timestamp: number;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Event data for completion
|
|
113
|
+
*/
|
|
114
|
+
export interface LoadCompleteEvent {
|
|
115
|
+
duration: number;
|
|
116
|
+
memoryUsage?: number;
|
|
117
|
+
stages: Record<ModelStage, StageState>;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Event data for error
|
|
122
|
+
*/
|
|
123
|
+
export interface LoadErrorEvent {
|
|
124
|
+
stage: ModelStage;
|
|
125
|
+
message: string;
|
|
126
|
+
timestamp: number;
|
|
127
|
+
}
|