@lotics/ui 31.0.0 → 32.0.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.
package/MIGRATION.md CHANGED
@@ -4,6 +4,27 @@ 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
+ ## 32.0.0 — `Table`'s `align` prop is gone; rows are centred
8
+
9
+ `align?: "center" | "top"` and the `TableAlign` type are removed. `center` was the
10
+ default and nothing shipped on `top`, so a caller passing nothing is unaffected.
11
+
12
+ **Why it went, so nobody rebuilds it.** It was added to close a measured 12px spread
13
+ between the first lines of cells carrying different numbers of lines. That number was
14
+ never compared against a baseline: the kit's own canonical register (`tpl_item_list`)
15
+ ships a **15px** spread, centred, and reads correctly. The case the prop existed for
16
+ is the case the reference example already handles.
17
+
18
+ It was also wrong as built. `top` moved the CELLS to a shared top edge but left the
19
+ row's ordinal, leading checkbox and trailing menu centred — so on a tall row a row's
20
+ number sat ~24px below the name it belonged to, and the register read as scatter.
21
+ Aligning the chrome too is possible, but that yields a correct prop with no consumers.
22
+
23
+ **If a register looks misaligned, the cell is too tall for a columnar row.** Centring
24
+ works because register cells are bounded; when they cannot be, the row is meant to
25
+ stack — `computeTableFit` already drops to stacked below the register floor. Reach for
26
+ that, or move the content to a record page. Do not reintroduce a cross-axis knob.
27
+
7
28
  ## 31.0.0 — avatar `size` is a rung, not a pixel count
8
29
 
9
30
  `Avatar`, `MemberChip` and `GroupAvatar` no longer take `size?: number`. They take
@@ -402,17 +402,6 @@ running total. `tpl_item_list` is the reference. Paginate OUTSIDE (slice + `Pagi
402
402
  Right-hand columns align only if every trailing element is FIXED-width — give each trailing action
403
403
  a fixed `width`, so amount/status columns don't jitter.
404
404
 
405
- **Cells whose LINE COUNTS differ need `align="top"`.** Cells are centred by default, which is
406
- right while every cell is one line. The moment they are not — an identity cell carrying a
407
- supporting line (2), a status cell with a bar over a label (3), a member chip (1) — centring four
408
- different heights puts their four FIRST lines at four different heights, and the eye steps down
409
- and back up reading across one row. Measured on a live register: a 12px spread, closed to 2px by
410
- `align="top"`, which makes cells share a top edge so first lines land on one baseline. It governs
411
- the CELLS only; the ordinal, the leading checkbox and the trailing ⋯ stay centred, being one line
412
- by construction. Note a cell whose first element is a BAR or an image still starts its text below
413
- that element — top-aligning the cell does not top-align the text inside it, so put the line you
414
- want on the baseline first.
415
-
416
405
  ## Row actions are always-visible siblings — never hover-revealed, never nested
417
406
 
418
407
  A pressable row = a role-less surface (the hover/press wash covers the whole row) + an accessible
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lotics/ui",
3
- "version": "31.0.0",
3
+ "version": "32.0.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./vite": {
package/src/table.tsx CHANGED
@@ -35,29 +35,6 @@ export interface TableColumn extends TableFitColumn {
35
35
  sortable?: boolean;
36
36
  }
37
37
 
38
- /**
39
- * How cells sit on the row's CROSS axis.
40
- *
41
- * `center` (the default) — every cell centred in the row. Right for a register
42
- * whose cells are one line each, which is most of them, and the reason this is
43
- * not being changed underneath anyone.
44
- *
45
- * `top` — cells share a top edge, so the FIRST LINE of every cell lands on one
46
- * baseline. Reach for it the moment cells carry different numbers of lines: an
47
- * identity cell with a supporting line (2), a status cell with a bar over a
48
- * label (3), a member chip (1) and a wrapped cell (2) centred together put four
49
- * first lines at four different heights, and the eye steps down and back up
50
- * across a single row. Measured on a live register: a 12px spread.
51
- *
52
- * It governs the CELLS only. The ordinal, the leading checkbox and the trailing
53
- * ⋯ stay centred in the row — they are chrome, they are one line by
54
- * construction, and pinning them to the top of a tall row would strand them.
55
- *
56
- * It applies to EVERY column row — pressable and read-only alike — because a
57
- * table that mixed the two would otherwise align its own rows differently from
58
- * each other. A STACKED row (tier 3) is unaffected: it has no columns to line up.
59
- */
60
- export type TableAlign = "center" | "top";
61
38
 
62
39
  interface TableCtx {
63
40
  columns: TableColumn[];
@@ -67,7 +44,6 @@ interface TableCtx {
67
44
  trailing: number;
68
45
  visibleKeys: ReadonlySet<string>;
69
46
  stacked: boolean;
70
- align: TableAlign;
71
47
  }
72
48
  const TableContext = createContext<TableCtx | null>(null);
73
49
 
@@ -148,9 +124,6 @@ export interface TableProps {
148
124
  count?: number;
149
125
  /** Reserve a trailing gutter (px) for rows that render a `trailing` slot (a ⋯ / button). */
150
126
  trailing?: number;
151
- /** How cells sit on the row's cross axis — see {@link TableAlign}. Default
152
- * `center`; pass `top` when cells carry different numbers of lines. */
153
- align?: TableAlign;
154
127
  /** The `TableRow`s. */
155
128
  children: ReactNode;
156
129
  }
@@ -170,7 +143,7 @@ export interface TableProps {
170
143
  * keeps its current order). See `computeTableFit`.
171
144
  */
172
145
  export function Table(props: TableProps) {
173
- const { columns, sort, onSort, sortLabels, selectAll, leading = 0, count, trailing = 0, align = "center", children } = props;
146
+ const { columns, sort, onSort, sortLabels, selectAll, leading = 0, count, trailing = 0, children } = props;
174
147
  const ordinal = count != null ? ORDINAL_W : 0;
175
148
  const rows = Children.toArray(children).filter(isValidElement);
176
149
 
@@ -188,7 +161,7 @@ export function Table(props: TableProps) {
188
161
  const visibleColumns = columns.filter((c) => fit.visibleKeys.has(c.key));
189
162
 
190
163
  return (
191
- <TableContext.Provider value={{ columns, leading, ordinal, trailing, visibleKeys: fit.visibleKeys, stacked: fit.stacked, align }}>
164
+ <TableContext.Provider value={{ columns, leading, ordinal, trailing, visibleKeys: fit.visibleKeys, stacked: fit.stacked }}>
192
165
  {/* ONE layout node: without this wrapper the header band + body land as two
193
166
  direct flex children of the app's container, and a parent column `gap`
194
167
  (the standard section spacing) opens a hole between the header and rows. */}
@@ -341,10 +314,8 @@ export function TableRow(props: TableRowProps) {
341
314
  .map(({ cell, column }, i) => cloneElement(cell, { _column: column, _stacked: ctx.stacked, _primary: i === 0 }));
342
315
 
343
316
  // ONE style for the column row, shared by the pressable and read-only paths
344
- // below. They rendered near-identical Views and `align` was added to only one,
345
- // so a table mixing the two aligned its own rows differently — computing it
346
- // once is what makes that divergence impossible rather than merely fixed.
347
- const cellsStyle = [styles.cells, { minHeight }, ctx.align === "top" ? styles.cellsTop : null];
317
+ // below, which render near-identical Views.
318
+ const cellsStyle = [styles.cells, { minHeight }];
348
319
 
349
320
  const body = ctx.stacked ? (
350
321
  <View style={styles.stackedBody}>
@@ -529,11 +500,6 @@ const styles = StyleSheet.create({
529
500
  gap: COLUMN_GAP,
530
501
  zIndex: 1,
531
502
  },
532
- // `align="top"` — see `TableAlign`. Overrides the centring above so unequal
533
- // cells share a first-line baseline; the row's own chrome stays centred.
534
- cellsTop: {
535
- alignItems: "flex-start",
536
- },
537
503
  // Leading/trailing gutters carry their own controls — lifted above the door
538
504
  // like the cells.
539
505
  slot: {