@godxjp/ui 23.2.1 → 23.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/timezones.js +2 -1
- package/dist/components/charts/chart-cartesian.js +2 -4
- package/dist/components/charts/chart-frame.js +2 -1
- package/dist/components/data-display/card.d.ts +87 -1
- package/dist/components/data-display/card.js +88 -15
- package/dist/components/data-display/index.d.ts +5 -1
- package/dist/components/data-display/index.js +5 -0
- package/dist/components/data-display/thought-chain.d.ts +42 -0
- package/dist/components/data-display/thought-chain.js +177 -0
- package/dist/components/data-display/welcome.d.ts +26 -0
- package/dist/components/data-display/welcome.js +37 -0
- package/dist/components/data-entry/attachments.d.ts +19 -0
- package/dist/components/data-entry/attachments.js +322 -0
- package/dist/components/data-entry/date-picker.js +12 -14
- package/dist/components/data-entry/index.d.ts +2 -0
- package/dist/components/data-entry/index.js +2 -0
- package/dist/components/data-entry/number-input.js +2 -1
- package/dist/components/feedback/dialog.d.ts +10 -7
- package/dist/components/feedback/dialog.js +40 -17
- package/dist/components/feedback/index.d.ts +3 -3
- package/dist/components/feedback/index.js +2 -0
- package/dist/components/feedback/skeleton.d.ts +11 -2
- package/dist/components/feedback/skeleton.js +8 -0
- package/dist/components/general/actions.d.ts +59 -0
- package/dist/components/general/actions.js +253 -0
- package/dist/components/general/activity.js +1 -0
- package/dist/components/general/button.js +2 -1
- package/dist/components/general/float-button.d.ts +41 -0
- package/dist/components/general/float-button.js +336 -0
- package/dist/components/general/index.d.ts +6 -2
- package/dist/components/general/index.js +12 -1
- package/dist/components/general/typography.d.ts +79 -4
- package/dist/components/general/typography.js +598 -54
- package/dist/components/layout/draggable-panel.d.ts +18 -0
- package/dist/components/layout/draggable-panel.js +189 -0
- package/dist/components/layout/error-surface.js +3 -2
- package/dist/components/layout/index.d.ts +2 -0
- package/dist/components/layout/index.js +2 -0
- package/dist/components/navigation/conversations.d.ts +39 -0
- package/dist/components/navigation/conversations.js +371 -0
- package/dist/components/navigation/index.d.ts +2 -0
- package/dist/components/navigation/index.js +2 -0
- package/dist/components/ui/card.js +1 -0
- package/dist/components/ui/toggle.js +2 -1
- package/dist/i18n/messages/en.json +53 -0
- package/dist/i18n/messages/ja.json +53 -0
- package/dist/i18n/messages/vi.json +53 -0
- package/dist/i18n/translate.js +3 -2
- package/dist/lib/datetime/picker-format.js +2 -1
- package/dist/lib/format.js +3 -2
- package/dist/lib/intl-cache.d.ts +32 -0
- package/dist/lib/intl-cache.js +29 -0
- package/dist/props/components/data-display.prop.d.ts +143 -1
- package/dist/props/components/data-entry.prop.d.ts +87 -0
- package/dist/props/components/feedback.prop.d.ts +53 -1
- package/dist/props/components/general.prop.d.ts +440 -3
- package/dist/props/components/index.d.ts +2 -2
- package/dist/props/components/layout.prop.d.ts +63 -1
- package/dist/props/components/navigation.prop.d.ts +150 -0
- package/dist/props/registry.d.ts +431 -0
- package/dist/props/registry.js +551 -0
- package/dist/props/vocabulary/index.d.ts +1 -1
- package/dist/props/vocabulary/interaction.prop.d.ts +113 -0
- package/dist/styles/alert-layout.css +22 -0
- package/dist/styles/card-layout.css +34 -0
- package/dist/styles/core.css +1 -0
- package/dist/styles/data-display-layout.css +236 -0
- package/dist/styles/float-button-layout.css +168 -0
- package/dist/styles/form-layout.css +11 -1
- package/dist/styles/index.css +1 -0
- package/dist/styles/layout.css +196 -0
- package/dist/styles/navigation-layout.css +139 -0
- package/dist/styles/text-layout.css +156 -0
- package/dist/tokens/axes.css +5 -0
- package/dist/tokens/base.css +7 -0
- package/dist/tokens/components/actions.css +14 -0
- package/dist/tokens/components/attachments.css +15 -0
- package/dist/tokens/components/conversations.css +28 -0
- package/dist/tokens/components/draggable-panel.css +25 -0
- package/dist/tokens/components/float-button.css +39 -0
- package/dist/tokens/components/text.css +13 -0
- package/dist/tokens/components/thought-chain.css +31 -0
- package/dist/tokens/components/welcome.css +19 -0
- package/dist/tokens/foundation.css +6 -4
- package/docs/DESIGN-AUTHORITY.md +133 -20
- package/docs/FRAME-COVERAGE-REPORT.md +5 -2
- package/docs/data-display/card/examples/tab-list.tsx +97 -0
- package/docs/data-display/thought-chain.tsx +176 -0
- package/docs/data-display/welcome.tsx +115 -0
- package/docs/data-entry/attachments.tsx +160 -0
- package/docs/feedback/dialog.tsx +50 -0
- package/docs/general/actions.tsx +175 -0
- package/docs/general/float-button.tsx +133 -0
- package/docs/general/typography.tsx +63 -1
- package/docs/layout/draggable-panel.tsx +127 -0
- package/docs/navigation/conversations.tsx +176 -0
- package/docs/roadmap/parity-audit-layout-navigation-general.md +17 -16
- package/package.json +20 -4
- package/scripts/_agent-setup.mjs +36 -5
- package/scripts/guinea-pig-skill.md +14 -0
- package/scripts/ui-audit.mjs +69 -9
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
:root {
|
|
3
|
+
|
|
4
|
+
--welcome-gap: var(--space-4);
|
|
5
|
+
|
|
6
|
+
--welcome-content-gap: var(--space-1);
|
|
7
|
+
|
|
8
|
+
--welcome-title-gap: var(--space-3);
|
|
9
|
+
|
|
10
|
+
--welcome-padding-block: var(--space-4);
|
|
11
|
+
--welcome-padding-inline: var(--space-4);
|
|
12
|
+
--welcome-radius: var(--radius-lg);
|
|
13
|
+
|
|
14
|
+
--welcome-icon-size: var(--icon-size-xl);
|
|
15
|
+
|
|
16
|
+
--welcome-filled-background: initial;
|
|
17
|
+
|
|
18
|
+
--welcome-filled-border: initial;
|
|
19
|
+
}
|
|
@@ -108,9 +108,10 @@
|
|
|
108
108
|
transparent 70%
|
|
109
109
|
);
|
|
110
110
|
|
|
111
|
-
--focus-outline:
|
|
111
|
+
--focus-outline: 1;
|
|
112
112
|
--focus-outline-weight: var(--stroke-hairline);
|
|
113
113
|
--focus-outline-color: var(--focus-ring-color, var(--ring));
|
|
114
|
+
|
|
114
115
|
--control-outline-width: calc(var(--stroke-md) * var(--focus-outline));
|
|
115
116
|
--focus-outline-offset: 0px;
|
|
116
117
|
|
|
@@ -125,7 +126,8 @@
|
|
|
125
126
|
--focus-ring-glow-color: var(--control-outline);
|
|
126
127
|
--focus-ring-glow-alpha: var(--control-outline-alpha);
|
|
127
128
|
|
|
128
|
-
--focus-field-shadow:
|
|
129
|
+
--focus-field-shadow: 0 0 0 var(--focus-ring-glow-width)
|
|
130
|
+
hsl(var(--focus-ring-glow-color) / var(--focus-ring-glow-alpha));
|
|
129
131
|
|
|
130
132
|
--focus-ring-offset: var(--focus-outline-offset);
|
|
131
133
|
|
|
@@ -179,6 +181,8 @@
|
|
|
179
181
|
--heading-h3: var(--font-size-base);
|
|
180
182
|
--heading-h4: var(--font-size-xs);
|
|
181
183
|
|
|
184
|
+
--heading-h5: var(--font-size-2xs);
|
|
185
|
+
|
|
182
186
|
--font-weight-normal: 400;
|
|
183
187
|
--font-weight-medium: 500;
|
|
184
188
|
|
|
@@ -255,7 +259,6 @@
|
|
|
255
259
|
--activity-interval: var(--duration-loop);
|
|
256
260
|
|
|
257
261
|
--activity-stagger-step: 160ms;
|
|
258
|
-
|
|
259
262
|
}
|
|
260
263
|
|
|
261
264
|
.ui-scale-fixed {
|
|
@@ -306,7 +309,6 @@
|
|
|
306
309
|
--space-chrome-y: var(--space-4);
|
|
307
310
|
--space-chrome-gap: var(--space-2);
|
|
308
311
|
--field-label-gap: var(--space-2);
|
|
309
|
-
|
|
310
312
|
}
|
|
311
313
|
|
|
312
314
|
.dark,
|
package/docs/DESIGN-AUTHORITY.md
CHANGED
|
@@ -12,17 +12,17 @@ It changes no code by itself. It is the tie-breaker a reviewer points at.
|
|
|
12
12
|
|
|
13
13
|
## The layers, and who owns each
|
|
14
14
|
|
|
15
|
-
| Layer | Authority
|
|
16
|
-
| ------------------------------------------------------------------ |
|
|
17
|
-
| Interaction semantics, keyboard, ARIA | **WAI-ARIA APG**
|
|
18
|
-
| Behaviour primitives | **Radix**
|
|
19
|
-
| Component composition shape | **shadcn**
|
|
20
|
-
| Component taxonomy / grouping | **Ant Design** groups
|
|
21
|
-
| Colour foundation | **SmartHR**
|
|
22
|
-
| **Derived colour — the interaction states hanging off each seed**
|
|
23
|
-
| **Japanese UI convention — density, JP typography, form patterns** | **SmartHR**
|
|
24
|
-
| **Japanese accessibility / public-sector convention** | **デジタル庁 Design System** (Digital Agency)
|
|
25
|
-
| **Spacing, density, type scale, information architecture** | **IBM Carbon**
|
|
15
|
+
| Layer | Authority | Status in this repo |
|
|
16
|
+
| ------------------------------------------------------------------ | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
17
|
+
| Interaction semantics, keyboard, ARIA | **WAI-ARIA APG** | already followed — 33 references in `src/` |
|
|
18
|
+
| Behaviour primitives | **Radix** | already the implementation — 193 references |
|
|
19
|
+
| Component composition shape | **shadcn** | already the structural convention — 23 references |
|
|
20
|
+
| Component taxonomy / grouping | **Ant Design** groups | already the catalog shape: `data-entry`, `data-display`, `layout`, `feedback`, `navigation`, `general` — a naming precedent, nothing is installed |
|
|
21
|
+
| Colour foundation | **SmartHR** | already the palette source — `--primary` = SmartHR MAIN `#0071bd`, `--foreground` = TEXT_BLACK, `--border` = BORDER |
|
|
22
|
+
| **Derived colour — the interaction states hanging off each seed** | **Measured contrast (WCAG 2.2 / JIS X 8341-3)** | Authored in `src/tokens/derived.css`; no algorithm derives them. Four contrast suites read that file and hold every value to a threshold — see below |
|
|
23
|
+
| **Japanese UI convention — density, JP typography, form patterns** | **SmartHR** | **NEW — this decision.** Extends SmartHR from "where the colours came from" to the authority for how a JP business screen behaves |
|
|
24
|
+
| **Japanese accessibility / public-sector convention** | **デジタル庁 Design System** (Digital Agency) | **NEW — this decision.** The reference when a JP customer asks which standard a screen meets (JIS X 8341-3) |
|
|
25
|
+
| **Spacing, density, type scale, information architecture** | **IBM Carbon** | **NEW — this decision** |
|
|
26
26
|
|
|
27
27
|
The first five were already true and merely unwritten. The last three are the choices being made
|
|
28
28
|
here. Carbon fills the one layer that had no outside answer at all: page rhythm, table density, form layout,
|
|
@@ -197,10 +197,34 @@ rows or a totals row — which is how a consumer ends up hand-rolling a `<tfoot>
|
|
|
197
197
|
in page CSS.
|
|
198
198
|
|
|
199
199
|
**The rule: where antd names a capability, this library takes antd's name and antd's semantics.**
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
200
|
+
|
|
201
|
+
> **Restated and widened by the repo owner on 2026-09-12, because the rule above was being read as
|
|
202
|
+
> advice rather than as the standard it is: Ant Design IS the standard. A missing capability is
|
|
203
|
+
> ported from antd 100% FIRST — its names, its props, its semantics — and improved afterwards.
|
|
204
|
+
> Not redesigned first, and not half-ported.**
|
|
205
|
+
>
|
|
206
|
+
> Two things forced the restatement, both measured rather than felt:
|
|
207
|
+
>
|
|
208
|
+
> - `Dialog` + `AlertDialog` ship **26** exports with **12 name-for-name pairs and 0 parts unique
|
|
209
|
+
> to `AlertDialog`**, whose entire difference is `role="alertdialog"` plus `isDismissable={false}`
|
|
210
|
+
> — two props the shell already takes. antd has exactly one `Modal`, where danger is `okType`
|
|
211
|
+
> and `Modal.confirm()`. The shape here came from Radix, silently, against this very rule
|
|
212
|
+
> (gh#567). A package-wide sweep over all 272 public exports found this is the ONLY such pair:
|
|
213
|
+
> `Skeleton.Avatar/Button/Input/Image/Node` looks identical in shape but is antd's own naming,
|
|
214
|
+
> so it is compliance, not drift.
|
|
215
|
+
> - Whole families arrived half-ported: Ant Design X without `Conversations`, `Attachments`,
|
|
216
|
+
> `ThoughtChain`, `Welcome` or `Actions` (gh#559); `FloatButton` never at all (gh#558);
|
|
217
|
+
> `Typography` reduced to `Text` + `Heading`, with `Paragraph`, `Link`, `copyable`, `editable`,
|
|
218
|
+
> `mark`, `keyboard` and `italic` simply absent.
|
|
219
|
+
>
|
|
220
|
+
> A deviation from antd is still allowed — the three below are — but it must be WRITTEN DOWN at
|
|
221
|
+
> the point of deviation. An undocumented deviation is a bug, and gh#567 is what that bug costs:
|
|
222
|
+
> a consumer forced to pick between the right ARIA role and a form it needs, and an accessibility
|
|
223
|
+
> decision pushed onto the party least able to make it.
|
|
224
|
+
> The gap is read out of the INSTALLED types (`antd/es/table/interface.d.ts`,
|
|
225
|
+
> `antd/es/table/InternalTable.d.ts` and the `@rc-component/table` interface they extend) — never
|
|
226
|
+
> from memory, because antd's own names move between majors (`fixed: 'left'` is deprecated in favour
|
|
227
|
+
> of `start` inside rc-table itself).
|
|
204
228
|
|
|
205
229
|
> Đọc sau 20.0.0: bản major ấy đã **gỡ `antd` khỏi devDependencies** cùng máy sinh màu của nó, và
|
|
206
230
|
> `check:no-antd-runtime` canh cho nó không quay lại. Câu trên mô tả cách bề mặt prop này ĐƯỢC ĐỌC
|
|
@@ -224,6 +248,95 @@ of `start` inside rc-table itself).
|
|
|
224
248
|
replace the rendered markup. This library answers that layer with tokens (cardinal rule #45), so
|
|
225
249
|
those are deliberately NOT adopted — adopting them would re-open the hole the token tiers close.
|
|
226
250
|
|
|
251
|
+
## One `Dialog`, not two families — and the rule a consumer picks by
|
|
252
|
+
|
|
253
|
+
**Status:** accepted · 2026-09-12 · gh#567
|
|
254
|
+
|
|
255
|
+
### The measurement that forced it
|
|
256
|
+
|
|
257
|
+
On `dist/components/feedback/dialog.d.ts` at `23.2.0`, the feedback group published **26** things:
|
|
258
|
+
**14** `Dialog*`, **12** `AlertDialog*`, **12 name-pairs**, **0** parts that only `AlertDialog`
|
|
259
|
+
had, and 2 that only `Dialog` had (`DialogBody`, `DialogClose`). `AlertDialog` carried no part of
|
|
260
|
+
its own; it was a full mirror minus two.
|
|
261
|
+
|
|
262
|
+
The real difference was two internal props on one shared shell — `role` and `isDismissable` — and
|
|
263
|
+
`AlertDialogRoot` is literally that shell with `role="alertdialog"` and `isDismissable={false}`.
|
|
264
|
+
Twelve exports were the price of publishing one ARIA attribute.
|
|
265
|
+
|
|
266
|
+
**A sweep of the whole public surface says this was the only place it happened.** Scanning the 270
|
|
267
|
+
callable exports in `component-api-manifest.json` for a prefixed mirror of another export
|
|
268
|
+
(`Alert*`, `Compact*`, `Simple*`, `Mini*`, `Basic*`, `Confirm*`, `Destructive*`) returns **11
|
|
269
|
+
pairs, all 11 of them this one family**. There is no second drifted pair to find.
|
|
270
|
+
|
|
271
|
+
### Why antd wins here
|
|
272
|
+
|
|
273
|
+
antd has **one** `Modal`. Danger is a prop — `okType="danger"`, `okButtonProps`, with
|
|
274
|
+
`Modal.confirm()` as the flat preset alongside `info/success/error/warning`. antd has no
|
|
275
|
+
`AlertModal`. The split came from Radix, which ships `@radix-ui/react-dialog` and
|
|
276
|
+
`@radix-ui/react-alert-dialog` as two packages — and this library no longer runs on Radix.
|
|
277
|
+
react-aria-components has a single `Dialog` whose `role` is an ordinary prop, so the shape that
|
|
278
|
+
made two families necessary is gone from the implementation as well as from the authority.
|
|
279
|
+
|
|
280
|
+
### The decision
|
|
281
|
+
|
|
282
|
+
`Dialog` takes **`variant`** (`"default" | "destructive"`), on the root or on `DialogContent`, and
|
|
283
|
+
that one prop decides three things that always travel together in practice:
|
|
284
|
+
|
|
285
|
+
| `variant` | ARIA role | outside click | primary action |
|
|
286
|
+
| --------------------- | ------------- | ------------- | --------------------------------------------- |
|
|
287
|
+
| `"default"` (default) | `dialog` | dismisses | default emphasis |
|
|
288
|
+
| `"destructive"` | `alertdialog` | ignored | destructive emphasis (antd `okType="danger"`) |
|
|
289
|
+
|
|
290
|
+
The 12 `AlertDialog*` exports **stay and keep working unchanged**. Deleting them is a breaking
|
|
291
|
+
change and belongs in a major; nothing here retints or re-roles an existing tree, because the new
|
|
292
|
+
prop defaults to `"default"` and no existing `AlertDialog*` call site passes it.
|
|
293
|
+
|
|
294
|
+
### The rule for choosing — answer these in order
|
|
295
|
+
|
|
296
|
+
1. **Is it dangerous or irreversible?** No → plain `Dialog`, no `variant`. Yes → keep going.
|
|
297
|
+
2. **Does the flat preset cover it?** Title, description, confirm/cancel labels, an optional typed
|
|
298
|
+
challenge, an optional step-up re-auth, a pending state, and nothing else in the body → use the
|
|
299
|
+
`AlertDialog` **preset**. It is one element and it already forces the destructive tone.
|
|
300
|
+
3. **Does the body need anything else** — a required reason field, a summary table, a diff, a
|
|
301
|
+
nested list? → `Dialog` with `variant="destructive"`. You get `role="alertdialog"` and the
|
|
302
|
+
non-dismissable scrim, plus `DialogBody` and `DialogClose`, which the `AlertDialog*` family
|
|
303
|
+
never had.
|
|
304
|
+
4. **Are you writing new code with the `AlertDialog*` compound parts?** Don't. They are the legacy
|
|
305
|
+
spelling of step 3. Existing code stays valid.
|
|
306
|
+
|
|
307
|
+
That third row is the reported case: a destructive confirmation with a **required free-text reason**
|
|
308
|
+
that still has to be announced as an alert dialog. Before this, `Dialog` gave the form and lost the
|
|
309
|
+
role, `AlertDialog` gave the role and forced the footer to be rebuilt, and either way it was a
|
|
310
|
+
rewrite rather than a prop.
|
|
311
|
+
|
|
312
|
+
### Four places this deliberately departs from the issue's proposal
|
|
313
|
+
|
|
314
|
+
1. **The prop is `variant`, not `severity`.** antd has no name for a one-knob-three-effects switch,
|
|
315
|
+
so there is nothing to port verbatim. But the axis already exists here as `ConfirmVariantProp`
|
|
316
|
+
and the `AlertDialog` preset already spells it `variant` — and "this library's controlled
|
|
317
|
+
vocabulary wins on values" is the rule two sections up. `check:prop-vocabulary` maps a field
|
|
318
|
+
named `variant` to a `*VariantProp` type for exactly this reason.
|
|
319
|
+
2. **Escape still closes a `destructive` dialog.** The issue wanted the prop to govern Escape too.
|
|
320
|
+
It does not, because Escape-closes-an-alertdialog is the behaviour the 12 existing exports have
|
|
321
|
+
today, with a test measuring it (`dialog-alert-primitives.test.tsx` · "closes on Escape and
|
|
322
|
+
restores focus"). Making the new prop disable Escape would make `variant="destructive"` differ
|
|
323
|
+
from `AlertDialogContent`, which is the one thing it must not do. antd agrees: `keyboard`
|
|
324
|
+
defaults to `true`. The prop governs the outside click; `maskClosable` is antd's name for that
|
|
325
|
+
same switch.
|
|
326
|
+
3. **The corner ✕ defaults off under `destructive`.** It is a fourth effect, and it follows from
|
|
327
|
+
the second: a ✕ is an accidental-dismiss affordance like the scrim. It keeps
|
|
328
|
+
`DialogContent variant="destructive"` byte-identical to `AlertDialogContent`, and
|
|
329
|
+
`showCloseButton` still overrides it either way.
|
|
330
|
+
4. **The header band tone is NOT forced.** `DialogHeader tone` is a separate published axis with
|
|
331
|
+
seven values; the preset is where a destructive tone is imposed on both the band and the button
|
|
332
|
+
at once. Forcing it from `variant` would put two props on the same pixel.
|
|
333
|
+
|
|
334
|
+
### And the `Sheet` question in the same issue
|
|
335
|
+
|
|
336
|
+
Asked, measured, no change. antd keeps `Drawer` and `Modal` as two components and splits them by
|
|
337
|
+
**where the surface comes from**, not by danger — which is exactly the `Sheet` / `Dialog` boundary
|
|
338
|
+
here. That pair never drifted from the authority, so there is nothing to merge.
|
|
339
|
+
|
|
227
340
|
## Derived colour is AUTHORED, and MEASUREMENT is what makes it authoritative
|
|
228
341
|
|
|
229
342
|
**Twenty values, in `src/tokens/derived.css`:** `--primary-hover`, `--primary-active`,
|
|
@@ -240,12 +353,12 @@ to trust them had to.
|
|
|
240
353
|
**The authority is now the measurement, not the derivation.** Four suites read `derived.css`
|
|
241
354
|
directly and hold every value in it to a threshold this repo has already committed to:
|
|
242
355
|
|
|
243
|
-
| suite
|
|
244
|
-
|
|
|
356
|
+
| suite | what it holds |
|
|
357
|
+
| -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
245
358
|
| `src/tokens/__tests__/focus-ring-contrast.test.ts` | the focus mark in both switch positions — ≥3:1 (WCAG 2.2 SC 1.4.11) on every surface a control sits on, and the halo proven to be decoration rather than the indicator |
|
|
246
|
-
| `src/tokens/__tests__/interactive-fill-contrast.test.ts` | an interactive fill must clear **4.5:1** against the label sitting on it
|
|
247
|
-
| `src/tokens/__tests__/destructive-contrast.test.ts` | `--destructive-hover` / `--destructive-active` against the same bar
|
|
248
|
-
| `src/lib/__tests__/theme-tokens-css.test.ts` | the tier is actually loaded, and complete in both themes
|
|
359
|
+
| `src/tokens/__tests__/interactive-fill-contrast.test.ts` | an interactive fill must clear **4.5:1** against the label sitting on it |
|
|
360
|
+
| `src/tokens/__tests__/destructive-contrast.test.ts` | `--destructive-hover` / `--destructive-active` against the same bar |
|
|
361
|
+
| `src/lib/__tests__/theme-tokens-css.test.ts` | the tier is actually loaded, and complete in both themes |
|
|
249
362
|
|
|
250
363
|
The first three also pin each value as a literal, so an edit to `derived.css` alone turns CI red
|
|
251
364
|
rather than quietly retinting the library. **That is a stronger claim than the generator made, not
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
> Generated by `scripts/frame-coverage.mjs` (issue #163). Do not edit by hand — run `pnpm check:frame-coverage`.
|
|
4
4
|
> Standard: [FRAME-COVERAGE-STANDARD.md](./FRAME-COVERAGE-STANDARD.md). A missing dimension is **UNTESTED**, never a pass.
|
|
5
5
|
|
|
6
|
-
- Public components: **
|
|
7
|
-
- With ≥1 frame: **
|
|
6
|
+
- Public components: **152**
|
|
7
|
+
- With ≥1 frame: **135** · zero-frame: **17**
|
|
8
8
|
- Fully covered (every contract axis declared): **0**
|
|
9
9
|
|
|
10
10
|
## UNTESTED — no `/frame/**` route
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
- [ ] `SkeletonAvatar`
|
|
23
23
|
- [ ] `SkeletonButton`
|
|
24
24
|
- [ ] `SkeletonInput`
|
|
25
|
+
- [ ] `SkeletonForm`
|
|
25
26
|
- [ ] `SkeletonNode`
|
|
26
27
|
- [ ] `SkeletonImage`
|
|
27
28
|
- [ ] `ChatBubbleList`
|
|
@@ -57,6 +58,7 @@ Legend: ✓ covered · N/A reasoned skip · · UNTESTED (blank cell = UNTESTED).
|
|
|
57
58
|
| ErrorSurface | ✓ | ✓ | N/A | N/A | · | · | · | · | · | · |
|
|
58
59
|
| LegalDocumentShell | ✓ | N/A | N/A | N/A | · | · | · | · | · | · |
|
|
59
60
|
| Breadcrumb | ✓ | N/A | N/A | N/A | · | · | · | · | · | · |
|
|
61
|
+
| FloatButton | ✓ | · | · | · | · | · | · | · | · | · |
|
|
60
62
|
| Button | ✓ | ✓ | · | · | · | · | · | · | · | · |
|
|
61
63
|
| Text | ✓ | ✓ | N/A | N/A | · | · | · | · | · | · |
|
|
62
64
|
| Heading | ✓ | ✓ | N/A | N/A | · | · | · | · | · | · |
|
|
@@ -141,6 +143,7 @@ Legend: ✓ covered · N/A reasoned skip · · UNTESTED (blank cell = UNTESTED).
|
|
|
141
143
|
| SkeletonAvatar | **✗** | ✓ | N/A | N/A | · | · | · | · | · | · |
|
|
142
144
|
| SkeletonButton | **✗** | ✓ | N/A | N/A | · | · | · | · | · | · |
|
|
143
145
|
| SkeletonInput | **✗** | ✓ | N/A | N/A | · | · | · | · | · | · |
|
|
146
|
+
| SkeletonForm | **✗** | N/A | N/A | N/A | · | · | · | · | · | · |
|
|
144
147
|
| SkeletonNode | **✗** | N/A | N/A | N/A | · | · | · | · | · | · |
|
|
145
148
|
| SkeletonImage | **✗** | N/A | N/A | N/A | · | · | · | · | · | · |
|
|
146
149
|
| Toggle | ✓ | ✓ | · | N/A | · | · | · | · | · | · |
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
Badge,
|
|
5
|
+
Card,
|
|
6
|
+
CardContent,
|
|
7
|
+
CardFooter,
|
|
8
|
+
CardHeader,
|
|
9
|
+
CardTitle,
|
|
10
|
+
DataTable,
|
|
11
|
+
Descriptions,
|
|
12
|
+
type CardTabItemProp,
|
|
13
|
+
} from "@godxjp/ui/data-display";
|
|
14
|
+
import { Button, Text } from "@godxjp/ui/general";
|
|
15
|
+
import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Card `tabList` — Ant Design's card-head tab strip.
|
|
19
|
+
*
|
|
20
|
+
* The strip lives INSIDE the card's head: under the title, on the same surface, inside the same
|
|
21
|
+
* border, so the card and its tabs read as one object. The card's children are the selected tab's
|
|
22
|
+
* body — here a `DataTable` in a `CardContent flush`, which is what lets the table reach the card
|
|
23
|
+
* edge instead of sitting in a second, narrower frame.
|
|
24
|
+
*
|
|
25
|
+
* What NOT to reach for instead: a `Tabs` parked on the page above a card (the strip floats off
|
|
26
|
+
* the card and the two read as two objects), or a `Card` repeated inside every tab (the same
|
|
27
|
+
* header and body shell copied once per view).
|
|
28
|
+
*/
|
|
29
|
+
const tabList: CardTabItemProp[] = [
|
|
30
|
+
{ key: "members", tab: "メンバー" },
|
|
31
|
+
{ key: "invitations", tab: "招待" },
|
|
32
|
+
{ key: "settings", tab: "設定" },
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
const members = [
|
|
36
|
+
{ id: "1", name: "佐藤 花子", email: "sato@example.co.jp", role: "管理者" },
|
|
37
|
+
{ id: "2", name: "鈴木 一郎", email: "suzuki@example.co.jp", role: "編集者" },
|
|
38
|
+
{ id: "3", name: "高橋 美咲", email: "takahashi@example.co.jp", role: "閲覧者" },
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
const invitations = [{ id: "4", name: "田中 健", email: "tanaka@example.co.jp", role: "編集者" }];
|
|
42
|
+
|
|
43
|
+
export default function Demo() {
|
|
44
|
+
const [activeTabKey, setActiveTabKey] = useState("members");
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<PageContainer title="組織設定" subtitle="株式会社ベトヤ">
|
|
48
|
+
<Card
|
|
49
|
+
tabList={tabList}
|
|
50
|
+
activeTabKey={activeTabKey}
|
|
51
|
+
onTabChange={setActiveTabKey}
|
|
52
|
+
extra={<Button size="sm">メンバーを招待</Button>}
|
|
53
|
+
>
|
|
54
|
+
<CardHeader>
|
|
55
|
+
<CardTitle level={2}>チーム</CardTitle>
|
|
56
|
+
</CardHeader>
|
|
57
|
+
|
|
58
|
+
{activeTabKey === "settings" ? (
|
|
59
|
+
<CardContent>
|
|
60
|
+
<Descriptions>
|
|
61
|
+
<Descriptions.Item label="組織名">株式会社ベトヤ</Descriptions.Item>
|
|
62
|
+
<Descriptions.Item label="ドメイン">example.co.jp</Descriptions.Item>
|
|
63
|
+
<Descriptions.Item label="既定の権限">閲覧者</Descriptions.Item>
|
|
64
|
+
</Descriptions>
|
|
65
|
+
</CardContent>
|
|
66
|
+
) : (
|
|
67
|
+
<CardContent flush>
|
|
68
|
+
<DataTable
|
|
69
|
+
data={activeTabKey === "members" ? members : invitations}
|
|
70
|
+
getRowId={(row) => row.id}
|
|
71
|
+
columns={[
|
|
72
|
+
{ key: "name", header: "名前" },
|
|
73
|
+
{ key: "email", header: "メール" },
|
|
74
|
+
{
|
|
75
|
+
key: "role",
|
|
76
|
+
header: "権限",
|
|
77
|
+
render: (row) => <Badge tone="info">{row.role}</Badge>,
|
|
78
|
+
},
|
|
79
|
+
]}
|
|
80
|
+
/>
|
|
81
|
+
</CardContent>
|
|
82
|
+
)}
|
|
83
|
+
|
|
84
|
+
<CardFooter separated>
|
|
85
|
+
<Flex direction="row" justify="between" align="center" gap="sm">
|
|
86
|
+
<Text tone="muted" size="sm">
|
|
87
|
+
{activeTabKey === "invitations" ? "1件の保留中の招待" : "3名のメンバー"}
|
|
88
|
+
</Text>
|
|
89
|
+
<Button variant="outline" size="sm">
|
|
90
|
+
CSV で書き出す
|
|
91
|
+
</Button>
|
|
92
|
+
</Flex>
|
|
93
|
+
</CardFooter>
|
|
94
|
+
</Card>
|
|
95
|
+
</PageContainer>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
|
|
3
|
+
import { ChatBubble, ThoughtChain, ThoughtChainItem } from "@godxjp/ui/data-display";
|
|
4
|
+
import { Text } from "@godxjp/ui/general";
|
|
5
|
+
import {
|
|
6
|
+
AppShell,
|
|
7
|
+
Flex,
|
|
8
|
+
PageContainer,
|
|
9
|
+
Sidebar,
|
|
10
|
+
type SidebarSectionProp,
|
|
11
|
+
Topbar,
|
|
12
|
+
} from "@godxjp/ui/layout";
|
|
13
|
+
import { Bot, MessageSquare, Search, Settings, Users } from "lucide-react";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* ThoughtChain — the assistant's reasoning, step by step (Ant Design X `ThoughtChain`).
|
|
17
|
+
*
|
|
18
|
+
* Each card is one axis at rest: the chain as it appears above an answer, the four statuses, the
|
|
19
|
+
* three connector strokes, and the standalone `ThoughtChainItem` chip in its three variants.
|
|
20
|
+
*
|
|
21
|
+
* The step that collapses is a real disclosure button, so this page is drivable from the keyboard
|
|
22
|
+
* alone; Ant X's own step is a `<div onClick>`.
|
|
23
|
+
*
|
|
24
|
+
* Composed only from real @godxjp/ui components.
|
|
25
|
+
*/
|
|
26
|
+
const sections: SidebarSectionProp[] = [
|
|
27
|
+
{
|
|
28
|
+
label: "アシスタント",
|
|
29
|
+
items: [
|
|
30
|
+
{ id: "chat", label: "チャット", icon: MessageSquare },
|
|
31
|
+
{ id: "agents", label: "エージェント", icon: Bot },
|
|
32
|
+
{ id: "members", label: "メンバー", icon: Users },
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
{ label: "管理", items: [{ id: "settings", label: "設定", icon: Settings }] },
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
export default function ThoughtChainDoc() {
|
|
39
|
+
const [open, setOpen] = useState<string[]>(["search"]);
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<AppShell
|
|
43
|
+
sidebar={
|
|
44
|
+
<Sidebar
|
|
45
|
+
activeId="chat"
|
|
46
|
+
sections={sections}
|
|
47
|
+
onSelect={() => {}}
|
|
48
|
+
product={{ name: "CoreDesk", role: "アシスタント", color: "hsl(var(--primary))" }}
|
|
49
|
+
/>
|
|
50
|
+
}
|
|
51
|
+
topbar={<Topbar />}
|
|
52
|
+
>
|
|
53
|
+
<PageContainer
|
|
54
|
+
title="思考の手順"
|
|
55
|
+
subtitle="ThoughtChain · 回答の前に何をしたのか。畳める手順は本物の開閉ボタン。"
|
|
56
|
+
>
|
|
57
|
+
{/* IN PLACE: above the answer it explains. */}
|
|
58
|
+
<Flex direction="col" gap="sm">
|
|
59
|
+
<Text size="sm" weight="medium">
|
|
60
|
+
in place · 回答の前
|
|
61
|
+
</Text>
|
|
62
|
+
<ThoughtChain
|
|
63
|
+
label="思考の手順"
|
|
64
|
+
expandedKeys={open}
|
|
65
|
+
onExpand={setOpen}
|
|
66
|
+
items={[
|
|
67
|
+
{
|
|
68
|
+
key: "read",
|
|
69
|
+
title: "添付の請求書を読む",
|
|
70
|
+
description: "3件",
|
|
71
|
+
status: "success",
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
key: "search",
|
|
75
|
+
title: "社内規程を検索",
|
|
76
|
+
description: "「支払期日」",
|
|
77
|
+
status: "success",
|
|
78
|
+
collapsible: true,
|
|
79
|
+
content: (
|
|
80
|
+
<Text size="xs" tone="muted">
|
|
81
|
+
第4章 支払 — 請求書の支払期日は受領月の翌月末日とする。
|
|
82
|
+
</Text>
|
|
83
|
+
),
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
key: "write",
|
|
87
|
+
title: "差分をまとめる",
|
|
88
|
+
status: "loading",
|
|
89
|
+
blink: true,
|
|
90
|
+
},
|
|
91
|
+
]}
|
|
92
|
+
/>
|
|
93
|
+
<ChatBubble placement="start" variant="filled">
|
|
94
|
+
差分は3件でした。金額、支払期日、宛名のうちどれから直しますか。
|
|
95
|
+
</ChatBubble>
|
|
96
|
+
</Flex>
|
|
97
|
+
|
|
98
|
+
{/* THE FOUR STATUSES. */}
|
|
99
|
+
<Flex direction="col" gap="sm">
|
|
100
|
+
<Text size="sm" weight="medium">
|
|
101
|
+
status · loading · success · error · abort
|
|
102
|
+
</Text>
|
|
103
|
+
<Text size="xs" tone="muted">
|
|
104
|
+
状態は字にもなる。読み上げでは各手順のあとに「完了」「失敗」などが続く。
|
|
105
|
+
</Text>
|
|
106
|
+
<ThoughtChain
|
|
107
|
+
label="状態の一覧"
|
|
108
|
+
items={[
|
|
109
|
+
{ key: "a", title: "実行中の手順", status: "loading" },
|
|
110
|
+
{ key: "b", title: "終わった手順", status: "success" },
|
|
111
|
+
{ key: "c", title: "失敗した手順", status: "error" },
|
|
112
|
+
{ key: "d", title: "中断した手順", status: "abort" },
|
|
113
|
+
]}
|
|
114
|
+
/>
|
|
115
|
+
</Flex>
|
|
116
|
+
|
|
117
|
+
{/* THE CONNECTOR. */}
|
|
118
|
+
<Flex direction="col" gap="sm">
|
|
119
|
+
<Text size="sm" weight="medium">
|
|
120
|
+
line · solid · dashed · none
|
|
121
|
+
</Text>
|
|
122
|
+
<ThoughtChain
|
|
123
|
+
label="実線"
|
|
124
|
+
line="solid"
|
|
125
|
+
items={[
|
|
126
|
+
{ key: "a", title: "一歩目" },
|
|
127
|
+
{ key: "b", title: "二歩目" },
|
|
128
|
+
]}
|
|
129
|
+
/>
|
|
130
|
+
<ThoughtChain
|
|
131
|
+
label="破線"
|
|
132
|
+
line="dashed"
|
|
133
|
+
items={[
|
|
134
|
+
{ key: "a", title: "一歩目" },
|
|
135
|
+
{ key: "b", title: "二歩目" },
|
|
136
|
+
]}
|
|
137
|
+
/>
|
|
138
|
+
<ThoughtChain
|
|
139
|
+
label="線なし"
|
|
140
|
+
line={false}
|
|
141
|
+
items={[
|
|
142
|
+
{ key: "a", title: "一歩目" },
|
|
143
|
+
{ key: "b", title: "二歩目" },
|
|
144
|
+
]}
|
|
145
|
+
/>
|
|
146
|
+
</Flex>
|
|
147
|
+
|
|
148
|
+
{/* THE STANDALONE CHIP. */}
|
|
149
|
+
<Flex direction="col" gap="sm">
|
|
150
|
+
<Text size="sm" weight="medium">
|
|
151
|
+
ThoughtChainItem · solid · outlined · text
|
|
152
|
+
</Text>
|
|
153
|
+
<Text size="xs" tone="muted">
|
|
154
|
+
押せる手順は本物のボタンとして描かれる。押せないものは div のまま。要素が実体に従う。
|
|
155
|
+
</Text>
|
|
156
|
+
<Flex gap="sm">
|
|
157
|
+
<ThoughtChainItem
|
|
158
|
+
variant="solid"
|
|
159
|
+
icon={<Search />}
|
|
160
|
+
title="社内規程を検索"
|
|
161
|
+
description="3件ヒット"
|
|
162
|
+
status="success"
|
|
163
|
+
/>
|
|
164
|
+
<ThoughtChainItem variant="outlined" icon={<Search />} title="再検索" />
|
|
165
|
+
<ThoughtChainItem
|
|
166
|
+
variant="text"
|
|
167
|
+
icon={<Search />}
|
|
168
|
+
title="詳細を見る"
|
|
169
|
+
onClick={() => setOpen(["search"])}
|
|
170
|
+
/>
|
|
171
|
+
</Flex>
|
|
172
|
+
</Flex>
|
|
173
|
+
</PageContainer>
|
|
174
|
+
</AppShell>
|
|
175
|
+
);
|
|
176
|
+
}
|