@godxjp/ui 18.12.11 → 18.12.13

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.
@@ -19,13 +19,11 @@ export type TableProps = React.HTMLAttributes<HTMLTableElement> & {
19
19
  bordered?: boolean;
20
20
  /**
21
21
  * Named collection contract. `"default"` (the default) emits no attribute and keeps the plain
22
- * table exactly as it is.
23
- *
24
- * `"action-collection"` is the canonical dense approval / action queue (gh#253): below
25
- * `collapseBelow`, the desktop intrinsic column widths the thing that pushes the last columns
26
- * outside a 390px viewport are replaced by the token-owned column PRIORITY measures
27
- * (`--table-action-collection-*`) under `table-layout: fixed`, and cells wrap instead of
28
- * forcing a horizontal scroll. Mark each column with `priority` on its `TableHead`/`TableCell`.
22
+ * table exactly as it is. `"action-collection"` is the canonical dense approval / action queue
23
+ * (gh#253): below `collapseBelow`, the desktop intrinsic column widths — the thing that pushes
24
+ * the last columns outside a 390px viewport are replaced by the token-owned column PRIORITY
25
+ * measures (`--table-action-collection-*`) under `table-layout: fixed`, and cells wrap instead
26
+ * of forcing a horizontal scroll. Mark each column with `priority` on its `TableHead`/`TableCell`.
29
27
  * The table keeps its real semantics: no `display` change, no role rewriting, no card swap, so
30
28
  * header association, `aria-sort` and screen-reader table navigation are identical at every width.
31
29
  *
@@ -34,26 +32,12 @@ export type TableProps = React.HTMLAttributes<HTMLTableElement> & {
34
32
  * its rem floor (`--table-action-collection-*-width-floor`, ~5 CJK glyphs per line) and the
35
33
  * table intentionally scrolls inside this wrapper — SC 1.4.10 permits one-dimensional scrolling
36
34
  * of a data table; compressing further would shred CJK headers one character per line.
37
- *
38
- * `"stacked-record-collection"` (gh#356) is the canonical RECORD list — a table whose columns
39
- * are independent facts about ONE record (client ID · purpose · scopes · last use · status ·
40
- * lifecycle actions) rather than a dense queue `action-collection` can reflow into a
41
- * column-priority budget. Below `collapseBelow` each row renders as a card-like block with
42
- * every column's label + value stacked vertically (a definition-list composition); row-level
43
- * actions stay in document flow at the end of the card, never scrolled off-canvas. Supply the
44
- * stacked-tier legend for each column with `label` on its `TableCell` (leave it unset on a
45
- * self-evident column, e.g. row actions). This DOES change `display` (table family → block), so
46
- * table/rowgroup/row/cell roles are re-asserted explicitly on every element that keeps
47
- * rendering — see the prop doc on `TableCell`. The one element that does NOT keep rendering is
48
- * the header row: below the step it is removed outright (not just visually hidden), because
49
- * each `TableCell`'s own `label` becomes the field name for every modality at that tier — see
50
- * `TableCellLabel`.
51
35
  */
52
36
  preset?: TablePresetProp;
53
37
  /**
54
- * Step at which a named `preset` switches tiers, measured against the TABLE's own container
55
- * (not the viewport), so a table inside a rail collapses before the page does. Defaults to
56
- * `"sm"` (40rem). Ignored while `preset` is `"default"`.
38
+ * Step at which `preset="action-collection"` switches to the priority measures, measured against
39
+ * the TABLE's own container (not the viewport), so a table inside a rail collapses before the
40
+ * page does. Defaults to `"sm"` (40rem). Ignored while `preset` is `"default"`.
57
41
  */
58
42
  collapseBelow?: BreakpointProp;
59
43
  };
@@ -76,13 +60,11 @@ export declare const Table: React.ForwardRefExoticComponent<React.HTMLAttributes
76
60
  bordered?: boolean;
77
61
  /**
78
62
  * Named collection contract. `"default"` (the default) emits no attribute and keeps the plain
79
- * table exactly as it is.
80
- *
81
- * `"action-collection"` is the canonical dense approval / action queue (gh#253): below
82
- * `collapseBelow`, the desktop intrinsic column widths the thing that pushes the last columns
83
- * outside a 390px viewport are replaced by the token-owned column PRIORITY measures
84
- * (`--table-action-collection-*`) under `table-layout: fixed`, and cells wrap instead of
85
- * forcing a horizontal scroll. Mark each column with `priority` on its `TableHead`/`TableCell`.
63
+ * table exactly as it is. `"action-collection"` is the canonical dense approval / action queue
64
+ * (gh#253): below `collapseBelow`, the desktop intrinsic column widths — the thing that pushes
65
+ * the last columns outside a 390px viewport are replaced by the token-owned column PRIORITY
66
+ * measures (`--table-action-collection-*`) under `table-layout: fixed`, and cells wrap instead
67
+ * of forcing a horizontal scroll. Mark each column with `priority` on its `TableHead`/`TableCell`.
86
68
  * The table keeps its real semantics: no `display` change, no role rewriting, no card swap, so
87
69
  * header association, `aria-sort` and screen-reader table navigation are identical at every width.
88
70
  *
@@ -91,26 +73,12 @@ export declare const Table: React.ForwardRefExoticComponent<React.HTMLAttributes
91
73
  * its rem floor (`--table-action-collection-*-width-floor`, ~5 CJK glyphs per line) and the
92
74
  * table intentionally scrolls inside this wrapper — SC 1.4.10 permits one-dimensional scrolling
93
75
  * of a data table; compressing further would shred CJK headers one character per line.
94
- *
95
- * `"stacked-record-collection"` (gh#356) is the canonical RECORD list — a table whose columns
96
- * are independent facts about ONE record (client ID · purpose · scopes · last use · status ·
97
- * lifecycle actions) rather than a dense queue `action-collection` can reflow into a
98
- * column-priority budget. Below `collapseBelow` each row renders as a card-like block with
99
- * every column's label + value stacked vertically (a definition-list composition); row-level
100
- * actions stay in document flow at the end of the card, never scrolled off-canvas. Supply the
101
- * stacked-tier legend for each column with `label` on its `TableCell` (leave it unset on a
102
- * self-evident column, e.g. row actions). This DOES change `display` (table family → block), so
103
- * table/rowgroup/row/cell roles are re-asserted explicitly on every element that keeps
104
- * rendering — see the prop doc on `TableCell`. The one element that does NOT keep rendering is
105
- * the header row: below the step it is removed outright (not just visually hidden), because
106
- * each `TableCell`'s own `label` becomes the field name for every modality at that tier — see
107
- * `TableCellLabel`.
108
76
  */
109
77
  preset?: TablePresetProp;
110
78
  /**
111
- * Step at which a named `preset` switches tiers, measured against the TABLE's own container
112
- * (not the viewport), so a table inside a rail collapses before the page does. Defaults to
113
- * `"sm"` (40rem). Ignored while `preset` is `"default"`.
79
+ * Step at which `preset="action-collection"` switches to the priority measures, measured against
80
+ * the TABLE's own container (not the viewport), so a table inside a rail collapses before the
81
+ * page does. Defaults to `"sm"` (40rem). Ignored while `preset` is `"default"`.
114
82
  */
115
83
  collapseBelow?: BreakpointProp;
116
84
  } & React.RefAttributes<HTMLTableElement>>;
@@ -126,17 +94,6 @@ export declare const TableRow: React.ForwardRefExoticComponent<React.HTMLAttribu
126
94
  type TableCellPriority = {
127
95
  priority?: TableColumnPriorityProp;
128
96
  };
129
- /**
130
- * Stacked-tier legend for ONE column, read only by `TableCell` under
131
- * `Table preset="stacked-record-collection"`. Rendered as an inline label ahead of the cell's
132
- * value, visible only below the collapse step (a wide container still shows the real `<th>`
133
- * header instead, so the label stays invisible — never duplicated — above the step). Leave unset
134
- * on a column whose value is self-evident without one (e.g. a row-actions cell whose buttons
135
- * already carry their own text). Ignored under every other preset.
136
- */
137
- type TableCellLabel = {
138
- label?: React.ReactNode;
139
- };
140
97
  export declare const TableHead: React.ForwardRefExoticComponent<React.ThHTMLAttributes<HTMLTableCellElement> & TableCellPriority & React.RefAttributes<HTMLTableCellElement>>;
141
- export declare const TableCell: React.ForwardRefExoticComponent<React.TdHTMLAttributes<HTMLTableCellElement> & TableCellPriority & TableCellLabel & React.RefAttributes<HTMLTableCellElement>>;
98
+ export declare const TableCell: React.ForwardRefExoticComponent<React.TdHTMLAttributes<HTMLTableCellElement> & TableCellPriority & React.RefAttributes<HTMLTableCellElement>>;
142
99
  export {};
@@ -1,9 +1,7 @@
1
- "use client";
2
- import { jsx, jsxs } from "react/jsx-runtime";
1
+ import { jsx } from "react/jsx-runtime";
3
2
  import * as React from "react";
4
3
  import { tableHeadHeightClass } from "../../lib/control-styles.js";
5
4
  import { cn } from "../../lib/utils.js";
6
- const TablePresetContext = React.createContext("default");
7
5
  const Table = React.forwardRef(
8
6
  ({
9
7
  className,
@@ -25,115 +23,62 @@ const Table = React.forwardRef(
25
23
  {
26
24
  className: cn(
27
25
  scrollable ? "relative w-full overflow-auto" : "relative w-full",
28
- preset === "action-collection" && "ui-table-collection",
29
- preset === "stacked-record-collection" && "ui-table-stacked-collection"
26
+ preset !== "default" && "ui-table-collection"
30
27
  ),
31
28
  "data-preset": preset === "default" ? void 0 : preset,
32
29
  "data-collapse-below": preset === "default" ? void 0 : collapseBelow,
33
30
  ...scrollable ? { tabIndex: 0 } : {},
34
- children: /* @__PURE__ */ jsx(TablePresetContext.Provider, { value: preset, children: /* @__PURE__ */ jsx(
31
+ children: /* @__PURE__ */ jsx(
35
32
  "table",
36
33
  {
37
34
  ref,
38
35
  "data-slot": "table",
39
- role: preset === "stacked-record-collection" ? "table" : void 0,
40
- className: cn(
41
- "w-full caption-bottom text-sm",
42
- bordered && "ui-table-bordered",
43
- className
44
- ),
36
+ className: cn("w-full caption-bottom text-sm", bordered && "ui-table-bordered", className),
45
37
  ...props
46
38
  }
47
- ) })
39
+ )
48
40
  }
49
41
  )
50
42
  )
51
43
  );
52
44
  Table.displayName = "Table";
53
- const TableHeader = React.forwardRef(({ className, ...props }, ref) => {
54
- const preset = React.useContext(TablePresetContext);
55
- const stacked = preset === "stacked-record-collection";
56
- return /* @__PURE__ */ jsx(
57
- "thead",
58
- {
59
- ref,
60
- role: stacked ? "rowgroup" : void 0,
61
- className: cn(
62
- "[&_tr]:border-b",
63
- // Removed below the collapse step (the stacked-tier CSS makes it display:none) — the
64
- // per-cell label TableCell renders inline (real text, not aria-hidden) replaces it for
65
- // every modality, so the raw header is fully redundant there, not just visually.
66
- stacked && "ui-table-stacked-collection-head",
67
- className
68
- ),
69
- ...props
70
- }
71
- );
72
- });
45
+ const TableHeader = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("thead", { ref, className: cn("[&_tr]:border-b", className), ...props }));
73
46
  TableHeader.displayName = "TableHeader";
74
- const TableBody = React.forwardRef(({ className, ...props }, ref) => {
75
- const preset = React.useContext(TablePresetContext);
76
- return /* @__PURE__ */ jsx(
77
- "tbody",
78
- {
79
- ref,
80
- role: preset === "stacked-record-collection" ? "rowgroup" : void 0,
81
- className: cn("[&_tr:last-child]:border-0", className),
82
- ...props
83
- }
84
- );
85
- });
47
+ const TableBody = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("tbody", { ref, className: cn("[&_tr:last-child]:border-0", className), ...props }));
86
48
  TableBody.displayName = "TableBody";
87
- const TableRow = React.forwardRef(({ className, ...props }, ref) => {
88
- const preset = React.useContext(TablePresetContext);
89
- return /* @__PURE__ */ jsx(
90
- "tr",
91
- {
92
- ref,
93
- role: preset === "stacked-record-collection" ? "row" : void 0,
94
- className: cn(
95
- "ui-table-row hover:bg-accent/70 data-[state=selected]:bg-primary/[0.06] border-b transition-colors",
96
- className
97
- ),
98
- ...props
99
- }
100
- );
101
- });
49
+ const TableRow = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
50
+ "tr",
51
+ {
52
+ ref,
53
+ className: cn(
54
+ "ui-table-row hover:bg-accent/70 data-[state=selected]:bg-primary/[0.06] border-b transition-colors",
55
+ className
56
+ ),
57
+ ...props
58
+ }
59
+ ));
102
60
  TableRow.displayName = "TableRow";
103
- const TableHead = React.forwardRef(({ className, priority, ...props }, ref) => {
104
- const preset = React.useContext(TablePresetContext);
105
- return /* @__PURE__ */ jsx(
106
- "th",
107
- {
108
- ref,
109
- "data-slot": "table-head",
110
- "data-priority": priority,
111
- role: preset === "stacked-record-collection" ? "columnheader" : void 0,
112
- className: cn(tableHeadHeightClass, className),
113
- ...props
114
- }
115
- );
116
- });
61
+ const TableHead = React.forwardRef(({ className, priority, ...props }, ref) => /* @__PURE__ */ jsx(
62
+ "th",
63
+ {
64
+ ref,
65
+ "data-slot": "table-head",
66
+ "data-priority": priority,
67
+ className: cn(tableHeadHeightClass, className),
68
+ ...props
69
+ }
70
+ ));
117
71
  TableHead.displayName = "TableHead";
118
- const TableCell = React.forwardRef(({ className, priority, label, children, ...props }, ref) => {
119
- const preset = React.useContext(TablePresetContext);
120
- const stacked = preset === "stacked-record-collection";
121
- return /* @__PURE__ */ jsxs(
122
- "td",
123
- {
124
- ref,
125
- "data-slot": "table-cell",
126
- "data-priority": priority,
127
- role: stacked ? "cell" : void 0,
128
- className: cn(className),
129
- ...props,
130
- children: [
131
- stacked && label != null ? /* @__PURE__ */ jsx("span", { className: "ui-table-stacked-collection-label", children: label }) : null,
132
- children
133
- ]
134
- }
135
- );
136
- });
72
+ const TableCell = React.forwardRef(({ className, priority, ...props }, ref) => /* @__PURE__ */ jsx(
73
+ "td",
74
+ {
75
+ ref,
76
+ "data-slot": "table-cell",
77
+ "data-priority": priority,
78
+ className: cn(className),
79
+ ...props
80
+ }
81
+ ));
137
82
  TableCell.displayName = "TableCell";
138
83
  export {
139
84
  Table,
@@ -1,2 +1 @@
1
- "use client";
2
1
  export * from "../data-display/table.js";
@@ -81,21 +81,8 @@ export type StickyProp = boolean;
81
81
  * the desktop intrinsic column widths are replaced by token-owned column-PRIORITY measures under
82
82
  * `table-layout: fixed` and cells wrap, so every column — including the row actions — stays inside
83
83
  * the initial narrow frame. The real `<table>` semantics are never rewritten.
84
- *
85
- * `"stacked-record-collection"` (gh#356) is the canonical RECORD list — a table whose columns
86
- * cannot be reflowed into a fixed-layout budget (a scopes/status/lifecycle-action record, not a
87
- * dense queue): below `collapseBelow` each row renders as a card-like block with every column's
88
- * label + value stacked vertically (a definition-list composition), and row-level actions stay in
89
- * document flow at the bottom of the card — never scrolled off-canvas. Unlike `action-collection`
90
- * this DOES change `display` (table → block), so the preset re-asserts table semantics with
91
- * explicit `role` attributes on every element that keeps rendering (browsers drop the IMPLICIT
92
- * table roles once `display` leaves the table family — the standard fix, see e.g. Scott O'Hara's
93
- * "breaking tables"). The header row is the one element that does NOT keep rendering below the
94
- * step — it is removed outright, because each `TableCell`'s own `label` becomes the field name
95
- * for every modality at that tier. Mark each column's stacked-tier legend with `label` on its
96
- * `TableCell`.
97
84
  */
98
- export type TablePresetProp = "default" | "action-collection" | "stacked-record-collection";
85
+ export type TablePresetProp = "default" | "action-collection";
99
86
  /**
100
87
  * Relative importance of a table column, used by `preset="action-collection"` to allocate the
101
88
  * narrow-frame measure. `"primary"` is the row's subject, `"secondary"` its object/target,
@@ -1271,7 +1271,19 @@
1271
1271
  align-items: center;
1272
1272
  gap: var(--topbar-gap);
1273
1273
  padding-inline: var(--topbar-inset);
1274
- overflow: hidden;
1274
+ /* Horizontal-only clip (gh#291). `hidden` clipped BOTH axes with no clip-margin,
1275
+ * cutting the focus ring of slot controls flat at top/bottom — the bar's content
1276
+ * box hugs --control-height exactly, and the rails' overflow-clip-margin below
1277
+ * cannot help when the parent already swallowed the ring. `clip` (not `hidden`)
1278
+ * is what lets overflow-y stay `visible` — a `hidden`/`visible` pair computes to
1279
+ * `auto` and still clips. Vertically the ring paints into the shell bar's box,
1280
+ * which has headroom; the horizontal shrink/truncation contract is unchanged. */
1281
+ overflow-x: clip;
1282
+ overflow-y: visible;
1283
+ /* Ring headroom on the clipped axis: the end rail sits flush against this
1284
+ * box, so without a margin the LAST control's ring loses its outer edge.
1285
+ * 2x the ring token — open/focus rings paint up to 3px (gh#291 follow-up). */
1286
+ overflow-clip-margin: calc(2 * var(--focus-ring-width));
1275
1287
  }
1276
1288
  .ui-topbar-start,
1277
1289
  .ui-topbar-center,
@@ -1280,8 +1292,17 @@
1280
1292
  min-width: 0;
1281
1293
  align-items: center;
1282
1294
  gap: var(--topbar-gap);
1283
- overflow: clip;
1284
- overflow-clip-margin: var(--focus-ring-width);
1295
+ /* Clip horizontally only (gh#291): the rails hug --control-height, so a
1296
+ * vertical clip eats the focus ring even WITH the clip-margin — the margin
1297
+ * is 2px while e.g. the toggle ring paints 3px, and Safari does not
1298
+ * implement overflow-clip-margin at all. The margin still buys horizontal
1299
+ * ring headroom where supported. */
1300
+ overflow-x: clip;
1301
+ overflow-y: visible;
1302
+ /* 2x the ring token, NOT 1x: focus/open rings paint up to 3px while the
1303
+ * token is 2px, so a flush-edge control (the locale picker is the first
1304
+ * child of `end`) lost 1px of ring on the clipped axis (gh#291 follow-up). */
1305
+ overflow-clip-margin: calc(2 * var(--focus-ring-width));
1285
1306
  }
1286
1307
  .ui-topbar-start {
1287
1308
  flex: 0 1 auto;
@@ -363,32 +363,6 @@
363
363
  }
364
364
  }
365
365
 
366
- @layer components {
367
- /* ── Table · `preset="stacked-record-collection"` (gh#356) ──────────────────────────────────
368
- * The canonical RECORD list: client ID · purpose · scopes · last use · status · lifecycle
369
- * actions — independent facts about ONE record, not a dense queue `action-collection`'s
370
- * column-priority budget can reflow. Below `collapseBelow` every row becomes a card-like block
371
- * and every column's label + value stack vertically (a definition-list composition), so every
372
- * field — the row's lifecycle actions included — stays inside the initial narrow frame instead
373
- * of requiring horizontal scroll.
374
- *
375
- * Unlike `action-collection` this DOES change `display` (table family → block) below the step,
376
- * so table.tsx re-asserts table/rowgroup/row/columnheader/cell explicitly via `role` — browsers
377
- * drop the IMPLICIT roles once an element's `display` leaves the table family. The static rules
378
- * here are unqueried (apply whenever the preset is on); the display-changing, card-drawing
379
- * rules live in the `godxjp-ui-responsive` layer below, same split as `action-collection`. */
380
- .ui-table-stacked-collection {
381
- container: ui-table-stacked-collection / inline-size;
382
- }
383
-
384
- /* The stacked-tier field label TableCell renders ahead of its value when `label` is supplied.
385
- * Hidden above the collapse step so a wide container never shows both the real `<th>` header
386
- * AND the inline label for the same column — the responsive layer below turns it back on. */
387
- .ui-table-stacked-collection-label {
388
- display: none;
389
- }
390
- }
391
-
392
366
  /* The compact tier lives in `godxjp-ui-responsive` — the LAST layer, declared after Tailwind in
393
367
  * styles/base.css — not in `@layer components`. `<table>` carries `text-sm`, a Tailwind utility,
394
368
  * and `utilities` outranks `components` by LAYER ORDER, so a `font-size:` re-point written here as
@@ -563,325 +537,3 @@
563
537
  }
564
538
  }
565
539
  }
566
-
567
- /* `preset="stacked-record-collection"` compact tier (gh#356) — same layer-contract reason as
568
- * `action-collection` above: `<table>` carries `text-sm`/`border-b`/`border-0`, all Tailwind
569
- * utilities, and `utilities` outranks `components` by LAYER ORDER, so the display-changing card
570
- * transform has to live in this LAST layer to ever win the cascade. One block per canonical step
571
- * (a container query cannot read a `var()`, so the scale is written out — sm 40rem · md 48rem ·
572
- * lg 64rem · xl 80rem, the same steps `action-collection` and `--master-detail-collapse-below`
573
- * use). See styles/base.css · THE LAYER CONTRACT. */
574
- @layer godxjp-ui-responsive {
575
- @container ui-table-stacked-collection (width < 40rem) {
576
- [data-collapse-below="sm"] [data-slot="table"] {
577
- display: block;
578
- }
579
-
580
- /* The header is fully removed below the step — see the rule's own comment for why
581
- * `display: none` (not a sr-only clip) is the right call here. */
582
- [data-collapse-below="sm"] .ui-table-stacked-collection-head {
583
- /* `display: none` (not a visually-hidden clip) removes the header from BOTH the paint
584
- * tree and the accessibility tree below the step — deliberate: TableCell's stacked-tier
585
- * label (rendered as real, non-aria-hidden text) is what carries the field name to every
586
- * modality at this tier, sighted and AT alike, so the raw `<th>` is fully redundant here,
587
- * not just visually. */
588
- display: none;
589
- }
590
-
591
- [data-collapse-below="sm"] tbody {
592
- display: block;
593
- }
594
-
595
- /* Card shell. `border`/`background` here are the SHORTHAND form, which beats the individual
596
- * `border-bottom-width` / `background-color` Tailwind utilities TableRow also carries — layer
597
- * order decides that, not specificity (this layer is declared after `utilities`). */
598
- [data-collapse-below="sm"] .ui-table-row {
599
- display: block;
600
- /* `.ui-table-row` carries a FIXED `height: var(--table-row-height)` from
601
- * control.css (an earlier layer, but that only matters for a property BOTH
602
- * layers declare — this preset never touches `height` anywhere else, so without
603
- * this reset the fixed row height survives untouched and every stacked field
604
- * below the first overflows the ~34px box, visually overlapping the next card).
605
- * `auto` lets the card grow to fit its stacked fields. */
606
- height: auto;
607
- border: 1px solid
608
- var(--table-stacked-record-collection-card-border-color, hsl(var(--border)));
609
- border-radius: var(--table-stacked-record-collection-card-radius);
610
- background: var(
611
- --table-stacked-record-collection-card-background,
612
- hsl(var(--card, var(--background)))
613
- );
614
- padding: var(--table-stacked-record-collection-card-padding);
615
- }
616
-
617
- [data-collapse-below="sm"] .ui-table-row + .ui-table-row {
618
- margin-block-start: var(--table-stacked-record-collection-card-gap);
619
- }
620
-
621
- /* Each column becomes its own block inside the card. Consistent vertical rhythm (the
622
- * field-gap padding below) separates fields — no rule between them, matching the
623
- * canonical's plain definition-list composition. */
624
- [data-collapse-below="sm"] [data-slot="table-cell"] {
625
- display: block;
626
- padding-block: var(--table-stacked-record-collection-field-gap);
627
- white-space: normal;
628
- overflow-wrap: anywhere;
629
- }
630
-
631
- [data-collapse-below="sm"] [data-slot="table-cell"]:first-child {
632
- padding-block-start: 0;
633
- }
634
-
635
- [data-collapse-below="sm"] [data-slot="table-cell"]:last-child {
636
- padding-block-end: 0;
637
- }
638
-
639
- /* A nowrap child (a Badge pill) would otherwise clip inside the narrow card. */
640
- [data-collapse-below="sm"] [data-slot="table-cell"] * {
641
- white-space: normal;
642
- }
643
-
644
- [data-collapse-below="sm"] .ui-table-stacked-collection-label {
645
- display: block;
646
- font-size: var(--table-stacked-record-collection-label-font-size);
647
- color: var(--table-stacked-record-collection-label-color, hsl(var(--muted-foreground)));
648
- margin-block-end: var(--table-stacked-record-collection-label-gap);
649
- }
650
-
651
- /* Lifecycle actions (`priority="actions"`) span the card edge-to-edge and split evenly —
652
- * the canonical's full-width button pair — instead of the compact right-aligned desktop
653
- * pair. Targets any actionable element inside the cell regardless of nesting, so it
654
- * still applies through a `Flex` wrapper. */
655
- [data-collapse-below="sm"] [data-slot="table-cell"][data-priority="actions"] :is(button, a) {
656
- flex: 1 1 0%;
657
- }
658
- }
659
-
660
- @container ui-table-stacked-collection (width < 48rem) {
661
- [data-collapse-below="md"] [data-slot="table"] {
662
- display: block;
663
- }
664
-
665
- [data-collapse-below="md"] .ui-table-stacked-collection-head {
666
- /* `display: none` (not a visually-hidden clip) removes the header from BOTH the paint
667
- * tree and the accessibility tree below the step — deliberate: TableCell's stacked-tier
668
- * label (rendered as real, non-aria-hidden text) is what carries the field name to every
669
- * modality at this tier, sighted and AT alike, so the raw `<th>` is fully redundant here,
670
- * not just visually. */
671
- display: none;
672
- }
673
-
674
- [data-collapse-below="md"] tbody {
675
- display: block;
676
- }
677
-
678
- [data-collapse-below="md"] .ui-table-row {
679
- display: block;
680
- /* `.ui-table-row` carries a FIXED `height: var(--table-row-height)` from
681
- * control.css (an earlier layer, but that only matters for a property BOTH
682
- * layers declare — this preset never touches `height` anywhere else, so without
683
- * this reset the fixed row height survives untouched and every stacked field
684
- * below the first overflows the ~34px box, visually overlapping the next card).
685
- * `auto` lets the card grow to fit its stacked fields. */
686
- height: auto;
687
- border: 1px solid
688
- var(--table-stacked-record-collection-card-border-color, hsl(var(--border)));
689
- border-radius: var(--table-stacked-record-collection-card-radius);
690
- background: var(
691
- --table-stacked-record-collection-card-background,
692
- hsl(var(--card, var(--background)))
693
- );
694
- padding: var(--table-stacked-record-collection-card-padding);
695
- }
696
-
697
- [data-collapse-below="md"] .ui-table-row + .ui-table-row {
698
- margin-block-start: var(--table-stacked-record-collection-card-gap);
699
- }
700
-
701
- [data-collapse-below="md"] [data-slot="table-cell"] {
702
- display: block;
703
- padding-block: var(--table-stacked-record-collection-field-gap);
704
- white-space: normal;
705
- overflow-wrap: anywhere;
706
- }
707
-
708
- [data-collapse-below="md"] [data-slot="table-cell"]:first-child {
709
- padding-block-start: 0;
710
- }
711
-
712
- [data-collapse-below="md"] [data-slot="table-cell"]:last-child {
713
- padding-block-end: 0;
714
- }
715
-
716
- [data-collapse-below="md"] [data-slot="table-cell"] * {
717
- white-space: normal;
718
- }
719
-
720
- [data-collapse-below="md"] .ui-table-stacked-collection-label {
721
- display: block;
722
- font-size: var(--table-stacked-record-collection-label-font-size);
723
- color: var(--table-stacked-record-collection-label-color, hsl(var(--muted-foreground)));
724
- margin-block-end: var(--table-stacked-record-collection-label-gap);
725
- }
726
-
727
- /* Lifecycle actions (`priority="actions"`) span the card edge-to-edge and split evenly —
728
- * the canonical's full-width button pair — instead of the compact right-aligned desktop
729
- * pair. Targets any actionable element inside the cell regardless of nesting, so it
730
- * still applies through a `Flex` wrapper. */
731
- [data-collapse-below="md"] [data-slot="table-cell"][data-priority="actions"] :is(button, a) {
732
- flex: 1 1 0%;
733
- }
734
- }
735
-
736
- @container ui-table-stacked-collection (width < 64rem) {
737
- [data-collapse-below="lg"] [data-slot="table"] {
738
- display: block;
739
- }
740
-
741
- [data-collapse-below="lg"] .ui-table-stacked-collection-head {
742
- /* `display: none` (not a visually-hidden clip) removes the header from BOTH the paint
743
- * tree and the accessibility tree below the step — deliberate: TableCell's stacked-tier
744
- * label (rendered as real, non-aria-hidden text) is what carries the field name to every
745
- * modality at this tier, sighted and AT alike, so the raw `<th>` is fully redundant here,
746
- * not just visually. */
747
- display: none;
748
- }
749
-
750
- [data-collapse-below="lg"] tbody {
751
- display: block;
752
- }
753
-
754
- [data-collapse-below="lg"] .ui-table-row {
755
- display: block;
756
- /* `.ui-table-row` carries a FIXED `height: var(--table-row-height)` from
757
- * control.css (an earlier layer, but that only matters for a property BOTH
758
- * layers declare — this preset never touches `height` anywhere else, so without
759
- * this reset the fixed row height survives untouched and every stacked field
760
- * below the first overflows the ~34px box, visually overlapping the next card).
761
- * `auto` lets the card grow to fit its stacked fields. */
762
- height: auto;
763
- border: 1px solid
764
- var(--table-stacked-record-collection-card-border-color, hsl(var(--border)));
765
- border-radius: var(--table-stacked-record-collection-card-radius);
766
- background: var(
767
- --table-stacked-record-collection-card-background,
768
- hsl(var(--card, var(--background)))
769
- );
770
- padding: var(--table-stacked-record-collection-card-padding);
771
- }
772
-
773
- [data-collapse-below="lg"] .ui-table-row + .ui-table-row {
774
- margin-block-start: var(--table-stacked-record-collection-card-gap);
775
- }
776
-
777
- [data-collapse-below="lg"] [data-slot="table-cell"] {
778
- display: block;
779
- padding-block: var(--table-stacked-record-collection-field-gap);
780
- white-space: normal;
781
- overflow-wrap: anywhere;
782
- }
783
-
784
- [data-collapse-below="lg"] [data-slot="table-cell"]:first-child {
785
- padding-block-start: 0;
786
- }
787
-
788
- [data-collapse-below="lg"] [data-slot="table-cell"]:last-child {
789
- padding-block-end: 0;
790
- }
791
-
792
- [data-collapse-below="lg"] [data-slot="table-cell"] * {
793
- white-space: normal;
794
- }
795
-
796
- [data-collapse-below="lg"] .ui-table-stacked-collection-label {
797
- display: block;
798
- font-size: var(--table-stacked-record-collection-label-font-size);
799
- color: var(--table-stacked-record-collection-label-color, hsl(var(--muted-foreground)));
800
- margin-block-end: var(--table-stacked-record-collection-label-gap);
801
- }
802
-
803
- /* Lifecycle actions (`priority="actions"`) span the card edge-to-edge and split evenly —
804
- * the canonical's full-width button pair — instead of the compact right-aligned desktop
805
- * pair. Targets any actionable element inside the cell regardless of nesting, so it
806
- * still applies through a `Flex` wrapper. */
807
- [data-collapse-below="lg"] [data-slot="table-cell"][data-priority="actions"] :is(button, a) {
808
- flex: 1 1 0%;
809
- }
810
- }
811
-
812
- @container ui-table-stacked-collection (width < 80rem) {
813
- [data-collapse-below="xl"] [data-slot="table"] {
814
- display: block;
815
- }
816
-
817
- [data-collapse-below="xl"] .ui-table-stacked-collection-head {
818
- /* `display: none` (not a visually-hidden clip) removes the header from BOTH the paint
819
- * tree and the accessibility tree below the step — deliberate: TableCell's stacked-tier
820
- * label (rendered as real, non-aria-hidden text) is what carries the field name to every
821
- * modality at this tier, sighted and AT alike, so the raw `<th>` is fully redundant here,
822
- * not just visually. */
823
- display: none;
824
- }
825
-
826
- [data-collapse-below="xl"] tbody {
827
- display: block;
828
- }
829
-
830
- [data-collapse-below="xl"] .ui-table-row {
831
- display: block;
832
- /* `.ui-table-row` carries a FIXED `height: var(--table-row-height)` from
833
- * control.css (an earlier layer, but that only matters for a property BOTH
834
- * layers declare — this preset never touches `height` anywhere else, so without
835
- * this reset the fixed row height survives untouched and every stacked field
836
- * below the first overflows the ~34px box, visually overlapping the next card).
837
- * `auto` lets the card grow to fit its stacked fields. */
838
- height: auto;
839
- border: 1px solid
840
- var(--table-stacked-record-collection-card-border-color, hsl(var(--border)));
841
- border-radius: var(--table-stacked-record-collection-card-radius);
842
- background: var(
843
- --table-stacked-record-collection-card-background,
844
- hsl(var(--card, var(--background)))
845
- );
846
- padding: var(--table-stacked-record-collection-card-padding);
847
- }
848
-
849
- [data-collapse-below="xl"] .ui-table-row + .ui-table-row {
850
- margin-block-start: var(--table-stacked-record-collection-card-gap);
851
- }
852
-
853
- [data-collapse-below="xl"] [data-slot="table-cell"] {
854
- display: block;
855
- padding-block: var(--table-stacked-record-collection-field-gap);
856
- white-space: normal;
857
- overflow-wrap: anywhere;
858
- }
859
-
860
- [data-collapse-below="xl"] [data-slot="table-cell"]:first-child {
861
- padding-block-start: 0;
862
- }
863
-
864
- [data-collapse-below="xl"] [data-slot="table-cell"]:last-child {
865
- padding-block-end: 0;
866
- }
867
-
868
- [data-collapse-below="xl"] [data-slot="table-cell"] * {
869
- white-space: normal;
870
- }
871
-
872
- [data-collapse-below="xl"] .ui-table-stacked-collection-label {
873
- display: block;
874
- font-size: var(--table-stacked-record-collection-label-font-size);
875
- color: var(--table-stacked-record-collection-label-color, hsl(var(--muted-foreground)));
876
- margin-block-end: var(--table-stacked-record-collection-label-gap);
877
- }
878
-
879
- /* Lifecycle actions (`priority="actions"`) span the card edge-to-edge and split evenly —
880
- * the canonical's full-width button pair — instead of the compact right-aligned desktop
881
- * pair. Targets any actionable element inside the cell regardless of nesting, so it
882
- * still applies through a `Flex` wrapper. */
883
- [data-collapse-below="xl"] [data-slot="table-cell"][data-priority="actions"] :is(button, a) {
884
- flex: 1 1 0%;
885
- }
886
- }
887
- }
@@ -136,21 +136,3 @@
136
136
  * Japanese at the compact type tier) and the table scrolls instead of crushing. */
137
137
  --table-action-collection-min-inline-size-compact: 0;
138
138
  }
139
-
140
- /* Table · stacked-record-collection preset (gh#356) — the canonical RECORD list: below the
141
- * collapse step each row becomes a card and every column's label + value stack vertically. Every
142
- * measure here is themeable so a service can retint/respace the cards without forking the
143
- * component (rule #45). Colour/background tokens are `initial` so the default re-resolves the
144
- * LIVE role at the call site (a :root binding would freeze a scoped [data-tenant] override —
145
- * docs/TOKENS.md). */
146
- :root {
147
- --table-stacked-record-collection-card-gap: var(--space-stack-sm);
148
- --table-stacked-record-collection-card-padding: var(--space-4);
149
- --table-stacked-record-collection-card-radius: var(--card-radius);
150
- --table-stacked-record-collection-card-border-color: initial; /* default = hsl(var(--border)) */
151
- --table-stacked-record-collection-card-background: initial; /* default = hsl(var(--card, var(--background))) */
152
- --table-stacked-record-collection-field-gap: var(--space-2);
153
- --table-stacked-record-collection-label-gap: var(--space-1);
154
- --table-stacked-record-collection-label-font-size: var(--font-size-xs);
155
- --table-stacked-record-collection-label-color: initial; /* default = hsl(var(--muted-foreground)) */
156
- }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@godxjp/ui",
3
- "version": "18.12.11",
4
- "godxUiMcp": "18.12.11",
3
+ "version": "18.12.13",
4
+ "godxUiMcp": "18.12.13",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
7
7
  "type": "git",