@godxjp/ui 33.22.2 → 33.24.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 +4 -4
- package/agent/DESIGN.md +1 -1
- package/agent/START-HERE.md +7 -7
- package/agent/components/AgentBadge.json +43 -0
- package/agent/components/AppShell.json +6 -0
- package/agent/components/Avatar.json +7 -0
- package/agent/components/PageContainer.json +5 -0
- package/agent/components/PageErrorBoundary.json +48 -0
- package/agent/components/Toaster.json +1 -1
- 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 +112 -3
- package/agent/index.json +7 -7
- package/agent/llms.txt +6 -6
- package/agent/tokens.json +84 -0
- 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.js +1 -1
- package/dist/components/data-display/index.d.ts +2 -2
- package/dist/components/data-display/index.js +2 -1
- package/dist/components/data-entry/record-picker.js +122 -98
- package/dist/components/data-entry/select.js +13 -3
- package/dist/components/layout/app-shell.d.ts +1 -1
- package/dist/components/layout/app-shell.js +3 -1
- 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/toolbar.js +2 -1
- package/dist/contracts/measurement.json +1 -1
- package/dist/i18n/messages/en.json +6 -0
- package/dist/i18n/messages/ja.json +6 -0
- package/dist/i18n/messages/vi.json +6 -0
- package/dist/props/components/data-display.prop.d.ts +27 -0
- package/dist/props/components/layout.prop.d.ts +45 -0
- package/dist/props/components/navigation.prop.d.ts +12 -1
- package/dist/props/registry.d.ts +50 -2
- package/dist/props/registry.js +72 -3
- package/dist/styles/alert-layout.css +4 -0
- package/dist/styles/badge-layout.css +14 -0
- package/dist/styles/data-display-layout.css +44 -0
- package/dist/styles/icon-layout.css +3 -0
- package/dist/styles/layers.json +22 -2
- package/dist/styles/layout.css +11 -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/data-display.css +9 -0
- package/dist/tokens/components/shell.css +2 -0
- package/dist/tokens/foundation.css +8 -0
- package/docs/CONSUMER-RULES.md +1 -1
- package/package.json +2 -2
- package/scripts/consumer-rule.md +1 -1
- 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, 3198 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,10 +53,10 @@ 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 3198 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
61
|
| [`agent/rules.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/rules.json) | 23 KB | the 44 cardinal rules |
|
|
62
62
|
<!-- prettier-ignore-end -->
|
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.24.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.
|
|
@@ -52,7 +52,7 @@ screen anatomy, the visual target the rules below do not give you. Then fetch in
|
|
|
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` — 3198 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
|
+
2862 `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` | 2862 | 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.",
|
|
@@ -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
|
+
}
|
|
@@ -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
|
},
|
|
@@ -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",
|
package/agent/components.json
CHANGED
|
@@ -692,6 +692,11 @@
|
|
|
692
692
|
"name": "extra",
|
|
693
693
|
"type": "ReactNode | { start?: ReactNode; end?: ReactNode }"
|
|
694
694
|
},
|
|
695
|
+
{
|
|
696
|
+
"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.",
|
|
697
|
+
"name": "help",
|
|
698
|
+
"type": "ReactNode"
|
|
699
|
+
},
|
|
695
700
|
{
|
|
696
701
|
"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`.",
|
|
697
702
|
"name": "toolbar",
|
|
@@ -3244,6 +3249,12 @@
|
|
|
3244
3249
|
"required": true,
|
|
3245
3250
|
"type": "ReactNode"
|
|
3246
3251
|
},
|
|
3252
|
+
{
|
|
3253
|
+
"defaultValue": "true",
|
|
3254
|
+
"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.",
|
|
3255
|
+
"name": "errorBoundary",
|
|
3256
|
+
"type": "boolean | { fallback?; resetKey?; onError? }"
|
|
3257
|
+
},
|
|
3247
3258
|
{
|
|
3248
3259
|
"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.",
|
|
3249
3260
|
"name": "topbar",
|
|
@@ -3767,7 +3778,7 @@
|
|
|
3767
3778
|
},
|
|
3768
3779
|
{
|
|
3769
3780
|
"defaultValue": "\"scroll\"",
|
|
3770
|
-
"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.",
|
|
3781
|
+
"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).",
|
|
3771
3782
|
"name": "overflow",
|
|
3772
3783
|
"type": "\"scroll\" | \"clip\" | \"menu\""
|
|
3773
3784
|
},
|
|
@@ -4426,6 +4437,54 @@
|
|
|
4426
4437
|
"Unexpected failure with a support correlation id: <ErrorSurface mode=\"system\" status={500} requestId=\"01J9Z0…\" action={<Button onClick={reload}>Reload</Button>} />."
|
|
4427
4438
|
]
|
|
4428
4439
|
},
|
|
4440
|
+
{
|
|
4441
|
+
"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>;",
|
|
4442
|
+
"group": "layout",
|
|
4443
|
+
"importPath": "@godxjp/ui/layout",
|
|
4444
|
+
"name": "PageErrorBoundary",
|
|
4445
|
+
"props": [
|
|
4446
|
+
{
|
|
4447
|
+
"description": "The page.",
|
|
4448
|
+
"name": "children",
|
|
4449
|
+
"type": "ReactNode"
|
|
4450
|
+
},
|
|
4451
|
+
{
|
|
4452
|
+
"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.",
|
|
4453
|
+
"name": "fallback",
|
|
4454
|
+
"type": "ReactNode | ({ error, reset }) => ReactNode"
|
|
4455
|
+
},
|
|
4456
|
+
{
|
|
4457
|
+
"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.",
|
|
4458
|
+
"name": "resetKey",
|
|
4459
|
+
"type": "unknown"
|
|
4460
|
+
},
|
|
4461
|
+
{
|
|
4462
|
+
"description": "Report the error (an error tracker). Replaces the development-time console.error.",
|
|
4463
|
+
"name": "onError",
|
|
4464
|
+
"type": "(error: unknown, info: React.ErrorInfo) => void"
|
|
4465
|
+
}
|
|
4466
|
+
],
|
|
4467
|
+
"related": [
|
|
4468
|
+
"AppShell — wraps its children in a PageErrorBoundary by default (`errorBoundary`).",
|
|
4469
|
+
"ErrorSurface — the default fallback; use it directly for an HTTP 400/403/404/500/503 page the server reports."
|
|
4470
|
+
],
|
|
4471
|
+
"rules": [
|
|
4472
|
+
23,
|
|
4473
|
+
24
|
|
4474
|
+
],
|
|
4475
|
+
"storyPath": "layout/page-error-boundary.tsx",
|
|
4476
|
+
"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.",
|
|
4477
|
+
"usage": [
|
|
4478
|
+
"DO rely on AppShell's built-in boundary: every page inside AppShell is already covered. Configure it with AppShell `errorBoundary={{ onError: report }}`.",
|
|
4479
|
+
"DO wrap a page that renders OUTSIDE AppShell (a CenteredShell page, an embedded view) in <PageErrorBoundary> yourself.",
|
|
4480
|
+
"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.",
|
|
4481
|
+
"DO NOT key the boundary on the URL yourself to make it reset — it already resets on navigation."
|
|
4482
|
+
],
|
|
4483
|
+
"useCases": [
|
|
4484
|
+
"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.",
|
|
4485
|
+
"Error reporting: <AppShell errorBoundary={{ onError: (error) => Sentry.captureException(error) }} …>."
|
|
4486
|
+
]
|
|
4487
|
+
},
|
|
4429
4488
|
{
|
|
4430
4489
|
"example": "import { CenteredShell, Flex, Topbar } from \"@godxjp/ui/layout\";\nimport { LegalDocumentShell } from \"@godxjp/ui/lab\";\nimport { Button, Text } from \"@godxjp/ui/general\";\nimport { useState } from \"react\";\n\nexport function TermsPage() {\n const [activeSection, setActiveSection] = useState(\"acceptance\");\n\n return (\n <CenteredShell width=\"lg\" topbar={<Topbar start={<Brand />} />}>\n <LegalDocumentShell\n title=\"利用規約\"\n version=\"2.4\"\n effectiveDate=\"2026-04-01\"\n summary=\"本規約は、当社が提供するサービスの利用条件を定めるものです。\"\n contentsLabel=\"目次\"\n activeSection={activeSection}\n onActiveSectionChange={setActiveSection}\n sections={[\n { id: \"acceptance\", title: \"第1条(本規約への同意)\", content: <Text as=\"p\">…</Text> },\n { id: \"accounts\", title: \"第2条(アカウントの管理)\", content: <Text as=\"p\">…</Text> },\n ]}\n documentNavigation={\n <Flex direction=\"col\" gap=\"xs\" role=\"group\" aria-label=\"法的文書\">\n <Button variant=\"secondary\" size=\"sm\" fullWidth aria-current=\"page\">利用規約</Button>\n <Button variant=\"ghost\" size=\"sm\" fullWidth>プライバシーポリシー</Button>\n </Flex>\n }\n footerAction={<Button size=\"sm\">同意する</Button>}\n />\n </CenteredShell>\n );\n}",
|
|
4431
4490
|
"group": "layout",
|
|
@@ -6195,6 +6254,49 @@
|
|
|
6195
6254
|
"A status or category an administrator coloured themselves, in an issue tracker or a CRM — `<Badge shape=\"pill\" color={status.color}>{status.name}</Badge>`. The colour comes out of a picker and is stored on the row, so it cannot be mapped to a tone."
|
|
6196
6255
|
]
|
|
6197
6256
|
},
|
|
6257
|
+
{
|
|
6258
|
+
"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>",
|
|
6259
|
+
"group": "data-display",
|
|
6260
|
+
"importPath": "@godxjp/ui/data-display",
|
|
6261
|
+
"name": "AgentBadge",
|
|
6262
|
+
"props": [
|
|
6263
|
+
{
|
|
6264
|
+
"defaultValue": "\"span\"",
|
|
6265
|
+
"description": "Render element. `span` (default) because the label sits in a name's text line, often inside a link or a <button>.",
|
|
6266
|
+
"name": "as",
|
|
6267
|
+
"type": "\"div\" | \"span\""
|
|
6268
|
+
},
|
|
6269
|
+
{
|
|
6270
|
+
"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.",
|
|
6271
|
+
"name": "children",
|
|
6272
|
+
"type": "ReactNode"
|
|
6273
|
+
},
|
|
6274
|
+
{
|
|
6275
|
+
"description": "Extra classes on the label root.",
|
|
6276
|
+
"name": "className",
|
|
6277
|
+
"type": "string"
|
|
6278
|
+
}
|
|
6279
|
+
],
|
|
6280
|
+
"related": [
|
|
6281
|
+
"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.",
|
|
6282
|
+
"Badge — the general chip; AgentBadge is a fixed-meaning label built on the same chip geometry."
|
|
6283
|
+
],
|
|
6284
|
+
"rules": [
|
|
6285
|
+
35
|
|
6286
|
+
],
|
|
6287
|
+
"storyPath": "data-display/avatar.tsx",
|
|
6288
|
+
"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.",
|
|
6289
|
+
"usage": [
|
|
6290
|
+
"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.",
|
|
6291
|
+
"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).",
|
|
6292
|
+
"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.",
|
|
6293
|
+
"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."
|
|
6294
|
+
],
|
|
6295
|
+
"useCases": [
|
|
6296
|
+
"A member list, a people picker, an assignee dropdown option — any row that prints a principal's name.",
|
|
6297
|
+
"A comment, an activity entry or a chat message authored by an AI agent."
|
|
6298
|
+
]
|
|
6299
|
+
},
|
|
6198
6300
|
{
|
|
6199
6301
|
"example": "import { Legend } from \"@godxjp/ui/data-display\";\n\n<CardAction>\n <Legend\n items={[\n { tone: \"destructive\", label: \"期限超過\" },\n { tone: \"warning\", label: \"期限間近\" },\n { tone: \"success\", label: \"対応済\" },\n ]}\n />\n</CardAction>",
|
|
6200
6302
|
"group": "data-display",
|
|
@@ -10578,7 +10680,7 @@
|
|
|
10578
10680
|
},
|
|
10579
10681
|
{
|
|
10580
10682
|
"defaultValue": "true",
|
|
10581
|
-
"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.",
|
|
10683
|
+
"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}`.",
|
|
10582
10684
|
"name": "expand",
|
|
10583
10685
|
"type": "boolean"
|
|
10584
10686
|
},
|
|
@@ -11174,7 +11276,7 @@
|
|
|
11174
11276
|
"type": "FilterBarSearchProp"
|
|
11175
11277
|
},
|
|
11176
11278
|
{
|
|
11177
|
-
"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).",
|
|
11279
|
+
"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 ✕.",
|
|
11178
11280
|
"name": "filters",
|
|
11179
11281
|
"type": "FilterBarFilterProp[]"
|
|
11180
11282
|
},
|
|
@@ -14378,6 +14480,12 @@
|
|
|
14378
14480
|
"name": "presenceLabel",
|
|
14379
14481
|
"type": "string"
|
|
14380
14482
|
},
|
|
14483
|
+
{
|
|
14484
|
+
"defaultValue": "\"person\"",
|
|
14485
|
+
"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.",
|
|
14486
|
+
"name": "kind",
|
|
14487
|
+
"type": "\"person\" | \"agent\""
|
|
14488
|
+
},
|
|
14381
14489
|
{
|
|
14382
14490
|
"description": "Compose AvatarImage and AvatarFallback.",
|
|
14383
14491
|
"name": "children",
|
|
@@ -14405,6 +14513,7 @@
|
|
|
14405
14513
|
"tagline": "Avatar mark with image and fallback slots for users, teams, and entities.",
|
|
14406
14514
|
"usage": [
|
|
14407
14515
|
"DO compose Avatar > AvatarImage + AvatarFallback so broken or missing images still show a readable fallback.",
|
|
14516
|
+
"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.",
|
|
14408
14517
|
"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.",
|
|
14409
14518
|
"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).",
|
|
14410
14519
|
"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.",
|
package/agent/index.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"counts": {
|
|
3
3
|
"anti-ai-tells": 35,
|
|
4
|
-
"components":
|
|
4
|
+
"components": 212,
|
|
5
5
|
"patterns": 28,
|
|
6
6
|
"rules": 44,
|
|
7
|
-
"tokens":
|
|
7
|
+
"tokens": 3198,
|
|
8
8
|
"vocabulary": 16
|
|
9
9
|
},
|
|
10
10
|
"design": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/DESIGN.md",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
"file": "components-index.json",
|
|
19
|
-
"note": "
|
|
19
|
+
"note": "47 KB — name + group + tagline for all 212. FETCH THIS FIRST, then fetch only the components you chose.",
|
|
20
20
|
"url": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/components-index.json"
|
|
21
21
|
},
|
|
22
22
|
{
|
|
@@ -54,19 +54,19 @@
|
|
|
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/v33.
|
|
57
|
+
"pinned": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/v33.24.0/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",
|
|
61
61
|
"tokenTiers": {
|
|
62
62
|
"component": "per-part knobs, --{component}-{part}-{property}; usually leave these alone",
|
|
63
63
|
"counts": {
|
|
64
|
-
"component":
|
|
65
|
-
"foundation":
|
|
64
|
+
"component": 2862,
|
|
65
|
+
"foundation": 223,
|
|
66
66
|
"semantic": 113
|
|
67
67
|
},
|
|
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": "33.
|
|
71
|
+
"version": "33.24.0"
|
|
72
72
|
}
|
package/agent/llms.txt
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# @godxjp/ui
|
|
2
2
|
|
|
3
|
-
> A Japanese-enterprise React design system:
|
|
4
|
-
> 44 cardinal rules. This file is the entry point for AI agents. Catalog version 33.
|
|
3
|
+
> A Japanese-enterprise React design system: 212 components, 3198 design tokens,
|
|
4
|
+
> 44 cardinal rules. This file is the entry point for AI agents. Catalog version 33.24.0.
|
|
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@33.
|
|
7
|
+
(`npx @godxjp/ui-mcp@33.24.0`). It is searchable and version-locked. These files exist for agents
|
|
8
8
|
that can only fetch URLs.
|
|
9
9
|
|
|
10
10
|
## Start
|
|
@@ -16,10 +16,10 @@ that can only fetch URLs.
|
|
|
16
16
|
## Catalog
|
|
17
17
|
|
|
18
18
|
- [patterns-index.json](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/patterns-index.json): 28 whole-task patterns (name, tagline, tags). Start here when the task is a TASK — "build a settings page" — then fetch `patterns/<name>.json` for complete code.
|
|
19
|
-
- [components-index.json](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/components-index.json):
|
|
19
|
+
- [components-index.json](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/components-index.json): 47 KB — all 212 components as name, group, tagline, plus `absorbed`: the names that do NOT exist and map to it (`Combobox` → `Select`).
|
|
20
20
|
- [components/<Name>.json](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/components/Select.json): one file per component (1 KB–38 KB, median 5 KB). Read the index, then fetch only the ones you chose — this is the selective route, and the reason you do not need the blob.
|
|
21
21
|
- [components.json](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/components.json): 1.4 MB — every entry in one file. Most URL fetchers truncate a response this size without saying so; prefer the per-component files.
|
|
22
|
-
- [tokens.json](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/tokens.json): every design token with its value, the reason it exists, and its `tier` —
|
|
22
|
+
- [tokens.json](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/tokens.json): every design token with its value, the reason it exists, and its `tier` — 223 `foundation` seeds (`--primary`, `--background`, `--radius`: set these when you are handed a brand), 113 `semantic` roles, 2862 `component` knobs.
|
|
23
23
|
- [vocabulary.json](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/vocabulary.json): the controlled prop vocabulary — which prop name means what, across every component.
|
|
24
24
|
- [rules.json](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/rules.json): 44 cardinal rules.
|
|
25
25
|
- [anti-ai-tells.json](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/anti-ai-tells.json): 35 shapes that make generated UI look generated, each with its fix.
|
|
@@ -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/v33.
|
|
30
|
+
the tag: `.../godx-jp/godxjp-ui/v33.24.0/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.
|