@godxjp/ui 31.10.0 → 31.10.1
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-display/table.js +84 -35
- package/dist/components/data-entry/search-select.js +7 -5
- package/dist/contracts/measurement.json +1 -1
- package/dist/styles/layers.json +1 -1
- package/dist/styles/table-layout.css +0 -4
- 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` 31.10.
|
|
6
|
+
**This catalog describes `@godxjp/ui` 31.10.1.** 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/v31.10.
|
|
51
|
+
"pinned": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/v31.10.1/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": "31.10.
|
|
65
|
+
"version": "31.10.1"
|
|
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: 177 components, 2104 design tokens,
|
|
4
|
-
> 50 cardinal rules. This file is the entry point for AI agents. Catalog version 31.10.
|
|
4
|
+
> 50 cardinal rules. This file is the entry point for AI agents. Catalog version 31.10.1.
|
|
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@31.10.
|
|
7
|
+
(`npx @godxjp/ui-mcp@31.10.1`). 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/v31.10.
|
|
29
|
+
the tag: `.../godx-jp/godxjp-ui/v31.10.1/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.
|
|
@@ -13,6 +13,8 @@ function useActionsColumnFit(ref, enabled) {
|
|
|
13
13
|
React.useLayoutEffect(() => {
|
|
14
14
|
const box = ref.current;
|
|
15
15
|
if (!enabled || !box || typeof ResizeObserver === "undefined") return void 0;
|
|
16
|
+
const measuredWidths = /* @__PURE__ */ new WeakMap();
|
|
17
|
+
const observedContents = /* @__PURE__ */ new Set();
|
|
16
18
|
const measure = () => {
|
|
17
19
|
box.style.removeProperty(ACTIONS_CONTENT_WIDTH);
|
|
18
20
|
let needed = 0;
|
|
@@ -22,29 +24,73 @@ function useActionsColumnFit(ref, enabled) {
|
|
|
22
24
|
const style = getComputedStyle(cell);
|
|
23
25
|
const inset = parseFloat(style.paddingInlineStart) + parseFloat(style.paddingInlineEnd);
|
|
24
26
|
const width = content.getBoundingClientRect().width;
|
|
27
|
+
measuredWidths.set(content, width);
|
|
25
28
|
if (width <= cell.clientWidth + 0.5) return;
|
|
26
29
|
const edges = style.boxSizing === "border-box" ? inset + parseFloat(style.borderInlineStartWidth) + parseFloat(style.borderInlineEndWidth) : 0;
|
|
27
30
|
needed = Math.max(needed, Math.ceil(width + edges));
|
|
28
31
|
});
|
|
29
32
|
if (needed > 0) box.style.setProperty(ACTIONS_CONTENT_WIDTH, `${needed}px`);
|
|
30
33
|
};
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
let frame = 0;
|
|
35
|
+
let rowsChanged = false;
|
|
36
|
+
const schedule = () => {
|
|
37
|
+
if (frame !== 0) return;
|
|
38
|
+
frame = requestAnimationFrame(() => {
|
|
39
|
+
frame = 0;
|
|
40
|
+
if (rowsChanged) {
|
|
41
|
+
rowsChanged = false;
|
|
42
|
+
observeStructure();
|
|
43
|
+
observeContents();
|
|
44
|
+
}
|
|
45
|
+
measure();
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
const resize = new ResizeObserver((entries) => {
|
|
49
|
+
if (entries.some((entry) => measuredWidths.get(entry.target) !== entry.contentRect.width)) {
|
|
50
|
+
schedule();
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
const observeContents = () => {
|
|
54
|
+
observedContents.forEach((content) => {
|
|
55
|
+
if (content.isConnected) return;
|
|
56
|
+
resize.unobserve(content);
|
|
57
|
+
observedContents.delete(content);
|
|
58
|
+
});
|
|
59
|
+
box.querySelectorAll(".ui-table-actions-content").forEach((content) => {
|
|
60
|
+
if (observedContents.has(content)) return;
|
|
61
|
+
observedContents.add(content);
|
|
62
|
+
resize.observe(content);
|
|
63
|
+
});
|
|
37
64
|
};
|
|
38
|
-
const mutations = new MutationObserver(
|
|
39
|
-
|
|
40
|
-
|
|
65
|
+
const mutations = new MutationObserver(() => {
|
|
66
|
+
rowsChanged = true;
|
|
67
|
+
schedule();
|
|
68
|
+
});
|
|
69
|
+
const observeStructure = () => {
|
|
70
|
+
mutations.disconnect();
|
|
71
|
+
const table = box.querySelector(":scope > table");
|
|
72
|
+
if (!table) return;
|
|
73
|
+
mutations.observe(table, { childList: true });
|
|
74
|
+
for (const section of Array.from(table.children)) {
|
|
75
|
+
mutations.observe(section, { childList: true });
|
|
76
|
+
for (const row of Array.from(section.children)) {
|
|
77
|
+
mutations.observe(row, { childList: true });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
resize.observe(box);
|
|
82
|
+
observeStructure();
|
|
83
|
+
observeContents();
|
|
84
|
+
measure();
|
|
41
85
|
return () => {
|
|
86
|
+
if (frame !== 0) cancelAnimationFrame(frame);
|
|
42
87
|
resize.disconnect();
|
|
43
88
|
mutations.disconnect();
|
|
44
89
|
box.style.removeProperty(ACTIONS_CONTENT_WIDTH);
|
|
45
90
|
};
|
|
46
91
|
}, [ref, enabled]);
|
|
47
92
|
}
|
|
93
|
+
const TablePresetContext = React.createContext("default");
|
|
48
94
|
const Table = React.forwardRef(
|
|
49
95
|
({
|
|
50
96
|
className,
|
|
@@ -91,7 +137,7 @@ const Table = React.forwardRef(
|
|
|
91
137
|
"--table-action-collection-min-inline-size-compact": columnWidths.minInlineSizeCompact
|
|
92
138
|
} : void 0,
|
|
93
139
|
...scrolls ? { role: "group", "aria-label": scrollRegionLabel(label, t), tabIndex: 0 } : {},
|
|
94
|
-
children: /* @__PURE__ */ jsx(
|
|
140
|
+
children: /* @__PURE__ */ jsx(TablePresetContext.Provider, { value: preset, children: /* @__PURE__ */ jsx(
|
|
95
141
|
"table",
|
|
96
142
|
{
|
|
97
143
|
ref,
|
|
@@ -100,7 +146,7 @@ const Table = React.forwardRef(
|
|
|
100
146
|
className: cn("w-full caption-bottom", bordered && "ui-table-bordered", className),
|
|
101
147
|
...props
|
|
102
148
|
}
|
|
103
|
-
)
|
|
149
|
+
) })
|
|
104
150
|
}
|
|
105
151
|
)
|
|
106
152
|
);
|
|
@@ -180,30 +226,33 @@ const TableCell = React.forwardRef(
|
|
|
180
226
|
children,
|
|
181
227
|
style,
|
|
182
228
|
...props
|
|
183
|
-
}, ref) =>
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
229
|
+
}, ref) => {
|
|
230
|
+
const preset = React.useContext(TablePresetContext);
|
|
231
|
+
return /* @__PURE__ */ jsxs(
|
|
232
|
+
"td",
|
|
233
|
+
{
|
|
234
|
+
ref,
|
|
235
|
+
"data-slot": "table-cell",
|
|
236
|
+
"data-priority": priority,
|
|
237
|
+
"data-flush": flush ? "" : void 0,
|
|
238
|
+
"data-indent": indent === void 0 ? void 0 : indent,
|
|
239
|
+
"data-align": align,
|
|
240
|
+
"data-numeric": numeric ? "" : void 0,
|
|
241
|
+
"data-wrap": wrap ? "" : void 0,
|
|
242
|
+
className: cn(className),
|
|
243
|
+
style: indent === void 0 && width === void 0 ? style : {
|
|
244
|
+
...style,
|
|
245
|
+
...indent === void 0 ? null : { "--table-cell-indent-level": indent },
|
|
246
|
+
...width === void 0 ? null : { inlineSize: cellWidth(width) }
|
|
247
|
+
},
|
|
248
|
+
...props,
|
|
249
|
+
children: [
|
|
250
|
+
label !== void 0 ? /* @__PURE__ */ jsx("span", { className: "ui-table-stacked-collection-label", "aria-hidden": "true", children: label }) : null,
|
|
251
|
+
priority === "actions" && preset === "action-collection" ? /* @__PURE__ */ jsx("span", { className: "ui-table-actions-content", children }) : children
|
|
252
|
+
]
|
|
253
|
+
}
|
|
254
|
+
);
|
|
255
|
+
}
|
|
207
256
|
);
|
|
208
257
|
TableCell.displayName = "TableCell";
|
|
209
258
|
export {
|
|
@@ -161,7 +161,7 @@ function SearchSelect(props) {
|
|
|
161
161
|
const isSelected = (optionValue) => multiple ? values.includes(optionValue) : value === optionValue;
|
|
162
162
|
const hasSelection = multiple ? values.length > 0 : Boolean(value);
|
|
163
163
|
const reqId = React.useRef(0);
|
|
164
|
-
const
|
|
164
|
+
const [freshPage, setFreshPage] = React.useState(0);
|
|
165
165
|
const matchesQuery = React.useCallback(
|
|
166
166
|
(option, needle) => {
|
|
167
167
|
if (filterOption) return filterOption(option, needle);
|
|
@@ -195,7 +195,7 @@ function SearchSelect(props) {
|
|
|
195
195
|
const result = await resolvedLoad({ query: search, page: nextPage });
|
|
196
196
|
if (ticket !== reqId.current) return;
|
|
197
197
|
setLoaded((prev) => append ? [...prev, ...result.options] : result.options);
|
|
198
|
-
if (!append)
|
|
198
|
+
if (!append) setFreshPage((tick) => tick + 1);
|
|
199
199
|
setHasMore(Boolean(result.hasMore));
|
|
200
200
|
setPage(nextPage);
|
|
201
201
|
} catch {
|
|
@@ -271,14 +271,16 @@ function SearchSelect(props) {
|
|
|
271
271
|
[grouped]
|
|
272
272
|
);
|
|
273
273
|
const lastTypedRef = React.useRef(typedText);
|
|
274
|
+
const lastFreshPageRef = React.useRef(freshPage);
|
|
274
275
|
React.useEffect(() => {
|
|
275
276
|
const typedChanged = lastTypedRef.current !== typedText;
|
|
277
|
+
const pageChanged = lastFreshPageRef.current !== freshPage;
|
|
276
278
|
lastTypedRef.current = typedText;
|
|
277
|
-
|
|
278
|
-
|
|
279
|
+
lastFreshPageRef.current = freshPage;
|
|
280
|
+
if (!typedChanged && !pageChanged) return;
|
|
279
281
|
const firstEnabled = flatOrdered.findIndex((option) => !option.disabled);
|
|
280
282
|
setActiveIndex(firstEnabled >= 0 ? firstEnabled : 0);
|
|
281
|
-
}, [flatOrdered, typedText]);
|
|
283
|
+
}, [flatOrdered, typedText, freshPage]);
|
|
282
284
|
const resolvedPlaceholder = placeholder ?? t("dataEntry.searchSelect.placeholder");
|
|
283
285
|
const optionFor = (optionValue) => pickedOptions[optionValue] ?? (staticOptions ?? []).find((option) => option.value === optionValue) ?? loaded.find((option) => option.value === optionValue) ?? null;
|
|
284
286
|
const selectedOption = value ? optionFor(value) : null;
|
|
@@ -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": "31.10.
|
|
3
|
+
"version": "31.10.1",
|
|
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/layers.json
CHANGED