@blakesteve/roster 4.8.1 → 4.8.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.
package/README.md CHANGED
@@ -260,6 +260,9 @@ Note also that a solid fill's contrast against the surface _behind_ it is a
260
260
  separate requirement (WCAG 1.4.11, 3:1) and is not covered here. Solid amber on
261
261
  a white page is 1.67:1, so it has effectively no visible edge.
262
262
 
263
+ Form controls **are** covered for that requirement, separately: see
264
+ `--roster-control-border` under [Control surface colors](#control-surface-colors).
265
+
263
266
  ### Focus
264
267
 
265
268
  Every focusable control draws the same ring: `--roster-ring` for the ring
@@ -268,6 +271,24 @@ control's own fill. Both flip with the theme — `primary-500` on white in light
268
271
  `primary-400` on `gray-950` in dark — which puts the indicator at 6.37:1 and
269
272
  7.31:1 against the surface either side of it, where WCAG 1.4.11 asks for 3:1.
270
273
 
274
+ Both tokens follow the **page**, which is right until a component deliberately
275
+ inverts against it. `Dialog`'s `slate` and `primary` are dark whatever the page
276
+ is doing, so on a light page they were handing their contents the light-mode
277
+ ring: `primary-500` on `gray-700` is **1.61:1**, and the white offset behind it
278
+ was 10.27:1, making the gap the most visible part of the indicator. Those two
279
+ variants now set both tokens on their own subtree, so a field inside them gets
280
+ 3.80:1 and 4.04:1 instead. `white` and `glass` are left alone because they
281
+ follow the page like everything else.
282
+
283
+ If you build your own inverted surface, do the same on it:
284
+
285
+ ```css
286
+ .my-dark-panel {
287
+ --roster-ring: var(--roster-primary-400);
288
+ --roster-ring-offset: /* that panel's own background */;
289
+ }
290
+ ```
291
+
271
292
  Retint it for your own accent:
272
293
 
273
294
  ```css
@@ -365,40 +386,55 @@ pseudo-elements for any element that sets either of them, so on anything modern
365
386
 
366
387
  ### Control surface colors
367
388
 
368
- `Input`, `PasswordInput` and `Select` read these variables in their `outline`
369
- variant, so a consumer can repaint a form control without restating the class
370
- list.
389
+ `Input`, `PasswordInput`, `Textarea` and `Select` read these variables, so a
390
+ consumer can repaint a form control without restating the class list. Both
391
+ `outline` and `soft` read the border: `soft` used to be borderless and lean on
392
+ its fill alone, which fails the moment the fill matches the surface — a `soft`
393
+ field inside a `white` Dialog in dark mode was exactly 1.00:1 and invisible
394
+ until focus.
371
395
 
372
396
  ```css
373
397
  :root {
374
- --roster-control-border: #d6d3d1;
398
+ --roster-control-border: #65635f; /* gray-500 */
375
399
  --roster-control-bg: transparent;
376
400
  --roster-control-text: #1c1917;
377
401
  --roster-control-border-focus: #0f6498;
378
402
  }
379
403
  .dark {
380
- --roster-control-border: #44403c;
404
+ --roster-control-border: #a8a29e; /* gray-400 */
381
405
  --roster-control-bg: transparent;
382
406
  --roster-control-text: #f5f5f4;
383
- --roster-control-border-focus: #0f6498;
407
+ --roster-control-border-focus: #5ea3de; /* primary-400 */
384
408
  }
385
409
  ```
386
410
 
411
+ `--roster-control-border` is the one token here whose two scopes hold different
412
+ values, and that is deliberate. WCAG 1.4.11 asks 3:1 to identify a control, and
413
+ a border has to move opposite its surface to get there: gray-500 reaches 5.99
414
+ on white but only 2.53 on a gray-800 Dialog, while gray-400 reaches 6.01 there
415
+ and 2.52 on white. No single step of the ramp clears 3:1 both ways. The old
416
+ gray-300 / gray-700 pair was 1.49 and 1.48 — a hairline rather than a boundary.
417
+
387
418
  Set them in both scopes, for the same reason the scrollbar thumb needs both:
388
419
  Roster's own `.dark` rule has equal specificity and comes later.
389
420
 
390
- The defaults are the values the component used to hardcode, so installing this
391
- version changes nothing on its own. Placeholder color, the error state, and the
421
+ Three of the four still default to what the components used to hardcode.
422
+ `--roster-control-border` does not — the 1.4.11 pass moved it two ramp steps —
423
+ so installing this version **does** change how your fields look, deliberately. Placeholder color, the error state, and the
392
424
  focus ring are deliberately not on tokens — the ring is already
393
425
  `--roster-ring`, and error styling should stay recognizably an error.
394
426
 
395
427
  Not every control uses every token: `Select` takes the first three, because
396
- focus on its trigger is the shared `--roster-ring` rather than a border color.
428
+ focus on its trigger is the shared `--roster-ring` rather than a border color,
429
+ and it draws the border as a ring rather than a border.
397
430
  One family rather than one per component is deliberate — these controls sit in
398
431
  the same row of the same form and are drawn to look identical, so being able to
399
432
  repaint one and not the other would be a bug, not a choice.
400
433
 
401
- The `outline` variant is the only one that reads them, in every component, and
434
+ `outline` reads all four. `soft` reads the border only, because a boundary is
435
+ the one thing a filled field cannot supply for itself on an arbitrary surface;
436
+ `white`, `slate` and `ghost` stay opinionated. `Checkbox` reads the border too,
437
+ for its unchecked box. Historically `outline` was the only reader, and
402
438
  it carries no hover fill. The other variants each name a concrete surface
403
439
  (`white`, `soft`, `slate`, `ghost`) and stay opinionated: a token that meant
404
440
  something different in each would not be a token.
package/dist/meta.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "4.8.1",
3
- "tests": 1117,
2
+ "version": "4.8.2",
3
+ "tests": 1132,
4
4
  "testFiles": 93
5
5
  }