@godxjp/ui 32.4.1 → 32.4.2
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/agent/START-HERE.md +1 -1
- package/agent/index.json +2 -2
- package/agent/llms.txt +3 -3
- package/dist/components/data-entry/upload.js +29 -13
- package/dist/contracts/measurement.json +1 -1
- package/dist/i18n/messages/en.json +4 -0
- package/dist/i18n/messages/ja.json +4 -0
- package/dist/i18n/messages/vi.json +4 -0
- package/dist/styles/layers.json +1 -1
- package/package.json +2 -2
package/agent/START-HERE.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
You are about to write code against a design system you did not author. This file is the whole
|
|
4
4
|
contract. Read it before you write JSX.
|
|
5
5
|
|
|
6
|
-
**This catalog describes `@godxjp/ui` 32.4.
|
|
6
|
+
**This catalog describes `@godxjp/ui` 32.4.2.** If the project you are editing has a different
|
|
7
7
|
version in its `package.json`, read the pinned catalog for THAT version instead
|
|
8
8
|
(`…/v<their-version>/agent/…`). A catalog newer than the installed package describes props that do
|
|
9
9
|
not exist yet; older, and it hides props that do. Neither failure announces itself.
|
package/agent/index.json
CHANGED
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"note": "Pin to the tag that matches the @godxjp/ui version you installed. A catalog newer than your package describes props you do not have; older, and it hides props you do.",
|
|
49
49
|
"read": {
|
|
50
50
|
"live": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/index.json",
|
|
51
|
-
"pinned": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/v32.4.
|
|
51
|
+
"pinned": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/v32.4.2/agent/index.json"
|
|
52
52
|
},
|
|
53
53
|
"source": "mcp/src/data — the same data @godxjp/ui-mcp serves — plus the foundation and semantic token tiers, read from src/tokens/*.css",
|
|
54
54
|
"start": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/START-HERE.md",
|
|
@@ -62,5 +62,5 @@
|
|
|
62
62
|
"foundation": "the seeds a consumer is invited to set — --primary, --background, --radius",
|
|
63
63
|
"semantic": "named roles that follow the seeds — --ring, --text-link, --overlay-background"
|
|
64
64
|
},
|
|
65
|
-
"version": "32.4.
|
|
65
|
+
"version": "32.4.2"
|
|
66
66
|
}
|
package/agent/llms.txt
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# @godxjp/ui
|
|
2
2
|
|
|
3
3
|
> A Japanese-enterprise React design system: 161 components, 2195 design tokens,
|
|
4
|
-
> 43 cardinal rules. This file is the entry point for AI agents. Catalog version 32.4.
|
|
4
|
+
> 43 cardinal rules. This file is the entry point for AI agents. Catalog version 32.4.2.
|
|
5
5
|
|
|
6
6
|
If your client can run a process, do not read these files — run the MCP server instead
|
|
7
|
-
(`npx @godxjp/ui-mcp@32.4.
|
|
7
|
+
(`npx @godxjp/ui-mcp@32.4.2`). It is searchable and version-locked. These files exist for agents
|
|
8
8
|
that can only fetch URLs.
|
|
9
9
|
|
|
10
10
|
## Start
|
|
@@ -26,7 +26,7 @@ that can only fetch URLs.
|
|
|
26
26
|
## Pinning
|
|
27
27
|
|
|
28
28
|
Every URL above tracks `main`. To pin to the release a project actually installed, swap `main` for
|
|
29
|
-
the tag: `.../godx-jp/godxjp-ui/v32.4.
|
|
29
|
+
the tag: `.../godx-jp/godxjp-ui/v32.4.2/agent/...`. A catalog that does not match the installed
|
|
30
30
|
package describes props that are absent, or hides props that are present, and says nothing either way.
|
|
31
31
|
|
|
32
32
|
Pinned catalogs only exist for releases whose tag actually contains `agent/`. If `…/v<version>/agent/index.json` returns 404, that release predates this catalog: read `…/main/…` instead and compare `index.json` → `version` against the package you have, so you at least know which way it drifted.
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
import { useTranslation } from "../../i18n/use-translation.js";
|
|
15
15
|
import { formatBytes } from "../../lib/format.js";
|
|
16
16
|
import { cn } from "../../lib/utils.js";
|
|
17
|
-
import { mergeAriaIds, pickFieldA11y } from "../../lib/field-a11y.js";
|
|
17
|
+
import { FieldNameContext, mergeAriaIds, pickFieldA11y } from "../../lib/field-a11y.js";
|
|
18
18
|
import { Button } from "../general/button.js";
|
|
19
19
|
import { Icon } from "../general/icon.js";
|
|
20
20
|
import { UploadCropDialog } from "./upload-crop-dialog.js";
|
|
@@ -41,6 +41,13 @@ function defaultMaxCount(variant) {
|
|
|
41
41
|
if (variant === "avatar" || variant === "avatar-crop" || variant === "picture") return 1;
|
|
42
42
|
return void 0;
|
|
43
43
|
}
|
|
44
|
+
const SINGLE_STATUS_KEY = {
|
|
45
|
+
idle: "dataEntry.upload.fileSelected",
|
|
46
|
+
uploading: "dataEntry.upload.fileUploading",
|
|
47
|
+
done: "dataEntry.upload.fileUploaded",
|
|
48
|
+
error: "dataEntry.upload.fileFailed",
|
|
49
|
+
removed: null
|
|
50
|
+
};
|
|
44
51
|
function fileMatchesAccept(file, accept) {
|
|
45
52
|
if (!accept) return true;
|
|
46
53
|
return accept.split(",").some((rule) => {
|
|
@@ -109,10 +116,12 @@ function Upload({
|
|
|
109
116
|
const disabled = disabledProp || readOnly;
|
|
110
117
|
const fieldA11y = pickFieldA11y(ariaProps);
|
|
111
118
|
const fieldLabelledBy = fieldA11y["aria-labelledby"];
|
|
119
|
+
const fieldName = React.useContext(FieldNameContext);
|
|
112
120
|
const triggerId = React.useId();
|
|
113
121
|
const selectionId = React.useId();
|
|
114
122
|
const triggerRef = React.useRef(null);
|
|
115
|
-
const
|
|
123
|
+
const ownAriaLabel = fieldA11y["aria-label"];
|
|
124
|
+
const callerAriaLabel = !fieldLabelledBy || fieldName && ownAriaLabel !== fieldName.label ? ownAriaLabel : void 0;
|
|
116
125
|
const setTriggerRef = (element) => {
|
|
117
126
|
triggerRef.current = element;
|
|
118
127
|
};
|
|
@@ -126,9 +135,9 @@ function Upload({
|
|
|
126
135
|
const [previewItem, setPreviewItem] = React.useState(null);
|
|
127
136
|
const [items, setItems] = useUploadList(value, defaultValue, onValueChange);
|
|
128
137
|
const triggerIsGroup = variant === "dropzone" && !openFileDialogOnClick;
|
|
129
|
-
const triggerA11y = {
|
|
138
|
+
const triggerA11y = (action2) => ({
|
|
130
139
|
id: triggerId,
|
|
131
|
-
"aria-labelledby": fieldLabelledBy ? `${fieldLabelledBy} ${triggerId}
|
|
140
|
+
"aria-labelledby": !fieldLabelledBy || callerAriaLabel !== void 0 || fieldName?.label && action2?.toLocaleLowerCase().includes(fieldName.label.trim().toLocaleLowerCase()) ? void 0 : `${fieldLabelledBy} ${triggerId}`,
|
|
132
141
|
"aria-describedby": mergeAriaIds(
|
|
133
142
|
fieldA11y["aria-describedby"],
|
|
134
143
|
triggerIsGroup && fieldA11y["aria-invalid"] ? fieldA11y["aria-errormessage"] : void 0,
|
|
@@ -136,7 +145,7 @@ function Upload({
|
|
|
136
145
|
),
|
|
137
146
|
"aria-errormessage": triggerIsGroup ? void 0 : fieldA11y["aria-errormessage"],
|
|
138
147
|
"aria-invalid": triggerIsGroup ? void 0 : fieldA11y["aria-invalid"]
|
|
139
|
-
};
|
|
148
|
+
});
|
|
140
149
|
const isSingleAvatar = variant === "avatar" || variant === "avatar-crop" || variant === "picture" && maxCount === 1;
|
|
141
150
|
const singleItem = isSingleAvatar ? items[0] ?? null : null;
|
|
142
151
|
const draft = useUploadDraft({
|
|
@@ -435,6 +444,7 @@ function Upload({
|
|
|
435
444
|
const uploadingCount = items.filter((it) => it.status === "uploading").length;
|
|
436
445
|
const doneCount = items.filter((it) => it.status === "done").length;
|
|
437
446
|
const errorCount = items.filter((it) => it.status === "error").length;
|
|
447
|
+
const singleFile = !multiple || maxCount === 1;
|
|
438
448
|
const liveRegion = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
439
449
|
/* @__PURE__ */ jsx(
|
|
440
450
|
Dialog,
|
|
@@ -456,7 +466,10 @@ function Upload({
|
|
|
456
466
|
] })
|
|
457
467
|
}
|
|
458
468
|
),
|
|
459
|
-
/* @__PURE__ */ jsx("span", { "aria-live": "polite", className: "sr-only", "data-slot": "upload-status", children:
|
|
469
|
+
/* @__PURE__ */ jsx("span", { "aria-live": "polite", className: "sr-only", "data-slot": "upload-status", children: singleFile && items[0] ? (() => {
|
|
470
|
+
const key = SINGLE_STATUS_KEY[items[0].status];
|
|
471
|
+
return key ? t(key, { name: items[0].name }) : "";
|
|
472
|
+
})() : errorCount > 0 ? t("dataEntry.upload.statusFailed", { count: errorCount }) : uploadingCount > 0 ? t("dataEntry.upload.statusUploading", { count: uploadingCount }) : items.length > 0 ? t("dataEntry.upload.statusReady", { count: items.length, done: doneCount }) : "" }),
|
|
460
473
|
items.length === 0 ? /* @__PURE__ */ jsx("span", { id: selectionId, className: "sr-only", "data-slot": "upload-selection", children: t("dataEntry.upload.noFileSelected") }) : null
|
|
461
474
|
] });
|
|
462
475
|
const openPicker = () => {
|
|
@@ -474,7 +487,7 @@ function Upload({
|
|
|
474
487
|
role: openFileDialogOnClick ? "button" : "group",
|
|
475
488
|
tabIndex: disabled ? -1 : 0,
|
|
476
489
|
"aria-disabled": disabled,
|
|
477
|
-
...triggerA11y,
|
|
490
|
+
...triggerA11y(t("dataEntry.upload.dropzoneLabel")),
|
|
478
491
|
"aria-label": callerAriaLabel ?? t("dataEntry.upload.dropzoneLabel"),
|
|
479
492
|
onClick: openPicker,
|
|
480
493
|
onKeyDown: (e) => {
|
|
@@ -527,7 +540,9 @@ function Upload({
|
|
|
527
540
|
disabled,
|
|
528
541
|
onClick: openPicker,
|
|
529
542
|
ref: setTriggerRef,
|
|
530
|
-
...triggerA11y
|
|
543
|
+
...triggerA11y(
|
|
544
|
+
iconOnly ? triggerAriaLabel : typeof label === "string" ? label : void 0
|
|
545
|
+
),
|
|
531
546
|
"aria-label": triggerAriaLabel,
|
|
532
547
|
className: "ui-upload-trigger",
|
|
533
548
|
children: [
|
|
@@ -573,7 +588,7 @@ function Upload({
|
|
|
573
588
|
"data-disabled": disabled ? "" : void 0,
|
|
574
589
|
className: "ui-upload-tile-add",
|
|
575
590
|
ref: setTriggerRef,
|
|
576
|
-
...triggerA11y,
|
|
591
|
+
...triggerA11y(t("dataEntry.upload.addImage")),
|
|
577
592
|
"aria-label": callerAriaLabel ?? t("dataEntry.upload.addImage"),
|
|
578
593
|
children: [
|
|
579
594
|
/* @__PURE__ */ jsx(ImagePlus, { className: "ui-upload-tile-add-icon", "aria-hidden": "true" }),
|
|
@@ -584,6 +599,7 @@ function Upload({
|
|
|
584
599
|
] });
|
|
585
600
|
}
|
|
586
601
|
if (variant === "picture" && !isSingleAvatar) {
|
|
602
|
+
const label = children ?? t("dataEntry.upload.addImage");
|
|
587
603
|
return /* @__PURE__ */ jsxs("div", { ...pasteProps, className: cn("ui-stack-sm", className), children: [
|
|
588
604
|
hiddenInput,
|
|
589
605
|
liveRegion,
|
|
@@ -596,10 +612,10 @@ function Upload({
|
|
|
596
612
|
variant: triggerVariant,
|
|
597
613
|
onClick: openPicker,
|
|
598
614
|
ref: setTriggerRef,
|
|
599
|
-
...triggerA11y,
|
|
615
|
+
...triggerA11y(typeof label === "string" ? label : void 0),
|
|
600
616
|
"aria-label": callerAriaLabel,
|
|
601
617
|
className: "ui-upload-trigger",
|
|
602
|
-
children:
|
|
618
|
+
children: label
|
|
603
619
|
}
|
|
604
620
|
),
|
|
605
621
|
list
|
|
@@ -622,7 +638,7 @@ function Upload({
|
|
|
622
638
|
disabled,
|
|
623
639
|
onClick: openPicker,
|
|
624
640
|
ref: setTriggerRef,
|
|
625
|
-
...triggerA11y,
|
|
641
|
+
...triggerA11y(t("dataEntry.upload.addImage")),
|
|
626
642
|
"aria-label": callerAriaLabel,
|
|
627
643
|
className: "ui-upload-picture-empty",
|
|
628
644
|
children: [
|
|
@@ -675,7 +691,7 @@ function Upload({
|
|
|
675
691
|
"data-disabled": disabled ? "" : void 0,
|
|
676
692
|
className: "ui-upload-avatar ui-focus-ring",
|
|
677
693
|
ref: setTriggerRef,
|
|
678
|
-
...triggerA11y,
|
|
694
|
+
...triggerA11y(t("dataEntry.upload.avatarLabel")),
|
|
679
695
|
"aria-label": callerAriaLabel ?? t("dataEntry.upload.avatarLabel"),
|
|
680
696
|
children: [
|
|
681
697
|
!showPlaceholder && item?.previewUrl ? /* @__PURE__ */ jsx("img", { src: item.previewUrl, alt: "", className: "ui-upload-avatar-image" }) : /* @__PURE__ */ jsx("span", { className: "ui-upload-avatar-placeholder", children: /* @__PURE__ */ jsx(Camera, { className: "ui-upload-avatar-icon", "aria-hidden": "true" }) }),
|
|
@@ -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": "32.4.
|
|
3
|
+
"version": "32.4.2",
|
|
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,
|
|
@@ -93,6 +93,10 @@
|
|
|
93
93
|
"statusUploading": "Uploading {count} file(s)…",
|
|
94
94
|
"statusReady": "{count} file(s), {done} uploaded",
|
|
95
95
|
"statusFailed": "{count} upload(s) failed",
|
|
96
|
+
"fileSelected": "{name} selected",
|
|
97
|
+
"fileUploading": "Uploading {name}…",
|
|
98
|
+
"fileUploaded": "{name} uploaded",
|
|
99
|
+
"fileFailed": "{name} failed to upload",
|
|
96
100
|
"removeImage": "Remove image",
|
|
97
101
|
"removeFile": "Remove {name}",
|
|
98
102
|
"cropDescription": "Drag the zoom slider, then save to crop your photo to a square.",
|
|
@@ -92,6 +92,10 @@
|
|
|
92
92
|
"statusUploading": "{count} 件をアップロード中…",
|
|
93
93
|
"statusReady": "{count} 件中 {done} 件アップロード済み",
|
|
94
94
|
"statusFailed": "{count} 件のアップロードに失敗",
|
|
95
|
+
"fileSelected": "{name} を選択済み",
|
|
96
|
+
"fileUploading": "{name} をアップロード中…",
|
|
97
|
+
"fileUploaded": "{name} をアップロード済み",
|
|
98
|
+
"fileFailed": "{name} のアップロードに失敗",
|
|
95
99
|
"removeImage": "画像を削除",
|
|
96
100
|
"removeFile": "{name} を削除",
|
|
97
101
|
"cropDescription": "ズームスライダーを調整し、保存すると写真を正方形に切り抜きます。",
|
|
@@ -92,6 +92,10 @@
|
|
|
92
92
|
"statusUploading": "Đang tải lên {count} tệp…",
|
|
93
93
|
"statusReady": "{count} tệp, đã tải lên {done}",
|
|
94
94
|
"statusFailed": "{count} tệp tải lên thất bại",
|
|
95
|
+
"fileSelected": "Đã chọn {name}",
|
|
96
|
+
"fileUploading": "Đang tải lên {name}…",
|
|
97
|
+
"fileUploaded": "Đã tải lên {name}",
|
|
98
|
+
"fileFailed": "Tải lên {name} thất bại",
|
|
95
99
|
"removeImage": "Xóa ảnh",
|
|
96
100
|
"removeFile": "Xóa {name}",
|
|
97
101
|
"cropDescription": "Kéo thanh thu phóng rồi lưu để cắt ảnh thành hình vuông.",
|
package/dist/styles/layers.json
CHANGED