@godxjp/ui 20.2.1 → 22.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.
- package/dist/app/app-provider.js +2 -1
- package/dist/components/data-display/badge.d.ts +28 -1
- package/dist/components/data-display/badge.js +2 -0
- package/dist/components/data-display/chat-bubble.d.ts +30 -0
- package/dist/components/data-display/chat-bubble.js +229 -0
- package/dist/components/data-display/data-table.d.ts +18 -2
- package/dist/components/data-display/data-table.js +4 -0
- package/dist/components/data-display/descriptions.js +4 -1
- package/dist/components/data-display/index.d.ts +5 -3
- package/dist/components/data-display/index.js +5 -2
- package/dist/components/data-display/popover.d.ts +19 -1
- package/dist/components/data-display/popover.js +12 -3
- package/dist/components/data-display/progress.d.ts +37 -0
- package/dist/components/data-display/progress.js +57 -5
- package/dist/components/data-display/scroll-area.js +26 -1
- package/dist/components/data-display/tree.d.ts +8 -0
- package/dist/components/data-display/tree.js +426 -0
- package/dist/components/data-entry/chat-composer.d.ts +50 -0
- package/dist/components/data-entry/chat-composer.js +163 -0
- package/dist/components/data-entry/chat-suggestion.d.ts +28 -0
- package/dist/components/data-entry/chat-suggestion.js +285 -0
- package/dist/components/data-entry/date-picker.d.ts +10 -3
- package/dist/components/data-entry/date-picker.js +503 -238
- package/dist/components/data-entry/form-field.d.ts +1 -1
- package/dist/components/data-entry/form-field.js +4 -1
- package/dist/components/data-entry/form.js +10 -1
- package/dist/components/data-entry/index.d.ts +4 -6
- package/dist/components/data-entry/index.js +4 -6
- package/dist/components/data-entry/label.d.ts +14 -1
- package/dist/components/data-entry/label.js +6 -1
- package/dist/components/data-entry/radio.d.ts +27 -6
- package/dist/components/data-entry/radio.js +88 -43
- package/dist/components/data-entry/search-select.js +8 -1
- package/dist/components/data-entry/select.js +2 -0
- package/dist/components/data-entry/switch.d.ts +6 -3
- package/dist/components/data-entry/switch.js +34 -11
- package/dist/components/data-entry/textarea.js +3 -1
- package/dist/components/data-entry/tree-utils.d.ts +10 -48
- package/dist/components/data-entry/tree-utils.js +1 -154
- package/dist/components/layout/mobile-shell.d.ts +1 -1
- package/dist/components/layout/mobile-shell.js +2 -0
- package/dist/components/navigation/menubar.d.ts +10 -3
- package/dist/components/navigation/steps.d.ts +1 -1
- package/dist/components/navigation/steps.js +3 -1
- package/dist/components/navigation/tabs-scroll.d.ts +27 -0
- package/dist/components/navigation/tabs-scroll.js +52 -1
- package/dist/components/navigation/tabs.d.ts +2 -2
- package/dist/components/navigation/tabs.js +88 -23
- package/dist/components/ui/index.d.ts +0 -1
- package/dist/components/ui/index.js +0 -1
- package/dist/components/ui/segmented.d.ts +15 -1
- package/dist/components/ui/segmented.js +13 -6
- package/dist/i18n/messages/en.json +48 -2
- package/dist/i18n/messages/ja.json +46 -2
- package/dist/i18n/messages/vi.json +47 -2
- package/dist/lib/datetime/picker-format.d.ts +18 -0
- package/dist/lib/datetime/picker-format.js +35 -1
- package/dist/lib/field-a11y.d.ts +12 -0
- package/dist/lib/field-a11y.js +14 -1
- package/dist/lib/tree.d.ts +53 -0
- package/dist/lib/tree.js +155 -0
- package/dist/props/components/data-display.prop.d.ts +194 -1
- package/dist/props/components/data-entry.prop.d.ts +307 -99
- package/dist/props/components/index.d.ts +1 -1
- package/dist/props/components/layout.prop.d.ts +12 -1
- package/dist/props/components/navigation.prop.d.ts +76 -1
- package/dist/props/registry.d.ts +156 -19
- package/dist/props/registry.js +218 -18
- package/dist/props/vocabulary/data.prop.d.ts +12 -0
- package/dist/props/vocabulary/index.d.ts +2 -2
- package/dist/props/vocabulary/layout.prop.d.ts +11 -0
- package/dist/styles/badge-layout.css +4 -0
- package/dist/styles/card-layout.css +6 -6
- package/dist/styles/control.css +22 -6
- package/dist/styles/data-display-layout.css +385 -68
- package/dist/styles/data-entry-layout.css +64 -0
- package/dist/styles/focus-ring.css +4 -2
- package/dist/styles/navigation-layout.css +25 -0
- package/dist/styles/shell-layout.css +7 -1
- package/dist/styles/table-layout.css +34 -0
- package/dist/tokens/base.css +3 -0
- package/dist/tokens/components/chat-bubble.css +36 -0
- package/dist/tokens/components/chat-composer.css +19 -0
- package/dist/tokens/components/data-display.css +9 -6
- package/dist/tokens/components/descriptions.css +4 -0
- package/dist/tokens/components/navigation.css +6 -0
- package/dist/tokens/components/segmented.css +0 -2
- package/dist/tokens/components/shell.css +3 -0
- package/dist/tokens/components/table.css +3 -0
- package/dist/tokens/components/tree.css +27 -0
- package/dist/tokens/foundation.css +7 -0
- package/docs/COMPONENTS.md +14 -14
- package/docs/CONSUMER-RULES.md +24 -1
- package/docs/FRAME-COVERAGE-LEDGER.md +1 -1
- package/docs/FRAME-COVERAGE-REPORT.md +9 -7
- package/docs/TOKENS.md +65 -0
- package/docs/data-display/badge.tsx +37 -0
- package/docs/data-display/chat-bubble.tsx +397 -0
- package/docs/data-display/data-table/index.tsx +18 -0
- package/docs/data-display/popover.tsx +41 -1
- package/docs/data-display/progress.tsx +28 -0
- package/docs/data-display/timeline.tsx +46 -0
- package/docs/data-display/tree.tsx +394 -0
- package/docs/data-entry/calendar.tsx +2 -2
- package/docs/data-entry/chat-composer.tsx +464 -0
- package/docs/data-entry/chat-suggestion.tsx +301 -0
- package/docs/data-entry/date-picker.tsx +143 -3
- package/docs/data-entry/form/examples/invoice-form.tsx +2 -2
- package/docs/data-entry/form-field/examples/a11y-contract.tsx +3 -5
- package/docs/data-entry/form.tsx +4 -4
- package/docs/data-entry/number-input.tsx +31 -0
- package/docs/data-entry/segmented.tsx +103 -1
- package/docs/layout/mobile-shell.tsx +5 -0
- package/docs/navigation/tabs.tsx +149 -0
- package/docs/roadmap/ai-chat-components.md +207 -0
- package/docs/roadmap/antd-parity.md +155 -0
- package/docs/roadmap/badge-tag-chip-count.md +172 -0
- package/docs/roadmap/list-masonry.md +159 -0
- package/docs/roadmap/parity-audit-data-display-feedback.md +567 -0
- package/docs/roadmap/parity-audit-data-entry.md +357 -0
- package/docs/roadmap/parity-audit-layout-navigation-general.md +464 -0
- package/docs/roadmap/parity-backlog.md +78 -0
- package/docs/roadmap/tree-components.md +151 -0
- package/docs/showcase/acme-portal.tsx +7 -0
- package/docs/showcase/table-tree-rows.tsx +4 -4
- package/package.json +13 -23
- package/scripts/ui-audit.mjs +17 -4
- package/dist/components/data-display/tree-list.d.ts +0 -13
- package/dist/components/data-display/tree-list.js +0 -26
- package/dist/components/data-entry/date-range-picker.d.ts +0 -11
- package/dist/components/data-entry/date-range-picker.js +0 -349
- package/dist/components/data-entry/month-picker.d.ts +0 -10
- package/dist/components/data-entry/month-picker.js +0 -241
- package/dist/components/data-entry/month-range-picker.d.ts +0 -10
- package/dist/components/data-entry/month-range-picker.js +0 -301
- package/dist/components/ui/date-range-picker.d.ts +0 -1
- package/dist/components/ui/date-range-picker.js +0 -2
- package/docs/data-display/tree-list.tsx +0 -107
- package/docs/data-entry/date-range-picker.tsx +0 -175
- package/docs/data-entry/month-picker.tsx +0 -101
- package/docs/data-entry/month-range-picker.tsx +0 -115
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Tree components — audit + normalized spec
|
|
2
|
+
|
|
3
|
+
> **Status:** audit complete 2026-09-10. `Tree` is NOT implemented. Read this before touching
|
|
4
|
+
> anything under `src/components/**/tree-*`.
|
|
5
|
+
> **Contract:** `.claude/skills/godxjp-ui-component/SKILL.md` is the hard gate. This document only
|
|
6
|
+
> normalizes *what* to build; the skill owns *how*.
|
|
7
|
+
|
|
8
|
+
## 1. What exists today (measured, not eyeballed)
|
|
9
|
+
|
|
10
|
+
| Thing | File | What it actually is |
|
|
11
|
+
| --- | --- | --- |
|
|
12
|
+
| `TreeSelect` | `src/components/data-entry/tree-select.tsx` (499 L) | A real tree, but only **inside a dropdown**. Ant-aligned API. |
|
|
13
|
+
| `TreeList` | `src/components/data-display/tree-list.tsx` (41 L) | **Not a tree.** A flat `<ul>` where `depth` is a number that only drives `margin-inline-start`. |
|
|
14
|
+
| `tree-utils` | `src/components/data-entry/tree-utils.ts` (216 L) | Normalize / flatten / filter / descendants. Sound, reusable. Currently private to `data-entry`. |
|
|
15
|
+
| `Tree` | — | **Does not exist.** |
|
|
16
|
+
|
|
17
|
+
### 1a. `TreeSelect` is fine — leave it alone
|
|
18
|
+
|
|
19
|
+
It is genuinely modeled on Ant Design: `treeData`, `fieldNames`, `treeCheckable`, `treeCheckStrictly`,
|
|
20
|
+
`showCheckedStrategy` (`SHOW_PARENT` / `SHOW_CHILD` / `SHOW_ALL`), `loadData`, `treeTitleRender`,
|
|
21
|
+
`maxTagCount`, `notFoundContent`. Markup carries `role="tree"` / `role="treeitem"` with
|
|
22
|
+
`aria-expanded` / `aria-selected` / `aria-multiselectable`. It is not the problem.
|
|
23
|
+
|
|
24
|
+
### 1b. `TreeList` is the problem — it promises a tree and delivers indentation
|
|
25
|
+
|
|
26
|
+
Verified against the source, the CSS (`src/styles/data-display-layout.css:282-334`) and its tests:
|
|
27
|
+
|
|
28
|
+
| Gap | Evidence |
|
|
29
|
+
| --- | --- |
|
|
30
|
+
| No nested data model | `items: TreeListItem[]` only — the caller must pre-flatten; there is no `children`. |
|
|
31
|
+
| No expand / collapse | No disclosure control anywhere in the component. NameThatUI calls this the **disclosure triangle**; an indented tree that expands is an **Outline View**. `TreeList` has neither. |
|
|
32
|
+
| No ARIA tree semantics | Only `aria-current`. No `role="tree"` / `role="treeitem"` / `aria-expanded` / `aria-level` / `aria-setsize` / `aria-posinset` / `aria-selected`. **Violates the mandatory WAI-ARIA APG gate.** |
|
|
33
|
+
| No keyboard | No arrows, Home/End, `*`, type-ahead. Rows are not focusable at all. |
|
|
34
|
+
| No selection contract | No `value` / `defaultValue` / `onValueChange`. **Violates the controlled-vocabulary rule (§2d).** |
|
|
35
|
+
| No `size`, no `ref`, no `className`/`...props` | Props are literally `{ items }`. **Violates §2d.** |
|
|
36
|
+
| Depth is uncapped but unstyled past 2 | Its own docs page says "Indentation is defined for depth 0-2, so flatten deeper branches". `tree-list-depth.test.tsx` asserts depth `5` sets the CSS var — which then renders at an indent nobody designed. |
|
|
37
|
+
| Missing every Ant affordance | no icons, no `showLine`, no drag & drop, no virtual scroll, no async `loadData`, no search/filter highlight, no `blockNode`, no DirectoryTree. |
|
|
38
|
+
|
|
39
|
+
**Conclusion:** the "tree components don't look like Ant Design" complaint is correct, and it is
|
|
40
|
+
localized: `TreeSelect` is fine, `TreeList` is a cosmetic indented list, and the standalone `Tree`
|
|
41
|
+
that every Ant-shaped app reaches for was never built.
|
|
42
|
+
|
|
43
|
+
## 2. GATE 0 ledger — `Tree` (required before any `src/components/**` addition)
|
|
44
|
+
|
|
45
|
+
| # | Criterion | Verdict | Why |
|
|
46
|
+
| --- | --- | --- | --- |
|
|
47
|
+
| C1 | Universal, not design-specific | **PASS** | File explorers, org charts, category pickers, permission trees, nav outlines. |
|
|
48
|
+
| C2 | Encapsulates reusable behavior | **PASS** | Roving tabindex, arrow/Home/End/`*` navigation, type-ahead, expand state, tri-state check propagation, async load. |
|
|
49
|
+
| C3 | Not composable from existing primitives | **PASS** | `Accordion` is single-level disclosure; `Timeline`/`NavList`/`ListRow` are flat. No primitive owns tree keyboard navigation on a page. |
|
|
50
|
+
| C4 | Single responsibility + controlled-vocabulary API | **PASS** | One job (render + navigate a hierarchy); maps cleanly onto the triads in §3. |
|
|
51
|
+
| C5 | Fully token-themeable | **PASS** | Indent, rail, glyph, row height all become `--tree-*` component tokens. |
|
|
52
|
+
| C6 | Earns the international contract | **PASS** | Needs correct APG semantics and RTL indentation; used everywhere. |
|
|
53
|
+
| C7 | Earns its bundle cost | **PASS** | Broad; also lets `TreeSelect` and `Tree` share one node renderer. |
|
|
54
|
+
|
|
55
|
+
**ALL PASS → `Tree` is a framework component.**
|
|
56
|
+
|
|
57
|
+
## 3. Normalized API — Ant Design name → godx controlled vocabulary
|
|
58
|
+
|
|
59
|
+
`Tree` mirrors Ant Design's *capabilities*, never its *prop names* where they conflict with
|
|
60
|
+
`docs/PROPS-VOCABULARY.md`. This mapping is the contract; do not invent a third spelling.
|
|
61
|
+
|
|
62
|
+
| Capability | Ant Design | **godx `Tree`** |
|
|
63
|
+
| --- | --- | --- |
|
|
64
|
+
| Data | `treeData` | `treeData: TreeOptionProp[]` (reuse the existing `TreeOptionProp` + `TreeFieldNamesProp`) |
|
|
65
|
+
| Field remap | `fieldNames` | `fieldNames` (unchanged — already in the registry) |
|
|
66
|
+
| Selection | `selectedKeys` / `defaultSelectedKeys` / `onSelect` | `value` / `defaultValue` / `onValueChange` |
|
|
67
|
+
| Multi-select | `multiple` | `multiple` |
|
|
68
|
+
| Checkboxes | `checkedKeys` / `onCheck` | `checkedValues` / `defaultCheckedValues` / `onCheckedValuesChange` |
|
|
69
|
+
| Checkbox mode | `checkable` | `checkable` |
|
|
70
|
+
| Independent checks | `checkStrictly` | `checkStrictly` |
|
|
71
|
+
| Expansion | `expandedKeys` / `onExpand` | `expandedValues` / `defaultExpandedValues` / `onExpandedValuesChange` |
|
|
72
|
+
| Expand all | `defaultExpandAll` | `defaultExpandAll` |
|
|
73
|
+
| Async children | `loadData` | `loadData` (same signature as `TreeSelect`'s) |
|
|
74
|
+
| Node label render | `titleRender` | `titleRender` |
|
|
75
|
+
| Connector lines | `showLine` | `showLine` |
|
|
76
|
+
| Node icons | `showIcon` / `icon` | `showIcon`, per-node `icon` |
|
|
77
|
+
| Full-width row | `blockNode` | *dropped* — always full-width row; that is the only correct hit area under WCAG 2.5.8 |
|
|
78
|
+
| Disclosure glyph | `switcherIcon` | *dropped* — the glyph is a token (`--tree-switcher-*`), not a prop |
|
|
79
|
+
| Density | — | `size: xs \| sm \| lg` (`md` is the default, never `"default"`) |
|
|
80
|
+
| Directory variant | `<DirectoryTree>` | `variant="directory"` |
|
|
81
|
+
| Drag & drop | `draggable` | **out of scope for v1** — file a follow-up issue |
|
|
82
|
+
| Virtual scroll | `virtual` / `height` | **out of scope for v1** — cap with `ScrollArea`; file a follow-up issue |
|
|
83
|
+
|
|
84
|
+
Plus the house rules: forward `ref`, spread `...props`, accept `className` + `id`, export
|
|
85
|
+
`TreeProp` and `TreeProp as TreeProps` from `src/props/components/data-display.prop.ts`, and
|
|
86
|
+
**register it in `src/props/registry.ts`**.
|
|
87
|
+
|
|
88
|
+
## 4. Required semantics (WAI-ARIA APG "Tree View")
|
|
89
|
+
|
|
90
|
+
- Container `role="tree"`, `aria-multiselectable` when `multiple` or `checkable`.
|
|
91
|
+
- Each node `role="treeitem"` with `aria-level` (1-based), `aria-setsize`, `aria-posinset`,
|
|
92
|
+
`aria-selected`, and `aria-expanded` **only on nodes that have children**.
|
|
93
|
+
- Grouping wrapper `role="group"`.
|
|
94
|
+
- **Roving tabindex** — exactly one node has `tabIndex={0}`; all others `-1`.
|
|
95
|
+
- Keyboard: `↓`/`↑` next/previous *visible* node · `→` expand, then move to first child ·
|
|
96
|
+
`←` collapse, then move to parent · `Home`/`End` first/last visible · `Enter`/`Space` select
|
|
97
|
+
(or toggle the checkbox when `checkable`) · `*` expand all siblings at the current level ·
|
|
98
|
+
type-ahead jumps to the next node whose label starts with the typed characters.
|
|
99
|
+
- Under `dir="rtl"`, `→`/`←` swap meaning and indentation flips — logical CSS only
|
|
100
|
+
(`margin-inline-start`, `padding-inline-start`), never `ml-`/`pl-`/`left-`.
|
|
101
|
+
- Tri-state parent checkbox: checked / unchecked / **indeterminate** when only some descendants
|
|
102
|
+
are checked (skip propagation entirely when `checkStrictly`).
|
|
103
|
+
- Ships `tree.a11y.test.tsx` with `expectNoA11yViolations` — 0 violations.
|
|
104
|
+
|
|
105
|
+
## 5. Tokens (tier: `src/tokens/components/tree.css`, `@import`ed from `src/tokens/base.css`)
|
|
106
|
+
|
|
107
|
+
Names must pass `pnpm check:token-tiers` (`--{component}-{part}-{property}`):
|
|
108
|
+
`--tree-node-height` (from the `--control-height` tier — never a literal), `--tree-indent-width`,
|
|
109
|
+
`--tree-switcher-size`, `--tree-switcher-color`, `--tree-line-color`, `--tree-node-selected-background`,
|
|
110
|
+
`--tree-node-hover-background`, `--tree-icon-size`. Row hit area ≥ 24×24px (WCAG 2.5.8).
|
|
111
|
+
|
|
112
|
+
## 6. i18n keys (`src/i18n/messages/{en,vi,ja}.json`)
|
|
113
|
+
|
|
114
|
+
`tree.expand`, `tree.collapse`, `tree.loading`, `tree.empty`, `tree.selected` (sr-only status —
|
|
115
|
+
selection must never be colour-only, WCAG 1.4.1). Every `aria-label` goes through `t()`.
|
|
116
|
+
|
|
117
|
+
## 7. `TreeList` — what happened to it
|
|
118
|
+
|
|
119
|
+
**Superseded here, then REMOVED in 21.0.0.** The plan above ("stays exported, it has consumers")
|
|
120
|
+
was written while it still had them. It stopped: the last two call sites in `godx-task`
|
|
121
|
+
(`pages/tests/show.tsx`, `pages/documents/index.tsx`) moved to `Tree`, and a sweep of all four
|
|
122
|
+
consumer repos (godx-task, godx-chat, ql, platform) found none left. A superseded export that
|
|
123
|
+
nobody calls is not a compatibility surface, it is a second answer to a question that already has
|
|
124
|
+
one — and the catalog blurb it shipped with promised a "chevron + package icon" the component
|
|
125
|
+
never rendered.
|
|
126
|
+
|
|
127
|
+
So it is gone, with no deprecated shim: component, types, barrel entries, tests, frame, catalog
|
|
128
|
+
entry, `--tree-item-*` tokens and `.ui-tree-item` CSS. `Tree` is the replacement, and the Tree
|
|
129
|
+
catalog entry carries the migration (`id`->`value`, `title`->`label`, `depth`->nesting).
|
|
130
|
+
`check-mcp-pattern-imports.mjs` now denylists an import of, or JSX for, the removed export, the
|
|
131
|
+
same way it denylists `Stack`/`Inline`.
|
|
132
|
+
|
|
133
|
+
## 8. Shared code
|
|
134
|
+
|
|
135
|
+
Move `src/components/data-entry/tree-utils.ts` to a location both groups can import
|
|
136
|
+
(`src/lib/tree.ts`), re-export from the old path so `TreeSelect` keeps working, and have `Tree`
|
|
137
|
+
consume the same `normalizeTreeOptions` / `flattenVisibleTree` / `getDescendantValues`.
|
|
138
|
+
**One tree model, two surfaces** — do not fork the traversal logic.
|
|
139
|
+
|
|
140
|
+
## 9. Definition of done
|
|
141
|
+
|
|
142
|
+
Cheap gates, then this component's tests only:
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
pnpm typecheck && pnpm lint && pnpm run audit \
|
|
146
|
+
&& pnpm check:prop-vocabulary && pnpm check:mcp-sync && pnpm check:mcp-orphans \
|
|
147
|
+
&& pnpm check:token-tiers && pnpm check:control-sizing && pnpm check:example-imports
|
|
148
|
+
pnpm vitest run src/components/data-display/__tests__ --maxWorkers=2
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
`pnpm test` / bare `pnpm vitest run` are **forbidden** — the full suite is CI's job.
|
|
@@ -112,6 +112,13 @@ const THEME = `
|
|
|
112
112
|
--warning: 41 73% 53%; --warning-foreground: 217 61% 12%; /* = brand gold */
|
|
113
113
|
--destructive: 12 83% 44%; --destructive-foreground: 0 0% 100%;
|
|
114
114
|
--info: 217 69% 47%; --info-foreground: 0 0% 100%;
|
|
115
|
+
/* A TRACK IS A QUIET SURFACE, AND THIS THEME REPOINTED --secondary AT AN ACTION COLOUR.
|
|
116
|
+
Progress reads --progress-track-background, which defaults to hsl(var(--secondary)) — a pale
|
|
117
|
+
neutral in the stock palette. Here --secondary is the navy BUTTON, so the bar's track came out
|
|
118
|
+
near-black and the fill (a MARK: nothing is written on it, so SC 1.4.11 asks 3:1 against the
|
|
119
|
+
track) measured 2.50:1 success / 2.90:1 warning on it. Naming the track is the fix; the fills
|
|
120
|
+
then sit on --muted like everywhere else. Any theme that repurposes --secondary owes this line. */
|
|
121
|
+
--progress-track-background: hsl(var(--muted));
|
|
115
122
|
/* Shape - base radius + exact ACME steps; re-declare the intermediates so the scope re-resolves */
|
|
116
123
|
--radius: 0.875rem; /* 14px card */
|
|
117
124
|
--radius-xs: 4px; --radius-sm: 6px; --radius-md: 10px;
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Tree / hierarchical rows inside the real @godxjp/ui DataTable.
|
|
5
5
|
*
|
|
6
|
-
* The lib's `
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* The lib's `Tree` owns the standalone tree view, but it is single-column — it
|
|
7
|
+
* cannot express a *tabular* hierarchy with per-row metrics, a parent-only
|
|
8
|
+
* disclosure twirl, and DataTable chrome (sticky header, density, sortable
|
|
9
|
+
* columns). So this composes the behaviour from real primitives:
|
|
10
10
|
*
|
|
11
11
|
* row model ........ flatten an org tree to rows carrying { depth, hasChildren,
|
|
12
12
|
* expanded }, then derive `visibleRows` from the open set.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@godxjp/ui",
|
|
3
|
-
"version": "
|
|
4
|
-
"godxUiMcp": "
|
|
3
|
+
"version": "22.0.0",
|
|
4
|
+
"godxUiMcp": "22.0.0",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -213,10 +213,6 @@
|
|
|
213
213
|
"types": "./dist/components/data-entry/date-picker.d.ts",
|
|
214
214
|
"import": "./dist/components/data-entry/date-picker.js"
|
|
215
215
|
},
|
|
216
|
-
"./ui/date-range-picker": {
|
|
217
|
-
"types": "./dist/components/data-entry/date-range-picker.d.ts",
|
|
218
|
-
"import": "./dist/components/data-entry/date-range-picker.js"
|
|
219
|
-
},
|
|
220
216
|
"./ui/time-picker": {
|
|
221
217
|
"types": "./dist/components/data-entry/time-picker.d.ts",
|
|
222
218
|
"import": "./dist/components/data-entry/time-picker.js"
|
|
@@ -350,14 +346,17 @@
|
|
|
350
346
|
"check:layout-nav-closure": "for frames in layout-flex,layout-app-shell,layout-aspect-ratio,layout-auth-shell layout-page-container,layout-resizable-panel,layout-separator,layout-sidebar layout-split-pane,layout-topbar,navigation-breadcrumb,navigation-app-setting-picker navigation-context-menu,navigation-dropdown-menu,navigation-menubar,navigation-navigation-menu navigation-steps,navigation-toolbar,navigation-tabs,navigation-pagination; do FRAMES=$frames node scripts/check-layout-nav-closure.mjs || exit 1; done",
|
|
351
347
|
"check:display-runtime-evidence": "node scripts/check-display-runtime-evidence.mjs",
|
|
352
348
|
"check:data-table-pagination-wrap": "node scripts/check-data-table-pagination-wrap.mjs",
|
|
349
|
+
"check:tabs-overflow-menu": "node scripts/check-tabs-overflow-menu.mjs",
|
|
353
350
|
"check:button-icon-xs": "node scripts/check-button-icon-xs.mjs",
|
|
351
|
+
"check:timeline-title-fill": "node scripts/check-timeline-title-fill.mjs",
|
|
352
|
+
"check:descriptions-label-value-step": "node scripts/check-descriptions-label-value-step.mjs",
|
|
354
353
|
"check:frame-contracts": "pnpm check:component-api-manifest && pnpm audit:component-cases && pnpm check:frame-coverage && pnpm check:frame-coverage-ledger && pnpm check:screen-reader-evidence && pnpm check:data-entry-owner-source && pnpm check:display-runtime-evidence",
|
|
355
354
|
"check:final-touch-rtl": "node scripts/check-final-touch-rtl.mjs",
|
|
356
|
-
"check:frame-runtime": "pnpm check:data-entry-frame-runtime && pnpm check:data-entry-touch-aria && pnpm check:layout-nav-frames && pnpm check:provider-feedback-query-runtime && pnpm check:layout-nav-closure && pnpm check:final-touch-rtl && pnpm check:data-table-pagination-wrap && pnpm check:button-icon-xs",
|
|
357
|
-
"verify": "pnpm typecheck && pnpm lint && pnpm format && pnpm build && pnpm preview:build && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:no-consumer-coupling && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:no-external-assets && pnpm check:token-scale-bypass && pnpm check:dist-tokens-resolve && pnpm check:no-hardcoded-geometry && pnpm check:no-hardcoded-css-values && pnpm check:no-inline-magic-numbers && pnpm check:no-tailwind-class-assertions && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-lockstep && pnpm check:mcp-sync && pnpm check:doc-prop-existence && pnpm check:mcp-catalog-coverage && pnpm check:mcp-orphans && pnpm check:mcp-pattern-imports && pnpm check:audit-sync && pnpm check:frame-coverage && pnpm test",
|
|
358
|
-
"verify:static": "pnpm build && pnpm check:packed-public-contract && pnpm typecheck && pnpm typecheck:docs && pnpm lint && pnpm preview:build && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:no-consumer-coupling && pnpm check:use-client && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:token-scale-bypass && pnpm check:dist-tokens-resolve && pnpm check:no-hardcoded-geometry && pnpm check:no-hardcoded-css-values && pnpm check:no-inline-magic-numbers && pnpm check:no-tailwind-class-assertions && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-lockstep && pnpm check:mcp-sync && pnpm check:doc-prop-existence && pnpm check:mcp-catalog-coverage && pnpm check:mcp-orphans && pnpm check:mcp-pattern-imports && pnpm check:audit-sync && pnpm check:mcp-prop-sync && pnpm check:contrast && pnpm check:visual-audit && pnpm test",
|
|
355
|
+
"check:frame-runtime": "pnpm check:data-entry-frame-runtime && pnpm check:data-entry-touch-aria && pnpm check:layout-nav-frames && pnpm check:provider-feedback-query-runtime && pnpm check:layout-nav-closure && pnpm check:final-touch-rtl && pnpm check:data-table-pagination-wrap && pnpm check:tabs-overflow-menu && pnpm check:button-icon-xs && pnpm check:timeline-title-fill && pnpm check:descriptions-label-value-step",
|
|
356
|
+
"verify": "pnpm typecheck && pnpm lint && pnpm format && pnpm build && pnpm preview:build && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:no-consumer-coupling && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:no-external-assets && pnpm check:token-scale-bypass && pnpm check:radix-surface && pnpm check:dist-tokens-resolve && pnpm check:no-hardcoded-geometry && pnpm check:no-hardcoded-css-values && pnpm check:disclosure-duplication && pnpm check:no-inline-magic-numbers && pnpm check:no-tailwind-class-assertions && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-lockstep && pnpm check:mcp-sync && pnpm check:doc-prop-existence && pnpm check:mcp-catalog-coverage && pnpm check:mcp-orphans && pnpm check:mcp-pattern-imports && pnpm check:audit-sync && pnpm check:frame-coverage && pnpm test",
|
|
357
|
+
"verify:static": "pnpm build && pnpm check:packed-public-contract && pnpm typecheck && pnpm typecheck:docs && pnpm lint && pnpm preview:build && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:no-consumer-coupling && pnpm check:use-client && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:token-scale-bypass && pnpm check:radix-surface && pnpm check:dist-tokens-resolve && pnpm check:no-hardcoded-geometry && pnpm check:no-hardcoded-css-values && pnpm check:disclosure-duplication && pnpm check:no-inline-magic-numbers && pnpm check:no-tailwind-class-assertions && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-lockstep && pnpm check:mcp-sync && pnpm check:doc-prop-existence && pnpm check:mcp-catalog-coverage && pnpm check:mcp-orphans && pnpm check:mcp-pattern-imports && pnpm check:audit-sync && pnpm check:mcp-prop-sync && pnpm check:contrast && pnpm check:visual-audit && pnpm test",
|
|
359
358
|
"verify:ci": "pnpm verify:ci:static && pnpm check:frame-contracts && pnpm test",
|
|
360
|
-
"verify:ci:static": "pnpm build && pnpm check:packed-public-contract && pnpm typecheck && pnpm typecheck:docs && pnpm lint && pnpm preview:build && pnpm check:registry && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:no-consumer-coupling && pnpm check:use-client && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:no-external-assets && pnpm check:token-scale-bypass && pnpm check:no-antd-runtime && pnpm check:dist-tokens-resolve && pnpm check:no-hardcoded-geometry && pnpm check:no-hardcoded-css-values && pnpm check:no-inline-magic-numbers && pnpm check:no-tailwind-class-assertions && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-lockstep && pnpm check:mcp-sync && pnpm check:doc-prop-existence && pnpm check:mcp-catalog-coverage && pnpm check:mcp-orphans && pnpm check:mcp-pattern-imports && pnpm check:audit-sync && pnpm check:gate-coverage && pnpm check:mcp-prop-sync && pnpm check:catalog-contradictions",
|
|
359
|
+
"verify:ci:static": "pnpm build && pnpm check:packed-public-contract && pnpm typecheck && pnpm typecheck:docs && pnpm lint && pnpm preview:build && pnpm check:registry && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:no-consumer-coupling && pnpm check:use-client && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:no-external-assets && pnpm check:token-scale-bypass && pnpm check:no-antd-runtime && pnpm check:radix-surface && pnpm check:dist-tokens-resolve && pnpm check:no-hardcoded-geometry && pnpm check:no-hardcoded-css-values && pnpm check:disclosure-duplication && pnpm check:no-inline-magic-numbers && pnpm check:no-tailwind-class-assertions && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-lockstep && pnpm check:mcp-sync && pnpm check:doc-prop-existence && pnpm check:mcp-catalog-coverage && pnpm check:mcp-orphans && pnpm check:mcp-pattern-imports && pnpm check:audit-sync && pnpm check:gate-coverage && pnpm check:mcp-prop-sync && pnpm check:catalog-contradictions && pnpm check:catalog-snippets",
|
|
361
360
|
"verify:browser": "pnpm check:contrast && pnpm check:text-ink-clip && pnpm check:visual-audit",
|
|
362
361
|
"verify:release": "pnpm verify:static && pnpm check:frame-contracts && pnpm check:frame-coverage && pnpm check:frame-axe",
|
|
363
362
|
"verify:publish-tree": "pnpm build && pnpm check:packed-public-contract && pnpm check:use-client && pnpm check:dist-tokens-resolve",
|
|
@@ -381,6 +380,7 @@
|
|
|
381
380
|
"check:no-hardcoded-geometry": "node scripts/check-no-hardcoded-geometry.mjs",
|
|
382
381
|
"check:no-external-assets": "node scripts/check-no-external-assets.mjs",
|
|
383
382
|
"check:no-hardcoded-css-values": "node scripts/check-no-hardcoded-css-values.mjs",
|
|
383
|
+
"check:disclosure-duplication": "node scripts/check-disclosure-duplication.mjs",
|
|
384
384
|
"check:no-inline-magic-numbers": "node scripts/check-no-inline-magic-numbers.mjs",
|
|
385
385
|
"check:no-tailwind-class-assertions": "node scripts/check-no-tailwind-class-assertions.mjs",
|
|
386
386
|
"check:control-sizing": "node scripts/check-control-sizing.mjs",
|
|
@@ -388,6 +388,7 @@
|
|
|
388
388
|
"check:typography": "node scripts/check-typography.mjs",
|
|
389
389
|
"gen:component-tokens": "node scripts/gen-component-tokens.mjs",
|
|
390
390
|
"check:no-antd-runtime": "node scripts/check-no-antd-runtime.mjs",
|
|
391
|
+
"check:radix-surface": "node scripts/check-radix-surface.mjs",
|
|
391
392
|
"gen:email-tokens": "node scripts/gen-email-tokens.mjs",
|
|
392
393
|
"check:core-isolation": "node scripts/check-core-isolation.mjs",
|
|
393
394
|
"check:no-consumer-coupling": "node scripts/check-no-consumer-coupling.mjs",
|
|
@@ -412,7 +413,8 @@
|
|
|
412
413
|
"check:frame-geometry": "node scripts/frame-geometry.mjs",
|
|
413
414
|
"postinstall": "node scripts/postinstall.mjs",
|
|
414
415
|
"init-agent": "node scripts/init-agent-kit.mjs",
|
|
415
|
-
"check:use-client": "node scripts/check-use-client.mjs"
|
|
416
|
+
"check:use-client": "node scripts/check-use-client.mjs",
|
|
417
|
+
"check:catalog-snippets": "node scripts/audit-catalog-snippets.mjs"
|
|
416
418
|
},
|
|
417
419
|
"peerDependencies": {
|
|
418
420
|
"@axe-core/playwright": "*",
|
|
@@ -447,31 +449,19 @@
|
|
|
447
449
|
"@fontsource/m-plus-2": "^5.3.0",
|
|
448
450
|
"@fontsource/noto-sans-jp": "^5.3.0",
|
|
449
451
|
"@radix-ui/react-accordion": "^1.2.20",
|
|
450
|
-
"@radix-ui/react-alert-dialog": "^1.1.23",
|
|
451
|
-
"@radix-ui/react-aspect-ratio": "^1.1.15",
|
|
452
452
|
"@radix-ui/react-avatar": "^1.2.6",
|
|
453
|
-
"@radix-ui/react-checkbox": "^1.3.11",
|
|
454
453
|
"@radix-ui/react-collapsible": "^1.1.20",
|
|
455
|
-
"@radix-ui/react-context": "^1.2.2",
|
|
456
454
|
"@radix-ui/react-context-menu": "^2.3.7",
|
|
457
|
-
"@radix-ui/react-dialog": "^1.1.23",
|
|
458
|
-
"@radix-ui/react-dropdown-menu": "^2.1.24",
|
|
459
|
-
"@radix-ui/react-hover-card": "^1.1.23",
|
|
460
455
|
"@radix-ui/react-label": "^2.1.15",
|
|
461
456
|
"@radix-ui/react-menubar": "^1.1.24",
|
|
462
457
|
"@radix-ui/react-navigation-menu": "^1.2.22",
|
|
463
|
-
"@radix-ui/react-popover": "^1.1.23",
|
|
464
|
-
"@radix-ui/react-radio-group": "^1.4.7",
|
|
465
458
|
"@radix-ui/react-scroll-area": "^1.2.18",
|
|
466
459
|
"@radix-ui/react-select": "^2.3.7",
|
|
467
460
|
"@radix-ui/react-separator": "^1.1.15",
|
|
468
461
|
"@radix-ui/react-slider": "^1.4.7",
|
|
469
462
|
"@radix-ui/react-slot": "^1.3.3",
|
|
470
|
-
"@radix-ui/react-switch": "^1.3.7",
|
|
471
|
-
"@radix-ui/react-tabs": "^1.1.21",
|
|
472
463
|
"@radix-ui/react-toggle": "^1.1.18",
|
|
473
464
|
"@radix-ui/react-toggle-group": "^1.1.19",
|
|
474
|
-
"@radix-ui/react-tooltip": "^1.2.16",
|
|
475
465
|
"@react-aria/utils": "^3.34.1",
|
|
476
466
|
"@tanstack/react-table": "^9.2.4",
|
|
477
467
|
"class-variance-authority": "^0.7.1",
|
package/scripts/ui-audit.mjs
CHANGED
|
@@ -33,7 +33,20 @@ const PALETTE =
|
|
|
33
33
|
* Emoji in product text — Unicode "Extended_Pictographic" set (UTS #51). Catches
|
|
34
34
|
* ✅🎉🔥🚀 etc. but NOT typographic punctuation (· — × ✓), which have their own rules.
|
|
35
35
|
*/
|
|
36
|
-
|
|
36
|
+
/*
|
|
37
|
+
* EMOJI — pictographs, but NOT the three typographic marks that happen to carry the property.
|
|
38
|
+
*
|
|
39
|
+
* `\p{Extended_Pictographic}` includes U+00A9 ©, U+00AE ® and U+2122 ™. All three are
|
|
40
|
+
* `Emoji_Presentation=No`: they default to TEXT presentation, they have been in typography since
|
|
41
|
+
* long before emoji existed, and none of the reasons in this rule's message applies to them — a
|
|
42
|
+
* copyright line does not "break on Win/Linux" and does not pollute an accessible name. The
|
|
43
|
+
* catalog's own CenteredShell recipe was flagged for the `©` in its footer, which is unavoidable
|
|
44
|
+
* product copy, and every consumer with a footer would be flagged for the same thing.
|
|
45
|
+
*
|
|
46
|
+
* Followed by U+FE0F they are asking for emoji presentation on purpose, and then they ARE emoji —
|
|
47
|
+
* so that spelling is still caught.
|
|
48
|
+
*/
|
|
49
|
+
const EMOJI = /[\u00A9\u00AE\u2122]\uFE0F|(?![\u00A9\u00AE\u2122])\p{Extended_Pictographic}/u;
|
|
37
50
|
/** Regional-indicator pairs = emoji flags (🇯🇵) — broken on Win/Linux; use Intl.DisplayNames. */
|
|
38
51
|
const EMOJI_FLAG = /\p{Regional_Indicator}/u;
|
|
39
52
|
|
|
@@ -169,7 +182,7 @@ const RULES = [
|
|
|
169
182
|
spansElement: true,
|
|
170
183
|
test: new RegExp(
|
|
171
184
|
"<(?:Checkbox\\.Group|Upload|Cascader|TreeSelect|Transfer|Select|SearchSelect|DatePicker|" +
|
|
172
|
-
`
|
|
185
|
+
`TimePicker|ColorPicker|LocalePicker|TimezonePicker|DateFormatPicker|TimeFormatPicker)\\b${ATTRS}\\bonChange=`,
|
|
173
186
|
"g",
|
|
174
187
|
),
|
|
175
188
|
message:
|
|
@@ -729,8 +742,8 @@ const CARD_FLUSH = new RegExp(
|
|
|
729
742
|
// legitimately, so they are NOT matched. Whole-file pass (the pair spans lines).
|
|
730
743
|
const BARE_FIELD = new RegExp(
|
|
731
744
|
`<(?:label|Label)\\b${ATTRS}>[\\s\\S]{0,240}?</(?:label|Label)>\\s*` +
|
|
732
|
-
"<(?:Input|Select|Textarea|NumberInput|SearchInput|SearchSelect|DatePicker|
|
|
733
|
-
"TimePicker|
|
|
745
|
+
"<(?:Input|Select|Textarea|NumberInput|SearchInput|SearchSelect|DatePicker|" +
|
|
746
|
+
"TimePicker|Cascader|TreeSelect|input)\\b",
|
|
734
747
|
"g",
|
|
735
748
|
);
|
|
736
749
|
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { ReactNode } from "react";
|
|
2
|
-
export type TreeListItem = {
|
|
3
|
-
id: string;
|
|
4
|
-
title: ReactNode;
|
|
5
|
-
description?: ReactNode;
|
|
6
|
-
depth?: number;
|
|
7
|
-
active?: boolean;
|
|
8
|
-
badge?: ReactNode;
|
|
9
|
-
};
|
|
10
|
-
export type TreeListProps = {
|
|
11
|
-
items: TreeListItem[];
|
|
12
|
-
};
|
|
13
|
-
export declare function TreeList({ items }: TreeListProps): import("react").JSX.Element;
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { Badge } from "./badge.js";
|
|
4
|
-
function TreeList({ items }) {
|
|
5
|
-
return /* @__PURE__ */ jsx("ul", { className: "ui-tree-list", children: items.map((item) => /* @__PURE__ */ jsxs(
|
|
6
|
-
"li",
|
|
7
|
-
{
|
|
8
|
-
className: "ui-tree-item",
|
|
9
|
-
"data-active": item.active ? "true" : void 0,
|
|
10
|
-
"data-depth": Math.max(0, item.depth ?? 0),
|
|
11
|
-
style: { "--tree-item-depth": Math.max(0, item.depth ?? 0) },
|
|
12
|
-
"aria-current": item.active ? "true" : void 0,
|
|
13
|
-
children: [
|
|
14
|
-
/* @__PURE__ */ jsxs("div", { className: "ui-tree-item-body", children: [
|
|
15
|
-
/* @__PURE__ */ jsx("div", { className: "ui-tree-item-title", children: item.title }),
|
|
16
|
-
item.description ? /* @__PURE__ */ jsx("div", { className: "ui-tree-item-description", children: item.description }) : null
|
|
17
|
-
] }),
|
|
18
|
-
item.badge != null ? /* @__PURE__ */ jsx(Badge, { variant: "secondary", children: item.badge }) : null
|
|
19
|
-
]
|
|
20
|
-
},
|
|
21
|
-
item.id
|
|
22
|
-
)) });
|
|
23
|
-
}
|
|
24
|
-
export {
|
|
25
|
-
TreeList
|
|
26
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import type { DateRangePickerProp } from "../../props/components/data-entry.prop.js";
|
|
3
|
-
export type { DateRangePickerProp, DateRangePickerProp as DateRangePickerProps, } from "../../props/components/data-entry.prop.js";
|
|
4
|
-
/**
|
|
5
|
-
* DateRangePicker — WAI-ARIA date-range combobox rendered as ONE input-styled control
|
|
6
|
-
* (the established RangePicker convention): `[ from → to ✕ 📅 ]`. The two inner fields stay
|
|
7
|
-
* real, typeable ISO `yyyy-MM-dd` inputs (form-submittable via `${name}_from` /
|
|
8
|
-
* `${name}_to`, screen-reader friendly, e2e-testable by filling either input); the
|
|
9
|
-
* range calendar is the visual affordance.
|
|
10
|
-
*/
|
|
11
|
-
export declare function DateRangePicker({ value: valueProp, defaultValue, onValueChange, placeholder, disabled, className, id, name, locale: localeProp, showToday, showClose, fromDate, toDate, disabledDate, cellRender, allowClear, format, parseFormat, minDate, maxDate, showWeek, presets, needConfirm, allowEmpty, order, open: openProp, defaultOpen, onOpenChange, inputReadOnly, preserveInvalidOnBlur, placement, renderExtraFooter, size, status, variant, ref, ...ariaProps }: DateRangePickerProp): React.JSX.Element;
|