@godxjp/ui 33.12.6 → 33.12.8
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/components/DatePicker.json +1 -1
- package/agent/components/Select.json +1 -1
- package/agent/components.json +2 -2
- package/agent/index.json +2 -2
- package/agent/llms.txt +3 -3
- package/dist/components/data-entry/date-picker.js +2 -1
- package/dist/components/data-entry/select.js +1 -1
- package/dist/components/feedback/dialog.js +1 -1
- package/dist/components/feedback/sheet.js +1 -1
- package/dist/contracts/measurement.json +1 -1
- package/dist/lab/timeline-grid.d.ts +9 -0
- package/dist/lab/timeline-grid.js +41 -5
- package/dist/styles/data-display-layout.css +32 -0
- package/dist/styles/dialog-layout.css +4 -0
- package/dist/styles/layers.json +1 -1
- package/dist/styles.css +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` 33.12.
|
|
6
|
+
**This catalog describes `@godxjp/ui` 33.12.8.** 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.
|
|
@@ -245,7 +245,7 @@
|
|
|
245
245
|
"type": "boolean | { clearIcon?: ReactNode; label?: string }"
|
|
246
246
|
},
|
|
247
247
|
{
|
|
248
|
-
"description": "Accessible NAME of the calendar button. The default (「カレンダーを開く」 / 'Open calendar') is right for one picker on a page and useless for three: a screen-reader user hears the same sentence three times with nothing to say which field each button belongs to (WCAG 2.2 SC 2.4.6). Name it after the FIELD — `開始日のカレンダーを開く`. Same axis and same reason as Select's `clearLabel`.",
|
|
248
|
+
"description": "Accessible NAME of the calendar button. The default (「カレンダーを開く」 / 'Open calendar') is right for one picker on a page and useless for three: a screen-reader user hears the same sentence three times with nothing to say which field each button belongs to (WCAG 2.2 SC 2.4.6). Name it after the FIELD — `開始日のカレンダーを開く`. Same axis and same reason as Select's `clearLabel`. The calendar DIALOG is named after the field too: the FormField label (or your `aria-labelledby` / `aria-label`) first, then `triggerLabel`, then the default.",
|
|
249
249
|
"name": "triggerLabel",
|
|
250
250
|
"type": "string"
|
|
251
251
|
}
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"type": "React.ReactNode"
|
|
82
82
|
},
|
|
83
83
|
{
|
|
84
|
-
"description": "Placeholder shown in the trigger when no value is selected.",
|
|
84
|
+
"description": "Placeholder shown in the trigger when no value is selected. Default: the catalogue's 「選択…」 / 'Chọn…' / 'Select…' — the same string with or without `showSearch`, so an unselected field never shows an empty trigger. Only a placeholder YOU pass can name an unlabelled trigger; the default never becomes the accessible name.",
|
|
85
85
|
"name": "placeholder",
|
|
86
86
|
"type": "string"
|
|
87
87
|
},
|
package/agent/components.json
CHANGED
|
@@ -6726,7 +6726,7 @@
|
|
|
6726
6726
|
"type": "React.ReactNode"
|
|
6727
6727
|
},
|
|
6728
6728
|
{
|
|
6729
|
-
"description": "Placeholder shown in the trigger when no value is selected.",
|
|
6729
|
+
"description": "Placeholder shown in the trigger when no value is selected. Default: the catalogue's 「選択…」 / 'Chọn…' / 'Select…' — the same string with or without `showSearch`, so an unselected field never shows an empty trigger. Only a placeholder YOU pass can name an unlabelled trigger; the default never becomes the accessible name.",
|
|
6730
6730
|
"name": "placeholder",
|
|
6731
6731
|
"type": "string"
|
|
6732
6732
|
},
|
|
@@ -7992,7 +7992,7 @@
|
|
|
7992
7992
|
"type": "boolean | { clearIcon?: ReactNode; label?: string }"
|
|
7993
7993
|
},
|
|
7994
7994
|
{
|
|
7995
|
-
"description": "Accessible NAME of the calendar button. The default (「カレンダーを開く」 / 'Open calendar') is right for one picker on a page and useless for three: a screen-reader user hears the same sentence three times with nothing to say which field each button belongs to (WCAG 2.2 SC 2.4.6). Name it after the FIELD — `開始日のカレンダーを開く`. Same axis and same reason as Select's `clearLabel`.",
|
|
7995
|
+
"description": "Accessible NAME of the calendar button. The default (「カレンダーを開く」 / 'Open calendar') is right for one picker on a page and useless for three: a screen-reader user hears the same sentence three times with nothing to say which field each button belongs to (WCAG 2.2 SC 2.4.6). Name it after the FIELD — `開始日のカレンダーを開く`. Same axis and same reason as Select's `clearLabel`. The calendar DIALOG is named after the field too: the FormField label (or your `aria-labelledby` / `aria-label`) first, then `triggerLabel`, then the default.",
|
|
7996
7996
|
"name": "triggerLabel",
|
|
7997
7997
|
"type": "string"
|
|
7998
7998
|
}
|
package/agent/index.json
CHANGED
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"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.",
|
|
55
55
|
"read": {
|
|
56
56
|
"live": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/index.json",
|
|
57
|
-
"pinned": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/v33.12.
|
|
57
|
+
"pinned": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/v33.12.8/agent/index.json"
|
|
58
58
|
},
|
|
59
59
|
"source": "mcp/src/data — the same data @godxjp/ui-mcp serves — plus the foundation and semantic token tiers, read from src/tokens/*.css",
|
|
60
60
|
"start": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/START-HERE.md",
|
|
@@ -68,5 +68,5 @@
|
|
|
68
68
|
"foundation": "the seeds a consumer is invited to set — --primary, --background, --radius",
|
|
69
69
|
"semantic": "named roles that follow the seeds — --ring, --text-link, --overlay-background"
|
|
70
70
|
},
|
|
71
|
-
"version": "33.12.
|
|
71
|
+
"version": "33.12.8"
|
|
72
72
|
}
|
package/agent/llms.txt
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# @godxjp/ui
|
|
2
2
|
|
|
3
3
|
> A Japanese-enterprise React design system: 169 components, 2241 design tokens,
|
|
4
|
-
> 44 cardinal rules. This file is the entry point for AI agents. Catalog version 33.12.
|
|
4
|
+
> 44 cardinal rules. This file is the entry point for AI agents. Catalog version 33.12.8.
|
|
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@33.12.
|
|
7
|
+
(`npx @godxjp/ui-mcp@33.12.8`). It is searchable and version-locked. These files exist for agents
|
|
8
8
|
that can only fetch URLs.
|
|
9
9
|
|
|
10
10
|
## Start
|
|
@@ -27,7 +27,7 @@ that can only fetch URLs.
|
|
|
27
27
|
## Pinning
|
|
28
28
|
|
|
29
29
|
Every URL above tracks `main`. To pin to the release a project actually installed, swap `main` for
|
|
30
|
-
the tag: `.../godx-jp/godxjp-ui/v33.12.
|
|
30
|
+
the tag: `.../godx-jp/godxjp-ui/v33.12.8/agent/...`. A catalog that does not match the installed
|
|
31
31
|
package describes props that are absent, or hides props that are present, and says nothing either way.
|
|
32
32
|
|
|
33
33
|
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.
|
|
@@ -511,7 +511,8 @@ function DatePicker(props) {
|
|
|
511
511
|
{
|
|
512
512
|
id: dialogId,
|
|
513
513
|
role: "dialog",
|
|
514
|
-
"aria-
|
|
514
|
+
"aria-labelledby": fieldA11y["aria-labelledby"],
|
|
515
|
+
"aria-label": fieldA11y["aria-labelledby"] !== void 0 ? void 0 : ariaProps["aria-label"] ?? triggerLabel ?? (isPeriod ? t("dataEntry.monthPicker.openGrid") : t("dataEntry.datePicker.openCalendar")) ?? "Calendar",
|
|
515
516
|
className: isPeriod ? "ui-month-picker-panel" : "ui-control-panel-flush",
|
|
516
517
|
side: placement.startsWith("top") ? "top" : "bottom",
|
|
517
518
|
align: placement.endsWith("end") ? "end" : "start",
|
|
@@ -771,7 +771,7 @@ function DataSelect(props) {
|
|
|
771
771
|
...ariaProps,
|
|
772
772
|
children: [
|
|
773
773
|
prefix === void 0 || prefix === null ? null : /* @__PURE__ */ jsx("span", { "data-slot": "select-prefix", className: "ui-select-prefix", children: prefix }),
|
|
774
|
-
/* @__PURE__ */ jsx(SelectValue, { placeholder, children: labelRender ? /* @__PURE__ */ jsx(DataSelectLabel, { labelRender, options }) : void 0 }),
|
|
774
|
+
/* @__PURE__ */ jsx(SelectValue, { placeholder: placeholder ?? t("dataEntry.searchSelect.placeholder"), children: labelRender ? /* @__PURE__ */ jsx(DataSelectLabel, { labelRender, options }) : void 0 }),
|
|
775
775
|
suffixIcon === void 0 || suffixIcon === null || showClear || loading ? null : /* @__PURE__ */ jsx("span", { "data-slot": "select-suffix", className: "ui-select-suffix", "aria-hidden": "true", children: suffixIcon })
|
|
776
776
|
]
|
|
777
777
|
}
|
|
@@ -116,7 +116,7 @@ function DialogShell({
|
|
|
116
116
|
"data-slot": "dialog-overlay",
|
|
117
117
|
"data-state": dataState,
|
|
118
118
|
className: cn(OVERLAY_CLASS, overlayClassName),
|
|
119
|
-
children: /* @__PURE__ */ jsx(Modal, { className: "contents", children: dialog })
|
|
119
|
+
children: /* @__PURE__ */ jsx(Modal, { className: "ui-overlay-modal contents", children: dialog })
|
|
120
120
|
}
|
|
121
121
|
);
|
|
122
122
|
}
|
|
@@ -201,7 +201,7 @@ function SheetContent({
|
|
|
201
201
|
"data-slot": "sheet-overlay",
|
|
202
202
|
"data-state": dataState,
|
|
203
203
|
className: cn(SHEET_OVERLAY_CLASS, overlayClassName),
|
|
204
|
-
children: /* @__PURE__ */ jsx(Modal, { className: "contents", children: dialog })
|
|
204
|
+
children: /* @__PURE__ */ jsx(Modal, { className: "ui-overlay-modal contents", children: dialog })
|
|
205
205
|
}
|
|
206
206
|
);
|
|
207
207
|
}
|
|
@@ -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": "33.12.
|
|
3
|
+
"version": "33.12.8",
|
|
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,
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import type { TimelineGridProp } from "../props/components/data-display.prop.js";
|
|
3
3
|
export type { TimelineGridColumnProp, TimelineGridEventProp, TimelineGridProp, TimelineGridProp as TimelineGridProps, } from "../props/components/data-display.prop.js";
|
|
4
|
+
export type TimelineGridEventLayout = {
|
|
5
|
+
mode: "compact" | "single";
|
|
6
|
+
} | {
|
|
7
|
+
mode: "stacked";
|
|
8
|
+
titleLines: number;
|
|
9
|
+
showDescription: boolean;
|
|
10
|
+
};
|
|
11
|
+
/** Layout of one block from its drawn length in minutes (already floored at the display minimum). */
|
|
12
|
+
export declare function eventTextLayout(drawnMinutes: number, hasDescription: boolean): TimelineGridEventLayout;
|
|
4
13
|
/**
|
|
5
14
|
* TimelineGrid — the time-axis half of the Timeline family: a vertical hour axis, one column per
|
|
6
15
|
* day (or room, or machine) and event blocks placed by start time and duration.
|
|
@@ -26,6 +26,22 @@ function resolveEvent(event) {
|
|
|
26
26
|
return { event, startMin, endMin: endMin > startMin ? endMin : endMin + MINUTES_PER_DAY };
|
|
27
27
|
}
|
|
28
28
|
const EVENT_MIN_MINUTES = 36;
|
|
29
|
+
const HOUR_HEIGHT_REM = 2.5;
|
|
30
|
+
const EVENT_GAP_REM = 0.25;
|
|
31
|
+
const EVENT_INSET_BLOCK_REM = 0.25;
|
|
32
|
+
const EVENT_LINE_REM = 1.1905;
|
|
33
|
+
function eventTextLayout(drawnMinutes, hasDescription) {
|
|
34
|
+
const bodyRem = drawnMinutes / 60 * HOUR_HEIGHT_REM - EVENT_GAP_REM;
|
|
35
|
+
const lines = Math.floor((bodyRem - 2 * EVENT_INSET_BLOCK_REM) / EVENT_LINE_REM);
|
|
36
|
+
if (lines < 1) return { mode: "compact" };
|
|
37
|
+
if (lines < 2) return { mode: "single" };
|
|
38
|
+
const showDescription = hasDescription && lines >= 3;
|
|
39
|
+
return { mode: "stacked", titleLines: lines - 1 - (showDescription ? 1 : 0), showDescription };
|
|
40
|
+
}
|
|
41
|
+
function plainText(node) {
|
|
42
|
+
if (typeof node === "string" || typeof node === "number") return String(node);
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
29
45
|
function placeColumn(events) {
|
|
30
46
|
const drawnEnd = (e) => Math.max(e.endMin, e.startMin + EVENT_MIN_MINUTES);
|
|
31
47
|
const sorted = [...events].sort((a, b) => a.startMin - b.startMin || a.endMin - b.endMin);
|
|
@@ -188,22 +204,39 @@ function renderEvent(entry, axis, onEventSelect) {
|
|
|
188
204
|
const clippedEnd = entry.endMin > axis.endMin;
|
|
189
205
|
const clipped = clippedStart && clippedEnd ? "both" : clippedStart ? "start" : "end";
|
|
190
206
|
const range = `${toClock(entry.startMin)}\u2013${toClock(entry.endMin)}`;
|
|
191
|
-
const
|
|
207
|
+
const layout = eventTextLayout(
|
|
208
|
+
Math.max(to - from, EVENT_MIN_MINUTES),
|
|
209
|
+
event.description !== void 0
|
|
210
|
+
);
|
|
211
|
+
const stacked = layout.mode === "stacked";
|
|
212
|
+
const titleText = plainText(event.title);
|
|
213
|
+
const descriptionText = plainText(event.description);
|
|
214
|
+
const fullName = titleText === null ? void 0 : [titleText, range, descriptionText].filter((part) => part !== null && part !== "").join(", ");
|
|
215
|
+
const title = /* @__PURE__ */ jsx("span", { className: "ui-timeline-grid-event-title", children: event.title });
|
|
216
|
+
const body = stacked ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
217
|
+
title,
|
|
192
218
|
/* @__PURE__ */ jsx("span", { className: "ui-timeline-grid-event-time", children: range }),
|
|
193
|
-
/* @__PURE__ */ jsx("span", { className: "ui-timeline-grid-event-
|
|
194
|
-
|
|
219
|
+
layout.showDescription ? /* @__PURE__ */ jsx("span", { className: "ui-timeline-grid-event-description", children: event.description }) : null
|
|
220
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
221
|
+
title,
|
|
222
|
+
/* @__PURE__ */ jsxs("span", { className: "ui-timeline-grid-event-time", children: [
|
|
223
|
+
toClock(entry.startMin),
|
|
224
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: `\u2013${toClock(entry.endMin)}` })
|
|
225
|
+
] })
|
|
195
226
|
] });
|
|
196
227
|
return /* @__PURE__ */ jsx(
|
|
197
228
|
"li",
|
|
198
229
|
{
|
|
199
230
|
"data-event-id": event.id,
|
|
200
231
|
"data-clipped": clippedStart || clippedEnd ? clipped : void 0,
|
|
232
|
+
"data-layout": layout.mode,
|
|
201
233
|
className: "ui-timeline-grid-event",
|
|
202
234
|
style: {
|
|
203
235
|
"--timeline-grid-event-offset": (from - axis.startMin) / 60,
|
|
204
236
|
"--timeline-grid-event-span": (to - from) / 60,
|
|
205
237
|
"--timeline-grid-event-lane": entry.lane,
|
|
206
238
|
"--timeline-grid-event-lanes": entry.lanes,
|
|
239
|
+
...stacked ? { "--timeline-grid-event-title-lines": layout.titleLines } : null,
|
|
207
240
|
...event.color === void 0 || event.color === "" ? null : { "--timeline-grid-event-color": event.color }
|
|
208
241
|
},
|
|
209
242
|
children: onEventSelect ? /* @__PURE__ */ jsx(
|
|
@@ -211,14 +244,17 @@ function renderEvent(entry, axis, onEventSelect) {
|
|
|
211
244
|
{
|
|
212
245
|
type: "button",
|
|
213
246
|
className: "ui-timeline-grid-event-body ui-focus-ring",
|
|
247
|
+
title: fullName,
|
|
248
|
+
"aria-label": fullName,
|
|
214
249
|
onClick: () => onEventSelect(event),
|
|
215
250
|
children: body
|
|
216
251
|
}
|
|
217
|
-
) : /* @__PURE__ */ jsx("span", { className: "ui-timeline-grid-event-body", children: body })
|
|
252
|
+
) : /* @__PURE__ */ jsx("span", { className: "ui-timeline-grid-event-body", title: fullName, children: body })
|
|
218
253
|
},
|
|
219
254
|
event.id
|
|
220
255
|
);
|
|
221
256
|
}
|
|
222
257
|
export {
|
|
223
|
-
TimelineGrid
|
|
258
|
+
TimelineGrid,
|
|
259
|
+
eventTextLayout
|
|
224
260
|
};
|
|
@@ -2007,6 +2007,38 @@
|
|
|
2007
2007
|
white-space: nowrap;
|
|
2008
2008
|
}
|
|
2009
2009
|
|
|
2010
|
+
.ui-timeline-grid-event:is([data-layout="single"], [data-layout="compact"])
|
|
2011
|
+
.ui-timeline-grid-event-body {
|
|
2012
|
+
flex-direction: row;
|
|
2013
|
+
align-items: baseline;
|
|
2014
|
+
gap: var(--space-1);
|
|
2015
|
+
}
|
|
2016
|
+
|
|
2017
|
+
.ui-timeline-grid-event[data-layout="compact"] .ui-timeline-grid-event-body {
|
|
2018
|
+
align-items: center;
|
|
2019
|
+
padding-block: 0;
|
|
2020
|
+
}
|
|
2021
|
+
|
|
2022
|
+
.ui-timeline-grid-event:is([data-layout="single"], [data-layout="compact"])
|
|
2023
|
+
.ui-timeline-grid-event-title {
|
|
2024
|
+
min-inline-size: 0;
|
|
2025
|
+
}
|
|
2026
|
+
|
|
2027
|
+
.ui-timeline-grid-event:is([data-layout="single"], [data-layout="compact"])
|
|
2028
|
+
.ui-timeline-grid-event-time {
|
|
2029
|
+
flex: none;
|
|
2030
|
+
}
|
|
2031
|
+
|
|
2032
|
+
.ui-timeline-grid-event[data-layout="stacked"] .ui-timeline-grid-event-title {
|
|
2033
|
+
display: -webkit-box;
|
|
2034
|
+
flex: none;
|
|
2035
|
+
-webkit-box-orient: vertical;
|
|
2036
|
+
-webkit-line-clamp: var(--timeline-grid-event-title-lines, 1);
|
|
2037
|
+
line-clamp: var(--timeline-grid-event-title-lines, 1);
|
|
2038
|
+
overflow-wrap: anywhere;
|
|
2039
|
+
white-space: normal;
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2010
2042
|
.ui-timeline-grid-event-description {
|
|
2011
2043
|
overflow: hidden;
|
|
2012
2044
|
color: var(--timeline-grid-event-muted-color);
|
package/dist/styles/layers.json
CHANGED