@godxjp/ui 32.9.0 → 32.10.1

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/DESIGN.md CHANGED
@@ -202,7 +202,7 @@ A list whose rows are decisions. Show requester, target, reason, submitted time;
202
202
 
203
203
  1. Pick the archetype, call `get_exemplar` and build from that screen, not from memory.
204
204
  2. `npx @godxjp/ui audit <files>` — zero errors.
205
- 3. `npx @godxjp/ui visual-audit <url> <routes>` — runs every route at 320, 390, 768, 1024, 1280 and 844×390 (landscape phone) and measures what a screenshot glance misses: clipped or squeezed controls (WCAG 1.4.10 has two halves — no two-way scrolling AND no lost information; page overflow alone checks only the first), compact search, avatar-only identity, editor inset, action count and target size, rail and search keylines, tiny tracked capitals. Zero machine failures at every width; an "unmapped" result is not a pass.
205
+ 3. `npx @godxjp/ui visual-audit <url> <routes>` — runs every route at 320, 390, 768, 1024, 1280 and 844×390 (landscape phone) and measures what a screenshot glance misses: clipped or squeezed controls (WCAG 1.4.10 has two halves — no two-way scrolling AND no lost information; page overflow alone checks only the first), compact search, avatar-only identity, editor inset, action count and target size, rail and search keylines, tiny tracked capitals. Zero machine failures at every width; an "unmapped" result is not a pass. Signed-in routes: `--storage-state state.json` (Playwright storageState).
206
206
  4. Inspect every screenshot at every width, region by region — top bar, page header, body, aside or rail, menus and drawers — against the checklist the report prints. A region you were told not to change is still inspected; a defect there becomes an issue, not a silent pass.
207
207
  5. No top-N and no round cap. Stop only when every width has zero machine failures and every checklist row is pass or a written N/A.
208
208
  6. The builder does not accept its own screen. Report "probes passed; independent acceptance pending" with the report JSON, the screenshots per width and the checklist; acceptance comes from someone who did not build it (a person, or a separate agent given only the build and the artifacts). Never call a screen done on self-review.
@@ -215,4 +215,5 @@ A list whose rows are decisions. Show requester, target, reason, submitted time;
215
215
  - `card-per-section` counts Cards per file, so a screen split across components can pass with a Card around every section.
216
216
  - Exemplar previews deploy on release tags, so they can lag `main`. On GitHub Pages a showcase URL answers HTTP 404 and renders through `404.html`, so open it in a browser; a plain fetch sees the 404.
217
217
  - Dark theme (`data-theme="dark"`) is supported; the exemplars are reviewed in light.
218
+ - From 640px up, `BlockEditor` text does not share the keyline of the `Input` above it: measured at 768/1024/1280, input text 13px inside its frame, editor text 57px inside (Δ44px), because the ⋮⋮/+ handles (two 24px targets) sit in a start gutter inside the frame. Aligning the text would put the handles outside the field border, where a content column 24px from the viewport edge has no room. Below 640px the gutter collapses (C05). Accepted, not a defect to fix in the app.
218
219
  - On narrow screens the `PageContainer` title steps down (≈17.6px) while body h2 stays ≈15.7px — one step apart. A document page not built on `LegalDocumentShell` keeps only that step on phones; there is no intermediate page-title size yet.
package/agent/DESIGN.md CHANGED
@@ -202,7 +202,7 @@ A list whose rows are decisions. Show requester, target, reason, submitted time;
202
202
 
203
203
  1. Pick the archetype, call `get_exemplar` and build from that screen, not from memory.
204
204
  2. `npx @godxjp/ui audit <files>` — zero errors.
205
- 3. `npx @godxjp/ui visual-audit <url> <routes>` — runs every route at 320, 390, 768, 1024, 1280 and 844×390 (landscape phone) and measures what a screenshot glance misses: clipped or squeezed controls (WCAG 1.4.10 has two halves — no two-way scrolling AND no lost information; page overflow alone checks only the first), compact search, avatar-only identity, editor inset, action count and target size, rail and search keylines, tiny tracked capitals. Zero machine failures at every width; an "unmapped" result is not a pass.
205
+ 3. `npx @godxjp/ui visual-audit <url> <routes>` — runs every route at 320, 390, 768, 1024, 1280 and 844×390 (landscape phone) and measures what a screenshot glance misses: clipped or squeezed controls (WCAG 1.4.10 has two halves — no two-way scrolling AND no lost information; page overflow alone checks only the first), compact search, avatar-only identity, editor inset, action count and target size, rail and search keylines, tiny tracked capitals. Zero machine failures at every width; an "unmapped" result is not a pass. Signed-in routes: `--storage-state state.json` (Playwright storageState).
206
206
  4. Inspect every screenshot at every width, region by region — top bar, page header, body, aside or rail, menus and drawers — against the checklist the report prints. A region you were told not to change is still inspected; a defect there becomes an issue, not a silent pass.
207
207
  5. No top-N and no round cap. Stop only when every width has zero machine failures and every checklist row is pass or a written N/A.
208
208
  6. The builder does not accept its own screen. Report "probes passed; independent acceptance pending" with the report JSON, the screenshots per width and the checklist; acceptance comes from someone who did not build it (a person, or a separate agent given only the build and the artifacts). Never call a screen done on self-review.
@@ -215,4 +215,5 @@ A list whose rows are decisions. Show requester, target, reason, submitted time;
215
215
  - `card-per-section` counts Cards per file, so a screen split across components can pass with a Card around every section.
216
216
  - Exemplar previews deploy on release tags, so they can lag `main`. On GitHub Pages a showcase URL answers HTTP 404 and renders through `404.html`, so open it in a browser; a plain fetch sees the 404.
217
217
  - Dark theme (`data-theme="dark"`) is supported; the exemplars are reviewed in light.
218
+ - From 640px up, `BlockEditor` text does not share the keyline of the `Input` above it: measured at 768/1024/1280, input text 13px inside its frame, editor text 57px inside (Δ44px), because the ⋮⋮/+ handles (two 24px targets) sit in a start gutter inside the frame. Aligning the text would put the handles outside the field border, where a content column 24px from the viewport edge has no room. Below 640px the gutter collapses (C05). Accepted, not a defect to fix in the app.
218
219
  - On narrow screens the `PageContainer` title steps down (≈17.6px) while body h2 stays ≈15.7px — one step apart. A document page not built on `LegalDocumentShell` keeps only that step on phones; there is no intermediate page-title size yet.
@@ -3,7 +3,7 @@
3
3
  You are about to write code against a design system you did not author. This file is the whole
4
4
  contract. Read it before you write JSX.
5
5
 
6
- **This catalog describes `@godxjp/ui` 32.9.0.** If the project you are editing has a different
6
+ **This catalog describes `@godxjp/ui` 32.10.1.** If the project you are editing has a different
7
7
  version in its `package.json`, read the pinned catalog for THAT version instead
8
8
  (`…/v<their-version>/agent/…`). A catalog newer than the installed package describes props that do
9
9
  not exist yet; older, and it hides props that do. Neither failure announces itself.
@@ -31,10 +31,10 @@
31
31
  "type": "string"
32
32
  },
33
33
  {
34
- "defaultValue": "\"success\"",
35
- "description": "Bar colour tone. Over-capacity defaults to destructive.",
34
+ "defaultValue": "\"primary\"",
35
+ "description": "Bar colour tone. `primary` (default since gh#1308) is the brand role for ordinary progress — a reading position, an upload; pass a status tone only when the bar reports that status (ADR C09: `success` for a completed/healthy state, `warning`/`destructive` for limits). Over-capacity defaults to destructive.",
36
36
  "name": "tone",
37
- "type": "\"success\" | \"warning\" | \"destructive\""
37
+ "type": "\"primary\" | \"success\" | \"warning\" | \"destructive\""
38
38
  },
39
39
  {
40
40
  "defaultValue": "false",
@@ -209,6 +209,7 @@
209
209
  "tagline": "The standalone WAI-ARIA tree view on a page (antd `Tree` / `DirectoryTree`) — nested `treeData`, a disclosure triangle per branch, roving-tabindex arrow navigation, optional tri-state checkboxes, async `loadData` and `draggable` reorder/reparent (antd `onDrop`). Reach for it whenever nodes expand, collapse or are navigated by keyboard; TreeSelect is the same hierarchy inside a Popover.",
210
210
  "usage": [
211
211
  "DO name the tree — pass `aria-label` (through your own `t()`) or `aria-labelledby`. A tree with no name is an unlabelled landmark for every screen reader user.",
212
+ "DO rely on Tree for a cut label (gh#1308): a label that is actually truncated gets its full text as a `title` and unfolds while its row holds keyboard focus (not in a windowed tree, whose rows share one height — the `title` stays). No `titleRender` wrapper with a hand-set `title` is needed; one you set is kept.",
212
213
  "DO keep SELECTION and CHECKS apart: `value`/`onValueChange` is which node is open in the detail pane; `checkedValues`/`onCheckedValuesChange` is which nodes are ticked. They are two axes, exactly as in antd — never drive one from the other.",
213
214
  "DO keep SELECTION and EXPANSION apart too — this is the THIRD axis and the one gh#910 tripped on. `onValueChange` says which node a detail pane should show; `onExpandedValuesChange` says which branches are unfolded. A sibling pane listens to the first and ignores the second, so unfolding a branch cannot reload it. If your pane reloads when a branch opens, it is being driven from the wrong event — not from a missing feature.",
214
215
  "DO let the keyboard work: the tree ships the full APG contract (Up/Down through visible nodes, Right expands then descends, Left collapses then climbs, Home/End, Enter/Space, `*` to expand the current level, type-ahead). Do not add your own key handling on top.",
@@ -4792,10 +4792,10 @@
4792
4792
  "type": "string"
4793
4793
  },
4794
4794
  {
4795
- "defaultValue": "\"success\"",
4796
- "description": "Bar colour tone. Over-capacity defaults to destructive.",
4795
+ "defaultValue": "\"primary\"",
4796
+ "description": "Bar colour tone. `primary` (default since gh#1308) is the brand role for ordinary progress — a reading position, an upload; pass a status tone only when the bar reports that status (ADR C09: `success` for a completed/healthy state, `warning`/`destructive` for limits). Over-capacity defaults to destructive.",
4797
4797
  "name": "tone",
4798
- "type": "\"success\" | \"warning\" | \"destructive\""
4798
+ "type": "\"primary\" | \"success\" | \"warning\" | \"destructive\""
4799
4799
  },
4800
4800
  {
4801
4801
  "defaultValue": "false",
@@ -11429,6 +11429,7 @@
11429
11429
  "tagline": "The standalone WAI-ARIA tree view on a page (antd `Tree` / `DirectoryTree`) — nested `treeData`, a disclosure triangle per branch, roving-tabindex arrow navigation, optional tri-state checkboxes, async `loadData` and `draggable` reorder/reparent (antd `onDrop`). Reach for it whenever nodes expand, collapse or are navigated by keyboard; TreeSelect is the same hierarchy inside a Popover.",
11430
11430
  "usage": [
11431
11431
  "DO name the tree — pass `aria-label` (through your own `t()`) or `aria-labelledby`. A tree with no name is an unlabelled landmark for every screen reader user.",
11432
+ "DO rely on Tree for a cut label (gh#1308): a label that is actually truncated gets its full text as a `title` and unfolds while its row holds keyboard focus (not in a windowed tree, whose rows share one height — the `title` stays). No `titleRender` wrapper with a hand-set `title` is needed; one you set is kept.",
11432
11433
  "DO keep SELECTION and CHECKS apart: `value`/`onValueChange` is which node is open in the detail pane; `checkedValues`/`onCheckedValuesChange` is which nodes are ticked. They are two axes, exactly as in antd — never drive one from the other.",
11433
11434
  "DO keep SELECTION and EXPANSION apart too — this is the THIRD axis and the one gh#910 tripped on. `onValueChange` says which node a detail pane should show; `onExpandedValuesChange` says which branches are unfolded. A sibling pane listens to the first and ignores the second, so unfolding a branch cannot reload it. If your pane reloads when a branch opens, it is being driven from the wrong event — not from a missing feature.",
11434
11435
  "DO let the keyboard work: the tree ships the full APG contract (Up/Down through visible nodes, Right expands then descends, Left collapses then climbs, Home/End, Enter/Space, `*` to expand the current level, type-ahead). Do not add your own key handling on top.",
package/agent/index.json CHANGED
@@ -54,7 +54,7 @@
54
54
  "note": "Pin to the tag that matches the @godxjp/ui version you installed. A catalog newer than your package describes props you do not have; older, and it hides props you do.",
55
55
  "read": {
56
56
  "live": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/index.json",
57
- "pinned": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/v32.9.0/agent/index.json"
57
+ "pinned": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/v32.10.1/agent/index.json"
58
58
  },
59
59
  "source": "mcp/src/data — the same data @godxjp/ui-mcp serves — plus the foundation and semantic token tiers, read from src/tokens/*.css",
60
60
  "start": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/START-HERE.md",
@@ -68,5 +68,5 @@
68
68
  "foundation": "the seeds a consumer is invited to set — --primary, --background, --radius",
69
69
  "semantic": "named roles that follow the seeds — --ring, --text-link, --overlay-background"
70
70
  },
71
- "version": "32.9.0"
71
+ "version": "32.10.1"
72
72
  }
package/agent/llms.txt CHANGED
@@ -1,10 +1,10 @@
1
1
  # @godxjp/ui
2
2
 
3
3
  > A Japanese-enterprise React design system: 162 components, 2203 design tokens,
4
- > 43 cardinal rules. This file is the entry point for AI agents. Catalog version 32.9.0.
4
+ > 43 cardinal rules. This file is the entry point for AI agents. Catalog version 32.10.1.
5
5
 
6
6
  If your client can run a process, do not read these files — run the MCP server instead
7
- (`npx @godxjp/ui-mcp@32.9.0`). It is searchable and version-locked. These files exist for agents
7
+ (`npx @godxjp/ui-mcp@32.10.1`). It is searchable and version-locked. These files exist for agents
8
8
  that can only fetch URLs.
9
9
 
10
10
  ## Start
@@ -27,7 +27,7 @@ that can only fetch URLs.
27
27
  ## Pinning
28
28
 
29
29
  Every URL above tracks `main`. To pin to the release a project actually installed, swap `main` for
30
- the tag: `.../godx-jp/godxjp-ui/v32.9.0/agent/...`. A catalog that does not match the installed
30
+ the tag: `.../godx-jp/godxjp-ui/v32.10.1/agent/...`. A catalog that does not match the installed
31
31
  package describes props that are absent, or hides props that are present, and says nothing either way.
32
32
 
33
33
  Pinned catalogs only exist for releases whose tag actually contains `agent/`. If `…/v<version>/agent/index.json` returns 404, that release predates this catalog: read `…/main/…` instead and compare `index.json` → `version` against the package you have, so you at least know which way it drifted.
package/agent/tokens.json CHANGED
@@ -5652,7 +5652,7 @@
5652
5652
  "value": "initial"
5653
5653
  },
5654
5654
  {
5655
- "description": "Progress track + fill — `initial` so the role defaults re-resolve under a scoped theme. Track reads --secondary, fill reads --success; a service re-tones once. Defaults = hsl(var(--secondary)) track · hsl(var(--success)) fill.",
5655
+ "description": "Progress track + fill — `initial` so the role defaults re-resolve under a scoped theme. Track reads --secondary, the default (`primary`) fill reads the brand mark; a service re-tones once. Defaults = hsl(var(--secondary)) track · hsl(var(--mark-primary, var(--primary))) fill (gh#1308 — it was the success mark; status tones are opt-in and do not read this knob).",
5656
5656
  "name": "--progress-track-background",
5657
5657
  "tier": "component",
5658
5658
  "value": "initial"
@@ -1,12 +1,18 @@
1
1
  import * as React from "react";
2
- export type ProgressTone = "success" | "warning" | "destructive";
3
2
  /**
4
- * A breakdown SLICE takes two more tones than the meter (gh#1302): `info` and `neutral`, the same
5
- * pair `Legend` already keys — a partition with four states (done · done-awaiting · in progress ·
6
- * not started) needs four distinguishable fills, and the meter's three made two of them identical.
7
- * Each paints exactly what the matching Legend swatch paints, so a key and its bar stay one.
3
+ * The METER's tone. `primary` (the default, gh#1308) is the brand role for ordinary progress — a
4
+ * reading position, an upload; the status tones are opt-in for a bar that reports that status
5
+ * (ADR C09). `primary` is the name `Badge` already gives its brand tone.
8
6
  */
9
- export type ProgressSegmentTone = ProgressTone | "info" | "neutral";
7
+ export type ProgressTone = "primary" | "success" | "warning" | "destructive";
8
+ /**
9
+ * A breakdown SLICE takes two more status tones than the meter (gh#1302): `info` and `neutral`, the
10
+ * same pair `Legend` already keys — a partition with four states (done · done-awaiting · in
11
+ * progress · not started) needs four distinguishable fills, and the meter's three made two of them
12
+ * identical. Each paints exactly what the matching Legend swatch paints, so a key and its bar stay
13
+ * one. No `primary`: a partition is states, and Legend keys no brand swatch.
14
+ */
15
+ export type ProgressSegmentTone = Exclude<ProgressTone, "primary"> | "info" | "neutral";
10
16
  /**
11
17
  * One slice of a BREAKDOWN bar — how much of the total this state holds, in the SAME unit as every
12
18
  * other slice (counts, bytes, yen). Never a percentage: the bar owns the ratio arithmetic, so the
@@ -73,7 +73,7 @@ function Progress(props) {
73
73
  const meterValue = value ?? 0;
74
74
  const isOver = over && meterValue > 100;
75
75
  const boundedValue = Math.max(0, Math.min(100, meterValue));
76
- const effectiveTone = tone ?? (isOver ? "destructive" : "success");
76
+ const effectiveTone = tone ?? (isOver ? "destructive" : "primary");
77
77
  return /* @__PURE__ */ jsx(
78
78
  "div",
79
79
  {
@@ -5,6 +5,7 @@ import { mergeRefs } from "@react-aria/utils";
5
5
  import { ChevronDown, ChevronRight, File as FileIcon, Folder, FolderOpen } from "lucide-react";
6
6
  import { useTranslation } from "../../i18n/use-translation.js";
7
7
  import { cn } from "../../lib/utils.js";
8
+ import { truncatedPart } from "../../lib/truncation.js";
8
9
  import { CheckboxVisual } from "../data-entry/checkbox.js";
9
10
  import { Skeleton } from "../feedback/skeleton.js";
10
11
  import {
@@ -273,6 +274,44 @@ function TreeRoot({
273
274
  const measured = firstRow?.offsetHeight ?? 0;
274
275
  if (measured > 0 && measured !== rowHeight) setRowHeight(measured);
275
276
  }, [isWindowed, rowHeight, size, visible.length]);
277
+ const markTruncatedLabels = React.useCallback(() => {
278
+ const tree = treeRef.current;
279
+ if (!tree) return;
280
+ for (const label of tree.querySelectorAll(".ui-tree-label")) {
281
+ if (label.dataset.truncated !== void 0 && label.parentElement === document.activeElement)
282
+ continue;
283
+ const ownTitle = label.dataset.truncatedTitle !== void 0;
284
+ const part = truncatedPart(label);
285
+ if (part) {
286
+ label.dataset.truncated = "";
287
+ if (!label.title || ownTitle) {
288
+ label.title = (label.textContent ?? "").replace(/\s+/g, " ").trim();
289
+ label.dataset.truncatedTitle = "";
290
+ }
291
+ } else if (label.dataset.truncated !== void 0) {
292
+ delete label.dataset.truncated;
293
+ if (ownTitle) {
294
+ label.removeAttribute("title");
295
+ delete label.dataset.truncatedTitle;
296
+ }
297
+ }
298
+ }
299
+ }, []);
300
+ React.useEffect(() => {
301
+ markTruncatedLabels();
302
+ });
303
+ React.useEffect(() => {
304
+ const tree = treeRef.current;
305
+ if (!tree || typeof ResizeObserver === "undefined") return;
306
+ const observer = new ResizeObserver(markTruncatedLabels);
307
+ observer.observe(tree);
308
+ const refold = () => requestAnimationFrame(markTruncatedLabels);
309
+ tree.addEventListener("focusout", refold);
310
+ return () => {
311
+ observer.disconnect();
312
+ tree.removeEventListener("focusout", refold);
313
+ };
314
+ }, [markTruncatedLabels]);
276
315
  const nodeRefs = React.useRef(/* @__PURE__ */ new Map());
277
316
  const pendingFocus = React.useRef(null);
278
317
  React.useEffect(() => {
@@ -26,8 +26,8 @@ function Breadcrumb({
26
26
  className: "ui-breadcrumb-item",
27
27
  "data-ellipsis": item.ellipsis ? "" : void 0,
28
28
  children: [
29
- renderBreadcrumbSegment({ item, index, isLast, items, itemRender, LinkComponent }),
30
- !isLast ? /* @__PURE__ */ jsx("span", { className: "ui-breadcrumb-separator", "aria-hidden": "true", children: separatorNode }) : null
29
+ index > 0 ? /* @__PURE__ */ jsx("span", { className: "ui-breadcrumb-separator", "aria-hidden": "true", children: separatorNode }) : null,
30
+ renderBreadcrumbSegment({ item, index, isLast, items, itemRender, LinkComponent })
31
31
  ]
32
32
  },
33
33
  item.to ?? index
@@ -123,6 +123,7 @@ function PageContainerRoot({
123
123
  className: "ui-breadcrumb-item",
124
124
  "data-ellipsis": item.ellipsis ? "" : void 0,
125
125
  children: [
126
+ i > 0 ? /* @__PURE__ */ jsx("span", { className: "ui-breadcrumb-separator", "aria-hidden": "true", children: /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true" }) }) : null,
126
127
  item.to && !isLast ? /* @__PURE__ */ jsx(BreadcrumbCrumbText, { item, children: /* @__PURE__ */ jsx(
127
128
  LinkComponent,
128
129
  {
@@ -138,8 +139,7 @@ function PageContainerRoot({
138
139
  "aria-current": isLast ? "page" : void 0,
139
140
  children: item.label
140
141
  }
141
- ) }),
142
- !isLast && /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true" })
142
+ ) })
143
143
  ]
144
144
  },
145
145
  i
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$comment": "AUTO-GENERATED by scripts/gen-measurement-contract.mjs — do not edit. Read this instead of guessing: docs/MEASUREMENT-CONTRACT.md.",
3
- "version": "32.9.0",
3
+ "version": "32.10.1",
4
4
  "targetSize": {
5
5
  "standard": "WCAG 2.2 SC 2.5.8 Target Size (Minimum), level AA — 24×24 CSS px",
6
6
  "min": 24,
@@ -189,7 +189,11 @@
189
189
  .ui-progress-bar {
190
190
  height: 100%;
191
191
  border-radius: inherit;
192
- background: var(--progress-fill-background, hsl(var(--mark-success, var(--text-success))));
192
+ background: var(--progress-fill-background, hsl(var(--mark-primary, var(--primary))));
193
+ }
194
+
195
+ .ui-progress[data-tone="success"] .ui-progress-bar {
196
+ background: hsl(var(--mark-success, var(--text-success)));
193
197
  }
194
198
 
195
199
  .ui-progress[data-tone="warning"] .ui-progress-bar {
@@ -291,11 +295,15 @@
291
295
  }
292
296
 
293
297
  .ui-progress-ring-indicator {
294
- stroke: var(--progress-fill-background, hsl(var(--mark-success, var(--text-success))));
298
+ stroke: var(--progress-fill-background, hsl(var(--mark-primary, var(--primary))));
295
299
 
296
300
  stroke-linecap: butt;
297
301
  }
298
302
 
303
+ .ui-progress[data-tone="success"] .ui-progress-ring-indicator {
304
+ stroke: hsl(var(--mark-success, var(--text-success)));
305
+ }
306
+
299
307
  .ui-progress[data-tone="warning"] .ui-progress-ring-indicator {
300
308
  stroke: hsl(var(--mark-warning, var(--text-warning)));
301
309
  }
@@ -2943,6 +2951,14 @@
2943
2951
  white-space: nowrap;
2944
2952
  }
2945
2953
 
2954
+ .ui-tree:not([data-virtual])
2955
+ .ui-tree-node:focus-visible
2956
+ > .ui-tree-label[data-truncated]:not(:has([data-ellipsis])) {
2957
+ overflow: visible;
2958
+ white-space: normal;
2959
+ overflow-wrap: anywhere;
2960
+ }
2961
+
2946
2962
  .ui-tree-group {
2947
2963
  display: flex;
2948
2964
  flex-direction: column;
@@ -458,6 +458,8 @@
458
458
 
459
459
  background-color: var(--sheet-surface-background, hsl(var(--background)));
460
460
  box-shadow: var(--sheet-shadow, var(--shadow-lg));
461
+
462
+ outline: none;
461
463
  }
462
464
 
463
465
  .ui-sheet-panel[data-side="top"] {
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "32.9.0",
2
+ "version": "32.10.1",
3
3
  "generatedBy": "scripts/gen-style-layers.mjs — do not edit by hand; run `pnpm gen:style-layers`",
4
4
  "base": "base.css",
5
5
  "fonts": "fonts.css",
@@ -802,6 +802,9 @@
802
802
  display: inline-flex;
803
803
  flex: 0 0 auto;
804
804
  align-items: center;
805
+
806
+ align-self: flex-start;
807
+ block-size: 1lh;
805
808
  }
806
809
 
807
810
  .ui-breadcrumb-menu-trigger {