@sensebox/flash-tool 0.1.0 → 1.0.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/dist/style.css CHANGED
@@ -15,7 +15,7 @@
15
15
  display: inline-flex;
16
16
  flex-direction: column;
17
17
  gap: 12px;
18
- width: 280px;
18
+ width: 100%;
19
19
  padding: 20px;
20
20
  border: 1px solid var(--sb-border);
21
21
  border-radius: 16px;
@@ -109,18 +109,19 @@
109
109
  letter-spacing: 0.04em;
110
110
  color: var(--sb-muted);
111
111
  }
112
- .sbflash__select-wrap {
112
+ .sbdropdown {
113
113
  position: relative;
114
- display: flex;
114
+ width: 100%;
115
115
  }
116
- .sbflash__select {
117
- flex: 1;
118
- appearance: none;
119
- -webkit-appearance: none;
116
+ .sbdropdown__trigger {
117
+ width: 100%;
118
+ display: flex;
119
+ align-items: center;
120
+ gap: 8px;
120
121
  border: 1px solid var(--sb-border);
121
122
  border-radius: 10px;
122
- background: var(--sb-surface) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%236b7a7a' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right 12px center;
123
- padding: 8px 32px 8px 12px;
123
+ background: var(--sb-surface);
124
+ padding: 8px 12px;
124
125
  font-size: 13px;
125
126
  font-weight: 600;
126
127
  font-family: inherit;
@@ -128,15 +129,121 @@
128
129
  cursor: pointer;
129
130
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
130
131
  }
131
- .sbflash__select:focus-visible {
132
+ .sbdropdown__trigger:hover:not(:disabled) {
133
+ border-color: var(--sb-secondary);
134
+ }
135
+ .sbdropdown__trigger:focus-visible {
132
136
  outline: none;
133
137
  border-color: var(--sb-secondary);
134
138
  box-shadow: 0 0 0 3px rgba(0, 204, 204, 0.18);
135
139
  }
136
- .sbflash__select:disabled {
140
+ .sbdropdown__trigger:disabled {
137
141
  opacity: 0.6;
138
142
  cursor: not-allowed;
139
143
  }
144
+ .sbdropdown__icon-slot {
145
+ display: flex;
146
+ align-items: center;
147
+ justify-content: center;
148
+ width: 18px;
149
+ height: 18px;
150
+ flex-shrink: 0;
151
+ color: var(--sb-muted);
152
+ }
153
+ .sbdropdown--open .sbdropdown__icon-slot,
154
+ .sbdropdown__option--selected .sbdropdown__icon-slot {
155
+ color: var(--sb-primary);
156
+ }
157
+ .sbdropdown__trigger-label {
158
+ flex: 1;
159
+ text-align: left;
160
+ overflow: hidden;
161
+ text-overflow: ellipsis;
162
+ white-space: nowrap;
163
+ }
164
+ .sbdropdown__chevron {
165
+ flex-shrink: 0;
166
+ color: var(--sb-muted);
167
+ transition: transform 0.2s cubic-bezier(0.25, 1, 0.5, 1);
168
+ }
169
+ .sbdropdown--open .sbdropdown__chevron {
170
+ transform: rotate(180deg);
171
+ }
172
+ .sbdropdown__menu {
173
+ position: absolute;
174
+ top: calc(100% + 6px);
175
+ left: 0;
176
+ right: 0;
177
+ z-index: 20;
178
+ margin: 0;
179
+ padding: 6px;
180
+ list-style: none;
181
+ background: #ffffff;
182
+ border: 1px solid var(--sb-border);
183
+ border-radius: 12px;
184
+ box-shadow: 0 10px 30px rgba(28, 43, 43, 0.14), 0 2px 8px rgba(28, 43, 43, 0.08);
185
+ max-height: 260px;
186
+ overflow: auto;
187
+ opacity: 0;
188
+ visibility: hidden;
189
+ transform: translateY(-6px) scale(0.98);
190
+ transform-origin: top center;
191
+ transition:
192
+ opacity 0.16s ease,
193
+ transform 0.16s cubic-bezier(0.25, 1, 0.5, 1),
194
+ visibility 0s linear 0.16s;
195
+ pointer-events: none;
196
+ }
197
+ .sbdropdown--open .sbdropdown__menu {
198
+ opacity: 1;
199
+ visibility: visible;
200
+ transform: translateY(0) scale(1);
201
+ pointer-events: auto;
202
+ transition:
203
+ opacity 0.16s ease,
204
+ transform 0.16s cubic-bezier(0.25, 1, 0.5, 1),
205
+ visibility 0s linear 0s;
206
+ }
207
+ .sbdropdown__option {
208
+ width: 100%;
209
+ display: flex;
210
+ align-items: center;
211
+ gap: 8px;
212
+ padding: 8px 10px;
213
+ border: none;
214
+ border-radius: 8px;
215
+ background: transparent;
216
+ font-family: inherit;
217
+ font-size: 13px;
218
+ font-weight: 500;
219
+ color: var(--sb-ink);
220
+ cursor: pointer;
221
+ text-align: left;
222
+ transition: background-color 0.12s ease;
223
+ }
224
+ .sbdropdown__option:disabled {
225
+ opacity: 0.5;
226
+ cursor: not-allowed;
227
+ }
228
+ .sbdropdown__option--active {
229
+ background: var(--sb-surface);
230
+ }
231
+ .sbdropdown__option--selected {
232
+ font-weight: 700;
233
+ }
234
+ .sbdropdown__option--selected .sbdropdown__option-label {
235
+ color: var(--sb-primary-dark);
236
+ }
237
+ .sbdropdown__option-label {
238
+ flex: 1;
239
+ overflow: hidden;
240
+ text-overflow: ellipsis;
241
+ white-space: nowrap;
242
+ }
243
+ .sbdropdown__option-check {
244
+ flex-shrink: 0;
245
+ color: var(--sb-primary);
246
+ }
140
247
  .sbflash__button {
141
248
  border: none;
142
249
  border-radius: 999px;
@@ -172,6 +279,119 @@
172
279
  .sbflash__button--secondary:hover:not(:disabled) {
173
280
  background: var(--sb-border);
174
281
  }
282
+ .sbflash__stepper {
283
+ display: flex;
284
+ flex-direction: column;
285
+ margin: 0;
286
+ padding: 0;
287
+ list-style: none;
288
+ }
289
+ .sbflash__step {
290
+ display: flex;
291
+ gap: 12px;
292
+ }
293
+ .sbflash__step-marker {
294
+ display: flex;
295
+ flex-direction: column;
296
+ align-items: center;
297
+ flex-shrink: 0;
298
+ }
299
+ .sbflash__step-index {
300
+ display: flex;
301
+ align-items: center;
302
+ justify-content: center;
303
+ width: 22px;
304
+ height: 22px;
305
+ border-radius: 50%;
306
+ font-size: 11px;
307
+ font-weight: 700;
308
+ background: var(--sb-surface);
309
+ color: var(--sb-faint);
310
+ border: 1.5px solid var(--sb-border);
311
+ transition:
312
+ background-color 0.15s ease,
313
+ border-color 0.15s ease,
314
+ color 0.15s ease;
315
+ }
316
+ .sbflash__step-line {
317
+ flex: 1;
318
+ width: 2px;
319
+ min-height: 18px;
320
+ margin: 2px 0;
321
+ background: var(--sb-border);
322
+ transition: background-color 0.15s ease;
323
+ }
324
+ .sbflash__step-line--done {
325
+ background: var(--sb-primary);
326
+ }
327
+ .sbflash__step-body {
328
+ display: flex;
329
+ flex-direction: column;
330
+ align-items: flex-start;
331
+ gap: 6px;
332
+ padding-bottom: 18px;
333
+ }
334
+ .sbflash__step-title {
335
+ font-size: 12px;
336
+ font-weight: 600;
337
+ letter-spacing: -0.01em;
338
+ color: var(--sb-faint);
339
+ transition: color 0.15s ease;
340
+ }
341
+ .sbflash__step-hint {
342
+ font-size: 12px;
343
+ color: var(--sb-muted);
344
+ }
345
+ .sbflash__step-detail {
346
+ font-size: 12px;
347
+ font-weight: 500;
348
+ color: var(--sb-ink);
349
+ overflow: hidden;
350
+ text-overflow: ellipsis;
351
+ white-space: nowrap;
352
+ max-width: 100%;
353
+ }
354
+ .sbflash__step--active .sbflash__step-index {
355
+ background: var(--sb-secondary);
356
+ border-color: var(--sb-secondary);
357
+ color: #ffffff;
358
+ box-shadow: 0 0 0 4px rgba(0, 204, 204, 0.16);
359
+ }
360
+ .sbflash__step--active .sbflash__step-title {
361
+ color: var(--sb-ink);
362
+ }
363
+ .sbflash__step--done .sbflash__step-index {
364
+ background: var(--sb-primary);
365
+ border-color: var(--sb-primary);
366
+ color: #ffffff;
367
+ }
368
+ .sbflash__step--done .sbflash__step-title {
369
+ color: var(--sb-muted);
370
+ }
371
+ .sbflash__step--error .sbflash__step-index {
372
+ background: var(--sb-red);
373
+ border-color: var(--sb-red);
374
+ color: #ffffff;
375
+ }
376
+ .sbflash__step--error .sbflash__step-title {
377
+ color: var(--sb-ink);
378
+ }
379
+ .sbflash__step--pending .sbflash__step-body {
380
+ opacity: 0.55;
381
+ }
382
+ .sbflash__field-description {
383
+ font-size: 12px;
384
+ line-height: 1.5;
385
+ color: var(--sb-muted);
386
+ }
387
+ .sbflash__field-description a {
388
+ color: var(--sb-secondary-dark);
389
+ font-weight: 500;
390
+ text-decoration: none;
391
+ }
392
+ .sbflash__field-description a:hover {
393
+ text-decoration: underline;
394
+ }
175
395
  .sbflash__link {
176
396
  background: none;
177
397
  border: none;
@@ -265,6 +485,63 @@
265
485
  .sbflash__status--error {
266
486
  color: var(--sb-red);
267
487
  }
488
+ .sbflash__done-banner {
489
+ display: flex;
490
+ align-items: center;
491
+ flex-wrap: wrap;
492
+ gap: 10px;
493
+ padding: 12px 14px;
494
+ border-radius: 12px;
495
+ background: rgba(102, 153, 51, 0.12);
496
+ border: 1px solid rgba(102, 153, 51, 0.3);
497
+ box-shadow: 0 4px 14px rgba(102, 153, 51, 0.16);
498
+ animation: sbflash-done-in 0.35s cubic-bezier(0.25, 1, 0.5, 1);
499
+ }
500
+ .sbflash__done-icon {
501
+ display: flex;
502
+ align-items: center;
503
+ justify-content: center;
504
+ flex-shrink: 0;
505
+ width: 28px;
506
+ height: 28px;
507
+ border-radius: 50%;
508
+ background: var(--sb-primary);
509
+ color: #ffffff;
510
+ box-shadow: 0 0 0 5px rgba(102, 153, 51, 0.16);
511
+ animation: sbflash-done-pop 0.45s cubic-bezier(0.25, 1, 0.5, 1);
512
+ }
513
+ .sbflash__done-icon svg {
514
+ width: 16px;
515
+ height: 16px;
516
+ }
517
+ .sbflash__done-text {
518
+ flex: 1;
519
+ font-size: 14px;
520
+ font-weight: 700;
521
+ letter-spacing: -0.01em;
522
+ color: var(--sb-primary-dark);
523
+ }
524
+ @keyframes sbflash-done-in {
525
+ from {
526
+ opacity: 0;
527
+ transform: translateY(4px);
528
+ }
529
+ to {
530
+ opacity: 1;
531
+ transform: translateY(0);
532
+ }
533
+ }
534
+ @keyframes sbflash-done-pop {
535
+ 0% {
536
+ transform: scale(0.5);
537
+ }
538
+ 60% {
539
+ transform: scale(1.15);
540
+ }
541
+ 100% {
542
+ transform: scale(1);
543
+ }
544
+ }
268
545
  .sbflash__icon-row {
269
546
  display: flex;
270
547
  align-items: center;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sensebox/flash-tool",
3
- "version": "0.1.0",
3
+ "version": "1.0.0",
4
4
  "description": "Drop-in React widget for flashing ESP32-based boards (e.g. senseBox MCU-S2) over the Web Serial API.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",