@jjlmoya/utils-hardware 1.12.0 → 1.14.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.
@@ -15,127 +15,7 @@ const t = (ui ?? {}) as ProbadorVibracionMandoUI;
15
15
  <div id="pv-root" class="pv-wrapper"
16
16
  data-s={JSON.stringify({ f: t.deviceFallback, cs: t.deviceConnectedSub, d: t.deviceDisconnected, ds: t.deviceDisconnectedSub })}>
17
17
 
18
- <style is:global>
19
- .pv-status-header.pv-connected {
20
- background: rgba(16, 185, 129, 0.1);
21
- border-color: rgba(16, 185, 129, 0.2);
22
- box-shadow: inset 0 0 20px rgba(16, 185, 129, 0.1);
23
- }
24
-
25
- .pv-status-header.pv-connected .pv-status-avatar {
26
- background: #10b981;
27
- color: white;
28
- box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
29
- animation: pv-bounce-in 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
30
- }
31
-
32
- .pv-status-header.pv-connected .pv-indicator {
33
- background: #10b981;
34
- box-shadow: 0 0 10px rgba(16, 185, 129, 0.4);
35
- }
36
-
37
- .pv-tab-btn.pv-active {
38
- background: var(--pv-surface);
39
- color: var(--pv-accent);
40
- box-shadow: 0 4px 10px rgba(0, 0, 0, 0.07);
41
- }
42
-
43
- .pv-preset-card.pv-vibrating {
44
- animation: pv-card-shake 0.1s infinite;
45
- background: var(--pv-accent);
46
- color: white;
47
- border-color: var(--pv-accent);
48
- }
49
-
50
- .pv-preset-card.pv-vibrating .pv-preset-icon {
51
- color: white;
52
- background: rgba(255, 255, 255, 0.2);
53
- }
54
-
55
- .pv-preset-card.pv-vibrating .pv-preset-desc {
56
- color: rgba(255, 255, 255, 0.8);
57
- }
58
-
59
- .pv-warning.pv-visible {
60
- display: block;
61
- }
62
-
63
- .pv-wrapper {
64
- --pv-accent: #8b5cf6;
65
- --pv-accent-glow: rgba(139, 92, 246, 0.4);
66
- --pv-accent-secondary: #ec4899;
67
- --pv-surface: #fff;
68
- --pv-surface-alt: #f1f5f9;
69
- --pv-surface-hover: #e2e8f0;
70
- --pv-border: rgba(0, 0, 0, 0.08);
71
- --pv-text: #1e293b;
72
- --pv-text-muted: #64748b;
73
- --pv-danger: #ef4444;
74
- }
75
-
76
- .theme-dark .pv-wrapper {
77
- --pv-surface: #0f172a;
78
- --pv-surface-alt: rgba(30, 41, 59, 0.8);
79
- --pv-surface-hover: rgba(51, 65, 85, 0.8);
80
- --pv-border: rgba(255, 255, 255, 0.1);
81
- --pv-text: #f8fafc;
82
- --pv-text-muted: #94a3b8;
83
- }
84
-
85
- .theme-dark .pv-card {
86
- box-shadow: 0 20px 40px -10px rgba(0, 0, 0, 0.5);
87
- }
88
-
89
- .theme-dark .pv-warning {
90
- background: rgba(245, 158, 11, 0.1);
91
- color: #fcd34d;
92
- }
93
-
94
- .pv-tab-pane {
95
- display: none;
96
- animation: pv-fade-up 300ms ease;
97
- }
98
-
99
- .pv-tab-pane.pv-active {
100
- display: flex;
101
- flex-direction: column;
102
- gap: 1.5rem;
103
- }
104
-
105
- @keyframes pv-bounce-in {
106
- 0% {
107
- transform: scale(0.5);
108
- opacity: 0;
109
- }
110
- 80% {
111
- transform: scale(1.1);
112
- }
113
- 100% {
114
- transform: scale(1);
115
- opacity: 1;
116
- }
117
- }
118
-
119
- @keyframes pv-card-shake {
120
- 0% { transform: translateX(0); }
121
- 25% { transform: translateX(-2px) rotate(-1deg); }
122
- 50% { transform: translateX(2px) rotate(1deg); }
123
- 75% { transform: translateX(-1px) rotate(-1deg); }
124
- 100% { transform: translateX(1px) rotate(1deg); }
125
- }
126
-
127
- @keyframes pv-fade-up {
128
- from {
129
- opacity: 0;
130
- transform: translateY(10px);
131
- }
132
- to {
133
- opacity: 1;
134
- transform: translateY(0);
135
- }
136
- }
137
- </style>
138
-
18
+
139
19
  <div class="pv-card">
140
20
 
141
21
  <div id="pv-status-head" class="pv-status-header">
@@ -265,289 +145,7 @@ const t = (ui ?? {}) as ProbadorVibracionMandoUI;
265
145
 
266
146
  </div>
267
147
 
268
- <style>
269
- .pv-wrapper {
270
- max-width: 650px;
271
- margin: 0 auto;
272
- color: var(--pv-text);
273
- }
274
-
275
- .pv-card {
276
- background: var(--pv-surface);
277
- border: 1px solid var(--pv-border);
278
- border-radius: 1.5rem;
279
- padding: 2rem;
280
- box-shadow: 0 20px 40px -10px rgba(0, 0, 0, 0.1);
281
- display: flex;
282
- flex-direction: column;
283
- gap: 1.5rem;
284
- }
285
-
286
- .pv-status-header {
287
- display: flex;
288
- align-items: center;
289
- gap: 1.25rem;
290
- padding: 1.25rem;
291
- background: var(--pv-surface-alt);
292
- border-radius: 1rem;
293
- border: 1px solid var(--pv-border);
294
- transition: all 300ms cubic-bezier(0.4, 0, 0.2, 1);
295
- }
296
-
297
- .pv-status-avatar {
298
- width: 3rem;
299
- height: 3rem;
300
- border-radius: 0.75rem;
301
- background: var(--pv-surface-hover);
302
- display: flex;
303
- align-items: center;
304
- justify-content: center;
305
- color: var(--pv-text-muted);
306
- flex-shrink: 0;
307
- transition: all 300ms;
308
- }
309
-
310
- .pv-status-icon {
311
- width: 1.75rem;
312
- height: 1.75rem;
313
- }
314
-
315
- .pv-status-info {
316
- flex: 1;
317
- min-width: 0;
318
- }
319
-
320
- .pv-dev-name {
321
- margin: 0;
322
- font-size: 1.1rem;
323
- font-weight: 800;
324
- white-space: nowrap;
325
- overflow: hidden;
326
- text-overflow: ellipsis;
327
- }
328
-
329
- .pv-dev-sub {
330
- margin: 0.25rem 0 0;
331
- font-size: 0.85rem;
332
- color: var(--pv-text-muted);
333
- }
334
-
335
- .pv-indicator {
336
- flex-shrink: 0;
337
- width: 0.75rem;
338
- height: 0.75rem;
339
- border-radius: 9999px;
340
- background: var(--pv-danger);
341
- box-shadow: 0 0 10px rgba(239, 68, 68, 0.4);
342
- transition: all 300ms;
343
- }
344
-
345
- .pv-warning {
346
- font-size: 0.85rem;
347
- color: #b45309;
348
- background: #fef3c7;
349
- padding: 0.75rem;
350
- border-radius: 0.5rem;
351
- border-left: 4px solid #f59e0b;
352
- display: none;
353
- }
354
-
355
- .pv-tabs-nav {
356
- display: flex;
357
- background: var(--pv-surface-alt);
358
- padding: 0.5rem;
359
- border-radius: 1rem;
360
- gap: 0.5rem;
361
- }
362
-
363
- .pv-tab-btn {
364
- flex: 1;
365
- display: flex;
366
- align-items: center;
367
- justify-content: center;
368
- gap: 0.5rem;
369
- padding: 0.75rem 1rem;
370
- border: none;
371
- background: transparent;
372
- color: var(--pv-text-muted);
373
- font-weight: 700;
374
- font-size: 0.9rem;
375
- border-radius: 0.75rem;
376
- cursor: pointer;
377
- transition: all 200ms;
378
- }
379
-
380
- .pv-tab-btn:hover {
381
- color: var(--pv-text);
382
- background: var(--pv-surface-hover);
383
- }
384
-
385
- .pv-tab-icon {
386
- width: 1.125rem;
387
- height: 1.125rem;
388
- }
389
-
390
- .pv-presets-grid {
391
- display: grid;
392
- grid-template-columns: repeat(2, 1fr);
393
- gap: 1rem;
394
- }
395
-
396
- @media (max-width: 480px) {
397
- .pv-presets-grid {
398
- grid-template-columns: 1fr;
399
- }
400
- }
401
-
402
- .pv-preset-card {
403
- background: var(--pv-surface-alt);
404
- border: 1px solid var(--pv-border);
405
- border-radius: 1rem;
406
- padding: 1.25rem;
407
- display: flex;
408
- flex-direction: column;
409
- align-items: flex-start;
410
- gap: 0.75rem;
411
- cursor: pointer;
412
- transition: all 200ms cubic-bezier(0.4, 0, 0.2, 1);
413
- position: relative;
414
- overflow: hidden;
415
- }
416
-
417
- .pv-preset-card:hover {
418
- transform: translateY(-2px);
419
- border-color: var(--pv-accent);
420
- box-shadow: 0 10px 20px rgba(139, 92, 246, 0.1);
421
- }
422
-
423
- .pv-preset-icon {
424
- width: 2.5rem;
425
- height: 2.5rem;
426
- background: var(--pv-surface);
427
- border-radius: 0.625rem;
428
- display: flex;
429
- align-items: center;
430
- justify-content: center;
431
- color: var(--pv-accent);
432
- box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
433
- transition: all 200ms;
434
- }
435
-
436
- .pv-preset-icon-svg {
437
- width: 1.5rem;
438
- height: 1.5rem;
439
- }
440
-
441
- .pv-preset-title {
442
- font-weight: 800;
443
- font-size: 1rem;
444
- margin: 0;
445
- }
446
-
447
- .pv-preset-desc {
448
- font-size: 0.8rem;
449
- color: var(--pv-text-muted);
450
- margin: 0;
451
- line-height: 1.4;
452
- transition: color 200ms;
453
- }
454
-
455
- .pv-custom-sliders {
456
- display: flex;
457
- flex-direction: column;
458
- gap: 1.25rem;
459
- background: var(--pv-surface-alt);
460
- padding: 1.5rem;
461
- border-radius: 1rem;
462
- border: 1px solid var(--pv-border);
463
- }
464
-
465
- .pv-slider-group {
466
- display: flex;
467
- flex-direction: column;
468
- gap: 0.75rem;
469
- }
470
-
471
- .pv-slider-header {
472
- display: flex;
473
- justify-content: space-between;
474
- align-items: center;
475
- font-size: 0.9rem;
476
- font-weight: 700;
477
- }
478
-
479
- .pv-slider-val {
480
- background: var(--pv-surface);
481
- padding: 0.25rem 0.5rem;
482
- border-radius: 0.375rem;
483
- font-size: 0.85rem;
484
- font-weight: 700;
485
- color: var(--pv-accent);
486
- min-width: 3rem;
487
- text-align: center;
488
- }
489
-
490
- .pv-slider {
491
- -webkit-appearance: none;
492
- appearance: none;
493
- width: 100%;
494
- height: 8px;
495
- background: var(--pv-surface-hover);
496
- border-radius: 4px;
497
- outline: none;
498
- }
499
-
500
- .pv-slider::-webkit-slider-thumb {
501
- -webkit-appearance: none;
502
- appearance: none;
503
- width: 1.5rem;
504
- height: 1.5rem;
505
- border-radius: 9999px;
506
- background: var(--pv-accent);
507
- cursor: pointer;
508
- border: 3px solid var(--pv-surface);
509
- box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
510
- transition: transform 100ms;
511
- }
512
-
513
- .pv-slider::-webkit-slider-thumb:hover {
514
- transform: scale(1.15);
515
- }
516
-
517
- .pv-btn-send {
518
- width: 100%;
519
- padding: 1.25rem;
520
- border-radius: 1rem;
521
- border: none;
522
- background: linear-gradient(135deg, var(--pv-accent), var(--pv-accent-secondary));
523
- color: white;
524
- font-size: 1.1rem;
525
- font-weight: 900;
526
- letter-spacing: 0.5px;
527
- cursor: pointer;
528
- box-shadow: 0 10px 25px var(--pv-accent-glow);
529
- display: flex;
530
- align-items: center;
531
- justify-content: center;
532
- gap: 0.75rem;
533
- transition: all 200ms cubic-bezier(0.4, 0, 0.2, 1);
534
- }
535
-
536
- .pv-btn-send:hover {
537
- transform: translateY(-2px);
538
- box-shadow: 0 15px 30px var(--pv-accent-glow);
539
- }
540
-
541
- .pv-btn-send:active {
542
- transform: translateY(1px);
543
- }
544
-
545
- .pv-btn-send-icon {
546
- width: 1.5rem;
547
- height: 1.5rem;
548
- }
549
- </style>
550
-
148
+
551
149
  <script>
552
150
  interface VibPad {
553
151
  vibrationActuator?: { playEffect: (t: string, p: object) => Promise<void> };
@@ -0,0 +1,280 @@
1
+ .pv-wrapper {
2
+ max-width: 650px;
3
+ margin: 0 auto;
4
+ color: var(--pv-text);
5
+ }
6
+
7
+ .pv-card {
8
+ background: var(--pv-surface);
9
+ border: 1px solid var(--pv-border);
10
+ border-radius: 1.5rem;
11
+ padding: 2rem;
12
+ box-shadow: 0 20px 40px -10px rgba(0, 0, 0, 0.1);
13
+ display: flex;
14
+ flex-direction: column;
15
+ gap: 1.5rem;
16
+ }
17
+
18
+ .pv-status-header {
19
+ display: flex;
20
+ align-items: center;
21
+ gap: 1.25rem;
22
+ padding: 1.25rem;
23
+ background: var(--pv-surface-alt);
24
+ border-radius: 1rem;
25
+ border: 1px solid var(--pv-border);
26
+ transition: all 300ms cubic-bezier(0.4, 0, 0.2, 1);
27
+ }
28
+
29
+ .pv-status-avatar {
30
+ width: 3rem;
31
+ height: 3rem;
32
+ border-radius: 0.75rem;
33
+ background: var(--pv-surface-hover);
34
+ display: flex;
35
+ align-items: center;
36
+ justify-content: center;
37
+ color: var(--pv-text-muted);
38
+ flex-shrink: 0;
39
+ transition: all 300ms;
40
+ }
41
+
42
+ .pv-status-icon {
43
+ width: 1.75rem;
44
+ height: 1.75rem;
45
+ }
46
+
47
+ .pv-status-info {
48
+ flex: 1;
49
+ min-width: 0;
50
+ }
51
+
52
+ .pv-dev-name {
53
+ margin: 0;
54
+ font-size: 1.1rem;
55
+ font-weight: 800;
56
+ white-space: nowrap;
57
+ overflow: hidden;
58
+ text-overflow: ellipsis;
59
+ }
60
+
61
+ .pv-dev-sub {
62
+ margin: 0.25rem 0 0;
63
+ font-size: 0.85rem;
64
+ color: var(--pv-text-muted);
65
+ }
66
+
67
+ .pv-indicator {
68
+ flex-shrink: 0;
69
+ width: 0.75rem;
70
+ height: 0.75rem;
71
+ border-radius: 9999px;
72
+ background: var(--pv-danger);
73
+ box-shadow: 0 0 10px rgba(239, 68, 68, 0.4);
74
+ transition: all 300ms;
75
+ }
76
+
77
+ .pv-warning {
78
+ font-size: 0.85rem;
79
+ color: #b45309;
80
+ background: #fef3c7;
81
+ padding: 0.75rem;
82
+ border-radius: 0.5rem;
83
+ border-left: 4px solid #f59e0b;
84
+ display: none;
85
+ }
86
+
87
+ .pv-tabs-nav {
88
+ display: flex;
89
+ background: var(--pv-surface-alt);
90
+ padding: 0.5rem;
91
+ border-radius: 1rem;
92
+ gap: 0.5rem;
93
+ }
94
+
95
+ .pv-tab-btn {
96
+ flex: 1;
97
+ display: flex;
98
+ align-items: center;
99
+ justify-content: center;
100
+ gap: 0.5rem;
101
+ padding: 0.75rem 1rem;
102
+ border: none;
103
+ background: transparent;
104
+ color: var(--pv-text-muted);
105
+ font-weight: 700;
106
+ font-size: 0.9rem;
107
+ border-radius: 0.75rem;
108
+ cursor: pointer;
109
+ transition: all 200ms;
110
+ }
111
+
112
+ .pv-tab-btn:hover {
113
+ color: var(--pv-text);
114
+ background: var(--pv-surface-hover);
115
+ }
116
+
117
+ .pv-tab-icon {
118
+ width: 1.125rem;
119
+ height: 1.125rem;
120
+ }
121
+
122
+ .pv-presets-grid {
123
+ display: grid;
124
+ grid-template-columns: repeat(2, 1fr);
125
+ gap: 1rem;
126
+ }
127
+
128
+ @media (max-width: 480px) {
129
+ .pv-presets-grid {
130
+ grid-template-columns: 1fr;
131
+ }
132
+ }
133
+
134
+ .pv-preset-card {
135
+ background: var(--pv-surface-alt);
136
+ border: 1px solid var(--pv-border);
137
+ border-radius: 1rem;
138
+ padding: 1.25rem;
139
+ display: flex;
140
+ flex-direction: column;
141
+ align-items: flex-start;
142
+ gap: 0.75rem;
143
+ cursor: pointer;
144
+ transition: all 200ms cubic-bezier(0.4, 0, 0.2, 1);
145
+ position: relative;
146
+ overflow: hidden;
147
+ }
148
+
149
+ .pv-preset-card:hover {
150
+ transform: translateY(-2px);
151
+ border-color: var(--pv-accent);
152
+ box-shadow: 0 10px 20px rgba(139, 92, 246, 0.1);
153
+ }
154
+
155
+ .pv-preset-icon {
156
+ width: 2.5rem;
157
+ height: 2.5rem;
158
+ background: var(--pv-surface);
159
+ border-radius: 0.625rem;
160
+ display: flex;
161
+ align-items: center;
162
+ justify-content: center;
163
+ color: var(--pv-accent);
164
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
165
+ transition: all 200ms;
166
+ }
167
+
168
+ .pv-preset-icon-svg {
169
+ width: 1.5rem;
170
+ height: 1.5rem;
171
+ }
172
+
173
+ .pv-preset-title {
174
+ font-weight: 800;
175
+ font-size: 1rem;
176
+ margin: 0;
177
+ }
178
+
179
+ .pv-preset-desc {
180
+ font-size: 0.8rem;
181
+ color: var(--pv-text-muted);
182
+ margin: 0;
183
+ line-height: 1.4;
184
+ transition: color 200ms;
185
+ }
186
+
187
+ .pv-custom-sliders {
188
+ display: flex;
189
+ flex-direction: column;
190
+ gap: 1.25rem;
191
+ background: var(--pv-surface-alt);
192
+ padding: 1.5rem;
193
+ border-radius: 1rem;
194
+ border: 1px solid var(--pv-border);
195
+ }
196
+
197
+ .pv-slider-group {
198
+ display: flex;
199
+ flex-direction: column;
200
+ gap: 0.75rem;
201
+ }
202
+
203
+ .pv-slider-header {
204
+ display: flex;
205
+ justify-content: space-between;
206
+ align-items: center;
207
+ font-size: 0.9rem;
208
+ font-weight: 700;
209
+ }
210
+
211
+ .pv-slider-val {
212
+ background: var(--pv-surface);
213
+ padding: 0.25rem 0.5rem;
214
+ border-radius: 0.375rem;
215
+ font-size: 0.85rem;
216
+ font-weight: 700;
217
+ color: var(--pv-accent);
218
+ min-width: 3rem;
219
+ text-align: center;
220
+ }
221
+
222
+ .pv-slider {
223
+ -webkit-appearance: none;
224
+ appearance: none;
225
+ width: 100%;
226
+ height: 8px;
227
+ background: var(--pv-surface-hover);
228
+ border-radius: 4px;
229
+ outline: none;
230
+ }
231
+
232
+ .pv-slider::-webkit-slider-thumb {
233
+ -webkit-appearance: none;
234
+ appearance: none;
235
+ width: 1.5rem;
236
+ height: 1.5rem;
237
+ border-radius: 9999px;
238
+ background: var(--pv-accent);
239
+ cursor: pointer;
240
+ border: 3px solid var(--pv-surface);
241
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
242
+ transition: transform 100ms;
243
+ }
244
+
245
+ .pv-slider::-webkit-slider-thumb:hover {
246
+ transform: scale(1.15);
247
+ }
248
+
249
+ .pv-btn-send {
250
+ width: 100%;
251
+ padding: 1.25rem;
252
+ border-radius: 1rem;
253
+ border: none;
254
+ background: linear-gradient(135deg, var(--pv-accent), var(--pv-accent-secondary));
255
+ color: white;
256
+ font-size: 1.1rem;
257
+ font-weight: 900;
258
+ letter-spacing: 0.5px;
259
+ cursor: pointer;
260
+ box-shadow: 0 10px 25px var(--pv-accent-glow);
261
+ display: flex;
262
+ align-items: center;
263
+ justify-content: center;
264
+ gap: 0.75rem;
265
+ transition: all 200ms cubic-bezier(0.4, 0, 0.2, 1);
266
+ }
267
+
268
+ .pv-btn-send:hover {
269
+ transform: translateY(-2px);
270
+ box-shadow: 0 15px 30px var(--pv-accent-glow);
271
+ }
272
+
273
+ .pv-btn-send:active {
274
+ transform: translateY(1px);
275
+ }
276
+
277
+ .pv-btn-send-icon {
278
+ width: 1.5rem;
279
+ height: 1.5rem;
280
+ }