@godxjp/ui 28.4.0 → 28.5.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/README.md +58 -0
- package/dist/app/theme-axes.js +6 -0
- package/dist/components/data-entry/index.d.ts +1 -0
- package/dist/components/data-entry/index.js +2 -0
- package/dist/contracts/measurement.json +1 -1
- package/dist/styles/base.css +5 -3
- package/dist/styles/card-layout.css +11 -6
- package/dist/styles/control.css +8 -8
- package/dist/styles/data-display-layout.css +26 -18
- package/dist/styles/data-entry-layout.css +3 -3
- package/dist/styles/table-layout.css +9 -6
- package/dist/styles/text-layout.css +1 -1
- package/dist/theme/famgia.service.css +2 -4
- package/dist/tokens/components/control.css +4 -3
- package/dist/tokens/derived.css +20 -0
- package/dist/tokens/foundation.css +6 -13
- package/docs/CUSTOMER-THEMING.md +82 -3
- package/docs/FRAME-COVERAGE-REPORT.md +1 -1
- package/docs/data-entry/upload-crop-dialog.tsx +110 -0
- package/package.json +99 -92
package/README.md
CHANGED
|
@@ -12,6 +12,64 @@ npm i @godxjp/ui
|
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
|
+
## Using this from an AI agent
|
|
16
|
+
|
|
17
|
+
The catalog — 165 components, 1616 tokens, 47 cardinal rules — is published in two forms from one
|
|
18
|
+
source. **Entry point for either: [`AGENTS.md`](AGENTS.md).**
|
|
19
|
+
|
|
20
|
+
### If your agent can run a process
|
|
21
|
+
|
|
22
|
+
Claude Code · Codex CLI · Cursor · any MCP client:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx @godxjp/ui sync-rules
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Writes `.mcp.json`, `CLAUDE.md` and `.ai/rules/` into the consumer repo and wires
|
|
29
|
+
`@godxjp/ui-mcp`. Prefer this: it is searchable, it drills down instead of dumping, and it is
|
|
30
|
+
**locked to the version on disk** — the failure it prevents is an agent being told a prop does not
|
|
31
|
+
exist because the catalog was two minors behind (gh#789).
|
|
32
|
+
|
|
33
|
+
### If your agent can only fetch URLs
|
|
34
|
+
|
|
35
|
+
ChatGPT on the web, Claude.ai, or any client without a local process. The same data is served as
|
|
36
|
+
static files straight from this public repo — no hosting, no deploy step:
|
|
37
|
+
|
|
38
|
+
| file | size | what it is |
|
|
39
|
+
| ----------------------------------------------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------ |
|
|
40
|
+
| [`agent/START-HERE.md`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/START-HERE.md) | 6 KB | **read first** — self-contained: the four rules, the token override model, a page that passes review |
|
|
41
|
+
| [`agent/llms.txt`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/llms.txt) | 2 KB | the [llms.txt](https://llmstxt.org/) entry point |
|
|
42
|
+
| [`agent/index.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/index.json) | 2 KB | manifest: version, counts, every file's URL |
|
|
43
|
+
| [`agent/components-index.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/components-index.json) | 42 KB | all 165 as name + group + tagline — **fetch this first** |
|
|
44
|
+
| [`agent/components/<Name>.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/components/Select.json) | 1–32 KB | one file per component, each with its `importPath` — **this is the route to take** |
|
|
45
|
+
| [`agent/components.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/components.json) | 1.1 MB | all 165 entries in one file — most URL fetchers truncate this silently; prefer the per-component files |
|
|
46
|
+
| [`agent/tokens.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/tokens.json) | 0.6 MB | every design token, its value and why it exists |
|
|
47
|
+
| [`agent/vocabulary.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/vocabulary.json) | 7 KB | the controlled prop vocabulary |
|
|
48
|
+
| [`agent/rules.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/rules.json) | 17 KB | the 47 cardinal rules |
|
|
49
|
+
|
|
50
|
+
Pasteable bootstrap:
|
|
51
|
+
|
|
52
|
+
> Read https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/START-HERE.md and follow it.
|
|
53
|
+
> Then fetch .../agent/components-index.json to choose components, and
|
|
54
|
+
> .../agent/components/<Name>.json for the props of each one you chose. Tell me which catalog
|
|
55
|
+
> version you read.
|
|
56
|
+
|
|
57
|
+
**Pin to the version you installed.** Every URL above tracks `main`. Swap `main` for the matching
|
|
58
|
+
tag — `https://raw.githubusercontent.com/godx-jp/godxjp-ui/v28.4.0/agent/...` — because a catalog
|
|
59
|
+
newer than your package describes props you do not have, an older one hides props you do, and
|
|
60
|
+
neither failure announces itself. Pinned URLs only resolve for releases whose tag contains
|
|
61
|
+
`agent/`; on a 404 the release predates this catalog, so read `main` and compare
|
|
62
|
+
`index.json` → `version` against what you installed.
|
|
63
|
+
|
|
64
|
+
### Why static files and not a hosted MCP endpoint
|
|
65
|
+
|
|
66
|
+
GitHub serves files; it does not run servers. MCP over the network needs a process handling POST
|
|
67
|
+
requests, which no amount of Pages or raw hosting provides. A hosted HTTP MCP would work and would
|
|
68
|
+
need real hosting, ops and an auth decision — so the static lane ships first, carrying the same
|
|
69
|
+
data at no operational cost. Regenerate both from the one source with `pnpm gen:agent-catalog`.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
15
73
|
## Role & boundary — read this first
|
|
16
74
|
|
|
17
75
|
This package is **the single source of UI truth**. It is shared, versioned infrastructure, which means two things are non-negotiable:
|
package/dist/app/theme-axes.js
CHANGED
|
@@ -68,6 +68,12 @@ function applyPrimaryColor(root, color, foreground) {
|
|
|
68
68
|
"--primary-active": "initial",
|
|
69
69
|
"--primary-border": "initial",
|
|
70
70
|
"--control-outline": "initial",
|
|
71
|
+
/* The brand TEXT roles derive from the seed too (gh#664), so they are reset for the same
|
|
72
|
+
* reason: an ancestor theme that pinned a link colour for the previous brand would otherwise
|
|
73
|
+
* outrank the seed just set, and a re-tinted product would keep the old brand's links. */
|
|
74
|
+
"--text-link": "initial",
|
|
75
|
+
"--text-brand": "initial",
|
|
76
|
+
"--text-primary": "initial",
|
|
71
77
|
"--primary-hover-channels": `var(--primary-hover-${polarity}-channels)`,
|
|
72
78
|
"--primary-active-channels": `var(--primary-active-${polarity}-channels)`,
|
|
73
79
|
"--ring": hsl(rgb)
|
|
@@ -42,6 +42,7 @@ export type { SelectProp, SelectProp as SelectProps } from "./select.js";
|
|
|
42
42
|
export type { SearchSelectOptionProp as SelectOption, SearchSelectLoadParamsProp as SelectLoadParams, SearchSelectLoadResultProp as SelectLoadResult, } from "./search-select.js";
|
|
43
43
|
export { UPLOAD_LIST_IGNORE, Upload, collectUploadCommitActions, createUploadItem, useUploadDraft, } from "./upload.js";
|
|
44
44
|
export type { UploadProps, UploadFileItem, UploadVariant, UploadCommitAction } from "./upload.js";
|
|
45
|
+
export { UploadCropDialog } from "./upload-crop-dialog.js";
|
|
45
46
|
export { Cascader } from "./cascader.js";
|
|
46
47
|
export type { CascaderProps, TreeOption, TreeFieldNames } from "./cascader.js";
|
|
47
48
|
export { TreeSelect, SHOW_CHILD, SHOW_PARENT, SHOW_ALL } from "./tree-select.js";
|
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
createUploadItem,
|
|
40
40
|
useUploadDraft
|
|
41
41
|
} from "./upload.js";
|
|
42
|
+
import { UploadCropDialog } from "./upload-crop-dialog.js";
|
|
42
43
|
import { Cascader } from "./cascader.js";
|
|
43
44
|
import { TreeSelect, SHOW_CHILD, SHOW_PARENT, SHOW_ALL } from "./tree-select.js";
|
|
44
45
|
import { Transfer } from "./transfer.js";
|
|
@@ -127,6 +128,7 @@ export {
|
|
|
127
128
|
TreeSelect,
|
|
128
129
|
UPLOAD_LIST_IGNORE,
|
|
129
130
|
Upload,
|
|
131
|
+
UploadCropDialog,
|
|
130
132
|
collectUploadCommitActions,
|
|
131
133
|
createUploadItem,
|
|
132
134
|
dateMatchModifiers,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "AUTO-GENERATED by scripts/gen-measurement-contract.mjs — do not edit. Read this instead of guessing: docs/MEASUREMENT-CONTRACT.md.",
|
|
3
|
-
"version": "28.
|
|
3
|
+
"version": "28.5.0",
|
|
4
4
|
"targetSize": {
|
|
5
5
|
"standard": "WCAG 2.2 SC 2.5.8 Target Size (Minimum), level AA — 24×24 CSS px",
|
|
6
6
|
"min": 24,
|
package/dist/styles/base.css
CHANGED
|
@@ -74,7 +74,9 @@
|
|
|
74
74
|
--color-attention: hsl(var(--attention));
|
|
75
75
|
--color-attention-foreground: hsl(var(--attention-foreground));
|
|
76
76
|
|
|
77
|
-
--color-primary-strong: hsl(
|
|
77
|
+
--color-primary-strong: hsl(
|
|
78
|
+
var(--text-primary, from hsl(var(--primary)) var(--text-primary-channels))
|
|
79
|
+
);
|
|
78
80
|
--color-success-strong: hsl(var(--text-success));
|
|
79
81
|
--color-warning-strong: hsl(var(--text-warning));
|
|
80
82
|
--color-info-strong: hsl(var(--text-info));
|
|
@@ -97,8 +99,8 @@
|
|
|
97
99
|
|
|
98
100
|
--color-foreground-tertiary: hsl(var(--text-tertiary));
|
|
99
101
|
--color-foreground-disabled: hsl(var(--text-disabled));
|
|
100
|
-
--color-link: hsl(var(--text-link));
|
|
101
|
-
--color-brand: hsl(var(--text-brand));
|
|
102
|
+
--color-link: hsl(var(--text-link, from hsl(var(--primary)) var(--text-link-channels)));
|
|
103
|
+
--color-brand: hsl(var(--text-brand, from hsl(var(--primary)) var(--text-brand-channels)));
|
|
102
104
|
|
|
103
105
|
--color-primary-hover: hsl(
|
|
104
106
|
var(--primary-hover, from hsl(var(--primary)) var(--primary-hover-channels))
|
|
@@ -55,27 +55,32 @@
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
[data-slot="card"][data-accent="primary"] {
|
|
58
|
-
--card-accent-color: hsl(
|
|
58
|
+
--card-accent-color: hsl(
|
|
59
|
+
var(
|
|
60
|
+
--mark-primary,
|
|
61
|
+
var(--text-primary, from hsl(var(--primary)) var(--text-primary-channels))
|
|
62
|
+
)
|
|
63
|
+
);
|
|
59
64
|
}
|
|
60
65
|
|
|
61
66
|
[data-slot="card"][data-accent="success"] {
|
|
62
|
-
--card-accent-color: hsl(var(--mark-success));
|
|
67
|
+
--card-accent-color: hsl(var(--mark-success, var(--text-success)));
|
|
63
68
|
}
|
|
64
69
|
|
|
65
70
|
[data-slot="card"][data-accent="warning"] {
|
|
66
|
-
--card-accent-color: hsl(var(--mark-warning));
|
|
71
|
+
--card-accent-color: hsl(var(--mark-warning, var(--text-warning)));
|
|
67
72
|
}
|
|
68
73
|
|
|
69
74
|
[data-slot="card"][data-accent="info"] {
|
|
70
|
-
--card-accent-color: hsl(var(--mark-info));
|
|
75
|
+
--card-accent-color: hsl(var(--mark-info, var(--text-info)));
|
|
71
76
|
}
|
|
72
77
|
|
|
73
78
|
[data-slot="card"][data-accent="attention"] {
|
|
74
|
-
--card-accent-color: hsl(var(--mark-attention));
|
|
79
|
+
--card-accent-color: hsl(var(--mark-attention, var(--attention)));
|
|
75
80
|
}
|
|
76
81
|
|
|
77
82
|
[data-slot="card"][data-accent="destructive"] {
|
|
78
|
-
--card-accent-color: hsl(var(--mark-destructive));
|
|
83
|
+
--card-accent-color: hsl(var(--mark-destructive, var(--text-error)));
|
|
79
84
|
}
|
|
80
85
|
|
|
81
86
|
[data-slot="card"][data-accent] {
|
package/dist/styles/control.css
CHANGED
|
@@ -999,7 +999,7 @@
|
|
|
999
999
|
.ui-otp-container:has(.ui-otp-input[data-status="warning"]) .ui-otp-slot,
|
|
1000
1000
|
.ui-otp-container:has(.ui-otp-input[data-status="warning"])
|
|
1001
1001
|
.ui-otp-group[data-appearance="grouped"] {
|
|
1002
|
-
border-color: var(--control-status-warning-border-color);
|
|
1002
|
+
border-color: var(--control-status-warning-border-color, hsl(var(--text-warning)));
|
|
1003
1003
|
}
|
|
1004
1004
|
|
|
1005
1005
|
.ui-otp-container:has(.ui-otp-input[readonly]) .ui-otp-slot {
|
|
@@ -1371,10 +1371,10 @@
|
|
|
1371
1371
|
}
|
|
1372
1372
|
|
|
1373
1373
|
.ui-control-surface[data-status="warning"] {
|
|
1374
|
-
border-color: var(--control-status-warning-border-color);
|
|
1374
|
+
border-color: var(--control-status-warning-border-color, hsl(var(--text-warning)));
|
|
1375
1375
|
--focus-ring-color: var(--warning);
|
|
1376
1376
|
--focus-outline-color: var(--warning);
|
|
1377
|
-
--focus-ring-glow-color: var(--control-status-warning-outline-color);
|
|
1377
|
+
--focus-ring-glow-color: var(--control-status-warning-outline-color, var(--text-warning));
|
|
1378
1378
|
}
|
|
1379
1379
|
|
|
1380
1380
|
.ui-number-input[data-size="sm"] {
|
|
@@ -2442,7 +2442,7 @@
|
|
|
2442
2442
|
|
|
2443
2443
|
.ui-calendar .ui-calendar-day.day-today:not(.day-selected) .ui-calendar-day-button {
|
|
2444
2444
|
box-shadow: inset 0 0 0 1px hsl(var(--primary));
|
|
2445
|
-
color: hsl(var(--text-primary));
|
|
2445
|
+
color: hsl(var(--text-primary, from hsl(var(--primary)) var(--text-primary-channels)));
|
|
2446
2446
|
font-weight: var(--font-weight-medium);
|
|
2447
2447
|
}
|
|
2448
2448
|
|
|
@@ -2471,7 +2471,7 @@
|
|
|
2471
2471
|
|
|
2472
2472
|
.ui-calendar .ui-calendar-day.day-today:not(:has(button)) {
|
|
2473
2473
|
box-shadow: inset 0 0 0 1px hsl(var(--primary));
|
|
2474
|
-
color: hsl(var(--text-primary));
|
|
2474
|
+
color: hsl(var(--text-primary, from hsl(var(--primary)) var(--text-primary-channels)));
|
|
2475
2475
|
font-weight: var(--font-weight-medium);
|
|
2476
2476
|
border-radius: var(--calendar-day-radius);
|
|
2477
2477
|
}
|
|
@@ -2806,8 +2806,8 @@
|
|
|
2806
2806
|
|
|
2807
2807
|
.ui-control[data-status="warning"],
|
|
2808
2808
|
.ui-control-multiline[data-status="warning"] {
|
|
2809
|
-
--focus-ring-color: var(--control-status-warning-outline-color);
|
|
2810
|
-
--focus-outline-color: var(--control-status-warning-outline-color);
|
|
2809
|
+
--focus-ring-color: var(--control-status-warning-outline-color, var(--text-warning));
|
|
2810
|
+
--focus-outline-color: var(--control-status-warning-outline-color, var(--text-warning));
|
|
2811
2811
|
--focus-ring-glow-color: var(--control-status-warning-glow-color);
|
|
2812
2812
|
--focus-ring-glow-alpha: var(--control-status-warning-glow-alpha);
|
|
2813
2813
|
}
|
|
@@ -2833,7 +2833,7 @@
|
|
|
2833
2833
|
}
|
|
2834
2834
|
|
|
2835
2835
|
.ui-control-count[data-exceeded="true"] {
|
|
2836
|
-
color: hsl(var(--control-count-exceeded-color));
|
|
2836
|
+
color: hsl(var(--control-count-exceeded-color, var(--text-error)));
|
|
2837
2837
|
}
|
|
2838
2838
|
|
|
2839
2839
|
.ui-textarea-count {
|
|
@@ -182,19 +182,19 @@
|
|
|
182
182
|
.ui-progress-bar {
|
|
183
183
|
height: 100%;
|
|
184
184
|
border-radius: inherit;
|
|
185
|
-
background: var(--progress-fill-background, hsl(var(--mark-success)));
|
|
185
|
+
background: var(--progress-fill-background, hsl(var(--mark-success, var(--text-success))));
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
.ui-progress[data-tone="warning"] .ui-progress-bar {
|
|
189
|
-
background: hsl(var(--mark-warning));
|
|
189
|
+
background: hsl(var(--mark-warning, var(--text-warning)));
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
.ui-progress[data-tone="destructive"] .ui-progress-bar {
|
|
193
|
-
background: hsl(var(--mark-destructive));
|
|
193
|
+
background: hsl(var(--mark-destructive, var(--text-error)));
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
.ui-progress[data-over] .ui-progress-bar {
|
|
197
|
-
background-color: hsl(var(--mark-destructive));
|
|
197
|
+
background-color: hsl(var(--mark-destructive, var(--text-error)));
|
|
198
198
|
background-image: repeating-linear-gradient(
|
|
199
199
|
45deg,
|
|
200
200
|
hsl(var(--destructive-foreground) / 0.4) 0,
|
|
@@ -223,15 +223,15 @@
|
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
.ui-progress-segment[data-tone="success"] {
|
|
226
|
-
background: hsl(var(--mark-success));
|
|
226
|
+
background: hsl(var(--mark-success, var(--text-success)));
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
.ui-progress-segment[data-tone="warning"] {
|
|
230
|
-
background: hsl(var(--mark-warning));
|
|
230
|
+
background: hsl(var(--mark-warning, var(--text-warning)));
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
.ui-progress-segment[data-tone="destructive"] {
|
|
234
|
-
background: hsl(var(--mark-destructive));
|
|
234
|
+
background: hsl(var(--mark-destructive, var(--text-error)));
|
|
235
235
|
}
|
|
236
236
|
|
|
237
237
|
.ui-progress-label {
|
|
@@ -273,17 +273,17 @@
|
|
|
273
273
|
}
|
|
274
274
|
|
|
275
275
|
.ui-progress-ring-indicator {
|
|
276
|
-
stroke: var(--progress-fill-background, hsl(var(--mark-success)));
|
|
276
|
+
stroke: var(--progress-fill-background, hsl(var(--mark-success, var(--text-success))));
|
|
277
277
|
|
|
278
278
|
stroke-linecap: butt;
|
|
279
279
|
}
|
|
280
280
|
|
|
281
281
|
.ui-progress[data-tone="warning"] .ui-progress-ring-indicator {
|
|
282
|
-
stroke: hsl(var(--mark-warning));
|
|
282
|
+
stroke: hsl(var(--mark-warning, var(--text-warning)));
|
|
283
283
|
}
|
|
284
284
|
|
|
285
285
|
.ui-progress[data-tone="destructive"] .ui-progress-ring-indicator {
|
|
286
|
-
stroke: hsl(var(--mark-destructive));
|
|
286
|
+
stroke: hsl(var(--mark-destructive, var(--text-error)));
|
|
287
287
|
}
|
|
288
288
|
|
|
289
289
|
.ui-progress-ring-label {
|
|
@@ -320,23 +320,28 @@
|
|
|
320
320
|
}
|
|
321
321
|
|
|
322
322
|
.ui-legend-swatch[data-tone="default"] {
|
|
323
|
-
background: hsl(
|
|
323
|
+
background: hsl(
|
|
324
|
+
var(
|
|
325
|
+
--mark-primary,
|
|
326
|
+
var(--text-primary, from hsl(var(--primary)) var(--text-primary-channels))
|
|
327
|
+
)
|
|
328
|
+
);
|
|
324
329
|
}
|
|
325
330
|
|
|
326
331
|
.ui-legend-swatch[data-tone="success"] {
|
|
327
|
-
background: hsl(var(--mark-success));
|
|
332
|
+
background: hsl(var(--mark-success, var(--text-success)));
|
|
328
333
|
}
|
|
329
334
|
|
|
330
335
|
.ui-legend-swatch[data-tone="warning"] {
|
|
331
|
-
background: hsl(var(--mark-warning));
|
|
336
|
+
background: hsl(var(--mark-warning, var(--text-warning)));
|
|
332
337
|
}
|
|
333
338
|
|
|
334
339
|
.ui-legend-swatch[data-tone="destructive"] {
|
|
335
|
-
background: hsl(var(--mark-destructive));
|
|
340
|
+
background: hsl(var(--mark-destructive, var(--text-error)));
|
|
336
341
|
}
|
|
337
342
|
|
|
338
343
|
.ui-legend-swatch[data-tone="info"] {
|
|
339
|
-
background: hsl(var(--mark-info));
|
|
344
|
+
background: hsl(var(--mark-info, var(--text-info)));
|
|
340
345
|
}
|
|
341
346
|
|
|
342
347
|
.ui-legend-swatch[data-tone="muted"],
|
|
@@ -386,11 +391,11 @@
|
|
|
386
391
|
}
|
|
387
392
|
|
|
388
393
|
.ui-feature-list-item[data-state="included"] .ui-feature-list-mark {
|
|
389
|
-
color: hsl(var(--mark-success));
|
|
394
|
+
color: hsl(var(--mark-success, var(--text-success)));
|
|
390
395
|
}
|
|
391
396
|
|
|
392
397
|
.ui-feature-list-item[data-state="limited"] .ui-feature-list-mark {
|
|
393
|
-
color: hsl(var(--mark-warning));
|
|
398
|
+
color: hsl(var(--mark-warning, var(--text-warning)));
|
|
394
399
|
}
|
|
395
400
|
|
|
396
401
|
.ui-feature-list-item[data-state="excluded"] .ui-feature-list-label {
|
|
@@ -1069,7 +1074,10 @@
|
|
|
1069
1074
|
|
|
1070
1075
|
.ui-code-block [data-code-token="link"],
|
|
1071
1076
|
.ui-prose pre [data-code-token="link"] {
|
|
1072
|
-
color: var(
|
|
1077
|
+
color: var(
|
|
1078
|
+
--code-block-token-link-color,
|
|
1079
|
+
hsl(var(--text-link, from hsl(var(--primary)) var(--text-link-channels)))
|
|
1080
|
+
);
|
|
1073
1081
|
text-decoration-line: underline;
|
|
1074
1082
|
|
|
1075
1083
|
text-underline-offset: var(--text-link-underline-offset);
|
|
@@ -92,15 +92,15 @@
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
.ui-password-strength-segment[data-tone="destructive"] {
|
|
95
|
-
background: hsl(var(--mark-destructive));
|
|
95
|
+
background: hsl(var(--mark-destructive, var(--text-error)));
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
.ui-password-strength-segment[data-tone="warning"] {
|
|
99
|
-
background: hsl(var(--mark-warning));
|
|
99
|
+
background: hsl(var(--mark-warning, var(--text-warning)));
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
.ui-password-strength-segment[data-tone="success"] {
|
|
103
|
-
background: hsl(var(--mark-success));
|
|
103
|
+
background: hsl(var(--mark-success, var(--text-success)));
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
.ui-password-strength-meta {
|
|
@@ -16,27 +16,30 @@
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
.ui-table-row[data-tone="primary"] {
|
|
19
|
-
--table-row-tone-color: var(
|
|
19
|
+
--table-row-tone-color: var(
|
|
20
|
+
--mark-primary,
|
|
21
|
+
var(--text-primary, from hsl(var(--primary)) var(--text-primary-channels))
|
|
22
|
+
);
|
|
20
23
|
}
|
|
21
24
|
|
|
22
25
|
.ui-table-row[data-tone="success"] {
|
|
23
|
-
--table-row-tone-color: var(--mark-success);
|
|
26
|
+
--table-row-tone-color: var(--mark-success, var(--text-success));
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
.ui-table-row[data-tone="warning"] {
|
|
27
|
-
--table-row-tone-color: var(--mark-warning);
|
|
30
|
+
--table-row-tone-color: var(--mark-warning, var(--text-warning));
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
.ui-table-row[data-tone="info"] {
|
|
31
|
-
--table-row-tone-color: var(--mark-info);
|
|
34
|
+
--table-row-tone-color: var(--mark-info, var(--text-info));
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
.ui-table-row[data-tone="attention"] {
|
|
35
|
-
--table-row-tone-color: var(--mark-attention);
|
|
38
|
+
--table-row-tone-color: var(--mark-attention, var(--attention));
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
.ui-table-row[data-tone="destructive"] {
|
|
39
|
-
--table-row-tone-color: var(--mark-destructive);
|
|
42
|
+
--table-row-tone-color: var(--mark-destructive, var(--text-error));
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
.ui-table-row[data-tone] {
|
|
@@ -134,7 +134,7 @@
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
[data-slot="text"][data-link][data-tone="primary"]:not([data-disabled]) {
|
|
137
|
-
color: hsl(var(--text-link));
|
|
137
|
+
color: hsl(var(--text-link, from hsl(var(--primary)) var(--text-link-channels)));
|
|
138
138
|
}
|
|
139
139
|
[data-slot="text"][data-link]:hover,
|
|
140
140
|
[data-slot="text"][data-link]:focus-visible {
|
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
--primary: 221 83% 53%;
|
|
9
9
|
--primary-foreground: 0 0% 100%;
|
|
10
|
-
|
|
11
|
-
--primary-active: 226 71% 40%;
|
|
10
|
+
|
|
12
11
|
--ring: 221 83% 53%;
|
|
13
12
|
|
|
14
13
|
--text-link: 224 76% 45%;
|
|
@@ -25,8 +24,7 @@
|
|
|
25
24
|
.dark {
|
|
26
25
|
--primary: 221 90% 66%;
|
|
27
26
|
--primary-foreground: 222 47% 11%;
|
|
28
|
-
|
|
29
|
-
--primary-active: 221 90% 60%;
|
|
27
|
+
|
|
30
28
|
--ring: 221 90% 66%;
|
|
31
29
|
--text-link: 221 90% 72%;
|
|
32
30
|
--text-brand: 221 90% 70%;
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
|
|
40
40
|
--control-count-font-size: var(--font-size-sm);
|
|
41
41
|
--control-count-color: var(--muted-foreground);
|
|
42
|
-
|
|
42
|
+
|
|
43
|
+
--control-count-exceeded-color: initial;
|
|
43
44
|
--control-count-space-inline: var(--space-1);
|
|
44
45
|
--textarea-count-inset-block-end: var(--space-1);
|
|
45
46
|
--textarea-count-inset-inline-end: var(--space-2);
|
|
@@ -388,9 +389,9 @@
|
|
|
388
389
|
--control-borderless-shadow: none;
|
|
389
390
|
|
|
390
391
|
--control-status-error-border-color: hsl(var(--destructive));
|
|
391
|
-
--control-status-warning-border-color:
|
|
392
|
+
--control-status-warning-border-color: initial;
|
|
392
393
|
|
|
393
|
-
--control-status-warning-outline-color:
|
|
394
|
+
--control-status-warning-outline-color: initial;
|
|
394
395
|
}
|
|
395
396
|
|
|
396
397
|
@media (pointer: coarse) {
|
package/dist/tokens/derived.css
CHANGED
|
@@ -20,6 +20,15 @@
|
|
|
20
20
|
--control-outline-channels: h s calc(l - 5.3);
|
|
21
21
|
--control-outline-alpha: 0.11;
|
|
22
22
|
|
|
23
|
+
--text-link: initial;
|
|
24
|
+
--text-brand: initial;
|
|
25
|
+
--text-primary: initial;
|
|
26
|
+
|
|
27
|
+
--text-link-channels: var(--primary-hover-channels);
|
|
28
|
+
--text-brand-channels: var(--primary-hover-channels);
|
|
29
|
+
|
|
30
|
+
--text-primary-channels: var(--primary-active-channels);
|
|
31
|
+
|
|
23
32
|
--destructive-hover: 359 50.6% 53.1%;
|
|
24
33
|
--destructive-active: 355 70.6% 33.3%;
|
|
25
34
|
|
|
@@ -39,6 +48,11 @@
|
|
|
39
48
|
--control-outline-channels: h calc(s * 0.99) calc(l - 25.1);
|
|
40
49
|
--control-outline-alpha: 0.29;
|
|
41
50
|
|
|
51
|
+
--text-link-channels: h s l;
|
|
52
|
+
--text-brand-channels: h s l;
|
|
53
|
+
|
|
54
|
+
--text-primary-channels: var(--primary-hover-channels);
|
|
55
|
+
|
|
42
56
|
--destructive-hover: 358.8 42.3% 53.1%;
|
|
43
57
|
--destructive-active: 357.3 50.6% 34.1%;
|
|
44
58
|
|
|
@@ -54,6 +68,9 @@
|
|
|
54
68
|
--primary-active: 268.7 100% 34.5%;
|
|
55
69
|
--primary-border: 268.7 68% 66%;
|
|
56
70
|
--control-outline: 268.7 100% 44.7%;
|
|
71
|
+
--text-link: 268.7 100% 41.6%;
|
|
72
|
+
--text-brand: 268.7 100% 41.6%;
|
|
73
|
+
--text-primary: 268.7 100% 34.5%;
|
|
57
74
|
}
|
|
58
75
|
|
|
59
76
|
.dark,
|
|
@@ -62,5 +79,8 @@
|
|
|
62
79
|
--primary-active: 268.7 100% 81.1%;
|
|
63
80
|
--primary-border: 268.7 46.7% 23.5%;
|
|
64
81
|
--control-outline: 268.7 99% 61.8%;
|
|
82
|
+
--text-link: 268.7 100% 86.9%;
|
|
83
|
+
--text-brand: 268.7 100% 86.9%;
|
|
84
|
+
--text-primary: 268.7 100% 92.7%;
|
|
65
85
|
}
|
|
66
86
|
}
|
|
@@ -40,21 +40,17 @@
|
|
|
40
40
|
--text-tertiary: 44 5% 55%;
|
|
41
41
|
--text-disabled: 40 6% 68%;
|
|
42
42
|
|
|
43
|
-
--text-link: 268.3 100% 41.6%;
|
|
44
|
-
--text-brand: 268.3 100% 41.6%;
|
|
45
|
-
|
|
46
|
-
--text-primary: 268 100% 34.5%;
|
|
47
43
|
--text-success: 152 84% 22%;
|
|
48
44
|
--text-warning: 36 100% 28%;
|
|
49
45
|
--text-info: 221 70% 38%;
|
|
50
46
|
--text-error: 357 75% 38%;
|
|
51
47
|
|
|
52
|
-
--mark-primary:
|
|
53
|
-
--mark-success:
|
|
54
|
-
--mark-warning:
|
|
55
|
-
--mark-info:
|
|
56
|
-
--mark-destructive:
|
|
57
|
-
--mark-attention:
|
|
48
|
+
--mark-primary: initial;
|
|
49
|
+
--mark-success: initial;
|
|
50
|
+
--mark-warning: initial;
|
|
51
|
+
--mark-info: initial;
|
|
52
|
+
--mark-destructive: initial;
|
|
53
|
+
--mark-attention: initial;
|
|
58
54
|
|
|
59
55
|
--secondary-hover: 45 15% 91%;
|
|
60
56
|
--secondary-active: 45 15% 88%;
|
|
@@ -349,10 +345,7 @@
|
|
|
349
345
|
|
|
350
346
|
--text-tertiary: 44 6% 56%;
|
|
351
347
|
--text-disabled: 45 6% 40%;
|
|
352
|
-
--text-link: 268.7 100% 86.9%;
|
|
353
|
-
--text-brand: 268.7 100% 86.9%;
|
|
354
348
|
|
|
355
|
-
--text-primary: 262.7 100% 92.7%;
|
|
356
349
|
--text-success: 146 55% 64%;
|
|
357
350
|
--text-warning: 44 95% 62%;
|
|
358
351
|
--text-info: 221 70% 72%;
|
package/docs/CUSTOMER-THEMING.md
CHANGED
|
@@ -6,6 +6,82 @@ The design system ships a complete, **zero-config default theme**. Two audiences
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
+
## The order to reach for things — read this before anything below
|
|
10
|
+
|
|
11
|
+
This document lists a lot of ways to change how the system looks. They are not alternatives; they
|
|
12
|
+
are a **priority order**, and the whole point of the order is that you stop at the first level that
|
|
13
|
+
does the job. Ant Design states the same rule for the same reason — _"In most cases, using Seed
|
|
14
|
+
Tokens is sufficient for custom themes"_ — and the cost of skipping down a level is real, not
|
|
15
|
+
stylistic.
|
|
16
|
+
|
|
17
|
+
| level | what it is | when | what you give up by going lower |
|
|
18
|
+
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | ------------------------------------------------------------------------- |
|
|
19
|
+
| **1 · seed** | `--primary`, `--radius`, `--font-size-base`, `--shadow-color` — the handful everything derives from. `pnpm gen:brand '#RRGGBB'` writes them for you | **almost always** | nothing — this is the main road |
|
|
20
|
+
| **2 · role** | a named semantic token: `--text-link`, `--accent`, `--card-radius` | when the seed is right but ONE role must differ | that role stops following the seed; a later brand change will not move it |
|
|
21
|
+
| **3 · scope** | the same token under `[data-tenant]` / `.dark` / any subtree | multi-tenant, or one region that differs | nothing extra, provided you set the token and not a literal |
|
|
22
|
+
| **4 · instance** | a documented prop, or `style={{ "--x": … }}` on one element | this one element, this one time | it is invisible to every audit and every future theme |
|
|
23
|
+
|
|
24
|
+
**Why the order matters more than the count of knobs.** Every level below the first is a value that
|
|
25
|
+
has stopped being derived. A literal at level 4 is not "more control" — it is a pixel that has left
|
|
26
|
+
the system, and nothing will tell you when the brand moves past it. That is why the generator
|
|
27
|
+
writes three tokens and not thirty: the ones it leaves out are not missing, they are _downstream_.
|
|
28
|
+
|
|
29
|
+
**If you find yourself at level 4 twice for the same reason, the token is missing.** File it —
|
|
30
|
+
`docs/COMPOSITION-VS-COMPONENT.md` has the test for whether it is a token or a composition. Adding
|
|
31
|
+
the knob is how the system absorbs the change; repeating the literal is how it drifts.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Start from one hex — `pnpm gen:brand`
|
|
36
|
+
|
|
37
|
+
Everything below this section is the manual route, and it is worth reading because it says what each
|
|
38
|
+
role means. But the colour half of a brand file is mechanical, and two of its decisions are ones CSS
|
|
39
|
+
cannot make at all, so there is a generator:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
pnpm gen:brand '#2563EB' --name acme --out src/theme
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
It writes `acme.service.css` and `acme.email.ts`, and prints what it measured:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
light seed #2563eb · dark seed #5586ef (lifted 10.4%)
|
|
49
|
+
|
|
50
|
+
✓ primary label on fill (light) 5.17:1 (needs 4.5:1)
|
|
51
|
+
✓ primary label on fill (dark) 6.03:1 (needs 4.5:1)
|
|
52
|
+
✓ primary fill on canvas (light) 5.09:1 (needs 3:1)
|
|
53
|
+
✓ primary fill on canvas (dark) 5.10:1 (needs 3:1)
|
|
54
|
+
✓ link ink on canvas (light) 6.73:1 (needs 4.5:1)
|
|
55
|
+
✓ link ink on canvas (dark) 6.36:1 (needs 4.5:1)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
It exits non-zero when a ratio misses, so a brand that cannot meet AA says so at the point you
|
|
59
|
+
choose the colour rather than at the point a user cannot read a link.
|
|
60
|
+
|
|
61
|
+
**The two things it does that hand-authoring keeps getting wrong:**
|
|
62
|
+
|
|
63
|
+
- **A dark seed.** Nothing in CSS lifts a light seed onto the dark spine, so a brand file that sets
|
|
64
|
+
`--primary` only in `:root` keeps the GoDX violet in dark mode and nothing says so. The generator
|
|
65
|
+
holds your hue and saturation and moves lightness until the dark seed reads against the dark
|
|
66
|
+
canvas the way the light seed reads against the light one.
|
|
67
|
+
- **Email.** `src/email/tokens.generated.ts` bakes literal hex at build time, because Gmail strips
|
|
68
|
+
`<style>` and Outlook ignores custom properties. Those literals are _this package's_ seed, so a
|
|
69
|
+
re-themed product still sends GoDX-violet mail — the one surface no amount of CSS reaches. The
|
|
70
|
+
emitted `acme.email.ts` is the override that corrects it.
|
|
71
|
+
|
|
72
|
+
**What it deliberately leaves out**, because writing them would be a regression:
|
|
73
|
+
|
|
74
|
+
- `--primary-hover`, `--primary-active`, `--primary-border`, `--control-outline` — these DERIVE from
|
|
75
|
+
the `--primary` in scope at the element that paints them (gh#678). A literal pins them to one seed
|
|
76
|
+
and stops them following the next change.
|
|
77
|
+
- `--brand` / `--brand-foreground` — the identity role is independent of the action colour on
|
|
78
|
+
purpose (gh#250), so the logo does not retint when a tenant changes its button colour.
|
|
79
|
+
|
|
80
|
+
The output is a starting point, not a ceiling: every role in the tables below can still be set by
|
|
81
|
+
hand in the generated file, and an explicit value always beats a derived default.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
9
85
|
## Internal apps — zero config
|
|
10
86
|
|
|
11
87
|
```ts
|
|
@@ -165,17 +241,20 @@ Import the styles, then set anchor tokens in your app's `theme.css` (loaded afte
|
|
|
165
241
|
|
|
166
242
|
### Focus ring — THE SWITCH FIRST, then three levels of override
|
|
167
243
|
|
|
168
|
-
**The indicator ships
|
|
244
|
+
**The indicator ships ON.** `--focus-outline` is `1` (`src/tokens/foundation.css`), and every painted focus length multiplies by it, so a focus mark paints by default and the package meets WCAG 2.2 SC 2.4.7. It did ship `0` once, and that earlier default — with its stated cost, a forfeited SC 2.4.7 and JIS X 8341-3 AA claim — is recorded in `docs/DESIGN-AUTHORITY.md`; gh#544 flipped it. Nothing has to be opted into.
|
|
245
|
+
|
|
246
|
+
Switching the paint is ONE attribute on the root element, no CSS:
|
|
169
247
|
|
|
170
248
|
```html
|
|
171
249
|
<html data-focus-outline="on"></html>
|
|
250
|
+
<html data-focus-outline="off"></html>
|
|
172
251
|
```
|
|
173
252
|
|
|
174
253
|
(`AppProvider` has the equivalent.) Every `:focus-visible` selector is present either way; only the paint is switched.
|
|
175
254
|
|
|
176
255
|
Every ring is then drawn by a single rule (`src/styles/focus-ring.css`) reading the tokens above. Nothing else paints one; a test fails the build if a stylesheet tries.
|
|
177
256
|
|
|
178
|
-
**Thickness is `--focus-ring-weight`, never `--focus-ring-width`.** The width is DERIVED — `calc(var(--focus-ring-weight) * var(--focus-outline))` — so assigning it directly paints a ring even
|
|
257
|
+
**Thickness is `--focus-ring-weight`, never `--focus-ring-width`.** The width is DERIVED — `calc(var(--focus-ring-weight) * var(--focus-outline))` — so assigning it directly paints a ring even where the indicator is switched off, and that is exactly what the build-failing test forbids a stylesheet to do.
|
|
179
258
|
|
|
180
259
|
```css
|
|
181
260
|
:root {
|
|
@@ -203,7 +282,7 @@ Every ring is then drawn by a single rule (`src/styles/focus-ring.css`) reading
|
|
|
203
282
|
<div style={{ "--focus-ring-color": "0 84% 60%" } as React.CSSProperties}>…</div>
|
|
204
283
|
```
|
|
205
284
|
|
|
206
|
-
**Turning it
|
|
285
|
+
**Turning it off** — set `--focus-outline: 0` (or `data-focus-outline="off"`). Do NOT reach for `--focus-ring-width`: it is derived from the weight and the switch, and pinning it to any value is the same mistake in the other direction. Note the cost: with no visible focus indicator the package no longer meets WCAG 2.2 SC 2.4.7, so this is a claim you are giving up, not a style preference.
|
|
207
286
|
|
|
208
287
|
**Adding your own component to the system**: put `ui-focus-ring` (or `ui-focus-ring-outline` when the mark needs a gap) on the focusable element.
|
|
209
288
|
|
|
@@ -135,7 +135,7 @@ Legend: ✓ covered · N/A reasoned skip · · UNTESTED (blank cell = UNTESTED).
|
|
|
135
135
|
| TreeSelect | ✓ | ✓ | · | · | · | · | · | · | · | · |
|
|
136
136
|
| Transfer | ✓ | N/A | · | · | · | · | · | · | · | · |
|
|
137
137
|
| Upload | ✓ | ✓ | · | · | · | · | · | · | · | · |
|
|
138
|
-
| UploadCropDialog | ✓ |
|
|
138
|
+
| UploadCropDialog | ✓ | N/A | N/A | · | · | · | · | · | · | · |
|
|
139
139
|
| ColorPicker | ✓ | N/A | · | · | · | · | · | · | · | · |
|
|
140
140
|
| Slider | ✓ | N/A | · | · | · | · | · | · | · | · |
|
|
141
141
|
| Calendar | ✓ | N/A | · | N/A | · | · | · | · | · | · |
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { useRef, useState } from "react";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
Avatar,
|
|
5
|
+
AvatarFallback,
|
|
6
|
+
AvatarImage,
|
|
7
|
+
Card,
|
|
8
|
+
CardContent,
|
|
9
|
+
CardDescription,
|
|
10
|
+
CardHeader,
|
|
11
|
+
CardTitle,
|
|
12
|
+
} from "@godxjp/ui/data-display";
|
|
13
|
+
import { Upload, UploadCropDialog } from "@godxjp/ui/data-entry";
|
|
14
|
+
import { Button, Text } from "@godxjp/ui/general";
|
|
15
|
+
import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* UploadCropDialog — the square-crop step of an avatar flow, on its own.
|
|
19
|
+
*
|
|
20
|
+
* MOST SCREENS SHOULD NOT REACH FOR THIS. `<Upload variant="avatar-crop">` already embeds this
|
|
21
|
+
* dialog and owns the picker, the object URL and the commit; mounting both double-mounts the
|
|
22
|
+
* dialog. The standalone component exists for the case where the FILE ARRIVES FROM SOMEWHERE ELSE
|
|
23
|
+
* — a drag-drop zone you already own, a paste handler, a file already on the server — and only the
|
|
24
|
+
* crop step is wanted. That is the case this frame shows, beside the composed one for contrast.
|
|
25
|
+
*
|
|
26
|
+
* It is fully controlled: `open`, `file` and `onConfirm` are all required, and the dialog never
|
|
27
|
+
* opens itself. It creates and revokes its own object URL, so a caller passes the raw `File` and
|
|
28
|
+
* does NOT pre-create one. The result is always a 256×256 image/jpeg.
|
|
29
|
+
*/
|
|
30
|
+
export default function Demo() {
|
|
31
|
+
const [cropFile, setCropFile] = useState<File | null>(null);
|
|
32
|
+
const [avatar, setAvatar] = useState<string | null>(null);
|
|
33
|
+
const [lastResult, setLastResult] = useState<string | null>(null);
|
|
34
|
+
const pickerRef = useRef<HTMLInputElement>(null);
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<PageContainer title="UploadCropDialog" subtitle="切り抜きだけを単体で使う場合">
|
|
38
|
+
<Flex direction="col" gap="lg">
|
|
39
|
+
<Card>
|
|
40
|
+
<CardHeader>
|
|
41
|
+
<CardTitle level={2}>単体で使う</CardTitle>
|
|
42
|
+
<CardDescription>
|
|
43
|
+
ファイルの取得は呼び出し側の責任です。ここではブラウザのピッカーから受け取り、
|
|
44
|
+
切り抜き結果だけをこのダイアログから受け取ります。
|
|
45
|
+
</CardDescription>
|
|
46
|
+
</CardHeader>
|
|
47
|
+
<CardContent>
|
|
48
|
+
<Flex direction="col" gap="md">
|
|
49
|
+
<Flex direction="row" gap="md" align="center" wrap>
|
|
50
|
+
<Avatar size="lg">
|
|
51
|
+
{avatar ? <AvatarImage src={avatar} alt="切り抜いたプロフィール写真" /> : null}
|
|
52
|
+
<AvatarFallback>田</AvatarFallback>
|
|
53
|
+
</Avatar>
|
|
54
|
+
<Button onClick={() => pickerRef.current?.click()}>写真を選ぶ</Button>
|
|
55
|
+
</Flex>
|
|
56
|
+
|
|
57
|
+
{/* The picker is the CONSUMER's, not the dialog's — that is the whole point of using
|
|
58
|
+
this component standalone. It is hidden because the Button above is the affordance;
|
|
59
|
+
a visible raw control beside a godx Button would be two controls for one job. */}
|
|
60
|
+
<input
|
|
61
|
+
ref={pickerRef}
|
|
62
|
+
type="file"
|
|
63
|
+
accept="image/*"
|
|
64
|
+
className="sr-only"
|
|
65
|
+
aria-hidden
|
|
66
|
+
tabIndex={-1}
|
|
67
|
+
onChange={(event) => {
|
|
68
|
+
const file = event.target.files?.[0] ?? null;
|
|
69
|
+
setCropFile(file);
|
|
70
|
+
// Clear the input so re-picking the SAME file fires change again.
|
|
71
|
+
event.target.value = "";
|
|
72
|
+
}}
|
|
73
|
+
/>
|
|
74
|
+
|
|
75
|
+
<Text size="sm" tone="muted" aria-live="polite">
|
|
76
|
+
{lastResult ?? "まだ切り抜いていません。"}
|
|
77
|
+
</Text>
|
|
78
|
+
|
|
79
|
+
<UploadCropDialog
|
|
80
|
+
open={cropFile !== null}
|
|
81
|
+
// Always clear the held File on close, or the next open shows a stale image.
|
|
82
|
+
onOpenChange={(open) => !open && setCropFile(null)}
|
|
83
|
+
file={cropFile}
|
|
84
|
+
onConfirm={(cropped) => {
|
|
85
|
+
setAvatar(URL.createObjectURL(cropped));
|
|
86
|
+
setLastResult(
|
|
87
|
+
`${cropped.name} · ${cropped.type} · ${Math.round(cropped.size / 1024)} KB`,
|
|
88
|
+
);
|
|
89
|
+
}}
|
|
90
|
+
/>
|
|
91
|
+
</Flex>
|
|
92
|
+
</CardContent>
|
|
93
|
+
</Card>
|
|
94
|
+
|
|
95
|
+
<Card>
|
|
96
|
+
<CardHeader>
|
|
97
|
+
<CardTitle level={2}>通常はこちら</CardTitle>
|
|
98
|
+
<CardDescription>
|
|
99
|
+
`Upload variant="avatar-crop"` は同じダイアログを内部に持ち、ピッカーも
|
|
100
|
+
オブジェクトURLも引き受けます。両方を同時に置いてはいけません。
|
|
101
|
+
</CardDescription>
|
|
102
|
+
</CardHeader>
|
|
103
|
+
<CardContent>
|
|
104
|
+
<Upload variant="avatar-crop" accept="image/*" />
|
|
105
|
+
</CardContent>
|
|
106
|
+
</Card>
|
|
107
|
+
</Flex>
|
|
108
|
+
</PageContainer>
|
|
109
|
+
);
|
|
110
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@godxjp/ui",
|
|
3
|
-
"version": "28.
|
|
4
|
-
"godxUiMcp": "28.
|
|
3
|
+
"version": "28.5.0",
|
|
4
|
+
"godxUiMcp": "28.5.0",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
22
|
"sideEffects": false,
|
|
23
|
-
"description": "@godxjp/ui
|
|
23
|
+
"description": "@godxjp/ui \u2014 shared React UI framework (shadcn + Radix + Tailwind v4).",
|
|
24
24
|
"files": [
|
|
25
25
|
"LICENSE",
|
|
26
26
|
"dist",
|
|
@@ -303,115 +303,121 @@
|
|
|
303
303
|
}
|
|
304
304
|
},
|
|
305
305
|
"scripts": {
|
|
306
|
-
"
|
|
307
|
-
"
|
|
308
|
-
"
|
|
309
|
-
"
|
|
310
|
-
"
|
|
311
|
-
"format": "prettier --check .",
|
|
312
|
-
"format:fix": "prettier --write .",
|
|
313
|
-
"test": "vitest run",
|
|
314
|
-
"test:manual": "vitest run --config vitest.manual.config.ts",
|
|
315
|
-
"test:visual:auth-login": "node scripts/auth-shell-login-visual.mjs",
|
|
316
|
-
"test:visual:auth-registration": "node scripts/auth-shell-registration-visual.mjs",
|
|
317
|
-
"test:visual:topbar-collision": "node scripts/topbar-collision-visual.mjs",
|
|
318
|
-
"test:visual:table-collection-cjk": "node scripts/table-collection-cjk-visual.mjs",
|
|
319
|
-
"test:visual:chart-cjk-axis": "node scripts/chart-cjk-axis-visual.mjs",
|
|
320
|
-
"test:visual:kanban-select": "node scripts/kanban-select-visual.mjs",
|
|
321
|
-
"test:watch": "vitest",
|
|
322
|
-
"test:coverage": "vitest run --coverage",
|
|
323
|
-
"check:example-imports": "node scripts/check-example-imports.mjs",
|
|
324
|
-
"check:frame-coverage": "node scripts/frame-coverage.mjs",
|
|
325
|
-
"check:frame-coverage-report": "node scripts/frame-coverage.mjs --check",
|
|
326
|
-
"check:frame-axe": "node scripts/check-frame-axe.mjs",
|
|
327
|
-
"gen:frame-coverage-ledger": "node scripts/gen-frame-coverage-ledger.mjs",
|
|
328
|
-
"check:frame-coverage-ledger": "node scripts/gen-frame-coverage-ledger.mjs --check && node scripts/check-frame-coverage-ledger.mjs",
|
|
329
|
-
"check:screen-reader-evidence": "node scripts/check-screen-reader-evidence.mjs",
|
|
330
|
-
"check:voiceover-capture": "node scripts/check-voiceover-capture.mjs",
|
|
306
|
+
"audit": "node scripts/ui-audit.mjs",
|
|
307
|
+
"audit:component-cases": "node scripts/check-component-case-evidence.mjs",
|
|
308
|
+
"audit:examples": "node scripts/ui-audit.mjs docs",
|
|
309
|
+
"build": "tsup && tsc -p tsconfig.build.json && node scripts/copy-styles.mjs && node scripts/fix-esm-extensions.mjs && node scripts/add-use-client.mjs",
|
|
310
|
+
"build:jis-level1-fonts": "node scripts/build-jis-level1-fonts.mjs",
|
|
331
311
|
"capture:voiceover": "node scripts/capture-voiceover-evidence.mjs",
|
|
312
|
+
"check:agent-catalog": "node scripts/gen-agent-catalog.mjs --check",
|
|
313
|
+
"check:app-shell-narrow-grid": "node scripts/check-app-shell-narrow-grid.mjs",
|
|
314
|
+
"check:app-shell-page-width": "node scripts/check-app-shell-page-width.mjs",
|
|
315
|
+
"check:audit-sync": "node scripts/check-audit-sync.mjs",
|
|
316
|
+
"check:catalog-contradictions": "node scripts/check-catalog-contradictions.mjs",
|
|
317
|
+
"check:catalog-snippets": "node scripts/audit-catalog-snippets.mjs",
|
|
318
|
+
"check:choice-hit-target": "node scripts/check-choice-hit-target.mjs",
|
|
319
|
+
"check:component-api-manifest": "node scripts/gen-component-api-manifest.mjs --check",
|
|
320
|
+
"check:contrast": "node scripts/check-contrast.mjs",
|
|
321
|
+
"check:control-sizing": "node scripts/check-control-sizing.mjs",
|
|
322
|
+
"check:core-isolation": "node scripts/check-core-isolation.mjs",
|
|
323
|
+
"check:data-entry-frame-runtime": "node scripts/check-data-entry-frame-runtime.mjs",
|
|
332
324
|
"check:data-entry-owner-source": "node scripts/check-data-entry-owner-source.mjs",
|
|
333
325
|
"check:data-entry-touch-aria": "node scripts/check-data-entry-touch-aria.mjs",
|
|
326
|
+
"check:data-table-empty-inset": "node scripts/check-data-table-empty-inset.mjs",
|
|
327
|
+
"check:disclosure-duplication": "node scripts/check-disclosure-duplication.mjs",
|
|
334
328
|
"check:display-runtime-evidence": "node scripts/check-display-runtime-evidence.mjs",
|
|
335
|
-
"check:
|
|
336
|
-
"check:
|
|
337
|
-
"check:
|
|
338
|
-
"check:
|
|
329
|
+
"check:dist-tokens-resolve": "node scripts/check-dist-tokens-resolve.mjs",
|
|
330
|
+
"check:doc-prop-existence": "node scripts/check-doc-prop-existence.mjs",
|
|
331
|
+
"check:email-token-sync": "node scripts/gen-email-tokens.mjs --check",
|
|
332
|
+
"check:example-imports": "node scripts/check-example-imports.mjs",
|
|
333
|
+
"check:focus-ring-paint": "node scripts/check-focus-ring-paint.mjs",
|
|
334
|
+
"check:font-fallback-metrics": "node scripts/check-font-fallback-metrics.mjs",
|
|
335
|
+
"check:frame-axe": "node scripts/check-frame-axe.mjs",
|
|
339
336
|
"check:frame-contracts": "pnpm check:component-api-manifest && pnpm audit:component-cases && pnpm check:frame-coverage && pnpm check:frame-coverage-ledger && pnpm check:screen-reader-evidence && pnpm check:data-entry-owner-source && pnpm check:display-runtime-evidence",
|
|
337
|
+
"check:frame-coverage": "node scripts/frame-coverage.mjs",
|
|
338
|
+
"check:frame-coverage-ledger": "node scripts/gen-frame-coverage-ledger.mjs --check && node scripts/check-frame-coverage-ledger.mjs",
|
|
339
|
+
"check:frame-coverage-report": "node scripts/frame-coverage.mjs --check",
|
|
340
|
+
"check:frame-geometry": "node scripts/frame-geometry.mjs",
|
|
340
341
|
"check:frame-runtime": "pnpm check:data-entry-touch-aria && pnpm check:app-shell-narrow-grid && pnpm check:app-shell-page-width && pnpm check:choice-hit-target",
|
|
341
|
-
"
|
|
342
|
-
"
|
|
343
|
-
"verify:ci": "pnpm verify:ci:static && pnpm check:frame-contracts && pnpm test",
|
|
344
|
-
"verify:ci:static": "pnpm build && pnpm check:packed-public-contract && pnpm typecheck && pnpm typecheck:docs && pnpm lint && pnpm preview:build && pnpm check:registry && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:no-consumer-coupling && pnpm check:use-client && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:no-external-assets && pnpm check:token-scale-bypass && pnpm check:no-antd-runtime && pnpm check:radix-surface && pnpm check:dist-tokens-resolve && pnpm check:no-hardcoded-geometry && pnpm check:no-hardcoded-css-values && pnpm check:disclosure-duplication && pnpm check:no-inline-magic-numbers && pnpm check:no-tailwind-class-assertions && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-lockstep && pnpm check:measurement-contract && pnpm check:mcp-token-sync && pnpm check:email-token-sync && pnpm check:mcp-sync && pnpm check:doc-prop-existence && pnpm check:mcp-catalog-coverage && pnpm check:mcp-orphans && pnpm check:mcp-catalog-completeness && pnpm check:mcp-pattern-imports && pnpm check:audit-sync && pnpm check:frame-coverage-report && pnpm check:gate-coverage && pnpm check:mcp-prop-sync && pnpm check:catalog-contradictions && pnpm check:catalog-snippets",
|
|
345
|
-
"verify:browser": "pnpm check:contrast && pnpm check:text-ink-clip && pnpm check:font-fallback-metrics && pnpm check:visual-audit",
|
|
346
|
-
"verify:release": "pnpm verify:static && pnpm check:frame-contracts && pnpm check:frame-coverage",
|
|
347
|
-
"verify:publish-tree": "pnpm build && pnpm check:packed-public-contract && pnpm check:use-client && pnpm check:dist-tokens-resolve",
|
|
348
|
-
"check:release-plan": "node scripts/check-release-command-plan.mjs",
|
|
349
|
-
"check:packed-public-contract": "node scripts/check-packed-public-contract.mjs",
|
|
350
|
-
"check:mcp-pattern-imports": "node scripts/check-mcp-pattern-imports.mjs",
|
|
351
|
-
"check:mcp-lockstep": "node scripts/check-release-lockstep.mjs",
|
|
352
|
-
"check:mcp-sync": "node scripts/check-mcp-sync.mjs",
|
|
342
|
+
"check:gate-coverage": "node scripts/check-gate-coverage.mjs",
|
|
343
|
+
"check:mcp-catalog-completeness": "node scripts/check-mcp-catalog-completeness.mjs",
|
|
353
344
|
"check:mcp-catalog-coverage": "node scripts/check-mcp-catalog-coverage.mjs",
|
|
345
|
+
"check:mcp-lockstep": "node scripts/check-release-lockstep.mjs",
|
|
354
346
|
"check:mcp-orphans": "node scripts/check-mcp-orphans.mjs",
|
|
355
|
-
"check:mcp-
|
|
356
|
-
"check:catalog-contradictions": "node scripts/check-catalog-contradictions.mjs",
|
|
347
|
+
"check:mcp-pattern-imports": "node scripts/check-mcp-pattern-imports.mjs",
|
|
357
348
|
"check:mcp-prop-sync": "node scripts/check-mcp-prop-sync.mjs",
|
|
358
|
-
"check:
|
|
359
|
-
"
|
|
360
|
-
"check:
|
|
361
|
-
"
|
|
362
|
-
"check:
|
|
363
|
-
"check:
|
|
364
|
-
"check:token-scale-bypass": "node scripts/check-token-scale-bypass.mjs",
|
|
365
|
-
"check:dist-tokens-resolve": "node scripts/check-dist-tokens-resolve.mjs",
|
|
366
|
-
"check:no-hardcoded-geometry": "node scripts/check-no-hardcoded-geometry.mjs",
|
|
349
|
+
"check:mcp-sync": "node scripts/check-mcp-sync.mjs",
|
|
350
|
+
"check:mcp-token-sync": "node scripts/gen-component-tokens.mjs --check",
|
|
351
|
+
"check:measurement-contract": "node scripts/gen-measurement-contract.mjs --check",
|
|
352
|
+
"check:measurement-contract-browser": "node scripts/check-measurement-contract.mjs",
|
|
353
|
+
"check:no-antd-runtime": "node scripts/check-no-antd-runtime.mjs",
|
|
354
|
+
"check:no-consumer-coupling": "node scripts/check-no-consumer-coupling.mjs",
|
|
367
355
|
"check:no-external-assets": "node scripts/check-no-external-assets.mjs",
|
|
368
356
|
"check:no-hardcoded-css-values": "node scripts/check-no-hardcoded-css-values.mjs",
|
|
369
|
-
"check:
|
|
357
|
+
"check:no-hardcoded-geometry": "node scripts/check-no-hardcoded-geometry.mjs",
|
|
370
358
|
"check:no-inline-magic-numbers": "node scripts/check-no-inline-magic-numbers.mjs",
|
|
371
359
|
"check:no-tailwind-class-assertions": "node scripts/check-no-tailwind-class-assertions.mjs",
|
|
372
|
-
"check:
|
|
360
|
+
"check:number-input-step-target": "node scripts/check-number-input-step-target.mjs",
|
|
361
|
+
"check:packed-public-contract": "node scripts/check-packed-public-contract.mjs",
|
|
362
|
+
"check:pr-closes-keyword": "node scripts/check-pr-closes-keyword.mjs",
|
|
363
|
+
"check:prop-vocabulary": "node scripts/check-prop-vocabulary.mjs",
|
|
364
|
+
"check:radix-surface": "node scripts/check-radix-surface.mjs",
|
|
365
|
+
"check:registry": "node scripts/gen-registry.mjs --check",
|
|
366
|
+
"check:release-plan": "node scripts/check-release-command-plan.mjs",
|
|
373
367
|
"check:rtl": "node scripts/check-rtl.mjs",
|
|
368
|
+
"check:screen-reader-evidence": "node scripts/check-screen-reader-evidence.mjs",
|
|
369
|
+
"check:state-legible": "node scripts/check-state-legible.mjs",
|
|
370
|
+
"check:text-ink-clip": "node scripts/check-text-ink-clip.mjs",
|
|
371
|
+
"check:token-scale-bypass": "node scripts/check-token-scale-bypass.mjs",
|
|
372
|
+
"check:token-tiers": "node scripts/check-token-tiers.mjs",
|
|
374
373
|
"check:typography": "node scripts/check-typography.mjs",
|
|
374
|
+
"check:use-client": "node scripts/check-use-client.mjs",
|
|
375
|
+
"check:visual-audit": "node scripts/visual-audit-smoke.mjs",
|
|
376
|
+
"check:voiceover-capture": "node scripts/check-voiceover-capture.mjs",
|
|
377
|
+
"dev": "node scripts/dev.mjs",
|
|
378
|
+
"docs:sync-primitives": "node preview/scripts/sync-primitive-docs.mjs && prettier --write \"docs/primitives/**/*.tsx\"",
|
|
379
|
+
"format": "prettier --check .",
|
|
380
|
+
"format:fix": "prettier --write .",
|
|
381
|
+
"gen:agent-catalog": "node scripts/gen-agent-catalog.mjs",
|
|
382
|
+
"gen:component-api-manifest": "node scripts/gen-component-api-manifest.mjs",
|
|
375
383
|
"gen:component-tokens": "node scripts/gen-component-tokens.mjs",
|
|
376
|
-
"check:no-antd-runtime": "node scripts/check-no-antd-runtime.mjs",
|
|
377
|
-
"check:radix-surface": "node scripts/check-radix-surface.mjs",
|
|
378
384
|
"gen:email-tokens": "node scripts/gen-email-tokens.mjs",
|
|
379
|
-
"
|
|
380
|
-
"check:no-consumer-coupling": "node scripts/check-no-consumer-coupling.mjs",
|
|
381
|
-
"release": "node scripts/release.mjs",
|
|
382
|
-
"preview": "node preview/scripts/kill-port.mjs && vite --config preview/vite.config.ts --port 6008 --strictPort",
|
|
383
|
-
"preview:build": "vite build --config preview/vite.config.ts && node scripts/gen-registry.mjs",
|
|
385
|
+
"gen:frame-coverage-ledger": "node scripts/gen-frame-coverage-ledger.mjs",
|
|
384
386
|
"gen:registry": "node scripts/gen-registry.mjs",
|
|
385
|
-
"check:registry": "node scripts/gen-registry.mjs --check",
|
|
386
|
-
"docs:sync-primitives": "node preview/scripts/sync-primitive-docs.mjs && prettier --write \"docs/primitives/**/*.tsx\"",
|
|
387
|
-
"audit": "node scripts/ui-audit.mjs",
|
|
388
|
-
"audit:examples": "node scripts/ui-audit.mjs docs",
|
|
389
|
-
"build": "tsup && tsc -p tsconfig.build.json && node scripts/copy-styles.mjs && node scripts/fix-esm-extensions.mjs && node scripts/add-use-client.mjs",
|
|
390
|
-
"build:jis-level1-fonts": "node scripts/build-jis-level1-fonts.mjs",
|
|
391
|
-
"dev": "node scripts/dev.mjs",
|
|
392
|
-
"prepublishOnly": "pnpm run build",
|
|
393
|
-
"check:audit-sync": "node scripts/check-audit-sync.mjs",
|
|
394
|
-
"check:gate-coverage": "node scripts/check-gate-coverage.mjs",
|
|
395
|
-
"check:contrast": "node scripts/check-contrast.mjs",
|
|
396
|
-
"check:text-ink-clip": "node scripts/check-text-ink-clip.mjs",
|
|
397
|
-
"check:font-fallback-metrics": "node scripts/check-font-fallback-metrics.mjs",
|
|
398
|
-
"visual-audit": "node scripts/visual-audit.mjs",
|
|
399
|
-
"check:visual-audit": "node scripts/visual-audit-smoke.mjs",
|
|
400
|
-
"check:frame-geometry": "node scripts/frame-geometry.mjs",
|
|
401
|
-
"postinstall": "node scripts/postinstall.mjs",
|
|
402
387
|
"init-agent": "node scripts/init-agent-kit.mjs",
|
|
403
|
-
"
|
|
404
|
-
"
|
|
405
|
-
"
|
|
406
|
-
"
|
|
407
|
-
"
|
|
408
|
-
"
|
|
409
|
-
"
|
|
410
|
-
"
|
|
411
|
-
"
|
|
412
|
-
"
|
|
388
|
+
"lint": "eslint .",
|
|
389
|
+
"lint:fix": "eslint . --fix",
|
|
390
|
+
"postinstall": "node scripts/postinstall.mjs",
|
|
391
|
+
"prepublishOnly": "pnpm run build",
|
|
392
|
+
"preview": "node preview/scripts/kill-port.mjs && vite --config preview/vite.config.ts --port 6008 --strictPort",
|
|
393
|
+
"preview:build": "vite build --config preview/vite.config.ts && node scripts/gen-registry.mjs",
|
|
394
|
+
"regen": "node scripts/regen-generated.mjs",
|
|
395
|
+
"release": "node scripts/release.mjs",
|
|
396
|
+
"ship:surface": "pnpm regen && pnpm verify:ci:static && pnpm check:frame-contracts",
|
|
397
|
+
"test": "vitest run",
|
|
398
|
+
"test:coverage": "vitest run --coverage",
|
|
399
|
+
"test:manual": "vitest run --config vitest.manual.config.ts",
|
|
400
|
+
"test:visual:auth-login": "node scripts/auth-shell-login-visual.mjs",
|
|
401
|
+
"test:visual:auth-registration": "node scripts/auth-shell-registration-visual.mjs",
|
|
402
|
+
"test:visual:chart-cjk-axis": "node scripts/chart-cjk-axis-visual.mjs",
|
|
403
|
+
"test:visual:kanban-select": "node scripts/kanban-select-visual.mjs",
|
|
404
|
+
"test:visual:table-collection-cjk": "node scripts/table-collection-cjk-visual.mjs",
|
|
405
|
+
"test:visual:topbar-collision": "node scripts/topbar-collision-visual.mjs",
|
|
406
|
+
"test:watch": "vitest",
|
|
407
|
+
"typecheck": "node node_modules/typescript-7/bin/tsc --noEmit -p tsconfig.json",
|
|
408
|
+
"typecheck:docs": "node node_modules/typescript-7/bin/tsc --noEmit -p tsconfig.docs.json",
|
|
413
409
|
"typecheck:mcp": "node node_modules/typescript-7/bin/tsc --noEmit -p mcp/tsconfig.json",
|
|
414
|
-
"
|
|
410
|
+
"typecheck:ts6": "tsc --noEmit -p tsconfig.json",
|
|
411
|
+
"verify": "pnpm typecheck && pnpm lint && pnpm format && pnpm build && pnpm preview:build && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:no-consumer-coupling && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:no-external-assets && pnpm check:token-scale-bypass && pnpm check:radix-surface && pnpm check:dist-tokens-resolve && pnpm check:no-hardcoded-geometry && pnpm check:no-hardcoded-css-values && pnpm check:disclosure-duplication && pnpm check:no-inline-magic-numbers && pnpm check:no-tailwind-class-assertions && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-lockstep && pnpm check:mcp-sync && pnpm check:doc-prop-existence && pnpm check:mcp-catalog-coverage && pnpm check:mcp-orphans && pnpm check:mcp-pattern-imports && pnpm check:audit-sync && pnpm check:frame-coverage && pnpm test",
|
|
412
|
+
"verify:browser": "pnpm check:contrast && pnpm check:text-ink-clip && pnpm check:font-fallback-metrics && pnpm check:visual-audit",
|
|
413
|
+
"verify:ci": "pnpm verify:ci:static && pnpm check:frame-contracts && pnpm test",
|
|
414
|
+
"verify:ci:static": "pnpm build && pnpm check:packed-public-contract && pnpm typecheck && pnpm typecheck:docs && pnpm lint && pnpm preview:build && pnpm check:registry && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:no-consumer-coupling && pnpm check:use-client && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:no-external-assets && pnpm check:token-scale-bypass && pnpm check:no-antd-runtime && pnpm check:radix-surface && pnpm check:dist-tokens-resolve && pnpm check:no-hardcoded-geometry && pnpm check:no-hardcoded-css-values && pnpm check:disclosure-duplication && pnpm check:no-inline-magic-numbers && pnpm check:no-tailwind-class-assertions && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-lockstep && pnpm check:measurement-contract && pnpm check:mcp-token-sync && pnpm check:email-token-sync && pnpm check:mcp-sync && pnpm check:doc-prop-existence && pnpm check:mcp-catalog-coverage && pnpm check:mcp-orphans && pnpm check:mcp-catalog-completeness && pnpm check:mcp-pattern-imports && pnpm check:audit-sync && pnpm check:frame-coverage-report && pnpm check:gate-coverage && pnpm check:mcp-prop-sync && pnpm check:catalog-contradictions && pnpm check:catalog-snippets && pnpm check:absorbed-names && pnpm check:agent-catalog",
|
|
415
|
+
"verify:publish-tree": "pnpm build && pnpm check:packed-public-contract && pnpm check:use-client && pnpm check:dist-tokens-resolve",
|
|
416
|
+
"verify:release": "pnpm verify:static && pnpm check:frame-contracts && pnpm check:frame-coverage",
|
|
417
|
+
"verify:static": "pnpm build && pnpm check:packed-public-contract && pnpm typecheck && pnpm typecheck:docs && pnpm lint && pnpm preview:build && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:no-consumer-coupling && pnpm check:use-client && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:token-scale-bypass && pnpm check:radix-surface && pnpm check:dist-tokens-resolve && pnpm check:no-hardcoded-geometry && pnpm check:no-hardcoded-css-values && pnpm check:disclosure-duplication && pnpm check:no-inline-magic-numbers && pnpm check:no-tailwind-class-assertions && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-lockstep && pnpm check:mcp-sync && pnpm check:doc-prop-existence && pnpm check:mcp-catalog-coverage && pnpm check:mcp-orphans && pnpm check:mcp-pattern-imports && pnpm check:audit-sync && pnpm check:mcp-prop-sync && pnpm check:contrast && pnpm check:visual-audit && pnpm test",
|
|
418
|
+
"visual-audit": "node scripts/visual-audit.mjs",
|
|
419
|
+
"gen:brand": "node scripts/gen-brand.mjs",
|
|
420
|
+
"check:absorbed-names": "node scripts/check-absorbed-names.mjs"
|
|
415
421
|
},
|
|
416
422
|
"peerDependencies": {
|
|
417
423
|
"@hookform/resolvers": "^5.2.0",
|
|
@@ -497,6 +503,7 @@
|
|
|
497
503
|
"@types/react-dom": "^19.2.5",
|
|
498
504
|
"@vitejs/plugin-react": "^6.1.1",
|
|
499
505
|
"@vitest/coverage-v8": "^4.1.11",
|
|
506
|
+
"esbuild": ">=0.28.1",
|
|
500
507
|
"eslint": "^10.9.1",
|
|
501
508
|
"eslint-plugin-react": "^7.37.5",
|
|
502
509
|
"eslint-plugin-react-hooks": "^7.1.1",
|