@godxjp/ui 32.13.1 → 32.15.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.
Files changed (47) hide show
  1. package/README.md +4 -4
  2. package/agent/START-HERE.md +7 -7
  3. package/agent/components/HeatmapChart.json +97 -0
  4. package/agent/components/ListRow.json +1 -1
  5. package/agent/components/PageContainer.json +2 -2
  6. package/agent/components/Segmented.json +1 -0
  7. package/agent/components/Tabs.json +3 -2
  8. package/agent/components-index.json +5 -0
  9. package/agent/components.json +104 -5
  10. package/agent/index.json +7 -7
  11. package/agent/llms.txt +6 -6
  12. package/agent/patterns/inertia-list-page.json +1 -1
  13. package/agent/patterns.json +1 -1
  14. package/agent/tokens.json +116 -2
  15. package/dist/components/charts/chart-summary.d.ts +32 -1
  16. package/dist/components/charts/chart-summary.js +49 -0
  17. package/dist/components/charts/heatmap-chart.d.ts +19 -0
  18. package/dist/components/charts/heatmap-chart.js +293 -0
  19. package/dist/components/charts/index.d.ts +3 -0
  20. package/dist/components/charts/index.js +2 -0
  21. package/dist/components/feedback/tooltip.d.ts +9 -0
  22. package/dist/components/feedback/tooltip.js +4 -1
  23. package/dist/contracts/measurement.json +1 -1
  24. package/dist/i18n/messages/en.json +8 -1
  25. package/dist/i18n/messages/ja.json +8 -1
  26. package/dist/i18n/messages/vi.json +8 -1
  27. package/dist/props/components/charts.prop.d.ts +58 -0
  28. package/dist/props/registry.d.ts +37 -0
  29. package/dist/props/registry.js +36 -0
  30. package/dist/styles/base.css +19 -19
  31. package/dist/styles/chart-layout.css +161 -0
  32. package/dist/styles/data-display-layout.css +3 -3
  33. package/dist/styles/layers.json +8 -1
  34. package/dist/styles/layout.css +1 -1
  35. package/dist/styles.css +1 -1
  36. package/dist/tokens/components/chart.css +27 -0
  37. package/dist/tokens/foundation.css +12 -0
  38. package/dist/tokens/semantic/layout.css +1 -1
  39. package/package.json +9 -2
  40. package/scripts/_agent-setup.mjs +118 -0
  41. package/scripts/agent-guard.mjs +176 -0
  42. package/scripts/cli.mjs +25 -2
  43. package/scripts/codemod.mjs +313 -42
  44. package/scripts/init-agent-kit.mjs +14 -0
  45. package/scripts/mcp-call.mjs +40 -0
  46. package/scripts/ui-audit.mjs +77 -0
  47. package/scripts/user-guard.mjs +78 -0
@@ -12,7 +12,9 @@ import {
12
12
  import { cn } from "../../lib/utils.js";
13
13
  import { Slot } from "../../lib/slot.js";
14
14
  const DEFAULT_DELAY_DURATION = 200;
15
- const TooltipAnchorContext = React.createContext(null);
15
+ const TooltipAnchorContext = React.createContext(
16
+ null
17
+ );
16
18
  function toPlacement(side, align) {
17
19
  if (align === "center") return side;
18
20
  if (side === "top" || side === "bottom") return `${side} ${align}`;
@@ -223,6 +225,7 @@ function EllipsisTooltip({
223
225
  export {
224
226
  EllipsisTooltip,
225
227
  Tooltip,
228
+ TooltipAnchorContext,
226
229
  TooltipContent,
227
230
  TooltipProvider,
228
231
  TooltipTrigger
@@ -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.13.1",
3
+ "version": "32.15.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,
@@ -787,7 +787,14 @@
787
787
  "summaryCartesian": "Chart with {series} series across {points} data points",
788
788
  "summaryPie": "Pie chart with {slices} slices",
789
789
  "summaryTrend": "Bar trend with {points} data points",
790
- "trendCurrent": "current"
790
+ "trendCurrent": "current",
791
+ "heatmapSummary": "Heatmap, {rows} × {columns}",
792
+ "heatmapHighest": "Highest: {value} at {row}, {column}",
793
+ "heatmapNoData": "No data",
794
+ "heatmapTop": "Top {rank}",
795
+ "heatmapLegend": "Color scale",
796
+ "heatmapLegendTop": "Top {count}",
797
+ "heatmapCell": "{row}, {column}: {value}"
791
798
  },
792
799
  "rangeTimeline": {
793
800
  "childRows": "Child rows",
@@ -761,7 +761,14 @@
761
761
  "summaryCartesian": "{series}系列・{points}データ点のグラフ",
762
762
  "summaryPie": "{slices}区分の円グラフ",
763
763
  "summaryTrend": "{points}データ点の推移棒グラフ",
764
- "trendCurrent": "現在"
764
+ "trendCurrent": "現在",
765
+ "heatmapSummary": "ヒートマップ({rows}行×{columns}列)",
766
+ "heatmapHighest": "最大 {value}({row}・{column})",
767
+ "heatmapNoData": "データなし",
768
+ "heatmapTop": "上位{rank}位",
769
+ "heatmapLegend": "色の濃さの凡例",
770
+ "heatmapLegendTop": "上位{count}件",
771
+ "heatmapCell": "{row}・{column}:{value}"
765
772
  },
766
773
  "rangeTimeline": {
767
774
  "childRows": "子の行",
@@ -762,7 +762,14 @@
762
762
  "summaryCartesian": "Biểu đồ gồm {series} chuỗi trên {points} điểm dữ liệu",
763
763
  "summaryPie": "Biểu đồ tròn gồm {slices} phần",
764
764
  "summaryTrend": "Biểu đồ cột xu hướng gồm {points} điểm dữ liệu",
765
- "trendCurrent": "hiện tại"
765
+ "trendCurrent": "hiện tại",
766
+ "heatmapSummary": "Bản đồ nhiệt {rows} × {columns}",
767
+ "heatmapHighest": "Cao nhất: {value} tại {row}, {column}",
768
+ "heatmapNoData": "Không có dữ liệu",
769
+ "heatmapTop": "Hạng {rank}",
770
+ "heatmapLegend": "Thang màu",
771
+ "heatmapLegendTop": "{count} ô cao nhất",
772
+ "heatmapCell": "{row}, {column}: {value}"
766
773
  },
767
774
  "rangeTimeline": {
768
775
  "childRows": "Hàng con",
@@ -138,6 +138,64 @@ export type CompactBarTrendProp = {
138
138
  id?: IdProp;
139
139
  ref?: React.Ref<HTMLElement>;
140
140
  };
141
+ /** One category on a HeatmapChart axis — a row (weekday) or a column (hour). */
142
+ export type HeatmapCategory = {
143
+ /** Stable key the `data` cells refer to (`row` / `column`). */
144
+ key: string | number;
145
+ /** Already-translated display label — the axis tick and the table header. */
146
+ label: string;
147
+ };
148
+ /** One HeatmapChart cell. A cell absent from `data`, or with a non-finite `value`, is EMPTY. */
149
+ export type HeatmapDatum = {
150
+ /** `key` of the row this cell belongs to. */
151
+ row: string | number;
152
+ /** `key` of the column this cell belongs to. */
153
+ column: string | number;
154
+ /** The measured value. `null`/`undefined`/`NaN` mean "no data" — not zero. */
155
+ value: number | null | undefined;
156
+ };
157
+ /**
158
+ * @see HeatmapChart
159
+ *
160
+ * Dependency-free (no `recharts`) rows × columns matrix — a weekday × hour heatmap. Cell intensity
161
+ * steps through the `--chart-heat-1..5` ramp; an empty cell is outlined, a zero cell is filled.
162
+ */
163
+ export type HeatmapChartProp = {
164
+ /** Row categories, top to bottom (the y axis — weekdays). */
165
+ rows: HeatmapCategory[];
166
+ /** Column categories, start to end (the x axis — hours). */
167
+ columns: HeatmapCategory[];
168
+ /** Cell values, keyed by `row` + `column`. Order does not matter; a missing cell is empty. */
169
+ data: HeatmapDatum[];
170
+ /** Accessible name + visible caption for the chart. REQUIRED (the grid needs a name). */
171
+ label: LabelProp;
172
+ /**
173
+ * Paint `label` as a visible caption above the plot. `false` keeps it in the DOM as `sr-only`,
174
+ * so the figure and its grid keep their accessible name.
175
+ */
176
+ showCaption?: boolean;
177
+ /** Extra context appended to the screen-reader description. */
178
+ description?: DescriptionProp;
179
+ /**
180
+ * CELL size tier — `xs|sm|md|lg` (`--chart-heatmap-cell-size-*`). Not a canvas height: the matrix
181
+ * is as tall as its rows, and when the columns do not fit it scrolls inside its own box.
182
+ */
183
+ size?: SizeProp;
184
+ /** `Intl.NumberFormat` options for cell values, the tooltip and the legend (locale is automatic). */
185
+ numberFormat?: Intl.NumberFormatOptions;
186
+ /**
187
+ * Emphasize the N highest cells with an outline ring and a "top N" note in the tooltip and the
188
+ * text alternative — never colour alone. Ties keep `data` order. Omitted or 0 = no emphasis.
189
+ */
190
+ topN?: number;
191
+ /** Show the colour-scale legend under the matrix. */
192
+ showLegend?: boolean;
193
+ /** Message shown when there are no rows, no columns or no cells. Defaults to a localized "no data". */
194
+ emptyMessage?: EmptyMessageProp;
195
+ className?: ClassNameProp;
196
+ id?: IdProp;
197
+ ref?: React.Ref<HTMLElement>;
198
+ };
141
199
  /** @see AreaChart */
142
200
  export type AreaChartProp = ChartCartesianBase & {
143
201
  /** Stack series areas instead of overlaying them. */
@@ -2331,6 +2331,43 @@ export declare const COMPONENT_PROP_REGISTRY: {
2331
2331
  readonly reason: "Forwarded ref to the <figure> element.";
2332
2332
  }];
2333
2333
  };
2334
+ readonly HeatmapChartProp: {
2335
+ readonly group: "data-display";
2336
+ readonly file: "components/charts.prop.ts";
2337
+ readonly vocabulary: readonly ["LabelProp", "DescriptionProp", "SizeProp", "EmptyMessageProp", "ClassNameProp", "IdProp", {
2338
+ readonly field: "rows";
2339
+ readonly local: true;
2340
+ readonly reason: "Row categories (y axis) — key + translated label.";
2341
+ }, {
2342
+ readonly field: "columns";
2343
+ readonly local: true;
2344
+ readonly reason: "Column categories (x axis) — key + translated label.";
2345
+ }, {
2346
+ readonly field: "data";
2347
+ readonly local: true;
2348
+ readonly reason: "Cell values keyed by row + column.";
2349
+ }, {
2350
+ readonly field: "showCaption";
2351
+ readonly local: true;
2352
+ readonly reason: "Paint the caption; false keeps it sr-only so the accessible name survives.";
2353
+ }, {
2354
+ readonly field: "numberFormat";
2355
+ readonly local: true;
2356
+ readonly reason: "Intl.NumberFormat options for cell values, tooltip and legend.";
2357
+ }, {
2358
+ readonly field: "topN";
2359
+ readonly local: true;
2360
+ readonly reason: "Emphasize the N highest cells (ring + text note, never colour alone).";
2361
+ }, {
2362
+ readonly field: "showLegend";
2363
+ readonly local: true;
2364
+ readonly reason: "Chart-specific legend toggle.";
2365
+ }, {
2366
+ readonly field: "ref";
2367
+ readonly local: true;
2368
+ readonly reason: "Forwarded ref to the <figure> element.";
2369
+ }];
2370
+ };
2334
2371
  readonly AreaChartProp: {
2335
2372
  readonly group: "data-display";
2336
2373
  readonly file: "components/charts.prop.ts";
@@ -2762,6 +2762,42 @@ const COMPONENT_PROP_REGISTRY = {
2762
2762
  { field: "ref", local: true, reason: "Forwarded ref to the <figure> element." }
2763
2763
  ]
2764
2764
  },
2765
+ HeatmapChartProp: {
2766
+ group: "data-display",
2767
+ file: "components/charts.prop.ts",
2768
+ vocabulary: [
2769
+ "LabelProp",
2770
+ "DescriptionProp",
2771
+ "SizeProp",
2772
+ "EmptyMessageProp",
2773
+ "ClassNameProp",
2774
+ "IdProp",
2775
+ { field: "rows", local: true, reason: "Row categories (y axis) \u2014 key + translated label." },
2776
+ {
2777
+ field: "columns",
2778
+ local: true,
2779
+ reason: "Column categories (x axis) \u2014 key + translated label."
2780
+ },
2781
+ { field: "data", local: true, reason: "Cell values keyed by row + column." },
2782
+ {
2783
+ field: "showCaption",
2784
+ local: true,
2785
+ reason: "Paint the caption; false keeps it sr-only so the accessible name survives."
2786
+ },
2787
+ {
2788
+ field: "numberFormat",
2789
+ local: true,
2790
+ reason: "Intl.NumberFormat options for cell values, tooltip and legend."
2791
+ },
2792
+ {
2793
+ field: "topN",
2794
+ local: true,
2795
+ reason: "Emphasize the N highest cells (ring + text note, never colour alone)."
2796
+ },
2797
+ { field: "showLegend", local: true, reason: "Chart-specific legend toggle." },
2798
+ { field: "ref", local: true, reason: "Forwarded ref to the <figure> element." }
2799
+ ]
2800
+ },
2765
2801
  AreaChartProp: {
2766
2802
  group: "data-display",
2767
2803
  file: "components/charts.prop.ts",
@@ -5,25 +5,6 @@
5
5
 
6
6
  @layer godxjp-ui-responsive;
7
7
 
8
- [lang="ja"] {
9
- --font-family-sans: var(--font-sans-ja, var(--font-sans-base));
10
- }
11
- [lang="ko"] {
12
- --font-family-sans: var(--font-sans-ko, var(--font-sans-base));
13
- }
14
- [lang="vi"] {
15
- --font-family-sans: var(--font-sans-vi, var(--font-sans-base));
16
- }
17
- [lang="zh"],
18
- [lang="zh-Hans"],
19
- [lang="zh-CN"] {
20
- --font-family-sans: var(--font-sans-zh-hans, var(--font-sans-base));
21
- }
22
- [lang="zh-Hant"],
23
- [lang="zh-TW"] {
24
- --font-family-sans: var(--font-sans-zh-hant, var(--font-sans-base));
25
- }
26
-
27
8
  @source inline(
28
9
  "{bg,text,border,ring}-{primary,secondary,muted,accent,destructive,success,warning,info,attention}"
29
10
  );
@@ -45,6 +26,25 @@
45
26
  @import "./focus-ring.css";
46
27
  @import "./density.css";
47
28
 
29
+ [lang="ja"] {
30
+ --font-family-sans: var(--font-sans-ja, var(--font-sans-base));
31
+ }
32
+ [lang="ko"] {
33
+ --font-family-sans: var(--font-sans-ko, var(--font-sans-base));
34
+ }
35
+ [lang="vi"] {
36
+ --font-family-sans: var(--font-sans-vi, var(--font-sans-base));
37
+ }
38
+ [lang="zh"],
39
+ [lang="zh-Hans"],
40
+ [lang="zh-CN"] {
41
+ --font-family-sans: var(--font-sans-zh-hans, var(--font-sans-base));
42
+ }
43
+ [lang="zh-Hant"],
44
+ [lang="zh-TW"] {
45
+ --font-family-sans: var(--font-sans-zh-hant, var(--font-sans-base));
46
+ }
47
+
48
48
  @theme inline {
49
49
  --color-background: hsl(var(--background));
50
50
  --color-foreground: hsl(var(--foreground));
@@ -165,3 +165,164 @@
165
165
  .ui-chart-canvas [tabindex="-1"]:focus:not(:focus-visible) {
166
166
  outline: none;
167
167
  }
168
+
169
+ .ui-chart-heatmap[data-size="xs"] {
170
+ --chart-heatmap-cell-size: var(--chart-heatmap-cell-size-xs);
171
+ }
172
+
173
+ .ui-chart-heatmap[data-size="sm"] {
174
+ --chart-heatmap-cell-size: var(--chart-heatmap-cell-size-sm);
175
+ }
176
+
177
+ .ui-chart-heatmap[data-size="md"] {
178
+ --chart-heatmap-cell-size: var(--chart-heatmap-cell-size-md);
179
+ }
180
+
181
+ .ui-chart-heatmap[data-size="lg"] {
182
+ --chart-heatmap-cell-size: var(--chart-heatmap-cell-size-lg);
183
+ }
184
+
185
+ .ui-chart-heatmap-scroll {
186
+ inline-size: 100%;
187
+ min-inline-size: 0;
188
+ overflow-x: auto;
189
+ overscroll-behavior-inline: contain;
190
+ }
191
+
192
+ .ui-chart-heatmap-grid {
193
+ inline-size: 100%;
194
+ border-collapse: separate;
195
+ border-spacing: var(--chart-heatmap-cell-gap);
196
+ font-size: var(--chart-heatmap-tick-font-size);
197
+ line-height: var(--line-height-normal);
198
+ }
199
+
200
+ .ui-chart-heatmap-column-header,
201
+ .ui-chart-heatmap-row-header {
202
+ padding: 0;
203
+ font-weight: var(--font-weight-normal);
204
+ color: hsl(var(--muted-foreground));
205
+ white-space: nowrap;
206
+ }
207
+
208
+ .ui-chart-heatmap-column-header {
209
+ text-align: center;
210
+ }
211
+
212
+ .ui-chart-heatmap-row-header {
213
+ position: sticky;
214
+ inset-inline-start: 0;
215
+ z-index: 1;
216
+ inline-size: 1%;
217
+ padding-inline-end: var(--space-2);
218
+ text-align: start;
219
+ background: var(--chart-heatmap-row-header-background, hsl(var(--card)));
220
+ }
221
+
222
+ .ui-chart-heatmap-corner {
223
+ padding: 0;
224
+ }
225
+
226
+ .ui-chart-heatmap-cell {
227
+ min-inline-size: var(--chart-heatmap-cell-size);
228
+ inline-size: var(--chart-heatmap-cell-size);
229
+ block-size: var(--chart-heatmap-cell-size);
230
+ padding: 0;
231
+
232
+ border: var(--stroke-hairline) solid transparent;
233
+ border-radius: var(
234
+ --chart-heatmap-cell-radius,
235
+ calc(var(--radius) / var(--radius-ratio) / var(--radius-ratio))
236
+ );
237
+ }
238
+
239
+ .ui-chart-heatmap-cell[data-step="1"],
240
+ .ui-chart-heatmap-legend-swatch[data-step="1"] {
241
+ background: var(--chart-heat-1);
242
+ }
243
+
244
+ .ui-chart-heatmap-cell[data-step="2"],
245
+ .ui-chart-heatmap-legend-swatch[data-step="2"] {
246
+ background: var(--chart-heat-2);
247
+ }
248
+
249
+ .ui-chart-heatmap-cell[data-step="3"],
250
+ .ui-chart-heatmap-legend-swatch[data-step="3"] {
251
+ background: var(--chart-heat-3);
252
+ }
253
+
254
+ .ui-chart-heatmap-cell[data-step="4"],
255
+ .ui-chart-heatmap-legend-swatch[data-step="4"] {
256
+ background: var(--chart-heat-4);
257
+ }
258
+
259
+ .ui-chart-heatmap-cell[data-step="5"],
260
+ .ui-chart-heatmap-legend-swatch[data-step="5"] {
261
+ background: var(--chart-heat-5);
262
+ }
263
+
264
+ .ui-chart-heatmap-cell[data-empty],
265
+ .ui-chart-heatmap-legend-swatch[data-empty] {
266
+ background: transparent;
267
+ border: var(
268
+ --chart-heatmap-empty-border,
269
+ var(--stroke-hairline) dashed hsl(var(--muted-foreground))
270
+ );
271
+ }
272
+
273
+ .ui-chart-heatmap-cell[data-emphasized],
274
+ .ui-chart-heatmap-legend-swatch[data-emphasized] {
275
+ box-shadow:
276
+ inset 0 0 0 var(--chart-heatmap-emphasis-width)
277
+ var(--chart-heatmap-emphasis-border, hsl(var(--foreground))),
278
+ inset 0 0 0 calc(var(--chart-heatmap-emphasis-width) * 2) hsl(var(--card));
279
+ }
280
+
281
+ .ui-chart-heatmap-tooltip {
282
+ display: flex;
283
+ flex-direction: column;
284
+ }
285
+
286
+ .ui-chart-heatmap-tooltip-title {
287
+ font-variant-numeric: tabular-nums;
288
+ }
289
+
290
+ .ui-chart-heatmap-legend {
291
+ display: flex;
292
+ flex-wrap: wrap;
293
+ align-items: center;
294
+ gap: var(--chart-heatmap-legend-gap) calc(var(--chart-heatmap-legend-gap) * 2);
295
+ font-size: var(--chart-heatmap-tick-font-size);
296
+ line-height: var(--line-height-normal);
297
+ color: hsl(var(--muted-foreground));
298
+ }
299
+
300
+ .ui-chart-heatmap-legend-scale,
301
+ .ui-chart-heatmap-legend-item {
302
+ display: inline-flex;
303
+ align-items: center;
304
+ gap: var(--chart-heatmap-legend-gap);
305
+ font-variant-numeric: tabular-nums;
306
+ }
307
+
308
+ .ui-chart-heatmap-legend-ramp {
309
+ display: flex;
310
+ margin: 0;
311
+ padding: 0;
312
+ list-style: none;
313
+ }
314
+
315
+ .ui-chart-heatmap-legend-swatch {
316
+ display: inline-block;
317
+ inline-size: calc(var(--chart-heatmap-legend-swatch-size) * 1.5);
318
+ block-size: var(--chart-heatmap-legend-swatch-size);
319
+ border: var(--stroke-hairline) solid transparent;
320
+ }
321
+
322
+ .ui-chart-heatmap-legend-item > .ui-chart-heatmap-legend-swatch {
323
+ inline-size: var(--chart-heatmap-legend-swatch-size);
324
+ border-radius: var(
325
+ --chart-heatmap-cell-radius,
326
+ calc(var(--radius) / var(--radius-ratio) / var(--radius-ratio))
327
+ );
328
+ }
@@ -922,10 +922,10 @@
922
922
  var(--list-row-compact-padding-x, var(--list-row-padding-x));
923
923
  }
924
924
 
925
- [data-slot="card-content"]:not([data-flush]) > [data-slot="list-row"],
926
925
  [data-slot="card-content"]:not([data-flush])
927
- > :is(ul, ol, [role="list"])
928
- > [data-slot="list-row"] {
926
+ [data-slot="list-row"]:not(
927
+ :where([data-slot="card-content"][data-flush], [data-slot="table-cell"], td, th) *
928
+ ) {
929
929
  padding-inline: 0;
930
930
  }
931
931
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "32.13.1",
2
+ "version": "32.15.0",
3
3
  "generatedBy": "scripts/gen-style-layers.mjs — do not edit by hand; run `pnpm gen:style-layers`",
4
4
  "base": "base.css",
5
5
  "fonts": "fonts.css",
@@ -564,6 +564,13 @@
564
564
  "dialog-layout.css"
565
565
  ]
566
566
  },
567
+ "HeatmapChart": {
568
+ "layers": [
569
+ "layout.css",
570
+ "dialog-layout.css",
571
+ "chart-layout.css"
572
+ ]
573
+ },
567
574
  "Icon": {
568
575
  "layers": [
569
576
  "icon-layout.css"
@@ -870,7 +870,7 @@
870
870
  .ui-page-toolbar {
871
871
  flex: none;
872
872
  margin-block: calc(-1 * var(--page-band-gap));
873
- padding-block: var(--page-toolbar-pad-block);
873
+ padding-block: var(--page-toolbar-pad-block, var(--page-band-gap));
874
874
  background: var(--page-toolbar-background);
875
875
  border-block-end: var(--page-toolbar-divider, var(--page-header-divider));
876
876
  }