@godxjp/ui 33.22.2 → 33.25.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/DESIGN.md +1 -1
- package/README.md +16 -5
- package/agent/DESIGN.md +1 -1
- package/agent/START-HERE.md +8 -8
- package/agent/components/AgentBadge.json +43 -0
- package/agent/components/AppShell.json +6 -0
- package/agent/components/Avatar.json +7 -0
- package/agent/components/CatalogDetail.json +7 -3
- package/agent/components/DatePicker.json +1 -1
- package/agent/components/DropdownMenu.json +1 -0
- package/agent/components/EditorialCard.json +2 -1
- package/agent/components/Image.json +6 -1
- package/agent/components/PageContainer.json +5 -0
- package/agent/components/PageErrorBoundary.json +48 -0
- package/agent/components/Pagination.json +5 -0
- package/agent/components/Popover.json +1 -0
- package/agent/components/Select.json +2 -1
- package/agent/components/Toaster.json +2 -2
- package/agent/components/Toolbar.json +1 -1
- package/agent/components/Topbar.json +1 -1
- package/agent/components-index.json +10 -0
- package/agent/components.json +138 -11
- package/agent/index.json +8 -8
- package/agent/llms.txt +7 -7
- package/agent/patterns/notice-bar.json +16 -0
- package/agent/patterns-index.json +15 -0
- package/agent/patterns.json +16 -0
- package/agent/rules.json +2 -2
- package/agent/tokens.json +121 -7
- package/dist/components/charts/chart-cartesian.js +5 -1
- package/dist/components/charts/chart-summary.d.ts +1 -1
- package/dist/components/charts/chart-summary.js +17 -6
- package/dist/components/charts/compact-bar-trend.js +4 -3
- package/dist/components/charts/pie-chart.js +2 -1
- package/dist/components/data-display/avatar.d.ts +1 -1
- package/dist/components/data-display/avatar.js +7 -1
- package/dist/components/data-display/badge.d.ts +11 -0
- package/dist/components/data-display/badge.js +20 -0
- package/dist/components/data-display/image.d.ts +1 -0
- package/dist/components/data-display/image.js +10 -2
- package/dist/components/data-display/index.d.ts +2 -2
- package/dist/components/data-display/index.js +2 -1
- package/dist/components/data-display/popover.js +11 -0
- package/dist/components/data-entry/calendar.js +1 -1
- package/dist/components/data-entry/date-picker.js +22 -5
- package/dist/components/data-entry/record-picker.js +122 -98
- package/dist/components/data-entry/select.js +13 -3
- package/dist/components/general/button.js +2 -2
- package/dist/components/layout/affix.js +1 -1
- package/dist/components/layout/app-shell.d.ts +1 -1
- package/dist/components/layout/app-shell.js +3 -1
- package/dist/components/layout/editorial-catalog.d.ts +1 -1
- package/dist/components/layout/editorial-catalog.js +53 -15
- package/dist/components/layout/index.d.ts +2 -0
- package/dist/components/layout/index.js +2 -0
- package/dist/components/layout/page-container.d.ts +1 -1
- package/dist/components/layout/page-container.js +6 -3
- package/dist/components/layout/page-error-boundary.d.ts +32 -0
- package/dist/components/layout/page-error-boundary.js +57 -0
- package/dist/components/layout/sidebar.d.ts +1 -1
- package/dist/components/layout/sidebar.js +100 -49
- package/dist/components/layout/topbar.js +108 -21
- package/dist/components/navigation/dropdown-menu.d.ts +13 -3
- package/dist/components/navigation/dropdown-menu.js +36 -6
- package/dist/components/navigation/pagination.d.ts +1 -1
- package/dist/components/navigation/pagination.js +13 -1
- package/dist/components/navigation/toolbar.js +2 -1
- package/dist/contracts/measurement.json +1 -1
- package/dist/i18n/messages/en.json +7 -0
- package/dist/i18n/messages/ja.json +7 -0
- package/dist/i18n/messages/vi.json +7 -0
- package/dist/props/components/data-display.prop.d.ts +29 -0
- package/dist/props/components/layout.prop.d.ts +52 -2
- package/dist/props/components/navigation.prop.d.ts +15 -1
- package/dist/props/registry.d.ts +65 -5
- package/dist/props/registry.js +90 -4
- package/dist/styles/alert-layout.css +4 -0
- package/dist/styles/application.css +24 -0
- package/dist/styles/badge-layout.css +14 -0
- package/dist/styles/base.css +11 -0
- package/dist/styles/control.css +32 -19
- package/dist/styles/core.css +1 -0
- package/dist/styles/data-display-layout.css +51 -0
- package/dist/styles/dialog-layout.css +9 -0
- package/dist/styles/editorial-layout.css +2076 -0
- package/dist/styles/editorial.css +3 -0
- package/dist/styles/icon-layout.css +3 -0
- package/dist/styles/index.css +1 -0
- package/dist/styles/layers.json +60 -9
- package/dist/styles/layout.css +9 -1985
- package/dist/styles/precompiled/alert-layout.css +2 -0
- package/dist/styles/precompiled/badge-layout.css +2 -0
- package/dist/styles/precompiled/base.css +2 -0
- package/dist/styles/precompiled/card-layout.css +2 -0
- package/dist/styles/precompiled/chart-layout.css +2 -0
- package/dist/styles/precompiled/control.css +2 -0
- package/dist/styles/precompiled/data-display-layout.css +2 -0
- package/dist/styles/precompiled/data-entry-layout.css +2 -0
- package/dist/styles/precompiled/dialog-layout.css +2 -0
- package/dist/styles/precompiled/editorial-account-layout.css +2 -0
- package/dist/styles/precompiled/editorial-layout.css +2 -0
- package/dist/styles/precompiled/float-button-layout.css +2 -0
- package/dist/styles/precompiled/form-layout.css +2 -0
- package/dist/styles/precompiled/icon-layout.css +2 -0
- package/dist/styles/precompiled/layout.css +2 -0
- package/dist/styles/precompiled/logo-layout.css +2 -0
- package/dist/styles/precompiled/motion.css +2 -0
- package/dist/styles/precompiled/navigation-layout.css +2 -0
- package/dist/styles/precompiled/shell-layout.css +2 -0
- package/dist/styles/precompiled/table-layout.css +2 -0
- package/dist/styles/precompiled/text-layout.css +2 -0
- package/dist/styles/precompiled/toggle.css +2 -0
- package/dist/styles/precompiled/vendor-day-picker.css +2 -0
- package/dist/styles/precompiled/vendor-sonner.css +2 -0
- package/dist/styles/shell-layout.css +17 -1
- package/dist/styles/table-layout.css +1 -1
- package/dist/styles.css +1 -1
- package/dist/tokens/components/badge.css +3 -0
- package/dist/tokens/components/control.css +3 -0
- package/dist/tokens/components/data-display.css +9 -0
- package/dist/tokens/components/editorial.css +9 -6
- package/dist/tokens/components/shell.css +2 -0
- package/dist/tokens/foundation.css +8 -0
- package/docs/CONSUMER-RULES.md +36 -1
- package/package.json +4 -2
- package/scripts/consumer-rule.md +1 -1
- package/scripts/prune-css.mjs +56 -8
- package/scripts/ui-audit.mjs +36 -0
- package/skills/godxjp-ui-navigation/SKILL.md +14 -9
- package/skills/godxjp-ui-navigation/references/principles.md +2 -2
package/DESIGN.md
CHANGED
|
@@ -160,7 +160,7 @@ Each section is a Heading (plus one muted line if it adds a fact) over its conte
|
|
|
160
160
|
|
|
161
161
|
### Dashboard
|
|
162
162
|
|
|
163
|
-
|
|
163
|
+
KPI tiles belong on pages whose job is monitoring — dashboards, report heads (a short count strip above a list or report is fine too). Keep the set small; around four `StatCard`s is a good default, not a limit. Give a tile a comparison `delta` when a meaningful baseline exists (previous period, target, plan), with `inverse` when up is bad; a count of work to do (pending, overdue, unread) instead links to the list already filtered to those items — never invent a comparison. Every tile states its label, unit, period and scope. Below, panels in `ResponsiveGrid`, each a Card with a title and one "view all" link: a work queue, a short table, a chart.
|
|
164
164
|
|
|
165
165
|
### Approval queue
|
|
166
166
|
|
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ npm i @godxjp/ui
|
|
|
18
18
|
|
|
19
19
|
<!-- agent-catalog-counts:start -->
|
|
20
20
|
|
|
21
|
-
The catalog —
|
|
21
|
+
The catalog — 212 components, 3203 tokens, 44 cardinal rules — is published in two forms from one
|
|
22
22
|
source. **Entry point for either: [`AGENTS.md`](AGENTS.md).**
|
|
23
23
|
<!-- agent-catalog-counts:end -->
|
|
24
24
|
|
|
@@ -53,12 +53,12 @@ static files straight from this public repo — no hosting, no deploy step:
|
|
|
53
53
|
| [`agent/llms.txt`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/llms.txt) | 3 KB | the [llms.txt](https://llmstxt.org/) entry point |
|
|
54
54
|
| [`agent/DESIGN.md`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/DESIGN.md) | 18 KB | the visual spec: tokens, colour scarcity, admin screen anatomy, do/don't |
|
|
55
55
|
| [`agent/index.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/index.json) | 3 KB | manifest: version, counts, every file's URL |
|
|
56
|
-
| [`agent/components-index.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/components-index.json) |
|
|
56
|
+
| [`agent/components-index.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/components-index.json) | 47 KB | all 212 as name + group + tagline — **fetch this first** |
|
|
57
57
|
| [`agent/components/<Name>.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/components/Select.json) | 1 KB–38 KB | one file per component, each with its `importPath` — **this is the route to take** |
|
|
58
|
-
| [`agent/components.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/components.json) | 1.4 MB | all
|
|
59
|
-
| [`agent/tokens.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/tokens.json) | 1.4 MB | all
|
|
58
|
+
| [`agent/components.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/components.json) | 1.4 MB | all 212 entries in one file — most URL fetchers truncate this silently; prefer the per-component files |
|
|
59
|
+
| [`agent/tokens.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/tokens.json) | 1.4 MB | all 3203 design tokens, their values and why they exist |
|
|
60
60
|
| [`agent/vocabulary.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/vocabulary.json) | 7 KB | the controlled prop vocabulary |
|
|
61
|
-
| [`agent/rules.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/rules.json) |
|
|
61
|
+
| [`agent/rules.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/rules.json) | 24 KB | the 44 cardinal rules |
|
|
62
62
|
<!-- prettier-ignore-end -->
|
|
63
63
|
<!-- agent-catalog-files:end -->
|
|
64
64
|
|
|
@@ -226,6 +226,17 @@ only when a used component renders them. **Re-run it whenever the set of compone
|
|
|
226
226
|
changes and after every upgrade** — the emitted header says so, and the tool refuses to run against
|
|
227
227
|
a manifest from a different package version.
|
|
228
228
|
|
|
229
|
+
No Tailwind (you import `@godxjp/ui/styles.css`)? Add `--precompiled` (gh#1455):
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
npx godxjp-ui prune-css src --out src/godx-ui.css --precompiled
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
The emitted file imports the precompiled slices instead (`@import "@godxjp/ui/styles/precompiled/base";` and one per kept layer): the same precompiled CSS as
|
|
236
|
+
`styles.css`, cut per manifest file at build time (`base` = tokens, preflight and the utilities
|
|
237
|
+
the components use; one slice per layer and vendor sheet). Your bundler only has to inline plain
|
|
238
|
+
`@import`s. Import it INSTEAD of `@godxjp/ui/styles.css`.
|
|
239
|
+
|
|
229
240
|
## Golden ratio (φ ≈ 1.618)
|
|
230
241
|
|
|
231
242
|
One token `--phi-unit` drives page/section/card spacing; micro control gaps use the 4px grid. Density (`compact` | `default` | `comfortable`) retunes `--phi-unit` with control + table heights together.
|
package/agent/DESIGN.md
CHANGED
|
@@ -160,7 +160,7 @@ Each section is a Heading (plus one muted line if it adds a fact) over its conte
|
|
|
160
160
|
|
|
161
161
|
### Dashboard
|
|
162
162
|
|
|
163
|
-
|
|
163
|
+
KPI tiles belong on pages whose job is monitoring — dashboards, report heads (a short count strip above a list or report is fine too). Keep the set small; around four `StatCard`s is a good default, not a limit. Give a tile a comparison `delta` when a meaningful baseline exists (previous period, target, plan), with `inverse` when up is bad; a count of work to do (pending, overdue, unread) instead links to the list already filtered to those items — never invent a comparison. Every tile states its label, unit, period and scope. Below, panels in `ResponsiveGrid`, each a Card with a title and one "view all" link: a work queue, a short table, a chart.
|
|
164
164
|
|
|
165
165
|
### Approval queue
|
|
166
166
|
|
package/agent/START-HERE.md
CHANGED
|
@@ -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` 33.
|
|
6
|
+
**This catalog describes `@godxjp/ui` 33.25.0.** 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.
|
|
@@ -48,11 +48,11 @@ inspect every screenshot at every width region by region (no top-N cap), and han
|
|
|
48
48
|
→ These files are for you. Read `DESIGN.md` (in this folder) first: tokens, scarcity rules and
|
|
49
49
|
screen anatomy, the visual target the rules below do not give you. Then fetch in this order:
|
|
50
50
|
|
|
51
|
-
0. `patterns-index.json` —
|
|
51
|
+
0. `patterns-index.json` — 29 whole-task patterns as name + tagline + tags. **If your
|
|
52
52
|
task is a task** — "build a settings page", "confirm a destructive delete", "a list page with
|
|
53
53
|
filters" — start HERE, not at the components. Then fetch `patterns/<name>.json` for complete,
|
|
54
54
|
copy-paste-ready code. A component index answers "does X exist"; it cannot answer "build Y".
|
|
55
|
-
1. `components-index.json` —
|
|
55
|
+
1. `components-index.json` — 47 KB, all 212 components as name + group +
|
|
56
56
|
tagline. Read this when you already know the SHAPE you need. Each entry may carry `absorbed`:
|
|
57
57
|
names that **do not exist** and map to it — `Combobox`, `Autocomplete`, `CountrySelect` and
|
|
58
58
|
`SearchSelect` are all `Select`. If you are about to hand-roll something, search this field
|
|
@@ -61,10 +61,10 @@ screen anatomy, the visual target the rules below do not give you. Then fetch in
|
|
|
61
61
|
its `importPath`, and its examples. Fetch only the handful you picked in step 1.
|
|
62
62
|
3. `rules.json` — 44 cardinal rules. The ones about raw HTML and hardcoded colour are not
|
|
63
63
|
style advice.
|
|
64
|
-
4. `tokens.json` —
|
|
65
|
-
brand, read the
|
|
64
|
+
4. `tokens.json` — 3203 design tokens, each tagged with its `tier`. **If you were handed a
|
|
65
|
+
brand, read the 223 `foundation` entries first** — `--primary`, `--background`,
|
|
66
66
|
`--radius`, `--font-size-base` are the handful everything else derives from. The
|
|
67
|
-
|
|
67
|
+
2867 `component` entries are per-part knobs; reach for one only when a role is
|
|
68
68
|
right everywhere except one component.
|
|
69
69
|
5. `anti-ai-tells.json` — 35 shapes that make generated UI look generated, each with the
|
|
70
70
|
fix. Read before you reach for a gradient hero or a wall of coloured chips.
|
|
@@ -148,9 +148,9 @@ has stopped following the brand.
|
|
|
148
148
|
|
|
149
149
|
| `tier` | count | what it is | set it? |
|
|
150
150
|
|---|---|---|---|
|
|
151
|
-
| `foundation` |
|
|
151
|
+
| `foundation` | 223 | the seeds — `--primary`, `--background`, `--foreground`, `--radius`, `--font-size-base`, `--shadow-color`. Everything below is derived from these | **yes — this is the main road.** The default `--primary` is a neutral placeholder: set it (`:root { --primary: <H> <S>% <L>%; }`, HSL components, no `hsl()` wrapper) or import a theme preset such as `@godxjp/ui/themes/godx.css` |
|
|
152
152
|
| `semantic` | 113 | named roles that follow the seeds — `--ring`, `--text-link`, `--primary-hover`, `--overlay-background` | only when the seed is right and ONE role must differ. That role then stops following a later brand change |
|
|
153
|
-
| `component` |
|
|
153
|
+
| `component` | 2867 | per-part knobs, `--{component}-{part}-{property}` | rarely. Most are declared `initial` with the real default at the call site — deliberate, so a scoped override re-resolves instead of freezing at `:root` |
|
|
154
154
|
|
|
155
155
|
A token whose `value` is `initial` is not empty and not broken: `initial` is the guaranteed-invalid
|
|
156
156
|
value, so the real default is computed where the element paints it. Set it and yours wins.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"example": "import { AgentBadge, Avatar, AvatarFallback, AvatarImage } from \"@godxjp/ui/data-display\";\nimport { Text } from \"@godxjp/ui/general\";\nimport { Flex } from \"@godxjp/ui/layout\";\n\n<Flex align=\"center\" gap=\"sm\">\n <Avatar kind=\"agent\">\n <AvatarImage src={agent.avatarUrl} alt=\"\" />\n <AvatarFallback>ハ</AvatarFallback>\n </Avatar>\n <Text>ハルカ</Text>\n <AgentBadge />\n</Flex>",
|
|
3
|
+
"group": "data-display",
|
|
4
|
+
"importPath": "@godxjp/ui/data-display",
|
|
5
|
+
"name": "AgentBadge",
|
|
6
|
+
"props": [
|
|
7
|
+
{
|
|
8
|
+
"defaultValue": "\"span\"",
|
|
9
|
+
"description": "Render element. `span` (default) because the label sits in a name's text line, often inside a link or a <button>.",
|
|
10
|
+
"name": "as",
|
|
11
|
+
"type": "\"div\" | \"span\""
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"description": "Overrides the localized default label (`dataDisplay.avatar.agent`: ja \"AIエージェント\", en \"AI agent\", vi \"Tác tử AI\"). Omit it — the default follows the locale.",
|
|
15
|
+
"name": "children",
|
|
16
|
+
"type": "ReactNode"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"description": "Extra classes on the label root.",
|
|
20
|
+
"name": "className",
|
|
21
|
+
"type": "string"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"related": [
|
|
25
|
+
"Avatar — `kind=\"agent\"` puts the \"AI\" tag on the mark itself; use it everywhere an agent's mark appears, and add AgentBadge where its name is printed.",
|
|
26
|
+
"Badge — the general chip; AgentBadge is a fixed-meaning label built on the same chip geometry."
|
|
27
|
+
],
|
|
28
|
+
"rules": [
|
|
29
|
+
35
|
|
30
|
+
],
|
|
31
|
+
"storyPath": "data-display/avatar.tsx",
|
|
32
|
+
"tagline": "The \"AI agent\" label beside a NAME — violet outline on a transparent ground, pill, never wraps. The text-row half of telling an AI agent apart from a person; `Avatar kind=\"agent\"` is the mark half. A list that shows names uses BOTH; a place with only a mark (assignee icon column, dense cell) uses the Avatar alone.",
|
|
33
|
+
"usage": [
|
|
34
|
+
"DO put it right after the agent's name, in the same text line: `<Flex align=\"center\" gap=\"xs\"><Text>{name}</Text><AgentBadge /></Flex>`, and pair it with `<Avatar kind=\"agent\">` on the same row.",
|
|
35
|
+
"DO leave `children` empty so the label follows the locale; it is real text, so it is announced as written and never colour-only (WCAG 1.4.1).",
|
|
36
|
+
"DON'T hand-roll it as `<Badge variant=\"outline\" className=\"text-violet-600\">AI</Badge>` — the colour reads the `--agent` role through `--badge-agent-border` / `--badge-agent-foreground`, which a theme retunes once.",
|
|
37
|
+
"DON'T add it where there is no name (an icon-only column, a 24px cell) — there the Avatar's own AI tag is the marker."
|
|
38
|
+
],
|
|
39
|
+
"useCases": [
|
|
40
|
+
"A member list, a people picker, an assignee dropdown option — any row that prints a principal's name.",
|
|
41
|
+
"A comment, an activity entry or a chat message authored by an AI agent."
|
|
42
|
+
]
|
|
43
|
+
}
|
|
@@ -25,6 +25,12 @@
|
|
|
25
25
|
"required": true,
|
|
26
26
|
"type": "ReactNode"
|
|
27
27
|
},
|
|
28
|
+
{
|
|
29
|
+
"defaultValue": "true",
|
|
30
|
+
"description": "Page-level error boundary around `children` (gh#1494). A page that throws while rendering is replaced by an application ErrorSurface inside <main> (localized title + one Reload action); the sidebar, topbar and breadcrumb stay, so the user can navigate away. It resets when the URL changes, so the next visit — or Back — draws the page again. Pass PageErrorBoundary's props as an object to configure it, or `false` when the app already wraps pages in its own boundary.",
|
|
31
|
+
"name": "errorBoundary",
|
|
32
|
+
"type": "boolean | { fallback?; resetKey?; onError? }"
|
|
33
|
+
},
|
|
28
34
|
{
|
|
29
35
|
"description": "Full topbar override; else a rail is built from topbarLeft/topbarRight/logo. Omit ALL FOUR bar slots (topbar, topbarLeft, topbarRight, logo) and there is NO `<header class=\"app-topbar\">` in the DOM at all: the shell publishes `data-topbar=\"none\"` on its root and the bar's grid row collapses to zero, for a shell whose PAGE owns the top row. The one exception is the AppShell-owned drawer trigger — at or below 900px the header comes back carrying the hamburger alone, so navigation is never unreachable.",
|
|
30
36
|
"name": "topbar",
|
|
@@ -32,6 +32,12 @@
|
|
|
32
32
|
"name": "presenceLabel",
|
|
33
33
|
"type": "string"
|
|
34
34
|
},
|
|
35
|
+
{
|
|
36
|
+
"defaultValue": "\"person\"",
|
|
37
|
+
"description": "Who the mark stands for. `person` (inert default) emits no attribute and no node. `agent` marks an AI AGENT wherever a person could be mistaken for one — a member list, an assignee picker, a comment author: a white-on-violet \"AI\" pill at the TOP/inline-end corner, spilling slightly past the mark behind a --background ring (presence owns the bottom corner, so the two compose), legible at every size xs..lg, plus a localized sr-only \"AI agent\" (t(\"dataDisplay.avatar.agent\")), so the difference is never the colour alone (WCAG 1.4.1). Same two values as OrgChart `variant`. Retune with --avatar-agent-* (colour from the --agent role). Where the NAME is printed too, add `<AgentBadge />` beside it; where only the mark appears (icon column, dense cell), the Avatar alone.",
|
|
38
|
+
"name": "kind",
|
|
39
|
+
"type": "\"person\" | \"agent\""
|
|
40
|
+
},
|
|
35
41
|
{
|
|
36
42
|
"description": "Compose AvatarImage and AvatarFallback.",
|
|
37
43
|
"name": "children",
|
|
@@ -59,6 +65,7 @@
|
|
|
59
65
|
"tagline": "Avatar mark with image and fallback slots for users, teams, and entities.",
|
|
60
66
|
"usage": [
|
|
61
67
|
"DO compose Avatar > AvatarImage + AvatarFallback so broken or missing images still show a readable fallback.",
|
|
68
|
+
"DO mark an AI agent with `kind=\"agent\"` everywhere its mark appears. A list that shows NAMES uses BOTH `<Avatar kind=\"agent\">` and `<AgentBadge />` beside the name; a place with only the mark (an assignee icon column, a dense 24px cell) uses the Avatar alone — its AI tag is the marker there.",
|
|
62
69
|
"DO pass `fit=\"contain\"` on AvatarImage for a logo or app icon that is wide, transparent or off-centre — the default `cover` crops to fill, right for a face (gh#1176). A full-bleed square icon (the GoDX service icon set) keeps the default.",
|
|
63
70
|
"DO use `presence` for who is reachable RIGHT NOW — a chat member list, a DM row, a message-stream author, the topbar account mark. It is the only supported way to put a status dot on an avatar: the dot's inset is a function of the mark's own --avatar-* radius/size and of the root's clip, neither of which a page can read, which is why the hand-rolled `<span className=\"relative\"><Avatar/><span className=\"absolute -end-0.5 -bottom-0.5 size-2.5 rounded-full bg-green-500 ring-2 ring-background\"/></span>` wrapper can never be got right from outside (and fails the DS audit on the raw palette).",
|
|
64
71
|
"DON'T announce a presence CHANGE from the avatar — it carries no aria-live on purpose. A roster of 40 marks resyncing over a socket would flood a screen reader; announce the change in the consumer's own live region if the product wants it.",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"example": "import { CatalogDetail, CatalogDetailTag, Eyebrow } from \"@godxjp/ui/layout\";\n\n<CatalogDetail
|
|
2
|
+
"example": "import { CatalogDetail, CatalogDetailTag, Eyebrow } from \"@godxjp/ui/layout\";\n\n<CatalogDetail image={{ src: \"/reference.svg\", alt: \"Reference\", priority: true }} overline={<Eyebrow>Pokémon</Eyebrow>} title={name} meta={<CatalogDetailTag>SAR</CatalogDetailTag>} summary={{ label: \"Market\", price: \"¥32,800\" }} facts={[{ key: \"set\", label: \"Expansion\", value: \"151\" }]} />",
|
|
3
3
|
"group": "layout",
|
|
4
4
|
"importPath": "@godxjp/ui/layout",
|
|
5
5
|
"name": "CatalogDetail",
|
|
@@ -11,11 +11,15 @@
|
|
|
11
11
|
"type": "\"card\" | \"sealed\""
|
|
12
12
|
},
|
|
13
13
|
{
|
|
14
|
-
"description": "
|
|
14
|
+
"description": "Custom picture; used when image is omitted.",
|
|
15
15
|
"name": "media",
|
|
16
|
-
"required": true,
|
|
17
16
|
"type": "ReactNode"
|
|
18
17
|
},
|
|
18
|
+
{
|
|
19
|
+
"description": "Kit Image keyed per src. Art frame exposes data-status loading|loaded|error and aria-busy; token-driven skeleton respects reduced motion. priority requests eager/high priority. Takes precedence over media.",
|
|
20
|
+
"name": "image",
|
|
21
|
+
"type": "{ src: string; alt: string; width?: number | string; height?: number | string; fallback?: string; priority?: boolean }"
|
|
22
|
+
},
|
|
19
23
|
{
|
|
20
24
|
"description": "Save toggle over the frame.",
|
|
21
25
|
"name": "favorite",
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
"type": "\"date\" | \"week\" | \"month\" | \"quarter\" | \"year\""
|
|
124
124
|
},
|
|
125
125
|
{
|
|
126
|
-
"description": "CARDINALITY: two endpoints in one control (antd `DatePicker.RangePicker`). value/defaultValue and the callback become `DateRange`; the pair submits as `${name}_from` / `${name}_to`. Composes with `picker`, so a month range is `<DatePicker range picker=\"month\" />`. Never place two DatePickers side by side to fake this.",
|
|
126
|
+
"description": "With no confirmation, holds the first endpoint internally while open, emits a complete range or clear, and discards half-ranges on close. CARDINALITY: two endpoints in one control (antd `DatePicker.RangePicker`). value/defaultValue and the callback become `DateRange`; the pair submits as `${name}_from` / `${name}_to`. Composes with `picker`, so a month range is `<DatePicker range picker=\"month\" />`. Never place two DatePickers side by side to fake this.",
|
|
127
127
|
"name": "range",
|
|
128
128
|
"type": "boolean"
|
|
129
129
|
},
|
|
@@ -89,6 +89,7 @@
|
|
|
89
89
|
],
|
|
90
90
|
"tagline": "Dropdown menu (react-aria). Compose DropdownMenu/DropdownMenuTrigger/DropdownMenuContent/DropdownMenuItem/DropdownMenuSeparator. `trigger` picks the gestures — click (default), hover, or contextMenu, which is what replaced the deleted ContextMenu component.",
|
|
91
91
|
"usage": [
|
|
92
|
+
"DO: Use only menu collection nodes inside DropdownMenuContent. Arbitrary headers, notification lists and links belong in Popover + ListRow; development diagnostics and the dropdown-menu-non-menu-children audit rule name this fix.",
|
|
92
93
|
"DO compose the full sub-part tree: DropdownMenu (root) → DropdownMenuTrigger (with asChild to delegate to your Button/icon) → DropdownMenuContent → DropdownMenuItem / DropdownMenuSeparator / DropdownMenuLabel / DropdownMenuGroup. Omitting any level (e.g. rendering DropdownMenuContent without DropdownMenu as ancestor) breaks Radix context and the menu will not open.",
|
|
93
94
|
"DO use DropdownMenuTrigger with asChild and pass a godx-ui Button or icon Button as the child — never render a raw <button> or <div> as the trigger, and never omit asChild when the child is already a button-like element (double-button nesting breaks a11y).",
|
|
94
95
|
"DO use variant='destructive' on DropdownMenuItem for irreversible actions (delete, revoke, void) — this applies the semantic destructive colour token automatically without any className override.",
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
],
|
|
66
66
|
"tagline": "A whole-card link (gh#1435). `variant=\"journal\"`: an edge-to-edge cover, category, title, two lines of description and a footer with a circled arrow; the link is named by its title (aria-labelledby). `variant=\"spotlight\"`: kicker, title and a line beside a tilted picture. Pass the link element (router Link or `<a href>`) as `link`; the card content is rendered into it. Geometry: `--editorial-journal-*`, `--editorial-spotlight-*`.",
|
|
67
67
|
"usage": [
|
|
68
|
-
"DO lay journal cards out with `ResponsiveGrid preset=\"trio\"`."
|
|
68
|
+
"DO lay journal cards out with `ResponsiveGrid preset=\"trio\"`.",
|
|
69
|
+
"DO use kit Image with preview={false} for media inside the whole-card link. Spotlight sizes the Image frame to fill its slot, including placeholder and fallback (gh#1474)."
|
|
69
70
|
]
|
|
70
71
|
}
|
|
@@ -8,6 +8,11 @@
|
|
|
8
8
|
"importPath": "@godxjp/ui/data-display",
|
|
9
9
|
"name": "Image",
|
|
10
10
|
"props": [
|
|
11
|
+
{
|
|
12
|
+
"description": "Reports resolved status, including cached images; error remains final while showing fallback.",
|
|
13
|
+
"name": "onStatusChange",
|
|
14
|
+
"type": "(status: \"loading\" | \"loaded\" | \"error\") => void"
|
|
15
|
+
},
|
|
11
16
|
{
|
|
12
17
|
"description": "Image URL.",
|
|
13
18
|
"name": "src",
|
|
@@ -29,7 +34,7 @@
|
|
|
29
34
|
"type": "string"
|
|
30
35
|
},
|
|
31
36
|
{
|
|
32
|
-
"description": "
|
|
37
|
+
"description": "After hydration, painted over the frame while the picture loads; SSR leaves pictures uncovered. `true` = a muted block. Child content can shrink to fit the frame.",
|
|
33
38
|
"name": "placeholder",
|
|
34
39
|
"type": "ReactNode | boolean"
|
|
35
40
|
},
|
|
@@ -45,6 +45,11 @@
|
|
|
45
45
|
"name": "extra",
|
|
46
46
|
"type": "ReactNode | { start?: ReactNode; end?: ReactNode }"
|
|
47
47
|
},
|
|
48
|
+
{
|
|
49
|
+
"description": "The page's Help control (gh#1494) — a ghost Button opening a help Sheet, or a link to the manual. ONE fixed place on every page: the last item at the header row's inline end, after the `extra` actions, and still flush with that end when the actions wrap or are absent (measured 1440/768/390, 0/1/5 actions). A page passing only `help` still renders a header. Do not put Help in `extra`, in the body, or in a second header band.",
|
|
50
|
+
"name": "help",
|
|
51
|
+
"type": "ReactNode"
|
|
52
|
+
},
|
|
48
53
|
{
|
|
49
54
|
"description": "FIXED chrome band between the page header and the body — a filter strip, a status bar, a \"channel workflow\" rail. It is a SIBLING of the body, not content inside it: with `fill` the body is the scroll viewport, so the band is `flex: none` OUTSIDE the scroller and never scrolls away or gets slid under. Shares the page gutters and the `measure` cap with the header and the body (the three bands line up on both edges), goes full-bleed under variant=\"flush\" (wrap padded strips in PageContainer.Inset), and renders NOTHING when omitted — no wrapper, no gap. Its BOX sits FLUSH against the header above and the body below (chrome is attached, not a third page section floating between two voids, so the band cancels the container gap from itself), and by default its inset gives the band's CONTENT that gap back: a plain filter strip (a Segmented, a row of filters) sits one band gap from the header and from the body (gh#1323 — it used to touch both, 0px). A theme that paints or rules the band sets a tighter inset with `--page-toolbar-pad-block`.",
|
|
50
55
|
"name": "toolbar",
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"example": "import { AppShell, PageErrorBoundary } from \"@godxjp/ui/layout\";\n\n// Inside AppShell nothing is needed: a throwing page keeps the shell.\n<AppShell sidebar={sidebar} topbar={topbar} errorBoundary={{ onError: report }}>\n {page}\n</AppShell>;\n\n// Outside AppShell, wrap the page yourself.\n<PageErrorBoundary onError={report}>{page}</PageErrorBoundary>;",
|
|
3
|
+
"group": "layout",
|
|
4
|
+
"importPath": "@godxjp/ui/layout",
|
|
5
|
+
"name": "PageErrorBoundary",
|
|
6
|
+
"props": [
|
|
7
|
+
{
|
|
8
|
+
"description": "The page.",
|
|
9
|
+
"name": "children",
|
|
10
|
+
"type": "ReactNode"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"description": "What replaces the page that threw. Default: <ErrorSurface mode=\"application\" status={500} titleLevel={1}> with the kit's localized title/description and ONE 'Reload page' action. The function form gets the error and a `reset()` that draws the page again without a reload.",
|
|
14
|
+
"name": "fallback",
|
|
15
|
+
"type": "ReactNode | ({ error, reset }) => ReactNode"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"description": "Draw the page again when this value changes (Object.is). The boundary ALREADY resets when the URL changes — it records the URL it failed on and resets on the next render under a different one, so it needs no router integration; pass a key only for a change the URL does not show.",
|
|
19
|
+
"name": "resetKey",
|
|
20
|
+
"type": "unknown"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"description": "Report the error (an error tracker). Replaces the development-time console.error.",
|
|
24
|
+
"name": "onError",
|
|
25
|
+
"type": "(error: unknown, info: React.ErrorInfo) => void"
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"related": [
|
|
29
|
+
"AppShell — wraps its children in a PageErrorBoundary by default (`errorBoundary`).",
|
|
30
|
+
"ErrorSurface — the default fallback; use it directly for an HTTP 400/403/404/500/503 page the server reports."
|
|
31
|
+
],
|
|
32
|
+
"rules": [
|
|
33
|
+
23,
|
|
34
|
+
24
|
|
35
|
+
],
|
|
36
|
+
"storyPath": "layout/page-error-boundary.tsx",
|
|
37
|
+
"tagline": "Page-level React error boundary (gh#1494): a page that throws while rendering is replaced by an application ErrorSurface and the shell around it stays. AppShell wraps its children in one by default; use this directly only around a page outside AppShell.",
|
|
38
|
+
"usage": [
|
|
39
|
+
"DO rely on AppShell's built-in boundary: every page inside AppShell is already covered. Configure it with AppShell `errorBoundary={{ onError: report }}`.",
|
|
40
|
+
"DO wrap a page that renders OUTSIDE AppShell (a CenteredShell page, an embedded view) in <PageErrorBoundary> yourself.",
|
|
41
|
+
"DO NOT wrap every Card in a boundary: it is PAGE-level. An in-page query failure is DataState / Alert.QueryError, not a render error.",
|
|
42
|
+
"DO NOT key the boundary on the URL yourself to make it reset — it already resets on navigation."
|
|
43
|
+
],
|
|
44
|
+
"useCases": [
|
|
45
|
+
"A list page whose row renderer hits an unexpected null: the page area shows the ErrorSurface, the sidebar still works, and navigating to another page draws that page normally.",
|
|
46
|
+
"Error reporting: <AppShell errorBoundary={{ onError: (error) => Sentry.captureException(error) }} …>."
|
|
47
|
+
]
|
|
48
|
+
}
|
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
"importPath": "@godxjp/ui/navigation",
|
|
5
5
|
"name": "Pagination",
|
|
6
6
|
"props": [
|
|
7
|
+
{
|
|
8
|
+
"description": "Pointer enter, focus or touch start on enabled page/previous/next controls, including simple and responsive forms. May repeat: preload/cache the target without changing value. Disabled or out-of-range targets do not emit.",
|
|
9
|
+
"name": "onPageIntent",
|
|
10
|
+
"type": "(page: number) => void"
|
|
11
|
+
},
|
|
7
12
|
{
|
|
8
13
|
"description": "Tên khả truy cập của landmark phân trang. Bắt buộc khi một trang có nhiều bộ phân trang.",
|
|
9
14
|
"name": "ariaLabel",
|
|
@@ -113,6 +113,7 @@
|
|
|
113
113
|
],
|
|
114
114
|
"tagline": "React Aria floating panel anchored to a trigger — always compose with PopoverTrigger + PopoverContent; never use a raw div overlay.",
|
|
115
115
|
"usage": [
|
|
116
|
+
"DO: PopoverContent scrolls automatically when its available height caps content. Focus rings remain contained at scroll edges, including flush panels.",
|
|
116
117
|
"HOVER CARD: `<Popover openOn=\"hover\"><PopoverTrigger asChild><a href=…>@yamada</a></PopoverTrigger><PopoverContent>…</PopoverContent></Popover>` for RICH preview content (an avatar + bio, an entity summary). For a short plain-text hint use Tooltip. DON'T put essential information only in a hover card — touch never opens it; make the same content reachable from the trigger's destination. There is no `HoverCard` component.",
|
|
117
118
|
"DO compose: <Popover> → <PopoverTrigger asChild> → <Button/> and <PopoverContent>. All four parts are required for any popover to function; omitting PopoverTrigger or PopoverContent produces nothing.",
|
|
118
119
|
"DO set `<PopoverContent width=\"auto\">` when the child brings its own measure — a Calendar, a chart, a fixed-width preview. The panel's own 18rem clips them, and a `w-*` utility on className is a per-call-site constant no service theme can retune, which is exactly what `flush` exists to avoid on the padding axis. `width=\"trigger\"` matches the anchor, the shape every select-like control wants.",
|
|
@@ -268,7 +268,7 @@
|
|
|
268
268
|
"type": "React.ReactNode"
|
|
269
269
|
},
|
|
270
270
|
{
|
|
271
|
-
"description": "antd `popupMatchSelectWidth`. true (default)
|
|
271
|
+
"description": "antd `popupMatchSelectWidth`. true (default): the trigger width is the floor and the popup grows to its longest row, up to --select-content-max-width (32rem) and the viewport less --select-content-viewport-inset, then wraps rows. false lets it hug its rows below the trigger width; a number pins it to that many pixels. The width never depends on where the popup is placed, so it cannot change while open.",
|
|
272
272
|
"name": "popupMatchSelectWidth",
|
|
273
273
|
"type": "boolean | number"
|
|
274
274
|
},
|
|
@@ -398,6 +398,7 @@
|
|
|
398
398
|
],
|
|
399
399
|
"tagline": "Polymorphic single-select: pass options/loadOptions for the data-driven (Ant-style) API, or compose sub-parts manually — never use a raw <select>.",
|
|
400
400
|
"usage": [
|
|
401
|
+
"DO: Searchable popup widths, including numeric popupMatchSelectWidth, are capped by --search-select-panel-max-width and --search-select-panel-viewport-inset, using the viewport width excluding classic scrollbars.",
|
|
401
402
|
"Coarse pointers: affix actions use --control-affix-touch-target-size (44px by default); text space is reserved separately. Fine-pointer geometry is unchanged.",
|
|
402
403
|
"FREE-TEXT TAGS WITH NO LIST (keywords, email recipients, labels typed from scratch): `<Select mode=\"tags\" open={false} value={tags} onValueChange={setTags} />` — the inline chip field. Use plain `mode=\"tags\"` (popup) only when there is a list of existing tags to pick from. There is no `TagInput` component.",
|
|
403
404
|
"DO use the data-driven API (options/loadOptions) for straightforward selects — it handles grouping, search, async, and custom rendering automatically. Only reach for the compound API when you need to inject arbitrary content into the trigger or listbox.",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
{
|
|
19
19
|
"defaultValue": "true",
|
|
20
|
-
"description": "Draw every visible toast whole, stacked with a gap. Default `true` (gh#1387): Sonner's collapsed deck (`expand={false}`) keeps earlier toasts as cards peeking behind the front one with their text hidden, which reads as an empty box. Pass `expand={false}` to opt back into the deck.",
|
|
20
|
+
"description": "Draw every visible toast whole, stacked with a gap. Default `true` (gh#1387): Sonner's collapsed deck (`expand={false}`) keeps earlier toasts as cards peeking behind the front one with their text hidden, which reads as an empty box. Pass `expand={false}` to opt back into the deck. While a MODAL Dialog or Sheet is open the toaster takes no pointer events (gh#1477): a toast drawn over the modal's footer stays visible and announced, and the click reaches the footer action — do not work around an overlap with `expand={false}`.",
|
|
21
21
|
"name": "expand",
|
|
22
22
|
"type": "boolean"
|
|
23
23
|
},
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"usage": [
|
|
43
43
|
"DO: Mount exactly ONE `<Toaster richColors />` at the app root (e.g. inside your layout or AppShell children). Multiple mounts create duplicate toast stacks — there is no provider context, only DOM portals.",
|
|
44
44
|
"DO: Import `toast` from `\"@godxjp/ui/feedback\"` to fire toasts anywhere: `toast.success(…)`, `toast.error(…)`, `toast.warning(…)`, `toast.info(…)`, `toast.loading(…)`, `toast.promise(…)`. It is Sonner's own API with one house default: `toast.error` and `toast.warning` carry a close button (opt out per call with `{ closeButton: false }`), success/info stay auto-dismiss only (gh#1253).",
|
|
45
|
-
"DON'T: Import `toast` from `\"sonner\"` directly —
|
|
45
|
+
"DON'T: Import `toast` from `\"sonner\"` directly — a consumer-installed version can own a different toast store from the kit Toaster, silently hiding toasts. Use `import { toast } from \"@godxjp/ui\"` (also available from `@godxjp/ui/feedback`); this also preserves close-button defaults. Also note `toast.promise` settling into an error does not gain the button; pass `closeButton` there yourself if the failure must stay dismissible.",
|
|
46
46
|
"DO: Tune how long toasts stay with the `--toast-duration` token in the theme (default 4000ms) rather than a `duration` prop on every mount. Never truncate a toast's body — it wraps.",
|
|
47
47
|
"DO: Let the wrapper handle theming — it uses `useDocumentTheme()` to sync with the document `dark` class and `prefers-color-scheme` automatically. Never pass a hardcoded `theme` prop unless you are deliberately overriding.",
|
|
48
48
|
"DON'T: Use `Toaster` for persistent errors or blocking confirmations. Toasts auto-dismiss; they are not a substitute for `Alert` (inline persistent warnings) or `Dialog` (decisions requiring user input).",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"type": "FilterBarSearchProp"
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
|
-
"description": "Typed model — labelled domain-neutral Select filters rendered after the search slot in array order. Each: { value (stable identity), label (rendered as the control's REAL <label htmlFor> — WCAG 2.5.3), options, selected/defaultSelected/onSelectedChange, placeholder, disabled }. Width is token-owned (--filter-bar-filter-width).",
|
|
37
|
+
"description": "Typed model — labelled domain-neutral Select filters rendered after the search slot in array order. Each: { value (stable identity), label (rendered as the control's REAL <label htmlFor> — WCAG 2.5.3), options, selected/defaultSelected/onSelectedChange, placeholder, disabled, required, allowClear }. Width is token-owned (--filter-bar-filter-width). A filter shows a ✕ by default (no filter is its resting state); a SCOPE filter that is never empty (branch, month) passes `required` — no ✕ and `aria-required` on the control — and `allowClear: false` hides the ✕ alone (gh#1495). Never rebuild a filter by hand on the bar's internal class to drop the ✕.",
|
|
38
38
|
"name": "filters",
|
|
39
39
|
"type": "FilterBarFilterProp[]"
|
|
40
40
|
},
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
{
|
|
41
41
|
"defaultValue": "\"scroll\"",
|
|
42
|
-
"description": "What a bar that does not fit does with the cells that do not fit (gh#728). scroll (default) lets the BAR scroll on the inline axis while the start and end clusters keep their cells whole — every cell stays in the DOM and in the accessibility tree, Tab reaches each one in order, and the browser scrolls a focused cell into view; the scrollbar is suppressed (a horizontal bar inside a 48px chrome row would eat the height that caused the deficit), so the pointer affordance is drag/wheel. clip is the pre-gh#728 behaviour: a cell past the cluster's edge is simply not painted — still focusable, still announced, invisible and unreachable by pointer. Independent of TopbarItem hideBelow, which REMOVES a cell at a step; this is only about what happens once there is no budget left.",
|
|
42
|
+
"description": "What a bar that does not fit does with the cells that do not fit (gh#728). scroll (default) lets the BAR scroll on the inline axis while the start and end clusters keep their cells whole — every cell stays in the DOM and in the accessibility tree, Tab reaches each one in order, and the browser scrolls a focused cell into view; the scrollbar is suppressed (a horizontal bar inside a 48px chrome row would eat the height that caused the deficit), so the pointer affordance is drag/wheel. clip is the pre-gh#728 behaviour: a cell past the cluster's edge is simply not painted — still focusable, still announced, invisible and unreachable by pointer. Independent of TopbarItem hideBelow, which REMOVES a cell at a step; this is only about what happens once there is no budget left. menu (gh#914) folds every cluster into ONE \"more\" cell when the bar does not fit; folding MOVES the controls (into the open menu, or a hidden holder while it is closed) and never unmounts them, so a CommandPalette in `start` keeps its ⌘K shortcut and a control keeps its state across folds (gh#1478).",
|
|
43
43
|
"name": "overflow",
|
|
44
44
|
"type": "\"scroll\" | \"clip\" | \"menu\""
|
|
45
45
|
},
|
|
@@ -329,6 +329,11 @@
|
|
|
329
329
|
"name": "ErrorSurface",
|
|
330
330
|
"tagline": "Package-owned semantic exception surface for 400 / 403 / 404 / 500 / 503."
|
|
331
331
|
},
|
|
332
|
+
{
|
|
333
|
+
"group": "layout",
|
|
334
|
+
"name": "PageErrorBoundary",
|
|
335
|
+
"tagline": "Page-level React error boundary (gh#1494): a page that throws while rendering is replaced by an application ErrorSurface and the shell around it stays."
|
|
336
|
+
},
|
|
332
337
|
{
|
|
333
338
|
"group": "layout",
|
|
334
339
|
"name": "LegalDocumentShell",
|
|
@@ -437,6 +442,11 @@
|
|
|
437
442
|
"name": "Badge",
|
|
438
443
|
"tagline": "Plain or lifecycle badge."
|
|
439
444
|
},
|
|
445
|
+
{
|
|
446
|
+
"group": "data-display",
|
|
447
|
+
"name": "AgentBadge",
|
|
448
|
+
"tagline": "The \"AI agent\" label beside a NAME — violet outline on a transparent ground, pill, never wraps."
|
|
449
|
+
},
|
|
440
450
|
{
|
|
441
451
|
"group": "data-display",
|
|
442
452
|
"name": "Legend",
|