@devslab/dds-css 0.32.0 → 0.32.2

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.
@@ -37,7 +37,17 @@
37
37
 
38
38
  .dds-btn:focus-visible {
39
39
  outline: var(--dds-space-2) solid var(--dds-color-border-focus);
40
- outline-offset: var(--dds-space-2);
40
+ /* Flush (D-047): the ring sits on the control's own edge, so border/fill
41
+ * and ring read as one thicker line instead of border, gap, ring. */
42
+ outline-offset: var(--dds-focus-offset);
43
+ }
44
+ /* Unfilled buttons (secondary, ghost, no variant) also paint their own 1px
45
+ * border in the focus color, so border + ring are one solid edge of one
46
+ * colour, not a pale line inside a dark one (D-047). Primary and danger are
47
+ * filled: their transparent border shows the fill, which the ring already
48
+ * meets directly. */
49
+ .dds-btn:not(.dds-btn--primary):not(.dds-btn--danger):focus-visible {
50
+ border-color: var(--dds-color-border-focus);
41
51
  }
42
52
 
43
53
  /* opacity is allowed for disabled only (spec §4.2) */
@@ -79,6 +79,9 @@
79
79
 
80
80
  .dds-check__input:focus-visible {
81
81
  outline: var(--dds-space-2) solid var(--dds-color-border-focus);
82
+ /* Kept apart, not flush (D-047): on an 18px box a flush ring just reads as
83
+ * a heavier box — the same signal the checked state gives — so the gap is
84
+ * what makes it read as focus. */
82
85
  outline-offset: var(--dds-space-2);
83
86
  }
84
87
 
@@ -34,7 +34,8 @@
34
34
  }
35
35
  .dds-chip:focus-visible {
36
36
  outline: var(--dds-space-2) solid var(--dds-color-border-focus);
37
- outline-offset: var(--dds-space-2);
37
+ /* Flush on the chip's own border (D-047). */
38
+ outline-offset: var(--dds-focus-offset);
38
39
  }
39
40
 
40
41
  .dds-chip[aria-pressed="true"],
@@ -43,6 +44,11 @@
43
44
  border-color: var(--dds-color-bg-brand);
44
45
  color: var(--dds-color-text-brand);
45
46
  }
47
+ /* Focus paints the chip's own border in the focus color, so border + ring are
48
+ * one solid edge (D-047). After the selected rule so it wins there too. */
49
+ .dds-chip:focus-visible {
50
+ border-color: var(--dds-color-border-focus);
51
+ }
46
52
 
47
53
  /* opacity is allowed for disabled only (spec §4.2) */
48
54
  .dds-chip[disabled] {
@@ -161,7 +161,9 @@
161
161
  }
162
162
  .dds-console-rail__item:focus-visible {
163
163
  outline: 2px solid var(--dds-color-border-focus);
164
- outline-offset: 2px;
164
+ /* Flush on the item's hover/current fill (D-047); the rail's 12px
165
+ * inline padding keeps the ring clear of its scroll edge. */
166
+ outline-offset: var(--dds-focus-offset);
165
167
  }
166
168
 
167
169
  .dds-console-rail__badge {
@@ -389,7 +391,7 @@
389
391
  .dds-console-rail__group-toggle:hover { background: var(--dds-color-bg-subtle); }
390
392
  .dds-console-rail__group-toggle:focus-visible {
391
393
  outline: 2px solid var(--dds-color-border-focus);
392
- outline-offset: 2px;
394
+ outline-offset: var(--dds-focus-offset);
393
395
  }
394
396
  .dds-console-rail__chevron {
395
397
  inline-size: .375rem;
@@ -13,7 +13,8 @@
13
13
  .dds-date-picker-table [data-outside-range] {color:var(--dds-color-text-secondary);}
14
14
  .dds-date-picker-table [data-part="table-cell-trigger"][data-selected] {background:var(--dds-color-bg-brand);color:var(--dds-color-text-on-brand);}
15
15
  .dds-date-picker-table [data-today]:not([data-selected]) {text-decoration:underline;text-underline-offset:var(--dds-space-4);}
16
- .dds-date-picker-content :focus-visible {outline:var(--dds-space-2) solid var(--dds-color-border-focus);outline-offset:var(--dds-space-2);}
16
+ /* Flush (D-047): day cells touch each other and the selected one is filled; a gap ring would double around it and spill onto the neighbours. */
17
+ .dds-date-picker-content :focus-visible {outline:var(--dds-space-2) solid var(--dds-color-border-focus);outline-offset:var(--dds-focus-offset);}
17
18
  .dds-date-picker-footer {display:flex;flex-wrap:wrap;justify-content:space-between;gap:var(--dds-space-12);margin-top:var(--dds-space-12);padding-top:var(--dds-space-12);border-top:calc(var(--dds-space-2) / 2) solid var(--dds-color-border-default);}
18
19
 
19
20
  /* Text box shared by DatePicker, MonthPicker and the DateRangePicker pair: same var(--dds-space-40) DDS input look. */
@@ -29,7 +29,8 @@
29
29
  }
30
30
  .dds-iconbtn:focus-visible {
31
31
  outline: var(--dds-space-2) solid var(--dds-color-border-focus);
32
- outline-offset: var(--dds-space-2);
32
+ /* Flush, same as .dds-btn (D-047) — the two sit side by side in toolbars. */
33
+ outline-offset: var(--dds-focus-offset);
33
34
  }
34
35
 
35
36
  /* opacity is allowed for disabled only (spec §4.2) */
@@ -52,6 +53,12 @@
52
53
  .dds-iconbtn--secondary {
53
54
  border-color: var(--dds-color-border-strong);
54
55
  }
56
+ /* Every icon-button variant is unfilled, so focus paints the 1px border in
57
+ * the focus color too: border + ring become one solid edge (D-047). After
58
+ * --secondary so it wins at equal specificity. */
59
+ .dds-iconbtn:focus-visible {
60
+ border-color: var(--dds-color-border-focus);
61
+ }
55
62
 
56
63
  .dds-iconbtn--danger {
57
64
  color: var(--dds-color-status-danger);
@@ -13,7 +13,8 @@
13
13
  .dds-input:has(.dds-input__clear) .dds-input__control {padding-inline-end:var(--dds-space-48);}
14
14
  .dds-input__clear {position:absolute;inset-inline-end:var(--dds-space-4);inset-block-end:var(--dds-space-4);display:grid;place-items:center;inline-size:var(--dds-space-32);block-size:var(--dds-space-32);padding:0;border:0;border-radius:var(--dds-radius-sm);background:transparent;color:var(--dds-color-text-secondary);font:inherit;cursor:pointer;}
15
15
  .dds-input__clear:hover {background:var(--dds-color-bg-subtle);}
16
- .dds-input__clear:focus-visible {outline:var(--dds-space-2) solid var(--dds-color-border-focus);outline-offset:var(--dds-space-2);}
16
+ /* Inset (D-047): the clear button sits 3px inside the field border, so any ring outside its own box would run beside that border as a second line. */
17
+ .dds-input__clear:focus-visible {outline:var(--dds-space-2) solid var(--dds-color-border-focus);outline-offset:calc(var(--dds-space-2) * -1);}
17
18
  .dds-input[data-disabled] {opacity:.45;cursor:not-allowed;}
18
19
  .dds-input[data-disabled] .dds-input__control {cursor:not-allowed;background:var(--dds-color-bg-subtle);}
19
20
  .dds-input[data-label-placement="hidden"] .dds-input__label {position:absolute;inline-size:1px;block-size:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;}
@@ -58,6 +58,8 @@
58
58
 
59
59
  .dds-switch__input:focus-visible {
60
60
  outline: var(--dds-space-2) solid var(--dds-color-border-focus);
61
+ /* Kept apart, not flush (D-047): the off track is a grey close to the focus
62
+ * color, so a flush ring would merge into a slightly bigger track. */
61
63
  outline-offset: var(--dds-space-2);
62
64
  }
63
65
 
@@ -142,6 +142,8 @@
142
142
  }
143
143
  .dds-table__sort:focus-visible {
144
144
  outline: 2px solid var(--dds-color-border-focus);
145
+ /* Kept apart (D-047): a borderless header label with no padding — flush,
146
+ * the ring would touch the glyphs. There is no edge to double. */
145
147
  outline-offset: 2px;
146
148
  }
147
149
 
@@ -52,7 +52,8 @@
52
52
  .dds-top-nav__trigger:focus-visible,
53
53
  .dds-top-nav__item:focus-visible {
54
54
  outline: 2px solid var(--dds-color-border-focus);
55
- outline-offset: 2px;
55
+ /* Flush on the hover/current fill (D-047). */
56
+ outline-offset: var(--dds-focus-offset);
56
57
  }
57
58
  .dds-top-nav__item[aria-current="page"] {
58
59
  color: var(--dds-color-text-brand);
package/dist/dds.css CHANGED
@@ -87,7 +87,17 @@
87
87
 
88
88
  .dds-btn:focus-visible {
89
89
  outline: var(--dds-space-2) solid var(--dds-color-border-focus);
90
- outline-offset: var(--dds-space-2);
90
+ /* Flush (D-047): the ring sits on the control's own edge, so border/fill
91
+ * and ring read as one thicker line instead of border, gap, ring. */
92
+ outline-offset: var(--dds-focus-offset);
93
+ }
94
+ /* Unfilled buttons (secondary, ghost, no variant) also paint their own 1px
95
+ * border in the focus color, so border + ring are one solid edge of one
96
+ * colour, not a pale line inside a dark one (D-047). Primary and danger are
97
+ * filled: their transparent border shows the fill, which the ring already
98
+ * meets directly. */
99
+ .dds-btn:not(.dds-btn--primary):not(.dds-btn--danger):focus-visible {
100
+ border-color: var(--dds-color-border-focus);
91
101
  }
92
102
 
93
103
  /* opacity is allowed for disabled only (spec §4.2) */
@@ -243,7 +253,8 @@
243
253
  }
244
254
  .dds-iconbtn:focus-visible {
245
255
  outline: var(--dds-space-2) solid var(--dds-color-border-focus);
246
- outline-offset: var(--dds-space-2);
256
+ /* Flush, same as .dds-btn (D-047) — the two sit side by side in toolbars. */
257
+ outline-offset: var(--dds-focus-offset);
247
258
  }
248
259
 
249
260
  /* opacity is allowed for disabled only (spec §4.2) */
@@ -266,6 +277,12 @@
266
277
  .dds-iconbtn--secondary {
267
278
  border-color: var(--dds-color-border-strong);
268
279
  }
280
+ /* Every icon-button variant is unfilled, so focus paints the 1px border in
281
+ * the focus color too: border + ring become one solid edge (D-047). After
282
+ * --secondary so it wins at equal specificity. */
283
+ .dds-iconbtn:focus-visible {
284
+ border-color: var(--dds-color-border-focus);
285
+ }
269
286
 
270
287
  .dds-iconbtn--danger {
271
288
  color: var(--dds-color-status-danger);
@@ -376,7 +393,8 @@
376
393
  .dds-input:has(.dds-input__clear) .dds-input__control {padding-inline-end:var(--dds-space-48);}
377
394
  .dds-input__clear {position:absolute;inset-inline-end:var(--dds-space-4);inset-block-end:var(--dds-space-4);display:grid;place-items:center;inline-size:var(--dds-space-32);block-size:var(--dds-space-32);padding:0;border:0;border-radius:var(--dds-radius-sm);background:transparent;color:var(--dds-color-text-secondary);font:inherit;cursor:pointer;}
378
395
  .dds-input__clear:hover {background:var(--dds-color-bg-subtle);}
379
- .dds-input__clear:focus-visible {outline:var(--dds-space-2) solid var(--dds-color-border-focus);outline-offset:var(--dds-space-2);}
396
+ /* Inset (D-047): the clear button sits 3px inside the field border, so any ring outside its own box would run beside that border as a second line. */
397
+ .dds-input__clear:focus-visible {outline:var(--dds-space-2) solid var(--dds-color-border-focus);outline-offset:calc(var(--dds-space-2) * -1);}
380
398
  .dds-input[data-disabled] {opacity:.45;cursor:not-allowed;}
381
399
  .dds-input[data-disabled] .dds-input__control {cursor:not-allowed;background:var(--dds-color-bg-subtle);}
382
400
  .dds-input[data-label-placement="hidden"] .dds-input__label {position:absolute;inline-size:1px;block-size:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;}
@@ -563,7 +581,8 @@
563
581
  .dds-date-picker-table [data-outside-range] {color:var(--dds-color-text-secondary);}
564
582
  .dds-date-picker-table [data-part="table-cell-trigger"][data-selected] {background:var(--dds-color-bg-brand);color:var(--dds-color-text-on-brand);}
565
583
  .dds-date-picker-table [data-today]:not([data-selected]) {text-decoration:underline;text-underline-offset:var(--dds-space-4);}
566
- .dds-date-picker-content :focus-visible {outline:var(--dds-space-2) solid var(--dds-color-border-focus);outline-offset:var(--dds-space-2);}
584
+ /* Flush (D-047): day cells touch each other and the selected one is filled; a gap ring would double around it and spill onto the neighbours. */
585
+ .dds-date-picker-content :focus-visible {outline:var(--dds-space-2) solid var(--dds-color-border-focus);outline-offset:var(--dds-focus-offset);}
567
586
  .dds-date-picker-footer {display:flex;flex-wrap:wrap;justify-content:space-between;gap:var(--dds-space-12);margin-top:var(--dds-space-12);padding-top:var(--dds-space-12);border-top:calc(var(--dds-space-2) / 2) solid var(--dds-color-border-default);}
568
587
 
569
588
  /* Text box shared by DatePicker, MonthPicker and the DateRangePicker pair: same var(--dds-space-40) DDS input look. */
@@ -1003,6 +1022,9 @@
1003
1022
 
1004
1023
  .dds-check__input:focus-visible {
1005
1024
  outline: var(--dds-space-2) solid var(--dds-color-border-focus);
1025
+ /* Kept apart, not flush (D-047): on an 18px box a flush ring just reads as
1026
+ * a heavier box — the same signal the checked state gives — so the gap is
1027
+ * what makes it read as focus. */
1006
1028
  outline-offset: var(--dds-space-2);
1007
1029
  }
1008
1030
 
@@ -1076,6 +1098,8 @@
1076
1098
 
1077
1099
  .dds-switch__input:focus-visible {
1078
1100
  outline: var(--dds-space-2) solid var(--dds-color-border-focus);
1101
+ /* Kept apart, not flush (D-047): the off track is a grey close to the focus
1102
+ * color, so a flush ring would merge into a slightly bigger track. */
1079
1103
  outline-offset: var(--dds-space-2);
1080
1104
  }
1081
1105
 
@@ -1179,7 +1203,8 @@
1179
1203
  }
1180
1204
  .dds-chip:focus-visible {
1181
1205
  outline: var(--dds-space-2) solid var(--dds-color-border-focus);
1182
- outline-offset: var(--dds-space-2);
1206
+ /* Flush on the chip's own border (D-047). */
1207
+ outline-offset: var(--dds-focus-offset);
1183
1208
  }
1184
1209
 
1185
1210
  .dds-chip[aria-pressed="true"],
@@ -1188,6 +1213,11 @@
1188
1213
  border-color: var(--dds-color-bg-brand);
1189
1214
  color: var(--dds-color-text-brand);
1190
1215
  }
1216
+ /* Focus paints the chip's own border in the focus color, so border + ring are
1217
+ * one solid edge (D-047). After the selected rule so it wins there too. */
1218
+ .dds-chip:focus-visible {
1219
+ border-color: var(--dds-color-border-focus);
1220
+ }
1191
1221
 
1192
1222
  /* opacity is allowed for disabled only (spec §4.2) */
1193
1223
  .dds-chip[disabled] {
@@ -1957,6 +1987,8 @@ dialog.dds-dialog::backdrop {
1957
1987
  }
1958
1988
  .dds-table__sort:focus-visible {
1959
1989
  outline: 2px solid var(--dds-color-border-focus);
1990
+ /* Kept apart (D-047): a borderless header label with no padding — flush,
1991
+ * the ring would touch the glyphs. There is no edge to double. */
1960
1992
  outline-offset: 2px;
1961
1993
  }
1962
1994
 
@@ -2227,7 +2259,9 @@ dialog.dds-dialog::backdrop {
2227
2259
  }
2228
2260
  .dds-console-rail__item:focus-visible {
2229
2261
  outline: 2px solid var(--dds-color-border-focus);
2230
- outline-offset: 2px;
2262
+ /* Flush on the item's hover/current fill (D-047); the rail's 12px
2263
+ * inline padding keeps the ring clear of its scroll edge. */
2264
+ outline-offset: var(--dds-focus-offset);
2231
2265
  }
2232
2266
 
2233
2267
  .dds-console-rail__badge {
@@ -2455,7 +2489,7 @@ dialog.dds-dialog::backdrop {
2455
2489
  .dds-console-rail__group-toggle:hover { background: var(--dds-color-bg-subtle); }
2456
2490
  .dds-console-rail__group-toggle:focus-visible {
2457
2491
  outline: 2px solid var(--dds-color-border-focus);
2458
- outline-offset: 2px;
2492
+ outline-offset: var(--dds-focus-offset);
2459
2493
  }
2460
2494
  .dds-console-rail__chevron {
2461
2495
  inline-size: .375rem;
@@ -2759,7 +2793,8 @@ dialog.dds-dialog::backdrop {
2759
2793
  .dds-top-nav__trigger:focus-visible,
2760
2794
  .dds-top-nav__item:focus-visible {
2761
2795
  outline: 2px solid var(--dds-color-border-focus);
2762
- outline-offset: 2px;
2796
+ /* Flush on the hover/current fill (D-047). */
2797
+ outline-offset: var(--dds-focus-offset);
2763
2798
  }
2764
2799
  .dds-top-nav__item[aria-current="page"] {
2765
2800
  color: var(--dds-color-text-brand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devslab/dds-css",
3
- "version": "0.32.0",
3
+ "version": "0.32.2",
4
4
  "description": "DDS CSS component layer — class-based, framework-neutral, semantic-token-only (spec §4.3 v1 inventory, 20 components)",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN LICENSE",