@filipgutica/ui 0.3.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.
@@ -1,12 +1,67 @@
1
1
  @layer components {
2
+ /* Package-owned typography keeps controls consistent across consuming apps. */
3
+ .fg-button, .fg-input, .fg-select, .fg-checkbox, .fg-field,
4
+ .fg-radio-card, .fg-badge, .fg-alert, .fg-surface, .fg-card,
5
+ .fg-dialog__content, .fg-code-block {
6
+ font-family: var(--font-ui);
7
+ font-size: 0.875rem;
8
+ font-weight: 400;
9
+ line-height: 1.5;
10
+ }
11
+
12
+ .fg-code-block {
13
+ min-width: 0;
14
+ max-width: 100%;
15
+ overflow: hidden;
16
+ border: 1px solid color-mix(in srgb, var(--color-code-text) 22%, var(--color-code));
17
+ border-radius: var(--radius-control);
18
+ background: var(--color-code);
19
+ color: var(--color-code-text);
20
+ }
21
+ .fg-code-block__header {
22
+ display: flex;
23
+ align-items: center;
24
+ gap: 0.75rem;
25
+ min-height: 2.5rem;
26
+ padding: 0.35rem 0.75rem;
27
+ border-bottom: 1px solid color-mix(in srgb, var(--color-code-text) 16%, transparent);
28
+ background: color-mix(in srgb, var(--color-code-text) 5%, var(--color-code));
29
+ font-size: 0.75rem;
30
+ }
31
+ .fg-code-block__title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
32
+ .fg-code-block__language { opacity: 0.7; }
33
+ .fg-code-block__actions { display: flex; align-items: center; gap: 0.5rem; margin-left: auto; flex-shrink: 0; }
34
+ .fg-code-block__copy {
35
+ display: inline-flex;
36
+ align-items: center;
37
+ gap: 0.4rem;
38
+ padding: 0.25rem 0.4rem;
39
+ border: 0;
40
+ border-radius: 0.25rem;
41
+ background: transparent;
42
+ color: inherit;
43
+ font: inherit;
44
+ cursor: pointer;
45
+ }
46
+ .fg-code-block__copy:hover { background: color-mix(in srgb, currentColor 12%, transparent); }
47
+ .fg-code-block__copy svg { width: 1rem; height: 1rem; }
48
+ .fg-code-block__copy:focus-visible, .fg-code-block__pre:focus-visible { outline: 2px solid var(--color-focus); outline-offset: -2px; }
49
+ .fg-code-block__pre { margin: 0; padding: 1rem; overflow: auto; max-height: 32rem; tab-size: 2; }
50
+ .fg-code-block__pre, .fg-code-block__pre code { font-family: var(--font-mono); font-size: 0.8125rem; line-height: 1.65; }
51
+ .fg-code-block__pre code { display: block; color: inherit; }
52
+ .fg-code-block__line { display: flex; min-height: 1.65em; }
53
+ .fg-code-block__text { white-space: pre; }
54
+ .fg-code-block__number { min-width: 2.5em; padding-right: 1em; flex-shrink: 0; text-align: right; opacity: 0.5; user-select: none; }
55
+ .fg-code-block[data-wrap="true"] .fg-code-block__text { min-width: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
56
+ .fg-code-block__status:empty { display: none; }
57
+ .fg-code-block__status:not(:empty) { display: block; padding: 0.5rem 0.75rem; font-size: 0.75rem; }
2
58
  .fg-button,
3
59
  .fg-input,
4
60
  .fg-select,
5
61
  .fg-dialog__close {
6
- min-height: 2.75rem;
7
62
  border: 1px solid transparent;
8
63
  border-radius: var(--radius-control);
9
- font: inherit;
64
+ font-family: var(--font-ui);
10
65
  transition:
11
66
  background-color var(--duration-fast) ease,
12
67
  border-color var(--duration-fast) ease,
@@ -20,11 +75,10 @@
20
75
  align-items: center;
21
76
  justify-content: center;
22
77
  gap: 0.5rem;
23
- padding: 0.65rem 1rem;
24
78
  color: var(--color-button-text);
25
79
  background: var(--color-button-bg);
26
- box-shadow: var(--shadow-control);
27
- font-weight: 700;
80
+ box-shadow: none;
81
+ font-weight: 500;
28
82
  letter-spacing: -0.01em;
29
83
  line-height: 1.25;
30
84
  cursor: pointer;
@@ -35,7 +89,6 @@
35
89
  }
36
90
 
37
91
  .fg-button:active:not(:disabled) {
38
- transform: translateY(1px);
39
92
  box-shadow: none;
40
93
  }
41
94
 
@@ -62,12 +115,51 @@
62
115
  animation: fg-button-spin 700ms linear infinite;
63
116
  }
64
117
 
118
+ .fg-button[data-size="sm"],
119
+ .fg-input[data-size="sm"],
120
+ .fg-select[data-size="sm"] {
121
+ font-size: 0.8125rem;
122
+ }
123
+
124
+ .fg-button[data-size="md"],
125
+ .fg-input[data-size="md"],
126
+ .fg-select[data-size="md"] {
127
+ font-size: 0.875rem;
128
+ }
129
+
130
+ .fg-button[data-size="lg"],
131
+ .fg-input[data-size="lg"],
132
+ .fg-select[data-size="lg"] {
133
+ font-size: 1rem;
134
+ }
135
+
136
+ .fg-button[data-size="sm"] { min-height: 2rem; }
137
+ .fg-button[data-size="md"] { min-height: 2.25rem; }
138
+ .fg-button[data-size="lg"] { min-height: 2.75rem; }
139
+ .fg-input[data-size="sm"],
140
+ .fg-select[data-size="sm"] { height: 2rem; }
141
+ .fg-input[data-size="md"],
142
+ .fg-select[data-size="md"] { height: 2.25rem; }
143
+ .fg-input[data-size="lg"],
144
+ .fg-select[data-size="lg"] { height: 2.75rem; }
145
+
146
+ .fg-button[data-size="sm"] { padding: 0 0.6rem; }
147
+ .fg-button[data-size="md"] { padding: 0 0.75rem; }
148
+ .fg-button[data-size="lg"] { padding: 0 1rem; }
149
+
150
+ /* Deprecated UiButton aliases retained for existing consumers. */
65
151
  .fg-button[data-size="compact"] {
66
152
  min-height: 2.25rem;
67
- padding: 0.4rem 0.7rem;
153
+ padding: 0 0.7rem;
68
154
  font-size: 0.8125rem;
69
155
  }
70
156
 
157
+ .fg-button[data-size="default"] {
158
+ min-height: 2.75rem;
159
+ padding: 0 1rem;
160
+ font-size: 1rem;
161
+ }
162
+
71
163
  .fg-button[data-variant="secondary"] {
72
164
  border-color: var(--color-border);
73
165
  color: var(--color-text);
@@ -100,8 +192,9 @@
100
192
  }
101
193
 
102
194
  .fg-button[data-variant="text"] {
195
+ height: auto;
103
196
  min-height: auto;
104
- padding: 0;
197
+ padding: 0.25rem;
105
198
  color: var(--color-link);
106
199
  background: transparent;
107
200
  text-decoration: underline;
@@ -117,14 +210,33 @@
117
210
  .fg-input,
118
211
  .fg-select {
119
212
  width: 100%;
120
- padding: 0.5rem 0.7rem;
121
213
  border-color: var(--color-input-border);
122
214
  color: var(--color-input-text);
123
215
  background: var(--color-input-bg);
124
- box-shadow: var(--shadow-control);
216
+ box-shadow: none;
125
217
  line-height: 1.35;
126
218
  }
127
219
 
220
+ .fg-select {
221
+ appearance: none;
222
+ background-image:
223
+ linear-gradient(45deg, transparent 50%, currentColor 50%),
224
+ linear-gradient(135deg, currentColor 50%, transparent 50%);
225
+ background-position:
226
+ calc(100% - 0.8rem) 52%,
227
+ calc(100% - 0.55rem) 52%;
228
+ background-repeat: no-repeat;
229
+ background-size: 0.3rem 0.3rem;
230
+ }
231
+
232
+ .fg-input[data-size="sm"] { padding: 0 0.55rem; }
233
+ .fg-input[data-size="md"] { padding: 0 0.65rem; }
234
+ .fg-input[data-size="lg"] { padding: 0 0.7rem; }
235
+
236
+ .fg-select[data-size="sm"] { padding: 0 1.6rem 0 0.5rem; }
237
+ .fg-select[data-size="md"] { padding: 0 1.7rem 0 0.6rem; }
238
+ .fg-select[data-size="lg"] { padding: 0 1.8rem 0 0.7rem; }
239
+
128
240
  .fg-input::placeholder {
129
241
  color: var(--color-input-placeholder);
130
242
  opacity: 1;
@@ -144,7 +256,7 @@
144
256
  .fg-field__label {
145
257
  color: var(--color-text);
146
258
  font-size: 0.8125rem;
147
- font-weight: 700;
259
+ font-weight: 600;
148
260
  }
149
261
 
150
262
  .fg-field__description,
@@ -191,6 +303,112 @@
191
303
 
192
304
  .fg-checkbox__label { line-height: 1.4; }
193
305
 
306
+ .fg-checkbox[data-size="sm"] {
307
+ min-height: 2rem;
308
+ align-items: center;
309
+ gap: 0.45rem;
310
+ font-size: 0.8125rem;
311
+ }
312
+
313
+ .fg-checkbox[data-size="md"] {
314
+ min-height: 2.25rem;
315
+ align-items: center;
316
+ gap: 0.55rem;
317
+ font-size: 0.875rem;
318
+ }
319
+
320
+ .fg-checkbox[data-size="lg"] {
321
+ min-height: 2.75rem;
322
+ align-items: center;
323
+ gap: 0.65rem;
324
+ font-size: 1rem;
325
+ }
326
+
327
+ .fg-checkbox[data-size] .fg-checkbox__control { margin-top: 0; }
328
+
329
+ .fg-checkbox[data-size="sm"] .fg-checkbox__control {
330
+ width: 1rem;
331
+ height: 1rem;
332
+ border-radius: 0.25rem;
333
+ }
334
+
335
+ .fg-checkbox[data-size="md"] .fg-checkbox__control {
336
+ width: 1.125rem;
337
+ height: 1.125rem;
338
+ }
339
+
340
+ .fg-checkbox[data-size="lg"] .fg-checkbox__control {
341
+ width: 1.25rem;
342
+ height: 1.25rem;
343
+ }
344
+
345
+ .fg-checkbox[data-size="sm"] .fg-checkbox__indicator { font-size: 0.68rem; }
346
+ .fg-checkbox[data-size="md"] .fg-checkbox__indicator { font-size: 0.74rem; }
347
+ .fg-checkbox[data-size="lg"] .fg-checkbox__indicator { font-size: 0.8rem; }
348
+
349
+ .fg-radio-card-group {
350
+ display: grid;
351
+ grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
352
+ gap: 0.75rem;
353
+ }
354
+
355
+ .fg-radio-card {
356
+ position: relative;
357
+ display: block;
358
+ min-width: 0;
359
+ padding: 0.75rem;
360
+ overflow: hidden;
361
+ border: 1px solid var(--color-border-subtle);
362
+ border-radius: var(--radius-panel);
363
+ color: var(--color-text);
364
+ background: var(--color-surface-raised);
365
+ box-shadow: none;
366
+ text-align: left;
367
+ cursor: pointer;
368
+ transition:
369
+ border-color var(--duration-fast) ease,
370
+ box-shadow var(--duration-fast) ease,
371
+ transform var(--duration-fast) ease;
372
+ }
373
+
374
+ .fg-radio-card:hover:not([data-disabled]) {
375
+ border-color: var(--color-border);
376
+ }
377
+
378
+ .fg-radio-card[data-state="checked"] {
379
+ border-color: var(--color-link);
380
+ box-shadow: 0 0 0 1px var(--color-link);
381
+ }
382
+
383
+ .fg-radio-card[data-disabled] {
384
+ cursor: not-allowed;
385
+ opacity: 0.58;
386
+ }
387
+
388
+ .fg-radio-card__content {
389
+ display: grid;
390
+ min-width: 0;
391
+ gap: 0.25rem;
392
+ padding-right: 1.75rem;
393
+ }
394
+
395
+ .fg-radio-card__indicator {
396
+ position: absolute;
397
+ z-index: 1;
398
+ top: 0.75rem;
399
+ right: 0.75rem;
400
+ display: block;
401
+ width: 1rem;
402
+ height: 1rem;
403
+ border: 1px solid var(--color-input-border);
404
+ border-radius: 50%;
405
+ background: var(--color-input-bg);
406
+ }
407
+
408
+ .fg-radio-card[data-state="checked"] .fg-radio-card__indicator {
409
+ border: 0.3rem solid var(--color-link);
410
+ }
411
+
194
412
  .fg-badge {
195
413
  display: inline-flex;
196
414
  align-items: center;
@@ -201,30 +419,30 @@
201
419
  color: var(--color-muted);
202
420
  background: var(--color-surface-muted);
203
421
  font-size: 0.75rem;
204
- font-weight: 700;
422
+ font-weight: 500;
205
423
  line-height: 1.25;
206
424
  }
207
425
 
208
426
  .fg-badge[data-tone="info"] { color: var(--color-info); background: var(--color-info-surface); }
209
427
  .fg-badge[data-tone="success"] { color: var(--color-success); background: var(--color-success-surface); }
210
428
  .fg-badge[data-tone="warning"] { color: var(--color-warning); background: var(--color-warning-surface); }
211
- .fg-badge[data-tone="danger"] { color: var(--color-error); background: var(--color-error-surface); }
429
+ .fg-badge[data-tone="danger"],
430
+ .fg-badge[data-tone="error"] { color: var(--color-error); background: var(--color-error-surface); }
212
431
 
213
432
  .fg-alert {
214
433
  display: flex;
215
434
  align-items: flex-start;
216
435
  gap: 0.75rem;
217
- padding: 0.85rem 1rem;
436
+ padding: 0.75rem 1rem;
218
437
  border: 1px solid var(--color-border-subtle);
219
- border-left: 3px solid var(--color-border);
220
438
  border-radius: var(--radius-control);
221
439
  color: var(--color-text);
222
440
  background: var(--color-surface);
223
441
  }
224
442
 
225
- .fg-alert[data-tone="info"] { border-left-color: var(--color-info); background: var(--color-info-surface); }
226
- .fg-alert[data-tone="success"] { border-left-color: var(--color-success); background: var(--color-success-surface); }
227
- .fg-alert[data-tone="warning"] { border-left-color: var(--color-warning); background: var(--color-warning-surface); }
443
+ .fg-alert[data-tone="info"] { border-color: color-mix(in srgb, var(--color-info) 35%, var(--color-border-subtle)); background: var(--color-info-surface); }
444
+ .fg-alert[data-tone="success"] { border-color: color-mix(in srgb, var(--color-success) 35%, var(--color-border-subtle)); background: var(--color-success-surface); }
445
+ .fg-alert[data-tone="warning"] { border-color: color-mix(in srgb, var(--color-warning) 35%, var(--color-border-subtle)); background: var(--color-warning-surface); }
228
446
  .fg-alert[data-tone="danger"],
229
447
  .fg-alert[data-tone="error"] {
230
448
  border-color: var(--color-error);
@@ -236,16 +454,42 @@
236
454
  border: 1px solid var(--color-border-subtle);
237
455
  border-radius: var(--radius-panel);
238
456
  background: var(--color-surface-raised);
239
- box-shadow: 0 1px 2px var(--color-shadow);
457
+ box-shadow: none;
240
458
  }
241
459
 
242
- .fg-surface[data-padding="compact"] { padding: 0.85rem; }
243
- .fg-surface[data-padding="default"] { padding: 1.2rem; }
460
+ .fg-surface[data-padding="compact"] { padding: 0.75rem; }
461
+ .fg-surface[data-padding="default"] { padding: 1rem; }
462
+
463
+ .fg-card {
464
+ overflow: hidden;
465
+ border: 1px solid var(--color-border-subtle);
466
+ border-radius: var(--radius-panel);
467
+ background: var(--color-surface-raised);
468
+ box-shadow: none;
469
+ }
470
+
471
+ .fg-card__header,
472
+ .fg-card__footer {
473
+ display: flex;
474
+ align-items: center;
475
+ justify-content: space-between;
476
+ gap: 0.75rem;
477
+ padding: 0.75rem 1rem;
478
+ }
479
+
480
+ .fg-card__footer {
481
+ background: var(--color-surface);
482
+ }
483
+
484
+ .fg-card__title { margin: 0; font-size: 0.875rem; font-weight: 600; line-height: 1.4; }
485
+ .fg-card__actions { display: flex; align-items: center; gap: 0.5rem; margin-left: auto; }
486
+ .fg-card__body { padding: 1rem; }
244
487
 
245
488
  .fg-progress {
246
489
  position: relative;
247
490
  height: 0.55rem;
248
491
  overflow: hidden;
492
+ border: 1px solid var(--color-border-subtle);
249
493
  border-radius: var(--radius-pill);
250
494
  background: var(--color-surface-muted);
251
495
  }
@@ -258,6 +502,50 @@
258
502
  transition: transform var(--duration-fast) ease-out;
259
503
  }
260
504
 
505
+ .fg-slider {
506
+ position: relative;
507
+ display: flex;
508
+ width: 100%;
509
+ align-items: center;
510
+ touch-action: none;
511
+ user-select: none;
512
+ }
513
+
514
+ .fg-slider[data-size="sm"] { min-height: 2rem; }
515
+ .fg-slider[data-size="md"] { min-height: 2.25rem; }
516
+ .fg-slider[data-size="lg"] { min-height: 2.75rem; }
517
+
518
+ .fg-slider__track {
519
+ position: relative;
520
+ height: 0.375rem;
521
+ flex: 1;
522
+ overflow: hidden;
523
+ border-radius: var(--radius-pill);
524
+ background: var(--color-surface-muted);
525
+ }
526
+
527
+ .fg-slider__range {
528
+ position: absolute;
529
+ height: 100%;
530
+ border-radius: inherit;
531
+ background: var(--color-progress);
532
+ }
533
+
534
+ .fg-slider__thumb {
535
+ display: block;
536
+ border: 2px solid var(--color-progress);
537
+ border-radius: 50%;
538
+ background: var(--color-input-bg);
539
+ box-shadow: var(--shadow-control);
540
+ cursor: grab;
541
+ }
542
+
543
+ .fg-slider__thumb:active { cursor: grabbing; }
544
+ .fg-slider[data-size="sm"] .fg-slider__thumb { width: 1rem; height: 1rem; }
545
+ .fg-slider[data-size="md"] .fg-slider__thumb { width: 1.125rem; height: 1.125rem; }
546
+ .fg-slider[data-size="lg"] .fg-slider__thumb { width: 1.25rem; height: 1.25rem; }
547
+ .fg-slider[data-disabled] { cursor: not-allowed; opacity: 0.58; }
548
+
261
549
  .fg-dialog__overlay {
262
550
  position: fixed;
263
551
  inset: 0;
@@ -272,11 +560,11 @@
272
560
  top: 50%;
273
561
  left: 50%;
274
562
  display: grid;
275
- width: min(42rem, calc(100vw - 2rem));
563
+ width: min(32rem, calc(100vw - 2rem));
276
564
  max-height: min(42rem, calc(100vh - 2rem));
277
565
  overflow: hidden;
278
566
  transform: translate(-50%, -50%);
279
- border: 1px solid var(--color-border);
567
+ border: 1px solid var(--color-border-subtle);
280
568
  border-radius: var(--radius-panel);
281
569
  color: var(--color-text);
282
570
  background: var(--color-surface-raised);
@@ -289,16 +577,16 @@
289
577
  align-items: flex-start;
290
578
  justify-content: space-between;
291
579
  gap: 1rem;
292
- padding: 1rem 1.2rem;
580
+ padding: 1rem;
293
581
  }
294
582
 
295
583
  .fg-dialog__header { border-bottom: 1px solid var(--color-border-subtle); }
296
- .fg-dialog__footer { justify-content: flex-end; border-top: 1px solid var(--color-border-subtle); }
584
+ .fg-dialog__footer { justify-content: flex-end; border-top: 1px solid var(--color-border-subtle); background: var(--color-surface); }
297
585
 
298
586
  .fg-dialog__title {
299
587
  margin: 0;
300
- font-size: 1.1rem;
301
- font-weight: 760;
588
+ font-size: 1.125rem;
589
+ font-weight: 600;
302
590
  letter-spacing: -0.02em;
303
591
  }
304
592
 
@@ -311,13 +599,14 @@
311
599
  .fg-dialog__body {
312
600
  min-height: 0;
313
601
  overflow: auto;
314
- padding: 1.2rem;
602
+ padding: 1rem;
315
603
  }
316
604
 
317
605
  .fg-dialog__close {
318
606
  display: inline-grid;
319
607
  flex: none;
320
608
  width: 2.75rem;
609
+ min-height: 2.75rem;
321
610
  padding: 0;
322
611
  place-items: center;
323
612
  color: var(--color-muted);
@@ -336,9 +625,11 @@
336
625
  .fg-input:focus-visible,
337
626
  .fg-select:focus-visible,
338
627
  .fg-checkbox__control:focus-visible,
628
+ .fg-radio-card:focus-visible,
629
+ .fg-slider__thumb:focus-visible,
339
630
  .fg-dialog__close:focus-visible,
340
631
  .fg-dialog__content:focus-visible {
341
- outline: 3px solid var(--color-focus);
632
+ outline: 2px solid var(--color-focus);
342
633
  outline-offset: 2px;
343
634
  }
344
635
 
@@ -346,8 +637,11 @@
346
637
  :root.high-contrast .fg-input,
347
638
  :root.high-contrast .fg-select,
348
639
  :root.high-contrast .fg-checkbox__control,
640
+ :root.high-contrast .fg-radio-card,
349
641
  :root.high-contrast .fg-alert,
350
642
  :root.high-contrast .fg-surface,
643
+ :root.high-contrast .fg-card,
644
+ :root.high-contrast .fg-code-block,
351
645
  :root.high-contrast .fg-dialog__content {
352
646
  border-width: 2px;
353
647
  border-color: var(--color-border);
@@ -369,6 +663,8 @@
369
663
  .fg-button,
370
664
  .fg-input,
371
665
  .fg-select,
666
+ .fg-radio-card,
667
+ .fg-slider__range,
372
668
  .fg-dialog__close,
373
669
  .fg-progress__indicator { transition: none; }
374
670
 
package/src/theme.css CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  :root {
4
4
  color-scheme: light;
5
+ --font-ui: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
6
+ --font-mono: 'SFMono-Regular', Consolas, monospace;
5
7
  --color-bg: #ffffff;
6
8
  --color-surface: #f7f8fa;
7
9
  --color-surface-raised: #fff;
@@ -25,6 +27,17 @@
25
27
  --color-row-selected-text: #143d8f;
26
28
  --color-code: #0c1426;
27
29
  --color-code-text: #edf2ff;
30
+ --color-syntax-comment: #a8b3c7;
31
+ --color-syntax-keyword: #cba6f7;
32
+ --color-syntax-string: #a6e3a1;
33
+ --color-syntax-number: #fab387;
34
+ --color-syntax-function: #89b4fa;
35
+ --color-syntax-type: #f9e2af;
36
+ --color-syntax-variable: #edf2ff;
37
+ --color-syntax-operator: #89dceb;
38
+ --color-syntax-punctuation: #cdd6f4;
39
+ --color-syntax-tag: #89b4fa;
40
+ --color-syntax-attribute: #f9e2af;
28
41
  --color-error: #c01048;
29
42
  --color-warning: #854a0e;
30
43
  --color-success: #067647;