@tensor_1/react 2.49.1 → 2.50.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.
@@ -37,6 +37,18 @@ interface DataWorkspaceLabels {
37
37
  filteredEmptyDetail: string;
38
38
  error: string;
39
39
  retry: string;
40
+ /** A sorted header's place among two or more sort keys (HAR-2623): `{n}`. */
41
+ sortPriority: string;
42
+ /** A group header's row count (HAR-2625): `{count}`. */
43
+ groupCount: string;
44
+ /** The same for one row. */
45
+ groupCountOne: string;
46
+ /** A group header's toggle while the group is open: `{name}`. */
47
+ collapseGroup: string;
48
+ /** The same while it is collapsed. */
49
+ expandGroup: string;
50
+ /** A group header's checkbox: `{name}`. */
51
+ selectGroup: string;
40
52
  }
41
53
  declare const DEFAULT_DATA_WORKSPACE_LABELS: DataWorkspaceLabels;
42
54
  interface DataWorkspaceColumn<T> {
@@ -48,22 +60,82 @@ interface DataWorkspaceColumn<T> {
48
60
  align?: 'start' | 'end';
49
61
  /** A CSS width for the column, e.g. `12rem`. */
50
62
  width?: string;
63
+ /**
64
+ * The column's floor, e.g. `14rem` (HAR-2624). In a fixed layout the table's own min-width is
65
+ * the sum of its columns' floors, so a squeezed table scrolls rather than narrow them.
66
+ */
67
+ minWidth?: string;
68
+ /**
69
+ * A class on the column's header and body cells, e.g. `uix-col--truncate` (HAR-2624). A width
70
+ * tier (`uix-col--w-md`) or `uix-col--flex` also sizes the column's `<col>` in a fixed layout.
71
+ */
72
+ className?: string;
73
+ /**
74
+ * The responsive ladder (`mobile`, HAR-2622): `low` columns go below 900 px of workspace width,
75
+ * `mid` ones below 600 px; `high` (the default) stay.
76
+ */
77
+ priority?: 'high' | 'mid' | 'low';
78
+ /** The column's name in words: a card's label under `mobile="cards"`. Default: `header` when it is a string. */
79
+ label?: string;
51
80
  }
52
81
  interface DataWorkspaceSort {
53
82
  columnId: string;
54
83
  direction: 'ascending' | 'descending';
55
84
  }
85
+ /** `sort` as a product passes it: one key (or none), or an ordered list of keys (HAR-2623). */
86
+ type DataWorkspaceSortState = DataWorkspaceSort | readonly DataWorkspaceSort[] | null;
87
+ /** What `onSortChange` receives: a list when `sort` is a list, else one key or `null`. */
88
+ type DataWorkspaceSortValue<S> = S extends readonly DataWorkspaceSort[] ? DataWorkspaceSort[] : DataWorkspaceSort | null;
56
89
  /** The record-id column: the first column, the row's way into its record. */
57
90
  interface DataWorkspaceIdColumn<T> {
58
91
  header: ReactNode;
59
92
  /** The id as shown, e.g. "INC-20418". Also names the row's checkbox and ↗ button. */
60
93
  text: (row: T) => string;
94
+ /**
95
+ * The cell's content instead of `text` (HAR-2622): e.g. a strong title over a muted line, with
96
+ * the search match marked. It sits inside the same button or link; `text` still names the
97
+ * checkbox and the ↗.
98
+ */
99
+ render?: (row: T) => ReactNode;
61
100
  /** The id button opens a peek of the record. */
62
101
  onPeek?: (row: T) => void;
63
102
  /** The ↗ link goes to the full record. */
64
103
  href?: (row: T) => string;
104
+ /**
105
+ * Without `onPeek`: the whole id is the link to `href`, with the ↗ inside it, for a row whose
106
+ * own record is the way in (HAR-2622). Off: the id is text and the ↗ is the link.
107
+ */
108
+ linkId?: boolean;
109
+ /** The column's width in a fixed layout (`fixed`), e.g. `16rem`. */
110
+ width?: string;
111
+ /** The column's floor in a fixed layout. Default: the `md` column tier. */
112
+ minWidth?: string;
65
113
  renderLink?: UixRenderLink;
66
114
  }
115
+ /** A group of rows under one header row (HAR-2625). The product computes the groups. */
116
+ interface DataWorkspaceGroup<T> {
117
+ id: string;
118
+ /** The group's value as shown, e.g. a status pill. */
119
+ label: ReactNode;
120
+ /** The group's name in words, for its toggle and checkbox. Default: `label` when a string, else `id`. */
121
+ name?: string;
122
+ rows: readonly T[];
123
+ /** The group's total, when it holds more than the rows on this page. Default: `rows.length`. */
124
+ count?: number;
125
+ /** Aggregated cells in the header row, by column id (a sum, a range), each under its column. */
126
+ aggregates?: Readonly<Record<string, ReactNode>>;
127
+ }
128
+ /** Windowing for a long unpaged list (HAR-2626), over `useVirtualRows`. */
129
+ interface DataWorkspaceVirtualize {
130
+ /** Window only above this many rows. Default 100. */
131
+ threshold?: number;
132
+ /** The first paint's row height in px; the mounted rows are measured after. Default: by density (44, 56, 68). */
133
+ estimatedRowHeight?: number;
134
+ /** The scrolling body's height cap in px. Default 640. */
135
+ maxHeight?: number;
136
+ /** Rows rendered beyond each edge. Default 8. */
137
+ overscan?: number;
138
+ }
67
139
  type DataWorkspacePagination = {
68
140
  mode: 'offset';
69
141
  page: number;
@@ -84,18 +156,31 @@ type DataWorkspacePagination = {
84
156
  pageSizes?: readonly number[];
85
157
  onPageSizeChange?: (size: number) => void;
86
158
  };
87
- interface DataWorkspaceProps<T> extends Omit<HTMLAttributes<HTMLElement>, 'children'> {
159
+ interface DataWorkspaceProps<T, S extends DataWorkspaceSortState = DataWorkspaceSort | null> extends Omit<HTMLAttributes<HTMLElement>, 'children'> {
88
160
  /** Names the workspace region and the table. */
89
161
  label: string;
90
162
  rows: readonly T[];
91
163
  getRowId: (row: T) => string;
92
164
  columns: readonly DataWorkspaceColumn<T>[];
93
165
  idColumn?: DataWorkspaceIdColumn<T>;
94
- sort?: DataWorkspaceSort | null;
95
- onSortChange?: (sort: DataWorkspaceSort | null) => void;
166
+ /**
167
+ * The sort: one key, or an ordered list of keys (HAR-2623). With a list, Shift + click (or
168
+ * Shift + Enter / Space) on a header adds, turns or removes that column as a further key, and
169
+ * each sorted header shows its place once two or more keys are set.
170
+ */
171
+ sort?: S;
172
+ /** Receives the same shape `sort` holds: a list for a list, else one key or `null`. */
173
+ onSortChange?: (sort: DataWorkspaceSortValue<S>) => void;
174
+ /**
175
+ * List mode even while `sort` is `null` or one key, for a product whose sort state starts
176
+ * empty. Type `sort` as a list (`[]` for none): `onSortChange` then receives a list.
177
+ */
178
+ multiSort?: boolean;
96
179
  /** The selected row ids. Kept by id, so a refresh or a new page keeps them. */
97
180
  selection?: ReadonlySet<string>;
98
181
  onSelectionChange?: (selection: Set<string>) => void;
182
+ /** At most this many rows can be selected: the unchecked boxes are disabled at the cap (HAR-2622). */
183
+ maxSelection?: number;
99
184
  /** The bulk bar's actions for the selection (a `Menu` for the overflow). */
100
185
  bulkActions?: (selectedIds: string[]) => ReactNode;
101
186
  /**
@@ -106,15 +191,38 @@ interface DataWorkspaceProps<T> extends Omit<HTMLAttributes<HTMLElement>, 'child
106
191
  /** More props for a row, e.g. a data attribute that marks it changed (see ChangeHighlight, PR #164). */
107
192
  getRowProps?: (row: T) => HTMLAttributes<HTMLTableRowElement> & Record<`data-${string}`, string | undefined>;
108
193
  density?: TableDensity;
194
+ /** Zebra rows (the `Table` default, on). The View menu's toggle (HAR-2624). */
195
+ zebra?: boolean;
196
+ /**
197
+ * Freeze the first column without an id column; with selection the checkbox is frozen too
198
+ * (HAR-2624). With `mobile`, nothing is frozen from the narrowest step (under 600 px).
199
+ */
200
+ freezeFirstColumn?: boolean;
201
+ /**
202
+ * `table-layout: fixed` with a `<colgroup>` from the columns' widths and tiers, and the table's
203
+ * min-width at the sum of the columns' floors (TENSOR HAR-997), so a truncating column clips
204
+ * instead of growing. Default: on when a column has `className` or `minWidth`. Not in cards.
205
+ */
206
+ fixed?: boolean;
207
+ /**
208
+ * The responsive ladder, from the workspace's own width (HAR-2622): `priority` drops `low`
209
+ * columns below 900 px and `mid` ones below 600 px; `cards` turns the rows into cards below
210
+ * 768 px (each value labelled by its column) and drops low-priority columns up to 900 px.
211
+ */
212
+ mobile?: 'priority' | 'cards';
109
213
  /**
110
214
  * Toolbar: the search field. Ctrl/⌘ + / focuses it from inside the workspace, or from the page
111
- * when nothing has focus and this is the page's first workspace.
215
+ * when nothing has focus and this is the page's first workspace. `onSubmit` (Enter), `onClear`
216
+ * (the × or Escape) and `maxLength` go to the `SearchBar`.
112
217
  */
113
218
  search?: {
114
219
  value: string;
115
220
  onChange: (value: string) => void;
116
221
  label?: string;
117
222
  placeholder?: string;
223
+ onSubmit?: (value: string) => void;
224
+ onClear?: () => void;
225
+ maxLength?: number;
118
226
  };
119
227
  /**
120
228
  * Toolbar: filter chips and "+ Filter" over `FilterEditor`. A chip whose value holds ids
@@ -127,11 +235,24 @@ interface DataWorkspaceProps<T> extends Omit<HTMLAttributes<HTMLElement>, 'child
127
235
  /** Rows matching each filter, shown on its chip. */
128
236
  counts?: Readonly<Record<string, number>>;
129
237
  summary?: SummarizeFilterOptions;
238
+ /**
239
+ * Clear every filter in one change (HAR-2622), instead of one `onChange` per field: a product
240
+ * whose state is the URL would otherwise navigate once per field from the same stale state.
241
+ * `search: true` from "Nothing matches" while searching: clear the search too (the kit then
242
+ * does not call `search.onChange('')`).
243
+ */
244
+ onClearAll?: (scope: {
245
+ search: boolean;
246
+ }) => void;
130
247
  };
131
- /** Toolbar: the saved-view trigger, named by the current view, opening a `SavedViewMenu`. */
248
+ /**
249
+ * Toolbar: the saved-view trigger, named by the current view, opening a `SavedViewMenu`.
250
+ * `note` sits above the list ("Saved views could not be loaded").
251
+ */
132
252
  savedViews?: {
133
253
  current: ReactNode;
134
254
  menu: SavedViewMenuProps;
255
+ note?: ReactNode;
135
256
  };
136
257
  /** Toolbar: the View button, opening a `ViewMenu` (columns, density). */
137
258
  viewMenu?: ViewMenuProps;
@@ -139,17 +260,63 @@ interface DataWorkspaceProps<T> extends Omit<HTMLAttributes<HTMLElement>, 'child
139
260
  viewChanged?: boolean;
140
261
  onSaveView?: () => void;
141
262
  onSaveViewAs?: () => void;
263
+ /** When Save as shows: `changed` (default) with `viewChanged`; `always`, to keep any view under a name (HAR-2622). */
264
+ saveViewAs?: 'changed' | 'always';
142
265
  /** Toolbar: a maximize toggle; Escape restores, unless an open popover or menu takes it first. */
143
266
  maximized?: boolean;
144
267
  onMaximizedChange?: (maximized: boolean) => void;
145
268
  /** Toolbar: the product's own actions at the end ("New incident"). */
146
269
  toolbarEnd?: ReactNode;
270
+ /** Between the toolbar (and bulk bar) and the rows: notices, a "3 new — show" pill, a truncation warning. */
271
+ beforeBody?: ReactNode;
147
272
  pagination?: DataWorkspacePagination;
148
273
  /** `loading`: the first load (skeleton rows). `error`: with `onRetry`. */
149
274
  status?: 'ready' | 'loading' | 'error';
150
275
  /** A refetch (filter, sort, page, saved view): the rows stay under `TableWrap refreshing`. */
151
276
  refreshing?: boolean;
152
277
  onRetry?: () => void;
278
+ /** Skeleton rows on a first load. Default 6. */
279
+ loadingRows?: number;
280
+ /** The empty body in place of the default one (HAR-2624), e.g. an `EmptyState` with the first action. */
281
+ empty?: ReactNode;
282
+ /** The default empty body's action ("Add the first book"). */
283
+ emptyAction?: ReactNode;
284
+ /** The filtered-empty body in place of the default one. */
285
+ filteredEmpty?: ReactNode;
286
+ /** A further action in the default filtered-empty body, after its Clear filters. */
287
+ filteredEmptyAction?: ReactNode;
288
+ /** The error body in place of the default one (a problem's title, a diagnostic line, Retry). */
289
+ error?: ReactNode;
290
+ /**
291
+ * A product state in place of the rows, whatever `status` says (a page past the end: "Go to the
292
+ * first page"). The toolbar stays; the footer goes. A refetch shows it busy.
293
+ */
294
+ stateOverride?: ReactNode;
295
+ /** Rows in groups under collapsible header rows, in place of `rows` (HAR-2625). Not windowed. */
296
+ groups?: readonly DataWorkspaceGroup<T>[];
297
+ /** The collapsed group ids. Without it the workspace keeps them itself. */
298
+ collapsedGroups?: ReadonlySet<string>;
299
+ /** A group was collapsed or opened: the new set of collapsed ids. */
300
+ onCollapsedGroupsChange?: (collapsed: Set<string>) => void;
301
+ /**
302
+ * Window a long unpaged list (HAR-2626): only the rows in view are mounted, in a body that
303
+ * scrolls under its sticky header. Off with `pagination`, `groups` and the cards ladder.
304
+ */
305
+ virtualize?: boolean | DataWorkspaceVirtualize;
306
+ /**
307
+ * The keyboard row model (HAR-2626): one row in the tab order, ↑ / ↓ / Home / End move between
308
+ * rows, Enter opens the row (`onRowActivate`, else its id: the peek or the link), Space does not
309
+ * scroll the page. Default: on with `onRowActivate`.
310
+ */
311
+ rowNavigation?: boolean;
312
+ /** A row's primary action: Enter on the row, and a click on the row (not on a control in it or its cell). Turns on `rowNavigation`. */
313
+ onRowActivate?: (row: T) => void;
314
+ /** `false`: only Enter activates a row, not a pointer click. Default `true`. */
315
+ activateOnClick?: boolean;
316
+ /** The row with the tab stop, to drive it from the product's own shortcuts (j / k). Changing it focuses that row. */
317
+ activeRowId?: string | null;
318
+ /** The tab stop moved to another row (a key, a click, focus entering a row). */
319
+ onActiveRowChange?: (rowId: string) => void;
153
320
  labels?: Partial<DataWorkspaceLabels>;
154
321
  }
155
322
  /**
@@ -161,7 +328,11 @@ interface DataWorkspaceProps<T> extends Omit<HTMLAttributes<HTMLElement>, 'child
161
328
  * footer with rows per page and `Pagination` (offset or cursor); first-load, empty,
162
329
  * filtered-empty and error states, and a refetch that keeps the rows. Prop-driven: the product
163
330
  * keeps its surface registry, URL state, data fetching and permissions.
331
+ *
332
+ * 2.50 (HAR-2622..2626, ADR-0005 addendum): a responsive ladder (`mobile`, `column.priority`), a
333
+ * rich id cell, multi-column sort, the product's state bodies and `beforeBody`, row groups,
334
+ * windowing (`virtualize`) and a keyboard row model (`onRowActivate`).
164
335
  */
165
- declare function DataWorkspace<T>({ label, rows, getRowId, columns, idColumn, sort, onSortChange, selection, onSelectionChange, bulkActions, rowActions, getRowProps, density, search, filters, savedViews, viewMenu, viewChanged, onSaveView, onSaveViewAs, maximized, onMaximizedChange, toolbarEnd, pagination, status, refreshing, onRetry, labels: labelOverrides, className, ...props }: DataWorkspaceProps<T>): react.JSX.Element;
336
+ declare function DataWorkspace<T, S extends DataWorkspaceSortState = DataWorkspaceSort | null>({ label, rows, getRowId, columns, idColumn, sort, onSortChange, selection, onSelectionChange, maxSelection, bulkActions, rowActions, getRowProps, density, zebra, freezeFirstColumn, fixed, mobile, search, filters, savedViews, viewMenu, viewChanged, onSaveView, onSaveViewAs, saveViewAs, maximized, onMaximizedChange, toolbarEnd, beforeBody, pagination, status, refreshing, onRetry, loadingRows, empty, emptyAction, filteredEmpty, filteredEmptyAction, error, stateOverride, groups, collapsedGroups, onCollapsedGroupsChange, virtualize, rowNavigation, onRowActivate, activateOnClick, activeRowId, onActiveRowChange, multiSort, labels: labelOverrides, className, ...props }: DataWorkspaceProps<T, S>): react.JSX.Element;
166
337
 
167
- export { DEFAULT_DATA_WORKSPACE_LABELS, DataWorkspace, type DataWorkspaceColumn, type DataWorkspaceIdColumn, type DataWorkspaceLabels, type DataWorkspacePagination, type DataWorkspaceProps, type DataWorkspaceSort };
338
+ export { DEFAULT_DATA_WORKSPACE_LABELS, DataWorkspace, type DataWorkspaceColumn, type DataWorkspaceGroup, type DataWorkspaceIdColumn, type DataWorkspaceLabels, type DataWorkspacePagination, type DataWorkspaceProps, type DataWorkspaceSort, type DataWorkspaceSortState, type DataWorkspaceSortValue, type DataWorkspaceVirtualize };