use-wc 1.0.0-pre.74 → 1.0.0-pre.76

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.
@@ -1841,6 +1841,88 @@
1841
1841
  }
1842
1842
  ]
1843
1843
  },
1844
+ {
1845
+ "kind": "javascript-module",
1846
+ "path": "src/elements/use-focusgroup/use-focusgroup.ts",
1847
+ "declarations": [
1848
+ {
1849
+ "kind": "class",
1850
+ "description": "Nested controls are removed from the tab flow until the user navigates the nested controls with arrow keys.\n\n`use-focusgroup` is most useful for things like WYSIWYG toolbars, sets of tabs, or lists of navigation links (like a list of emails in a master detail layout).\n\n## To do\n\n- [ ] add `grid` navigation feature\n- [ ] add `autofocus` attribute support\n\n## Long term plan\n\nThis web component was built with the intent to be replaced by browser-native focusgroup support once it becomes baseline. Hopefully migration will be as simple as changing the tag name from `use-focusgroup` to `div` and the `options` attribute to `focusgroup`.\n\n<baseline-status featureId=\"focusgroup_attribute\"></baseline-status>\n\n## Sources\n\n- [Open UI focusgroup Explainer](https://open-ui.org/components/focusgroup.explainer/)\n- [tabbable](https://www.npmjs.com/package/tabbable)\n- [Toolbar Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/toolbar/)\n- [@gfellerph/focusgroup-polyfill](https://github.com/gfellerph/focusgroup-polyfill)",
1851
+ "name": "UseFocusgroup",
1852
+ "members": [
1853
+ {
1854
+ "kind": "field",
1855
+ "name": "features",
1856
+ "type": {
1857
+ "text": "string"
1858
+ },
1859
+ "default": "\"\"",
1860
+ "description": "A list of space-separated features that can be used to customize the behavior of the focusgroup.\n\nThe following options are available:\n\n- `inline` opts into keyboard navigation via left and right arrow keys\n- `block` opts into keyboard navigation via up and down arrow keys\n- `wrap` arrow navigation should wrap around when reaching the end\n- `no-memory` whether the focusgroup should not remember the last focused element\n\nIf nothing if neither `inline` nor `block` is specified, both are assumed.",
1861
+ "attribute": "features"
1862
+ },
1863
+ {
1864
+ "kind": "field",
1865
+ "name": "focusedElement",
1866
+ "type": {
1867
+ "text": "HTMLElement | null"
1868
+ },
1869
+ "default": "null",
1870
+ "description": "The most recently focused element in the focusgroup."
1871
+ },
1872
+ {
1873
+ "kind": "method",
1874
+ "name": "focus"
1875
+ },
1876
+ {
1877
+ "kind": "field",
1878
+ "name": "promoted",
1879
+ "description": "Whether the use-focusgroup is promoted to the top of the tab order inside a parent use-focusgroup.",
1880
+ "readonly": true,
1881
+ "default": "false"
1882
+ },
1883
+ {
1884
+ "kind": "method",
1885
+ "name": "promote",
1886
+ "description": "Promotes the use-focusgroup to the top of the tab order inside a parent use-focusgroup."
1887
+ }
1888
+ ],
1889
+ "attributes": [
1890
+ {
1891
+ "name": "features",
1892
+ "type": {
1893
+ "text": "string"
1894
+ },
1895
+ "default": "\"\"",
1896
+ "description": "A list of space-separated features that can be used to customize the behavior of the focusgroup.\n\nThe following options are available:\n\n- `inline` opts into keyboard navigation via left and right arrow keys\n- `block` opts into keyboard navigation via up and down arrow keys\n- `wrap` arrow navigation should wrap around when reaching the end\n- `no-memory` whether the focusgroup should not remember the last focused element\n\nIf nothing if neither `inline` nor `block` is specified, both are assumed.",
1897
+ "fieldName": "features"
1898
+ }
1899
+ ],
1900
+ "superclass": {
1901
+ "name": "HTMLElement"
1902
+ },
1903
+ "tagName": "use-focusgroup",
1904
+ "customElement": true
1905
+ }
1906
+ ],
1907
+ "exports": [
1908
+ {
1909
+ "kind": "js",
1910
+ "name": "UseFocusgroup",
1911
+ "declaration": {
1912
+ "name": "UseFocusgroup",
1913
+ "module": "src/elements/use-focusgroup/use-focusgroup.ts"
1914
+ }
1915
+ },
1916
+ {
1917
+ "kind": "custom-element-definition",
1918
+ "name": "use-focusgroup",
1919
+ "declaration": {
1920
+ "name": "UseFocusgroup",
1921
+ "module": "src/elements/use-focusgroup/use-focusgroup.ts"
1922
+ }
1923
+ }
1924
+ ]
1925
+ },
1844
1926
  {
1845
1927
  "kind": "javascript-module",
1846
1928
  "path": "src/elements/use-duration-input/use-duration-input.ts",
@@ -2155,88 +2237,6 @@
2155
2237
  }
2156
2238
  ]
2157
2239
  },
2158
- {
2159
- "kind": "javascript-module",
2160
- "path": "src/elements/use-focusgroup/use-focusgroup.ts",
2161
- "declarations": [
2162
- {
2163
- "kind": "class",
2164
- "description": "Nested controls are removed from the tab flow until the user navigates the nested controls with arrow keys.\n\n`use-focusgroup` is most useful for things like WYSIWYG toolbars, sets of tabs, or lists of navigation links (like a list of emails in a master detail layout).\n\n## To do\n\n- [ ] add `grid` navigation feature\n- [ ] add `autofocus` attribute support\n\n## Long term plan\n\nThis web component was built with the intent to be replaced by browser-native focusgroup support once it becomes baseline. Hopefully migration will be as simple as changing the tag name from `use-focusgroup` to `div` and the `options` attribute to `focusgroup`.\n\n<baseline-status featureId=\"focusgroup_attribute\"></baseline-status>\n\n## Sources\n\n- [Open UI focusgroup Explainer](https://open-ui.org/components/focusgroup.explainer/)\n- [tabbable](https://www.npmjs.com/package/tabbable)\n- [Toolbar Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/toolbar/)\n- [@gfellerph/focusgroup-polyfill](https://github.com/gfellerph/focusgroup-polyfill)",
2165
- "name": "UseFocusgroup",
2166
- "members": [
2167
- {
2168
- "kind": "field",
2169
- "name": "features",
2170
- "type": {
2171
- "text": "string"
2172
- },
2173
- "default": "\"\"",
2174
- "description": "A list of space-separated features that can be used to customize the behavior of the focusgroup.\n\nThe following options are available:\n\n- `inline` opts into keyboard navigation via left and right arrow keys\n- `block` opts into keyboard navigation via up and down arrow keys\n- `wrap` arrow navigation should wrap around when reaching the end\n- `no-memory` whether the focusgroup should not remember the last focused element\n\nIf nothing if neither `inline` nor `block` is specified, both are assumed.",
2175
- "attribute": "features"
2176
- },
2177
- {
2178
- "kind": "field",
2179
- "name": "focusedElement",
2180
- "type": {
2181
- "text": "HTMLElement | null"
2182
- },
2183
- "default": "null",
2184
- "description": "The most recently focused element in the focusgroup."
2185
- },
2186
- {
2187
- "kind": "method",
2188
- "name": "focus"
2189
- },
2190
- {
2191
- "kind": "field",
2192
- "name": "promoted",
2193
- "description": "Whether the use-focusgroup is promoted to the top of the tab order inside a parent use-focusgroup.",
2194
- "readonly": true,
2195
- "default": "false"
2196
- },
2197
- {
2198
- "kind": "method",
2199
- "name": "promote",
2200
- "description": "Promotes the use-focusgroup to the top of the tab order inside a parent use-focusgroup."
2201
- }
2202
- ],
2203
- "attributes": [
2204
- {
2205
- "name": "features",
2206
- "type": {
2207
- "text": "string"
2208
- },
2209
- "default": "\"\"",
2210
- "description": "A list of space-separated features that can be used to customize the behavior of the focusgroup.\n\nThe following options are available:\n\n- `inline` opts into keyboard navigation via left and right arrow keys\n- `block` opts into keyboard navigation via up and down arrow keys\n- `wrap` arrow navigation should wrap around when reaching the end\n- `no-memory` whether the focusgroup should not remember the last focused element\n\nIf nothing if neither `inline` nor `block` is specified, both are assumed.",
2211
- "fieldName": "features"
2212
- }
2213
- ],
2214
- "superclass": {
2215
- "name": "HTMLElement"
2216
- },
2217
- "tagName": "use-focusgroup",
2218
- "customElement": true
2219
- }
2220
- ],
2221
- "exports": [
2222
- {
2223
- "kind": "js",
2224
- "name": "UseFocusgroup",
2225
- "declaration": {
2226
- "name": "UseFocusgroup",
2227
- "module": "src/elements/use-focusgroup/use-focusgroup.ts"
2228
- }
2229
- },
2230
- {
2231
- "kind": "custom-element-definition",
2232
- "name": "use-focusgroup",
2233
- "declaration": {
2234
- "name": "UseFocusgroup",
2235
- "module": "src/elements/use-focusgroup/use-focusgroup.ts"
2236
- }
2237
- }
2238
- ]
2239
- },
2240
2240
  {
2241
2241
  "kind": "javascript-module",
2242
2242
  "path": "src/elements/use-grid/constants.ts",
@@ -4016,63 +4016,6 @@
4016
4016
  }
4017
4017
  ]
4018
4018
  },
4019
- {
4020
- "kind": "javascript-module",
4021
- "path": "src/elements/use-scrollarea/index.ts",
4022
- "declarations": [],
4023
- "exports": [
4024
- {
4025
- "kind": "js",
4026
- "name": "UseScrollarea",
4027
- "declaration": {
4028
- "name": "UseScrollarea",
4029
- "module": "./use-scrollarea"
4030
- }
4031
- }
4032
- ]
4033
- },
4034
- {
4035
- "kind": "javascript-module",
4036
- "path": "src/elements/use-scrollarea/use-scrollarea.ts",
4037
- "declarations": [
4038
- {
4039
- "kind": "class",
4040
- "description": "A scroll container that exposes custom states for scroll edge detection.\n\n## Custom States\nThe following CSS custom states are available for styling:\n\n- `:state(at-block-start)` — scrolled to the block-start edge (top in horizontal writing modes)\n- `:state(at-block-end)` — scrolled to the block-end edge (bottom in horizontal writing modes)\n- `:state(at-inline-start)` — scrolled to the inline-start edge (left in LTR)\n- `:state(at-inline-end)` — scrolled to the inline-end edge (right in LTR)",
4041
- "name": "UseScrollarea",
4042
- "slots": [
4043
- {
4044
- "description": "Scrollable content",
4045
- "name": ""
4046
- }
4047
- ],
4048
- "members": [],
4049
- "superclass": {
4050
- "name": "LitElement",
4051
- "package": "lit"
4052
- },
4053
- "tagName": "use-scrollarea",
4054
- "customElement": true
4055
- }
4056
- ],
4057
- "exports": [
4058
- {
4059
- "kind": "js",
4060
- "name": "UseScrollarea",
4061
- "declaration": {
4062
- "name": "UseScrollarea",
4063
- "module": "src/elements/use-scrollarea/use-scrollarea.ts"
4064
- }
4065
- },
4066
- {
4067
- "kind": "custom-element-definition",
4068
- "name": "use-scrollarea",
4069
- "declaration": {
4070
- "name": "UseScrollarea",
4071
- "module": "src/elements/use-scrollarea/use-scrollarea.ts"
4072
- }
4073
- }
4074
- ]
4075
- },
4076
4019
  {
4077
4020
  "kind": "javascript-module",
4078
4021
  "path": "src/elements/use-time-input/use-time-input.ts",
@@ -4338,6 +4281,63 @@
4338
4281
  }
4339
4282
  ]
4340
4283
  },
4284
+ {
4285
+ "kind": "javascript-module",
4286
+ "path": "src/elements/use-scrollarea/index.ts",
4287
+ "declarations": [],
4288
+ "exports": [
4289
+ {
4290
+ "kind": "js",
4291
+ "name": "UseScrollarea",
4292
+ "declaration": {
4293
+ "name": "UseScrollarea",
4294
+ "module": "./use-scrollarea"
4295
+ }
4296
+ }
4297
+ ]
4298
+ },
4299
+ {
4300
+ "kind": "javascript-module",
4301
+ "path": "src/elements/use-scrollarea/use-scrollarea.ts",
4302
+ "declarations": [
4303
+ {
4304
+ "kind": "class",
4305
+ "description": "A scroll container that exposes custom states for scroll edge detection.\n\n## Custom States\nThe following CSS custom states are available for styling:\n\n- `:state(at-block-start)` — scrolled to the block-start edge (top in horizontal writing modes)\n- `:state(at-block-end)` — scrolled to the block-end edge (bottom in horizontal writing modes)\n- `:state(at-inline-start)` — scrolled to the inline-start edge (left in LTR)\n- `:state(at-inline-end)` — scrolled to the inline-end edge (right in LTR)",
4306
+ "name": "UseScrollarea",
4307
+ "slots": [
4308
+ {
4309
+ "description": "Scrollable content",
4310
+ "name": ""
4311
+ }
4312
+ ],
4313
+ "members": [],
4314
+ "superclass": {
4315
+ "name": "LitElement",
4316
+ "package": "lit"
4317
+ },
4318
+ "tagName": "use-scrollarea",
4319
+ "customElement": true
4320
+ }
4321
+ ],
4322
+ "exports": [
4323
+ {
4324
+ "kind": "js",
4325
+ "name": "UseScrollarea",
4326
+ "declaration": {
4327
+ "name": "UseScrollarea",
4328
+ "module": "src/elements/use-scrollarea/use-scrollarea.ts"
4329
+ }
4330
+ },
4331
+ {
4332
+ "kind": "custom-element-definition",
4333
+ "name": "use-scrollarea",
4334
+ "declaration": {
4335
+ "name": "UseScrollarea",
4336
+ "module": "src/elements/use-scrollarea/use-scrollarea.ts"
4337
+ }
4338
+ }
4339
+ ]
4340
+ },
4341
4341
  {
4342
4342
  "kind": "javascript-module",
4343
4343
  "path": "src/elements/use-tree/use-tree.ts",
@@ -68,7 +68,13 @@
68
68
  --usewc-color-input-border: var(--usewc-color-input-border-hover);
69
69
  }
70
70
 
71
- &:where(:focus, :has(input:focus), :focus-within) {
71
+ /* Matches the hover rule's own specificity (a real pseudo-class, not `:where()`-zeroed) so
72
+ that when both apply at once — hovering a focused control — source order decides and this,
73
+ declared after, wins; wrapping this in `:where()` as before let hover's specificity beat
74
+ it regardless of order. */
75
+ &:focus,
76
+ &:focus-within,
77
+ &:has(input:focus) {
72
78
  --usewc-color-input-border: var(--usewc-color-input-border-focus);
73
79
  --usewc-effect-outline-width: var(--usewc-effect-outline-size);
74
80
  }
@@ -313,7 +319,7 @@
313
319
 
314
320
  @layer use-theme.link {
315
321
  :is(nav, header, footer, [role="navigation"], [role="menubar"], [role="tablist"], [role="toolbar"]) {
316
- --usewc-effect-link-decoration: var(--usewc-effect-link-chrome-text-decoration);
322
+ --usewc-local-link-decoration-line: var(--usewc-effect-link-chrome-text-decoration);
317
323
  }
318
324
 
319
325
  :is(a:not([class*="appearance-"]), .appearance-a) {
@@ -321,11 +327,23 @@
321
327
  all: unset;
322
328
  }
323
329
 
324
- --usewc-color-link-text: var(--usewc-color-link-text-static);
330
+ /* `--usewc-local-*` names the variables below as rule-scoped plumbing rather than themeable
331
+ tokens — set here to thread the current state (hover/active, chrome context, sidebar) into
332
+ the properties further down, as opposed to the real tokens in `semantic.css` they read
333
+ from. `--usewc-local-link-decoration-color` in particular has to be derived here rather
334
+ than hoisted into `semantic.css`: relative-color syntax reading a `var()` only resolves
335
+ once the referenced custom property is defined on the same element/rule, and
336
+ `--usewc-local-link-text` only ever exists on this one. */
337
+ --usewc-local-link-text: var(--usewc-color-link-text-static);
338
+ --usewc-local-link-decoration-opacity: var(--usewc-effect-link-decoration-opacity);
339
+ --usewc-local-link-decoration-color: oklch(
340
+ from var(--usewc-local-link-text) l c h / var(--usewc-local-link-decoration-opacity)
341
+ );
325
342
  --usewc-effect-outline-width: 0;
326
343
 
327
- color: var(--usewc-color-link-text);
328
- text-decoration: var(--usewc-effect-link-decoration, var(--usewc-effect-link-text-decoration));
344
+ color: var(--usewc-local-link-text);
345
+ text-decoration: var(--usewc-local-link-decoration-line, var(--usewc-effect-link-text-decoration));
346
+ text-decoration-color: var(--usewc-local-link-decoration-color);
329
347
  cursor: pointer;
330
348
  outline: var(--usewc-effect-outline-width) var(--usewc-effect-outline-style) var(--usewc-color-outline);
331
349
  outline-offset: var(--usewc-effect-outline-offset);
@@ -336,7 +354,7 @@
336
354
  }
337
355
 
338
356
  &:is(:hover, :focus-visible) {
339
- --usewc-color-link-text: var(--usewc-color-link-text-hover);
357
+ --usewc-local-link-text: var(--usewc-color-link-text-hover);
340
358
  }
341
359
 
342
360
  &:focus-visible {
@@ -344,12 +362,15 @@
344
362
  }
345
363
 
346
364
  &:active {
347
- --usewc-color-link-text: var(--usewc-color-link-text-active);
365
+ --usewc-local-link-text: var(--usewc-color-link-text-active);
366
+ /* Pressed reads as committed rather than merely hinted at, so the underline matches the
367
+ text exactly here instead of staying a lighter tint of it. */
368
+ --usewc-local-link-decoration-opacity: 1;
348
369
  }
349
370
 
350
371
  nav.sidebar > & {
351
372
  display: block;
352
- /* Swapping these source tokens, rather than the resolved `--usewc-color-link-text` slot
373
+ /* Swapping these source tokens, rather than the resolved `--usewc-local-link-text` slot
353
374
  itself, means the existing `:hover`/`:active` rules above keep working unmodified — they
354
375
  already read through `-hover`/`-active`, so overriding what those resolve to here is
355
376
  enough to recolor every state at once. */
@@ -1401,6 +1422,24 @@
1401
1422
  }
1402
1423
  }
1403
1424
 
1425
+ /* A link inside a cell reads as the cell's own text rather than the document's default link
1426
+ blue — the grid draws attention with its row/selection bands, not link-colored text, so a
1427
+ link that broke from the cell's color would read as an anomaly instead of an affordance.
1428
+ Hover/active still need to move, the same as the default link darkening through
1429
+ blue-600/700/800 — `currentColor` alone can't step down like that, so each state is the
1430
+ cell's own color with its lightness nudged instead. `link.css`'s own decoration-color rule
1431
+ already derives from `--usewc-local-link-text`, so the underline follows every step here for
1432
+ free, staying a lighter tint of whichever shade the text itself is in. */
1433
+ use-gridcell :is(a:not([class*="appearance-"]), .appearance-a) {
1434
+ --usewc-color-link-text-static: currentColor;
1435
+ --usewc-color-link-text-hover: oklch(
1436
+ from currentColor calc(l + var(--usewc-color-grid-cell-link-hover-lightness-shift)) c h
1437
+ );
1438
+ --usewc-color-link-text-active: oklch(
1439
+ from currentColor calc(l + var(--usewc-color-grid-cell-link-active-lightness-shift)) c h
1440
+ );
1441
+ }
1442
+
1404
1443
  use-grid:not(.chips, .list, .appearance-native) {
1405
1444
  display: block;
1406
1445
  overflow: clip;
@@ -1495,6 +1534,11 @@
1495
1534
  border-inline-start so it can sit shorter than the cell rather than spanning it. */
1496
1535
  use-gridhead use-gridcell[role="columnheader"] {
1497
1536
  position: relative;
1537
+ /* A header with no label has no line box, so its own height (and the divider's `%`
1538
+ height off it) would otherwise collapse to just the cell's own block padding —
1539
+ reserve the same total height a labeled cell gets (padding plus a full line) so an
1540
+ unlabeled column still gets a full-height divider next to its neighbors. */
1541
+ min-block-size: calc(var(--usewc-layout-grid-cell-line-height) + var(--usewc-layout-grid-cell-padding-block) * 2);
1498
1542
 
1499
1543
  use-theme-escape & {
1500
1544
  all: revert-layer;
@@ -2261,6 +2305,17 @@
2261
2305
  min-inline-size: 0;
2262
2306
  }
2263
2307
 
2308
+ /* `--usewc-layout-region-gap`/`-padding` are custom properties, which inherit by default — left
2309
+ alone, a nested `use-layout` would pick up its ancestor's density instead of its own default
2310
+ of "no gap/padding of its own." Resetting them here, at `:where()`'s zero specificity, stops
2311
+ that inheritance at every `use-layout` boundary without affecting a variant class or a
2312
+ `gap`/`padding` attribute below, both of which carry real specificity and still win on the
2313
+ element they target. */
2314
+ :where(use-layout) {
2315
+ --usewc-layout-region-gap: initial;
2316
+ --usewc-layout-region-padding: initial;
2317
+ }
2318
+
2264
2319
  /* ── Variant density ────────────────────────────────────────────────────────────────────────
2265
2320
  A variant class sets its own scale and nothing else; the generic region rules below read
2266
2321
  these properties. Keeping the arrangement in one ruleset rather than four means a future
@@ -2277,6 +2332,14 @@
2277
2332
  --usewc-layout-footer-justify: space-between;
2278
2333
  }
2279
2334
 
2335
+ /* A page's own `h1` — its title, wherever it sits in the topbar — reads at the page's title
2336
+ size and weight rather than the browser's default heading style. Matched at any depth, since
2337
+ a topbar routinely nests it a `<section>` or an `<hgroup>` down. */
2338
+ use-layout.page h1 {
2339
+ font-size: var(--usewc-font-page-title-size);
2340
+ font-weight: var(--usewc-font-page-title-weight);
2341
+ }
2342
+
2280
2343
  use-layout.entry {
2281
2344
  --usewc-layout-region-padding: var(--usewc-layout-entry-padding);
2282
2345
  --usewc-layout-region-gap: var(--usewc-layout-entry-gap);
package/dist/tokens.css CHANGED
@@ -37,6 +37,7 @@
37
37
  --usewc-font-size-18: 1.125rem;
38
38
  --usewc-font-size-20: 1.25rem;
39
39
  --usewc-font-size-24: 1.5rem;
40
+ --usewc-font-size-28: 1.75rem;
40
41
 
41
42
  /** Font weight */
42
43
  --usewc-font-weight-light: 300;
@@ -203,6 +204,12 @@
203
204
  --usewc-color-link-text-visited-hover: var(--usewc-color-indigo-600);
204
205
  --usewc-color-link-text-visited-active: var(--usewc-color-indigo-700);
205
206
  --usewc-effect-link-text-decoration: underline;
207
+ /* The underline is always this much fainter than whatever the link's own text color resolves
208
+ to, in whichever state — a plain number rather than a full `oklch(from ...)` expression,
209
+ since relative-color syntax reading a `var()` only resolves reliably when the referenced
210
+ custom property lives on the same rule; `link.css` does the actual derivation locally,
211
+ alongside the (also local) `--usewc-local-link-text` it reads from. */
212
+ --usewc-effect-link-decoration-opacity: 0.3;
206
213
  --usewc-effect-link-chrome-text-decoration: none;
207
214
  /* - Sidebar nav item */
208
215
  /* A sidebar item reads as chrome, not a hyperlink, so its text stays the document's own ink
@@ -578,6 +585,15 @@
578
585
  --usewc-color-grid-header-background: transparent;
579
586
  --usewc-color-grid-header-text: var(--usewc-color-gray-600);
580
587
  --usewc-color-grid-row-background-hover: oklch(from var(--usewc-color-gray-300) l c h / 0.55);
588
+ /* A link inside a cell inherits its resting color from the cell (`currentColor`), so hover/active
589
+ can't reach for a fixed color the way the default link does — they shift that same color's own
590
+ lightness instead. Light mode's cell text is usually dark, so darkening it further (moving
591
+ toward black) reads as pressed, the same direction the default link's blue-600/700/800
592
+ progression darkens on hover/active; the dark-mode block below flips both to lighten instead,
593
+ since a light-on-dark cell darkening toward the page background would lose contrast rather
594
+ than gain it — the same reason `button.css`'s own hover/active derivation carries a shift. */
595
+ --usewc-color-grid-cell-link-hover-lightness-shift: -0.08;
596
+ --usewc-color-grid-cell-link-active-lightness-shift: -0.16;
581
597
  /* A super-light tint of the primary — its hue and a whisper of its chroma, floated up to
582
598
  near-white — so it tracks the primary even if that's overridden. */
583
599
  --usewc-color-grid-row-background-selected: oklch(from var(--usewc-color-brand-primary) 0.96 0.03 h);
@@ -756,6 +772,8 @@
756
772
  --usewc-layout-page-padding: var(--usewc-space-20);
757
773
  --usewc-layout-page-gap: var(--usewc-space-12);
758
774
  --usewc-layout-page-avatar-size: var(--usewc-layout-region-title-block-size);
775
+ --usewc-font-page-title-size: var(--usewc-font-size-28);
776
+ --usewc-font-page-title-weight: var(--usewc-font-weight-medium);
759
777
 
760
778
  --usewc-layout-card-padding: var(--usewc-space-16);
761
779
  --usewc-layout-card-gap: var(--usewc-space-10);
@@ -817,7 +835,7 @@
817
835
  --usewc-color-outline: var(--usewc-color-blue-400);
818
836
  --usewc-color-prose-code-background: var(--usewc-color-gray-900);
819
837
  --usewc-color-input-background-static: oklch(from var(--usewc-color-gray-100) l c h / 0.025);
820
- --usewc-color-input-border-static: var(--usewc-color-gray-600);
838
+ --usewc-color-input-border-static: var(--usewc-color-gray-800);
821
839
  --usewc-color-input-text-static: var(--usewc-color-gray-200);
822
840
  --usewc-color-input-text-placeholder: var(--usewc-color-gray-500);
823
841
  --usewc-color-form-label-text: var(--usewc-color-gray-100);
@@ -875,8 +893,9 @@
875
893
  --usewc-color-link-text-static: var(--usewc-color-blue-400);
876
894
  --usewc-color-link-text-hover: var(--usewc-color-blue-500);
877
895
  --usewc-color-link-text-active: var(--usewc-color-blue-600);
896
+ --usewc-effect-link-decoration-opacity: 0.5;
878
897
  --usewc-color-code-text: var(--usewc-color-red-200);
879
- --usewc-color-input-border-hover: var(--usewc-color-gray-500);
898
+ --usewc-color-input-border-hover: var(--usewc-color-gray-700);
880
899
  --usewc-color-input-border-focus: var(--usewc-color-blue-400);
881
900
  --usewc-color-input-border-invalid: var(--usewc-color-red-300);
882
901
  --usewc-color-input-segment-background-focus: var(--usewc-color-blue-100);
@@ -898,6 +917,11 @@
898
917
  --usewc-color-grid-header-text: var(--usewc-color-gray-200);
899
918
  --usewc-color-avatar-background: var(--usewc-color-gray-800);
900
919
  --usewc-color-avatar-text: var(--usewc-color-gray-200);
920
+ /* A cell's own text is usually light against a dark page, so hover/active need to lighten it
921
+ further instead of darkening it toward the background — the opposite direction from light
922
+ mode, same as the sign flip below. */
923
+ --usewc-color-grid-cell-link-hover-lightness-shift: 0.08;
924
+ --usewc-color-grid-cell-link-active-lightness-shift: 0.16;
901
925
  }
902
926
  }
903
927
 
package/dist/use-wc.mjs CHANGED
@@ -5223,13 +5223,7 @@ let UseGridCell = class UseGridCell extends UseWidget {
5223
5223
  this.#action = null;
5224
5224
  this.#actionsInitialized = false;
5225
5225
  this.#handleFocusIn = () => {
5226
- if (!this.#actionsInitialized) {
5227
- focusable(this).forEach((el) => {
5228
- el.tabIndex = -1;
5229
- if (!this.#action) this.#action = el;
5230
- });
5231
- this.#actionsInitialized = true;
5232
- }
5226
+ this.#initializeAction();
5233
5227
  if (this.#action) {
5234
5228
  this.#action.focus();
5235
5229
  this.tabIndex = -1;
@@ -5246,10 +5240,19 @@ let UseGridCell = class UseGridCell extends UseWidget {
5246
5240
  if (!this.hasAttribute("role")) this.setAttribute("role", this.closest("use-gridhead") ? "columnheader" : "gridcell");
5247
5241
  this.tabIndex = -1;
5248
5242
  if (this.mode === "action") {
5243
+ queueMicrotask(() => this.#initializeAction());
5249
5244
  this.addEventListener("focusin", this.#handleFocusIn);
5250
5245
  this.addEventListener("focusout", this.#handleFocusOut);
5251
5246
  }
5252
5247
  }
5248
+ #initializeAction() {
5249
+ if (this.#actionsInitialized) return;
5250
+ focusable(this).forEach((el) => {
5251
+ el.tabIndex = -1;
5252
+ if (!this.#action) this.#action = el;
5253
+ });
5254
+ this.#actionsInitialized = true;
5255
+ }
5253
5256
  #handleFocusIn;
5254
5257
  #handleFocusOut;
5255
5258
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "use-wc",
3
- "version": "1.0.0-pre.74",
3
+ "version": "1.0.0-pre.76",
4
4
  "private": false,
5
5
  "homepage": "https://usewc.com",
6
6
  "bugs": "https://github.com/dang-rabbits/use-wc/issues",
@@ -139,6 +139,18 @@
139
139
  ],
140
140
  "references": []
141
141
  },
142
+ {
143
+ "name": "use-focusgroup",
144
+ "description": "Nested controls are removed from the tab flow until the user navigates the nested controls with arrow keys.\n\n`use-focusgroup` is most useful for things like WYSIWYG toolbars, sets of tabs, or lists of navigation links (like a list of emails in a master detail layout).\n\n## To do\n\n- [ ] add `grid` navigation feature\n- [ ] add `autofocus` attribute support\n\n## Long term plan\n\nThis web component was built with the intent to be replaced by browser-native focusgroup support once it becomes baseline. Hopefully migration will be as simple as changing the tag name from `use-focusgroup` to `div` and the `options` attribute to `focusgroup`.\n\n<baseline-status featureId=\"focusgroup_attribute\"></baseline-status>\n\n## Sources\n\n- [Open UI focusgroup Explainer](https://open-ui.org/components/focusgroup.explainer/)\n- [tabbable](https://www.npmjs.com/package/tabbable)\n- [Toolbar Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/toolbar/)\n- [@gfellerph/focusgroup-polyfill](https://github.com/gfellerph/focusgroup-polyfill)\n---\n\n\n### **Methods:**\n - **promote()** - Promotes the use-focusgroup to the top of the tab order inside a parent use-focusgroup.",
145
+ "attributes": [
146
+ {
147
+ "name": "features",
148
+ "description": "A list of space-separated features that can be used to customize the behavior of the focusgroup.\n\nThe following options are available:\n\n- `inline` opts into keyboard navigation via left and right arrow keys\n- `block` opts into keyboard navigation via up and down arrow keys\n- `wrap` arrow navigation should wrap around when reaching the end\n- `no-memory` whether the focusgroup should not remember the last focused element\n\nIf nothing if neither `inline` nor `block` is specified, both are assumed.",
149
+ "values": []
150
+ }
151
+ ],
152
+ "references": []
153
+ },
142
154
  {
143
155
  "name": "use-duration-input",
144
156
  "description": "Displays the parts of an ISO 8601 duration string using [`Intl.DurationFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DurationFormat).\n\nUses the [`duration-fns`](https://www.npmjs.com/package/duration-fns) library for parsing ISO 8601 values.\n\n<baseline-status featureId=\"intl-duration-format\"></baseline-status>\n---\n",
@@ -167,18 +179,6 @@
167
179
  ],
168
180
  "references": []
169
181
  },
170
- {
171
- "name": "use-focusgroup",
172
- "description": "Nested controls are removed from the tab flow until the user navigates the nested controls with arrow keys.\n\n`use-focusgroup` is most useful for things like WYSIWYG toolbars, sets of tabs, or lists of navigation links (like a list of emails in a master detail layout).\n\n## To do\n\n- [ ] add `grid` navigation feature\n- [ ] add `autofocus` attribute support\n\n## Long term plan\n\nThis web component was built with the intent to be replaced by browser-native focusgroup support once it becomes baseline. Hopefully migration will be as simple as changing the tag name from `use-focusgroup` to `div` and the `options` attribute to `focusgroup`.\n\n<baseline-status featureId=\"focusgroup_attribute\"></baseline-status>\n\n## Sources\n\n- [Open UI focusgroup Explainer](https://open-ui.org/components/focusgroup.explainer/)\n- [tabbable](https://www.npmjs.com/package/tabbable)\n- [Toolbar Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/toolbar/)\n- [@gfellerph/focusgroup-polyfill](https://github.com/gfellerph/focusgroup-polyfill)\n---\n\n\n### **Methods:**\n - **promote()** - Promotes the use-focusgroup to the top of the tab order inside a parent use-focusgroup.",
173
- "attributes": [
174
- {
175
- "name": "features",
176
- "description": "A list of space-separated features that can be used to customize the behavior of the focusgroup.\n\nThe following options are available:\n\n- `inline` opts into keyboard navigation via left and right arrow keys\n- `block` opts into keyboard navigation via up and down arrow keys\n- `wrap` arrow navigation should wrap around when reaching the end\n- `no-memory` whether the focusgroup should not remember the last focused element\n\nIf nothing if neither `inline` nor `block` is specified, both are assumed.",
177
- "values": []
178
- }
179
- ],
180
- "references": []
181
- },
182
182
  {
183
183
  "name": "use-grid",
184
184
  "description": "Accessible grid component following [WAI-ARIA grid pattern](https://www.w3.org/WAI/ARIA/apg/patterns/grid/).\n\n## Grid Cell Modes\nThe `mode` attribute of the `use-gridcell` element determines how the cell behaves in terms of focus and interaction. The possible values are:\n\n- `'none'` - the cell itself is focusable and it does not contain any interactive elements.\n- `'widget'` - the cell itself is focusable and it contains more than one interactive element. To access the interactive elements, the user must press `Enter` or `F2`, and to restore focus to the cell, the user must press `Esc` or `F2`.\n- `'action'` - the cell itself is not focusable and it contains a single interactive element. The user can tab to the interactive elements directly.\n\n## Accessible Label\nProvide `aria-label` or `aria-labelledby` on the `use-grid` element so screen readers can identify the grid.\n---\n\n\n### **Slots:**\n - _default_ - Grid content (use-gridhead/use-gridbody rows)",
@@ -452,12 +452,6 @@
452
452
  ],
453
453
  "references": []
454
454
  },
455
- {
456
- "name": "use-scrollarea",
457
- "description": "A scroll container that exposes custom states for scroll edge detection.\n\n## Custom States\nThe following CSS custom states are available for styling:\n\n- `:state(at-block-start)` — scrolled to the block-start edge (top in horizontal writing modes)\n- `:state(at-block-end)` — scrolled to the block-end edge (bottom in horizontal writing modes)\n- `:state(at-inline-start)` — scrolled to the inline-start edge (left in LTR)\n- `:state(at-inline-end)` — scrolled to the inline-end edge (right in LTR)\n---\n\n\n### **Slots:**\n - _default_ - Scrollable content",
458
- "attributes": [],
459
- "references": []
460
- },
461
455
  {
462
456
  "name": "use-time-input",
463
457
  "description": "Displays time picker using [`Intl.DateTimeFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat).\n\nAllows users to pick time values with proper localization and formatting.\n---\n\n\n### **Events:**\n - **input**",
@@ -487,6 +481,12 @@
487
481
  ],
488
482
  "references": []
489
483
  },
484
+ {
485
+ "name": "use-scrollarea",
486
+ "description": "A scroll container that exposes custom states for scroll edge detection.\n\n## Custom States\nThe following CSS custom states are available for styling:\n\n- `:state(at-block-start)` — scrolled to the block-start edge (top in horizontal writing modes)\n- `:state(at-block-end)` — scrolled to the block-end edge (bottom in horizontal writing modes)\n- `:state(at-inline-start)` — scrolled to the inline-start edge (left in LTR)\n- `:state(at-inline-end)` — scrolled to the inline-end edge (right in LTR)\n---\n\n\n### **Slots:**\n - _default_ - Scrollable content",
487
+ "attributes": [],
488
+ "references": []
489
+ },
490
490
  {
491
491
  "name": "use-tree",
492
492
  "description": "Custom input control for managing selected values in a hierarchy.\n\nA convenience for distributing a custom indicator to every item at once: slot an icon into\n`use-tree` itself under `expanded-indicator`, `collapsed-indicator`, `selected-indicator`, or\n`deselected-indicator`, and it's cloned into each lazily-discovered `use-treeitem`'s matching\nslot. This is per-item slotting, just done once for the whole tree — it doesn't replace\n`use-treeitem`'s own static hooks (`expandedIcon`, `collapsedIcon`, `selectedIcon`,\n`deselectedIcon`), which still apply for indicators the tree hasn't cloned one over.\n---\n\n\n### **Slots:**\n - **default** - NodeList of `use-treeitem` elements\n- **expanded-indicator** - Cloned into every item's `expanded-indicator` slot.\n- **collapsed-indicator** - Cloned into every item's `collapsed-indicator` slot.\n- **selected-indicator** - Cloned into every item's `selected-indicator` slot.\n- **deselected-indicator** - Cloned into every item's `deselected-indicator` slot.",