@lotics/ui 27.13.2 → 27.13.3

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/MIGRATION.md CHANGED
@@ -4,6 +4,25 @@ Breaking changes, newest first — normally per major, plus the rare minor that
4
4
  anyway (recorded under its exact version). The current contract lives in `AGENTS.md` + `docs/`;
5
5
  this file exists only to move an app from one release to the next.
6
6
 
7
+ ## 27.13.3 — a stacked `Table` row's identity cell no longer renders its column label
8
+
9
+ No API change, but the rendered output changed on NARROW containers only (below the
10
+ two-column floor, where `Table` stacks). The identity cell — column 0 — used to render as a
11
+ `DetailRow` spread like every other cell, so its column label appeared beside the value. It
12
+ now heads the row bare. **A test or script that finds that label inside a stacked row must be
13
+ updated**:
14
+
15
+ ```ts
16
+ // a 375px-wide register whose first column is labelled "Customer"
17
+ getByText("Customer") // BEFORE — the identity cell's label, once per ROW
18
+ // AFTER — matches the column HEADER only (wide containers)
19
+ ```
20
+
21
+ Field cells (index ≥ 1) keep their labels, and register mode is untouched — this is stacked
22
+ mode only. The label restated the value it sat beside (`Customer` over `Northwind Packaging`),
23
+ and it had nowhere to go: a label and a full-width identity on one line with nothing to give
24
+ made the label collapse under a long value, which is what a narrow register used to render.
25
+
7
26
  ## 27.4.0 — a `Select` trigger announces as `combobox`, not `button`
8
27
 
9
28
  No API change, but the DOM and the accessibility tree changed, so **a test or script that
package/docs/catalog.md CHANGED
@@ -973,9 +973,10 @@ source (`src/<module>.tsx`/`.ts`) is the API reference.
973
973
  CONTAINER-RESPONSIVE with no prop (measures itself, like `Breakdown`/`DetailTable`): when
974
974
  the width can't fit every column it hides columns by `TableColumn.priority` (higher drops
975
975
  first; default = column order, rightmost first; column 0 — the identity — never drops), and
976
- below the two-column floor every row STACKS: each cell renders as a `DetailRow`-spread
977
- line (muted label left, value at the right edge one vocabulary with the drawer's detail
978
- rows), the lines sitting on the identity column's text edge, never under the checkbox;
976
+ below the two-column floor every row STACKS: the identity cell (column 0) HEADS the pile
977
+ unlabelled its column name would only restate the valueand each REMAINING cell renders
978
+ as a `DetailRow`-spread line (muted label left, value at the right edge one vocabulary with
979
+ the drawer's detail rows), the lines sitting on the identity column's text edge, never under the checkbox;
979
980
  the header band gives way, so sorting is a wide-container affordance. Rows carry TWO right-side slots: `action`
980
981
  (the primary CTA `Button` — register: in the trailing gutter; stacked: closes the content,
981
982
  right-aligned) and `trailing` (the ⋯ overflow — stays beside the identity on the top line).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lotics/ui",
3
- "version": "27.13.2",
3
+ "version": "27.13.3",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./vite": {
package/src/table.tsx CHANGED
@@ -229,7 +229,10 @@ export function TableRow(props: TableRowProps) {
229
229
  // A dropped column drops its cell (stacked shows everything). Cells beyond
230
230
  // the declared columns stay — same tolerance as the width mapping.
231
231
  .filter(({ column }) => ctx.stacked || column == null || ctx.visibleKeys.has(column.key))
232
- .map(({ cell, column }) => cloneElement(cell, { _column: column, _stacked: ctx.stacked }));
232
+ // Index 0 is the identity cell it HEADS the stacked pile rather than becoming
233
+ // one of its labelled field lines. (Safe to read post-filter: stacked mode drops
234
+ // no cell, and column 0 never drops in register mode either.)
235
+ .map(({ cell, column }, i) => cloneElement(cell, { _column: column, _stacked: ctx.stacked, _primary: i === 0 }));
233
236
 
234
237
  const body = ctx.stacked ? (
235
238
  <View style={styles.stackedBody}>
@@ -314,19 +317,31 @@ export interface TableCellProps {
314
317
  _column?: TableColumn;
315
318
  /** @internal — injected by `TableRow`; the Table is in stacked mode. */
316
319
  _stacked?: boolean;
320
+ /** @internal — injected by `TableRow`; this is the identity cell (column 0), which
321
+ * in stacked mode leads the row instead of becoming one of its field lines. */
322
+ _primary?: boolean;
317
323
  }
318
324
 
319
325
  /** One cell — its width/align come from the column `TableRow` injects by position.
320
- * In stacked mode it IS a `DetailRow` (spread: muted label left, value at the
321
- * right edge) — the drawer's detail-row component, not a lookalike, so a
326
+ * In stacked mode a FIELD cell is a `DetailRow` (spread: muted label left, value
327
+ * at the right edge) — the drawer's detail-row component, not a lookalike, so a
322
328
  * stacked register and the record workspace behind its door share one
323
329
  * vocabulary by construction. `DetailRow` values are arbitrary nodes (the
324
330
  * drawer renders badges, money stacks, editors, popover triggers in them), so
325
331
  * register cell content needs no adaptation. A label-less control column has
326
- * no line to spread — its content pins to the right edge. */
332
+ * no line to spread — its content pins to the right edge.
333
+ *
334
+ * The IDENTITY cell is not a field line and carries no label. It heads the row —
335
+ * the thing you read to know WHICH record this is — so its column name ("Hợp đồng",
336
+ * "Customer") only restates what the value already says, and it already sits on the
337
+ * top line beside the selection checkbox and the ⋯ overflow, where a label has no
338
+ * field grid to align to. */
327
339
  export function TableCell(props: TableCellProps) {
328
- const { children, _column, _stacked } = props;
340
+ const { children, _column, _stacked, _primary } = props;
329
341
  if (_stacked) {
342
+ if (_primary) {
343
+ return <>{children}</>;
344
+ }
330
345
  if (!_column?.label) {
331
346
  return <View style={styles.stackedBareCell}>{children}</View>;
332
347
  }