@godxjp/ui 31.5.0 → 31.7.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/agent/START-HERE.md +5 -5
- package/agent/components/BranchScopePicker.json +5 -0
- package/agent/components/Breadcrumb.json +1 -1
- package/agent/components/Cascader.json +1 -1
- package/agent/components/DataTable.json +2 -2
- package/agent/components/InfiniteQueryState.json +6 -1
- package/agent/components/PageContainer.json +1 -1
- package/agent/components/Progress.json +12 -1
- package/agent/components/RangeTimeline.json +6 -0
- package/agent/components/RecordPicker.json +10 -0
- package/agent/components/Text.json +1 -1
- package/agent/components/Transfer.json +5 -0
- package/agent/components/Tree.json +21 -4
- package/agent/components/TreeSelect.json +1 -1
- package/agent/components.json +72 -13
- package/agent/index.json +5 -5
- package/agent/llms.txt +6 -6
- package/agent/tokens.json +12 -0
- package/dist/components/data-display/data-table.d.ts +3 -0
- package/dist/components/data-display/data-table.js +415 -370
- package/dist/components/data-display/progress.d.ts +16 -0
- package/dist/components/data-display/progress.js +17 -3
- package/dist/components/data-display/range-timeline.d.ts +20 -0
- package/dist/components/data-display/range-timeline.js +217 -197
- package/dist/components/data-display/tree.js +179 -23
- package/dist/components/data-entry/branch-scope-picker.d.ts +1 -0
- package/dist/components/data-entry/branch-scope-picker.js +2 -1
- package/dist/components/data-entry/cascader.js +4 -5
- package/dist/components/data-entry/record-picker.d.ts +2 -0
- package/dist/components/data-entry/record-picker.js +22 -3
- package/dist/components/data-entry/transfer.d.ts +1 -1
- package/dist/components/data-entry/transfer.js +5 -2
- package/dist/components/data-entry/tree-select.js +14 -5
- package/dist/components/feedback/tooltip.d.ts +21 -0
- package/dist/components/feedback/tooltip.js +101 -0
- package/dist/components/general/typography.js +30 -11
- package/dist/components/layout/breadcrumb-ellipsis.d.ts +16 -0
- package/dist/components/layout/breadcrumb-ellipsis.js +28 -0
- package/dist/components/layout/breadcrumb.js +16 -7
- package/dist/components/layout/page-container.js +29 -20
- package/dist/components/query/infinite-query-state.d.ts +1 -1
- package/dist/components/query/infinite-query-state.js +2 -1
- package/dist/contracts/measurement.json +1 -1
- package/dist/i18n/messages/en.json +18 -3
- package/dist/i18n/messages/ja.json +9 -3
- package/dist/i18n/messages/vi.json +9 -3
- package/dist/lib/hooks.d.ts +8 -4
- package/dist/lib/hooks.js +5 -2
- package/dist/lib/tree.d.ts +23 -0
- package/dist/lib/tree.js +29 -0
- package/dist/props/components/data-display.prop.d.ts +21 -2
- package/dist/props/components/data-entry.prop.d.ts +31 -4
- package/dist/props/components/query.prop.d.ts +8 -1
- package/dist/props/registry.d.ts +29 -6
- package/dist/props/registry.js +46 -4
- package/dist/props/vocabulary/data.prop.d.ts +32 -2
- package/dist/props/vocabulary/index.d.ts +2 -2
- package/dist/props/vocabulary/navigation.prop.d.ts +14 -0
- package/dist/styles/data-display-layout.css +52 -0
- package/dist/styles/layers.json +3 -2
- package/dist/styles/layout.css +22 -0
- package/dist/styles/table-layout.css +24 -1
- package/dist/tokens/components/navigation.css +2 -0
- package/dist/tokens/components/tree.css +2 -0
- package/docs/data-display/data-table/examples/server-paged.tsx +23 -0
- package/docs/data-display/data-table/index.md +2 -0
- package/docs/data-display/progress.tsx +24 -6
- package/docs/data-display/timeline.tsx +33 -0
- package/docs/data-display/tree.tsx +154 -0
- package/docs/data-entry/branch-scope-picker.tsx +6 -1
- package/docs/data-entry/record-picker.tsx +1 -0
- package/docs/data-entry/transfer.tsx +1 -0
- package/docs/general/typography.tsx +84 -1
- package/docs/i18n/messages/en.json +48 -1
- package/docs/i18n/messages/ja.json +47 -1
- package/docs/i18n/messages/vi.json +47 -1
- package/docs/navigation/breadcrumb.tsx +24 -0
- package/docs/query/infinite-query-state.tsx +5 -1
- package/docs/roadmap/tree-components.md +2 -1
- package/package.json +2 -2
- package/scripts/ui-audit.mjs +15 -5
|
@@ -6,7 +6,18 @@
|
|
|
6
6
|
"breakDescription": "Định danh không có chỗ ngắt — địa chỉ email, mã giảm giá, ID đăng nhập — dùng break=\"anywhere\", và cột vẫn nằm gọn trong bề ngang màn hình kể cả trong ô của bảng. whitespace=\"pre-wrap\" dành cho ký tự xuống dòng do người nhập; nó không ngắt được một định danh trong ô bảng.",
|
|
7
7
|
"breakColumnOwner": "Phụ trách",
|
|
8
8
|
"breakColumnEmail": "Địa chỉ email",
|
|
9
|
-
"breakSampleName": "Sato"
|
|
9
|
+
"breakSampleName": "Sato",
|
|
10
|
+
"ellipsisTitle": "ellipsis · toàn văn trong tooltip khi bị cắt",
|
|
11
|
+
"ellipsisDescription": "ellipsis={{ tooltip: true }} giữ một dòng và hiện toàn văn khi rê chuột và khi bàn phím đưa tiêu điểm tới điều khiển chứa nó (liên kết, mục cây, nút sắp xếp). Tiêu đề vừa chỗ thì không có tooltip, và Text không bao giờ tự thành một điểm dừng Tab.",
|
|
12
|
+
"ellipsisPlain": "Text thường",
|
|
13
|
+
"ellipsisLink": "Text asChild · liên kết",
|
|
14
|
+
"ellipsisTree": "titleRender của Tree",
|
|
15
|
+
"ellipsisTable": "Bộ kiểm thử",
|
|
16
|
+
"ellipsisBreadcrumb": "Breadcrumb có cắt chữ",
|
|
17
|
+
"ellipsisCrumbHome": "Trang chủ",
|
|
18
|
+
"ellipsisLongTitle": "Kiểm thử tích hợp quý 3 · mô-đun thanh toán · kịch bản xuất lại hoá đơn và rà soát tiêu chí nghiệm thu",
|
|
19
|
+
"ellipsisShortTitle": "Kiểm thử nhanh đăng nhập",
|
|
20
|
+
"ellipsisLongHeader": "Tên lần chạy gần nhất (bản ứng viên 2026-09)"
|
|
10
21
|
},
|
|
11
22
|
"themeShowcase": {
|
|
12
23
|
"page": {
|
|
@@ -1444,5 +1455,40 @@
|
|
|
1444
1455
|
"nameColumn": "Họ tên",
|
|
1445
1456
|
"inviteTitle": "Gửi lời mời",
|
|
1446
1457
|
"send": "Gửi"
|
|
1458
|
+
},
|
|
1459
|
+
"treeDocs": {
|
|
1460
|
+
"longList": {
|
|
1461
|
+
"title": "Danh sách con dài (height · virtual · filterTreeNode)",
|
|
1462
|
+
"description": "2 bộ → 28 mục → tối đa 421 ca. Với height, cây cuộn trong chiều cao đó và chỉ vẽ các hàng đang thấy (antd height + virtual). Nút khớp từ tìm kiếm được filterTreeNode làm nổi bật, không bị ẩn. Mục 2 thất bại ở lần loadData đầu và tải lại khi mở lần nữa. Mục 3 là ví dụ ghép cho API phân trang: chọn lá cuối để tải thêm 100 ca.",
|
|
1463
|
+
"searchLabel": "Tìm ca kiểm thử",
|
|
1464
|
+
"searchPlaceholder": "Làm nổi bật theo tên ca (vd: 042)",
|
|
1465
|
+
"treeLabel": "Bộ kiểm thử",
|
|
1466
|
+
"suiteIntegration": "Kiểm thử tích hợp",
|
|
1467
|
+
"suiteAcceptance": "Kiểm thử chấp nhận",
|
|
1468
|
+
"section": "Mục {number}",
|
|
1469
|
+
"sectionFailing": "Mục {number} (lần tải đầu thất bại)",
|
|
1470
|
+
"sectionPaged": "Mục {number} (mỗi lần {count} ca)",
|
|
1471
|
+
"case": "Ca {number}",
|
|
1472
|
+
"loadMore": {
|
|
1473
|
+
"other": "Tải thêm {count} ca"
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
},
|
|
1477
|
+
"progressDocs": {
|
|
1478
|
+
"testRun": {
|
|
1479
|
+
"passed": "Đạt",
|
|
1480
|
+
"failed": "Lỗi",
|
|
1481
|
+
"blocked": "Bị chặn",
|
|
1482
|
+
"notRun": "Chưa chạy",
|
|
1483
|
+
"caption": "Bộ kiểm thử hồi quy — {total} ca"
|
|
1484
|
+
}
|
|
1485
|
+
},
|
|
1486
|
+
"breadcrumbExamples": {
|
|
1487
|
+
"ellipsisTitle": "ellipsis · một đoạn dài trên một dòng",
|
|
1488
|
+
"ellipsisDescription": "ellipsis trên một đoạn giữ breadcrumb trên một dòng và cắt nhãn đó bằng \"…\"; toàn văn hiện trong tooltip khi rê chuột và khi liên kết của đoạn nhận tiêu điểm bàn phím. Breadcrumb của antd không có ellipsis theo từng mục — hình dạng lấy theo Typography. breadcrumb của PageContainer nhận cùng trường này.",
|
|
1489
|
+
"ellipsisAria": "Breadcrumb có cắt chữ",
|
|
1490
|
+
"home": "Trang chủ",
|
|
1491
|
+
"longSuite": "Kiểm thử tích hợp quý 3 · mô-đun thanh toán · kịch bản xuất lại hoá đơn",
|
|
1492
|
+
"longSection": "Rà soát tiêu chí nghiệm thu cho bản ứng viên tháng 9/2026"
|
|
1447
1493
|
}
|
|
1448
1494
|
}
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
CodeBlock,
|
|
10
10
|
} from "@godxjp/ui/data-display";
|
|
11
11
|
import { Text } from "@godxjp/ui/general";
|
|
12
|
+
import { useTranslation } from "@godxjp/ui/i18n";
|
|
12
13
|
import { Breadcrumb } from "@godxjp/ui/layout";
|
|
13
14
|
import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
14
15
|
|
|
@@ -25,6 +26,9 @@ const RouterLink = forwardRef<
|
|
|
25
26
|
});
|
|
26
27
|
|
|
27
28
|
export default function Demo() {
|
|
29
|
+
const { t } = useTranslation();
|
|
30
|
+
const suite = t("breadcrumbExamples.longSuite");
|
|
31
|
+
const section = t("breadcrumbExamples.longSection");
|
|
28
32
|
return (
|
|
29
33
|
<PageContainer
|
|
30
34
|
title="Breadcrumb"
|
|
@@ -177,6 +181,26 @@ export default function Demo() {
|
|
|
177
181
|
</Flex>
|
|
178
182
|
</CardContent>
|
|
179
183
|
</Card>
|
|
184
|
+
|
|
185
|
+
{/* gh#1046 — a long segment cut to one line, the full label in a tooltip. */}
|
|
186
|
+
<Card>
|
|
187
|
+
<CardHeader>
|
|
188
|
+
<CardTitle level={2}>{t("breadcrumbExamples.ellipsisTitle")}</CardTitle>
|
|
189
|
+
<CardDescription>{t("breadcrumbExamples.ellipsisDescription")}</CardDescription>
|
|
190
|
+
</CardHeader>
|
|
191
|
+
<CardContent>
|
|
192
|
+
<div id="breadcrumb-ellipsis">
|
|
193
|
+
<Breadcrumb
|
|
194
|
+
ariaLabel={t("breadcrumbExamples.ellipsisAria")}
|
|
195
|
+
items={[
|
|
196
|
+
{ label: t("breadcrumbExamples.home"), to: "/" },
|
|
197
|
+
{ label: suite, to: "/suites/412", ellipsis: true },
|
|
198
|
+
{ label: section, ellipsis: true },
|
|
199
|
+
]}
|
|
200
|
+
/>
|
|
201
|
+
</div>
|
|
202
|
+
</CardContent>
|
|
203
|
+
</Card>
|
|
180
204
|
</Flex>
|
|
181
205
|
</PageContainer>
|
|
182
206
|
);
|
|
@@ -54,6 +54,7 @@ function Block() {
|
|
|
54
54
|
flatten={flattenItemPages}
|
|
55
55
|
isEmpty={(items) => items.length === 0}
|
|
56
56
|
empty={<EmptyState title="アクティビティがありません" />}
|
|
57
|
+
loadMoreLabel="Show older activity"
|
|
57
58
|
>
|
|
58
59
|
{(items) => (
|
|
59
60
|
<Timeline
|
|
@@ -80,7 +81,10 @@ export default function Demo() {
|
|
|
80
81
|
<Card>
|
|
81
82
|
<CardHeader>
|
|
82
83
|
<CardTitle level={2}>アクティビティ</CardTitle>
|
|
83
|
-
<CardDescription>
|
|
84
|
+
<CardDescription>
|
|
85
|
+
Click “Show older activity” to append the next page. loadMoreLabel renames the
|
|
86
|
+
built-in button; its pending state stays the component's.
|
|
87
|
+
</CardDescription>
|
|
84
88
|
</CardHeader>
|
|
85
89
|
<CardContent>
|
|
86
90
|
<Block />
|
|
@@ -79,7 +79,8 @@ that every Ant-shaped app reaches for was never built.
|
|
|
79
79
|
| Density | — | `size: xs \| sm \| lg` (`md` is the default, never `"default"`) |
|
|
80
80
|
| Directory variant | `<DirectoryTree>` | `variant="directory"` |
|
|
81
81
|
| Drag & drop | `draggable` | **out of scope for v1** — file a follow-up issue |
|
|
82
|
-
| Virtual scroll | `virtual` / `height` |
|
|
82
|
+
| Virtual scroll | `virtual` / `height` | `height` + `virtual` (gh#1042) — windowed rows are a flat run of treeitems; antd has no "load more" node, so none is shipped |
|
|
83
|
+
| Match highlight | `filterTreeNode` | `filterTreeNode` (gh#1043) — `data-filter-node="true"` for antd's `filter-node` class, plus an sr-only "matches" |
|
|
83
84
|
|
|
84
85
|
Plus the house rules: forward `ref`, spread `...props`, accept `className` + `id`, export
|
|
85
86
|
`TreeProp` and `TreeProp as TreeProps` from `src/props/components/data-display.prop.ts`, and
|
package/package.json
CHANGED
package/scripts/ui-audit.mjs
CHANGED
|
@@ -1916,6 +1916,16 @@ for (const dir of SCAN_DIRS) {
|
|
|
1916
1916
|
*/
|
|
1917
1917
|
const stack = [];
|
|
1918
1918
|
const bareByParent = new Map();
|
|
1919
|
+
/*
|
|
1920
|
+
* Every exported tag that renders @godxjp/ui's <Form> around its children (gh#1039). A field
|
|
1921
|
+
* under any of them has the Form layout context, so it must count like a literal <Form>.
|
|
1922
|
+
* `FormRoot` (@godxjp/ui/form, src/form/form-root.tsx) wraps its <form> in <Form asChild>
|
|
1923
|
+
* whenever a layout prop is set, and is the form shell with one stacked layout otherwise.
|
|
1924
|
+
* Pagination also renders <Form>, but around its own controls, not a consumer's fields. Add a
|
|
1925
|
+
* tag here when another exported wrapper starts rendering <Form> around children.
|
|
1926
|
+
*/
|
|
1927
|
+
const FORM_TAGS = new Set(["Form", "FormRoot"]);
|
|
1928
|
+
const formOpenTag = new RegExp(`<(${[...FORM_TAGS].join("|")})(?=[\\s>])([^>]*)>`, "g");
|
|
1919
1929
|
let formDepth = 0;
|
|
1920
1930
|
for (const m of scanContent.matchAll(
|
|
1921
1931
|
/(?<![\w.$])<(\/?)([A-Za-z][\w.]*)(?=[\s>/])([^<>]*?(?:\{[^{}]*\}[^<>]*?)*)(\/?)>/g,
|
|
@@ -1928,7 +1938,7 @@ for (const dir of SCAN_DIRS) {
|
|
|
1928
1938
|
break;
|
|
1929
1939
|
}
|
|
1930
1940
|
}
|
|
1931
|
-
if (tag
|
|
1941
|
+
if (FORM_TAGS.has(tag)) formDepth = Math.max(0, formDepth - 1);
|
|
1932
1942
|
continue;
|
|
1933
1943
|
}
|
|
1934
1944
|
if (tag === "FormField" && formDepth === 0) {
|
|
@@ -1937,7 +1947,7 @@ for (const dir of SCAN_DIRS) {
|
|
|
1937
1947
|
}
|
|
1938
1948
|
if (selfClose) continue;
|
|
1939
1949
|
stack.push({ tag, index: m.index });
|
|
1940
|
-
if (tag
|
|
1950
|
+
if (FORM_TAGS.has(tag)) formDepth += 1;
|
|
1941
1951
|
}
|
|
1942
1952
|
for (const group of bareByParent.values()) {
|
|
1943
1953
|
if (group.length < 2) continue;
|
|
@@ -1975,9 +1985,9 @@ for (const dir of SCAN_DIRS) {
|
|
|
1975
1985
|
for (const m of scanContent.matchAll(/<FormField(?=[\s>])([^>]*)>([\s\S]*?)<\/FormField>/g)) {
|
|
1976
1986
|
if (!/<Select(?=[\s>/])/.test(m[2]) || /controlWidth=/.test(m[1])) continue;
|
|
1977
1987
|
const before = scanContent.slice(0, m.index);
|
|
1978
|
-
const lastForm = [...before.matchAll(
|
|
1979
|
-
const insideForm = lastForm && before.lastIndexOf(
|
|
1980
|
-
if (insideForm && /controlWidth=/.test(lastForm[
|
|
1988
|
+
const lastForm = [...before.matchAll(formOpenTag)].at(-1);
|
|
1989
|
+
const insideForm = lastForm && before.lastIndexOf(`</${lastForm[1]}>`) < lastForm.index;
|
|
1990
|
+
if (insideForm && /controlWidth=/.test(lastForm[2])) continue;
|
|
1981
1991
|
const lineNo = lineAt(m.index);
|
|
1982
1992
|
if (suppressed("select-width-hint", lineNo - 1)) continue;
|
|
1983
1993
|
findings.push({
|