@box-kite/react 2.2.0 → 2.2.2
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/.claude/rules/box-kite-rules.md +1 -1
- package/.claude/skills/box-kite/SKILL.md +1 -1
- package/.claude/skills/box-kite/references/components.md +3 -3
- package/.claude/skills/box-kite/references/styling.md +2 -1
- package/.cursor/rules/box-kite.mdc +1 -1
- package/AGENTS.md +1 -1
- package/BOX_AI_CONTEXT.md +95 -77
- package/BOX_KITE_AI_CONTEXT.md +95 -77
- package/README.md +1 -1
- package/client.cjs +1 -1
- package/client.mjs +61 -51
- package/components/dataGrid/components/dataGridBottomBarSelection.d.ts +7 -0
- package/components/dataGrid/components/dataGridColumnsPanel.d.ts +10 -0
- package/components/dataGrid/components/dataGridDetailRow.d.ts +3 -3
- package/components/dataGrid/components/dataGridGroupRow.d.ts +3 -3
- package/components/dataGrid/components/dataGridHeader.d.ts +6 -2
- package/components/dataGrid/components/dataGridRow.d.ts +3 -3
- package/components/dataGrid/contracts/dataGridContract.d.ts +13 -0
- package/components/dataGrid/gridNavigationContext.d.ts +7 -2
- package/components/dataGrid/models/columnModel.d.ts +2 -0
- package/components/dataGrid/models/columnVisibilityModel.d.ts +16 -2
- package/components/dataGrid/models/editModel.d.ts +6 -4
- package/components/dataGrid/models/exportModel.d.ts +1 -1
- package/components/dataGrid/models/gridModel.d.ts +60 -2
- package/components/dataGrid/models/groupRowModel.d.ts +2 -2
- package/components/dataGrid/models/headerCellModel.d.ts +10 -0
- package/components/dataGrid/models/localeText.d.ts +108 -0
- package/components/dataGrid/models/rangeModel.d.ts +2 -0
- package/components/dataGrid/models/rowModel.d.ts +1 -1
- package/components/dataGrid/useFilterDraft.d.ts +9 -0
- package/components/dataGrid.cjs +3 -3
- package/components/dataGrid.d.ts +1 -0
- package/components/dataGrid.mjs +1631 -1120
- package/components/semantics.d.ts +29 -29
- package/docs/components.md +1 -1
- package/docs/props.md +1 -1
- package/layer.cjs +1 -1
- package/layer.mjs +4 -1
- package/package.json +76 -46
- package/react/theme/theme.d.ts +5 -3
- package/utils/dataGrid/activeCellStore.d.ts +14 -0
- package/utils/dataGrid/filterDraftUtils.d.ts +19 -0
- package/utils/dataGrid/headerCellUtils.d.ts +50 -0
- package/components/dataGrid/components/dataGridTopBarContextMenu.d.ts +0 -6
|
@@ -4,6 +4,7 @@ import { ComponentsAndVariants } from '../../../types';
|
|
|
4
4
|
import { SortDirection } from '../../../utils/array/arrayUtils';
|
|
5
5
|
import { default as AggregateCellModel } from '../models/aggregateCellModel';
|
|
6
6
|
import { default as CellModel } from '../models/cellModel';
|
|
7
|
+
import { DataGridLocaleText } from '../models/localeText';
|
|
7
8
|
export type { SortDirection };
|
|
8
9
|
export type Key = string | number;
|
|
9
10
|
/**
|
|
@@ -589,10 +590,22 @@ export interface GridDefinition<TRow> {
|
|
|
589
590
|
resizerStyle?: 'visible' | 'hover' | 'hidden';
|
|
590
591
|
/** How the column follows the pointer during a resize drag. 'smooth' (default): updates batched once per animation frame (~60fps, ~1 frame behind the cursor). 'instant': updates synchronously on every pointer move so the column tracks the cursor with no added latency. */
|
|
591
592
|
resizeMode?: 'smooth' | 'instant';
|
|
593
|
+
/**
|
|
594
|
+
* How a sortable header cell answers the pointer. `'static'` (default): each cell paints its own inset
|
|
595
|
+
* pill. `'sliding'`: one pill for the whole header that flows from cell to cell, leading with the edge it
|
|
596
|
+
* moves towards — measured, so it needs JavaScript, and reduced motion makes it jump instead.
|
|
597
|
+
*/
|
|
598
|
+
headerHover?: 'static' | 'sliding';
|
|
592
599
|
/** Control the header context menu for all columns. false hides it entirely. Object controls individual sections. Default: true. Individual column settings take priority. */
|
|
593
600
|
contextMenu?: boolean | ContextMenuConfig;
|
|
594
601
|
/** Custom component to render when data is empty */
|
|
595
602
|
noDataComponent?: React.ReactNode;
|
|
603
|
+
/**
|
|
604
|
+
* Every word the grid writes itself — labels, accessible names, announcements, messages — for a
|
|
605
|
+
* translation or a house style. Any subset: what is left out stays English (`DATA_GRID_LOCALE_TEXT`).
|
|
606
|
+
* A value with something in it is a function, so a language can put the words in its own order.
|
|
607
|
+
*/
|
|
608
|
+
localeText?: Partial<DataGridLocaleText>;
|
|
596
609
|
/**
|
|
597
610
|
* A row of grand totals pinned under the rows, over every column carrying an `aggregate`. It covers the
|
|
598
611
|
* rows the grid holds after filtering — which is the page, not the table, when the server is paginating.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ChangeDetails } from '../../react/a11y/useControllableState';
|
|
2
2
|
import { RovingFocusItemProps, RovingFocusReason } from '../../react/a11y/useRovingFocus';
|
|
3
|
+
import { default as ActiveCellStore } from '../../utils/dataGrid/activeCellStore';
|
|
3
4
|
/**
|
|
4
5
|
* The grid's keyboard coordinates, shared with every cell. Rows are numbered as `aria-rowindex` is —
|
|
5
6
|
* headers, then the filter row, then the body — and a cell asks for its roving tabindex by that pair, so
|
|
@@ -12,8 +13,10 @@ export interface GridNavigation {
|
|
|
12
13
|
columnCount: number;
|
|
13
14
|
/** How many rows sit above the body — the offset from a body row's index to its row number. */
|
|
14
15
|
headerRowCount: number;
|
|
15
|
-
/** The
|
|
16
|
-
cellProps: (row: number, column: number) => RovingFocusItemProps
|
|
16
|
+
/** The ref and the focus handler for one cell, in the coordinates above. Stable: the tabindex is `activeCell`. */
|
|
17
|
+
cellProps: (row: number, column: number) => Omit<RovingFocusItemProps, 'tabIndex'>;
|
|
18
|
+
/** Which cell holds the tab stop. Subscribed to per cell, so a move re-renders two cells rather than all of them. */
|
|
19
|
+
activeCell: ActiveCellStore;
|
|
17
20
|
/**
|
|
18
21
|
* Move the tab stop to a cell without a keystroke having done it — what Tab out of an editor and into
|
|
19
22
|
* the next editable cell moves. `'programmatic'` rather than `'keyboard'` on purpose: a keyboard move
|
|
@@ -30,3 +33,5 @@ declare const GridNavigationContext: import('react').Context<GridNavigation | nu
|
|
|
30
33
|
export default GridNavigationContext;
|
|
31
34
|
/** The grid navigation a cell belongs to. */
|
|
32
35
|
export declare function useGridNavigationContext(): GridNavigation | null;
|
|
36
|
+
/** One cell's roving tabindex, ref and focus handler — re-rendering the cell only when its own tabindex changes. */
|
|
37
|
+
export declare function useGridCellProps(navigation: GridNavigation | null, row: number, column: number): Partial<RovingFocusItemProps>;
|
|
@@ -52,6 +52,8 @@ export default class ColumnModel<TRow> {
|
|
|
52
52
|
get isLastLeaf(): boolean;
|
|
53
53
|
get key(): Key;
|
|
54
54
|
get header(): string | undefined;
|
|
55
|
+
/** The header group this column sits under, if any. A pinned half of a group is a copy with the same header. */
|
|
56
|
+
get group(): ColumnModel<TRow> | undefined;
|
|
55
57
|
get align(): "center" | "left" | "right" | "start" | "end" | undefined;
|
|
56
58
|
/** End-aligned either way it is spelled — `right` is the physical name of `end` in a left-to-right grid. */
|
|
57
59
|
get isEndAligned(): boolean;
|
|
@@ -3,12 +3,19 @@ import { default as GridModel } from './gridModel';
|
|
|
3
3
|
export interface ColumnVisibilityEntry<TRow> {
|
|
4
4
|
id: string;
|
|
5
5
|
label: string;
|
|
6
|
+
/** The header group's text, when the column sits under one. */
|
|
7
|
+
group?: string;
|
|
6
8
|
column: ColumnModel<TRow>;
|
|
7
9
|
visible: boolean;
|
|
8
10
|
}
|
|
11
|
+
/** A run of entries under one header group, in column order. `group` is absent for ungrouped columns. */
|
|
12
|
+
export interface ColumnVisibilitySection<TRow> {
|
|
13
|
+
group?: string;
|
|
14
|
+
entries: ColumnVisibilityEntry<TRow>[];
|
|
15
|
+
}
|
|
9
16
|
/**
|
|
10
|
-
* Backs the top-bar
|
|
11
|
-
*
|
|
17
|
+
* Backs the top-bar columns panel: the toggleable (user data) columns, which are currently shown, the
|
|
18
|
+
* search over them, and a diff-based bulk setter.
|
|
12
19
|
*/
|
|
13
20
|
export default class ColumnVisibilityModel<TRow> {
|
|
14
21
|
readonly grid: GridModel<TRow>;
|
|
@@ -17,8 +24,15 @@ export default class ColumnVisibilityModel<TRow> {
|
|
|
17
24
|
get entries(): ColumnVisibilityEntry<TRow>[];
|
|
18
25
|
get selectedIds(): string[];
|
|
19
26
|
get total(): number;
|
|
27
|
+
get visibleCount(): number;
|
|
20
28
|
get hiddenCount(): number;
|
|
21
29
|
get hasHidden(): boolean;
|
|
30
|
+
/** The entries whose label or group contains `query`, ignoring case and surrounding space. */
|
|
31
|
+
search(query: string): ColumnVisibilityEntry<TRow>[];
|
|
32
|
+
/** `entries` cut into consecutive runs that share a group, which is what the panel draws a heading over. */
|
|
33
|
+
sections(entries: ColumnVisibilityEntry<TRow>[]): ColumnVisibilitySection<TRow>[];
|
|
22
34
|
/** Make exactly the columns in `ids` visible, toggling only those whose state must change. */
|
|
23
35
|
setVisibility: (ids: string[]) => void;
|
|
36
|
+
/** Show or hide every column in `entries` (all of them by default), leaving the rest as they are. */
|
|
37
|
+
setAll: (visible: boolean, entries?: ColumnVisibilityEntry<TRow>[]) => void;
|
|
24
38
|
}
|
|
@@ -3,10 +3,6 @@ import { default as ColumnModel } from './columnModel';
|
|
|
3
3
|
import { default as GridModel } from './gridModel';
|
|
4
4
|
import { RangeBounds } from './rangeModel';
|
|
5
5
|
import { default as RowModel } from './rowModel';
|
|
6
|
-
/** What a rejection with no message of its own says. A silent refusal is one nobody can act on. */
|
|
7
|
-
export declare const DEFAULT_EDIT_ERROR = "Invalid value";
|
|
8
|
-
/** What a pasted value is refused with when it is not the kind of value the cell holds at all. */
|
|
9
|
-
export declare const WRONG_KIND_ERROR = "Wrong kind of value";
|
|
10
6
|
/** A key that starts an edit by replacing the value: one printable character, unmodified. */
|
|
11
7
|
export declare function isTypingKey(event: React.KeyboardEvent): boolean;
|
|
12
8
|
/**
|
|
@@ -22,6 +18,10 @@ export declare function isTypingKey(event: React.KeyboardEvent): boolean;
|
|
|
22
18
|
export default class EditModel<TRow> {
|
|
23
19
|
readonly grid: GridModel<TRow>;
|
|
24
20
|
constructor(grid: GridModel<TRow>);
|
|
21
|
+
/** What a rejection with no message of its own says. A silent refusal is one nobody can act on. */
|
|
22
|
+
private get invalidValue();
|
|
23
|
+
/** A validator that threw is a refusal, and what it threw is the message. */
|
|
24
|
+
private errorText;
|
|
25
25
|
/** The accepted values, keyed by cell. Cleared by `clearEdits()` and by a datasource refresh. */
|
|
26
26
|
private readonly values;
|
|
27
27
|
/** The cells the last paste was refused on. They keep the invalid ring, which is all a batch can show. */
|
|
@@ -36,6 +36,8 @@ export default class EditModel<TRow> {
|
|
|
36
36
|
/** The editor a cell opens, worked out from the value in it when the column names none. */
|
|
37
37
|
editorFor(column: ColumnModel<TRow>, value: unknown): CellEditorConfig<TRow>;
|
|
38
38
|
isEditing(rowKey: Key, columnKey: Key): boolean;
|
|
39
|
+
/** Everything about this row the editor draws: which cell is open, what is in it and what it was told. */
|
|
40
|
+
rowDigest(rowKey: Key): string;
|
|
39
41
|
/** Whether an editor is open anywhere. A Ctrl+V while one is belongs to the editor, not to the grid. */
|
|
40
42
|
get isOpen(): boolean;
|
|
41
43
|
/** Whether the last paste was refused on this cell, which is the only mark a batch of them can carry. */
|
|
@@ -47,6 +47,6 @@ export default class ExportModel<TRow> {
|
|
|
47
47
|
* of its own to say — the same column it occupies on screen when that column is exported at all.
|
|
48
48
|
*/
|
|
49
49
|
private footerRow;
|
|
50
|
-
/** The file's name, without an extension: what was asked for, else the grid's title, else `
|
|
50
|
+
/** The file's name, without an extension: what was asked for, else the grid's title, else `localeText.exportFileName`. */
|
|
51
51
|
fileName(options?: DataGridExportOptions): string;
|
|
52
52
|
}
|
|
@@ -9,6 +9,7 @@ import { default as EditModel } from './editModel';
|
|
|
9
9
|
import { default as ExportModel } from './exportModel';
|
|
10
10
|
import { default as FilterModel } from './filterModel';
|
|
11
11
|
import { default as GroupRowModel } from './groupRowModel';
|
|
12
|
+
import { DataGridLocaleText } from './localeText';
|
|
12
13
|
import { default as PaginationModel } from './paginationModel';
|
|
13
14
|
import { default as RangeModel } from './rangeModel';
|
|
14
15
|
import { default as RowModel } from './rowModel';
|
|
@@ -25,8 +26,27 @@ export default class GridModel<TRow> {
|
|
|
25
26
|
subscribe: (listener: () => void) => (() => void);
|
|
26
27
|
/** Monotonic snapshot version — stable between changes, increments on notify(). */
|
|
27
28
|
getSnapshot: () => number;
|
|
28
|
-
|
|
29
|
+
private static drawnPropsChanged;
|
|
30
|
+
/** Bumped by a change every row draws from — a sort, a filter, the columns — and by nothing row-local. */
|
|
31
|
+
private _epoch;
|
|
32
|
+
/** Signal subscribers that state changed and a re-render is needed. Every rendered row redraws. */
|
|
29
33
|
notify: () => void;
|
|
34
|
+
/**
|
|
35
|
+
* A change that `rowVersion` sees row by row — a selection, the current cell, a keystroke in an editor —
|
|
36
|
+
* so only the rows whose version moved redraw, rather than every row on screen (bug #237).
|
|
37
|
+
*/
|
|
38
|
+
notifyRows: () => void;
|
|
39
|
+
/**
|
|
40
|
+
* What a rendered row's memo compares: the grid-wide epoch plus the row's own state. A `Cell` of your own
|
|
41
|
+
* that reads something outside its row redraws on a grid-wide change, not on another row's selection.
|
|
42
|
+
*/
|
|
43
|
+
rowVersion(row: RowModel<TRow> | GroupRowModel<TRow> | DetailRowModel<TRow>, index: number): string;
|
|
44
|
+
private _selectionVersion;
|
|
45
|
+
/**
|
|
46
|
+
* What the memoized header compares: a grid-wide change, or the selection its checkbox shows. A focus move
|
|
47
|
+
* re-renders the component holding the tab stop, and the header — filter row included — no longer with it.
|
|
48
|
+
*/
|
|
49
|
+
get headerVersion(): string;
|
|
30
50
|
/**
|
|
31
51
|
* Sync incoming props. Called during render by the framework adapter — clears
|
|
32
52
|
* the affected memos but does NOT notify (no extra render cycle; memos recompute
|
|
@@ -56,6 +76,10 @@ export default class GridModel<TRow> {
|
|
|
56
76
|
get titleId(): string;
|
|
57
77
|
get resizerStyle(): 'visible' | 'hover' | 'hidden';
|
|
58
78
|
get resizeMode(): 'smooth' | 'instant';
|
|
79
|
+
get headerHover(): 'static' | 'sliding';
|
|
80
|
+
private _localeText?;
|
|
81
|
+
/** The grid's words: `def.localeText` over the English defaults, merged once per object it is given. */
|
|
82
|
+
get localeText(): DataGridLocaleText;
|
|
59
83
|
readonly sourceColumns: import('../../../utils/memo').Memo<ColumnModel<TRow>[]>;
|
|
60
84
|
readonly columns: import('../../../utils/memo').Memo<{
|
|
61
85
|
start: ColumnModel<TRow>[];
|
|
@@ -155,6 +179,11 @@ export default class GridModel<TRow> {
|
|
|
155
179
|
private _sizingElement;
|
|
156
180
|
get sizingElement(): HTMLElement | null;
|
|
157
181
|
setSizingElement: (el: HTMLElement | null) => void;
|
|
182
|
+
/**
|
|
183
|
+
* Writes the width variables straight onto the sizing element, ahead of the render that will agree with
|
|
184
|
+
* them: a resize drag repaints without re-rendering every row, and a new scroller width lands before paint.
|
|
185
|
+
*/
|
|
186
|
+
paintSizes: () => void;
|
|
158
187
|
/**
|
|
159
188
|
* Which way the grid reads, resolved off the element the widths are written to. A model with no
|
|
160
189
|
* element yet — a server render, a headless host — reads as left to right, the initial value.
|
|
@@ -231,9 +260,34 @@ export default class GridModel<TRow> {
|
|
|
231
260
|
/** Whether any user-facing column is currently visible (else the empty-columns state shows). */
|
|
232
261
|
get hasVisibleColumns(): boolean;
|
|
233
262
|
get isEmpty(): boolean;
|
|
234
|
-
/**
|
|
263
|
+
/**
|
|
264
|
+
* The rows the header checkbox acts on: what the filters leave on screen. A select-all reaching rows
|
|
265
|
+
* nobody can see is a bulk action on rows nobody chose; with a datasource it is the blocks it holds.
|
|
266
|
+
*/
|
|
267
|
+
get selectableRows(): TRow[];
|
|
268
|
+
/** The keys of `selectableRows`. A datasource's grow as blocks arrive, so only the client side is kept. */
|
|
269
|
+
private readonly _selectableKeys;
|
|
270
|
+
private get selectableKeys();
|
|
271
|
+
private _selectionCounts?;
|
|
272
|
+
/** How many selected rows are on screen — read by the header and the footer on every render, so kept. */
|
|
273
|
+
private get shownSelectedCount();
|
|
274
|
+
/** Header select-all checkbox state: every row on screen is selected, whatever the filters hide. */
|
|
235
275
|
get allRowsSelected(): boolean;
|
|
236
276
|
get someRowsSelected(): boolean;
|
|
277
|
+
/**
|
|
278
|
+
* Selected rows the filters hide. A filter never drops a selection, so the footer says what it is
|
|
279
|
+
* keeping out of sight; a server's rows are unknown until fetched, so there it is never counted.
|
|
280
|
+
*/
|
|
281
|
+
get hiddenSelectedCount(): number;
|
|
282
|
+
/** The keys "Show selected" froze when it was pressed, so a row unticked in that view stays put. */
|
|
283
|
+
private _selectionView;
|
|
284
|
+
get isSelectionView(): boolean;
|
|
285
|
+
/** Only the grid's own filtering can be set aside; a server's or a tree's cannot. */
|
|
286
|
+
get canShowSelection(): boolean;
|
|
287
|
+
/** "Show selected" sets the filters aside rather than adding to them: the rows it is for are the hidden ones. */
|
|
288
|
+
toggleSelectionView: () => void;
|
|
289
|
+
/** A filter typed while viewing the selection is a new question, so the view gives way to it. */
|
|
290
|
+
private leaveSelectionView;
|
|
237
291
|
private _selectionAnnounced;
|
|
238
292
|
/**
|
|
239
293
|
* What the grid's live region says. Ticking a checkbox halfway down a virtualized grid changes nothing a
|
|
@@ -279,7 +333,11 @@ export default class GridModel<TRow> {
|
|
|
279
333
|
toggleRowSelection: (rowKey: Key) => void;
|
|
280
334
|
/** `all` is the header checkbox rather than a count: a group covering every row is still not select-all. */
|
|
281
335
|
toggleRowsSelection: (rowKeys: Key[], all?: boolean) => void;
|
|
336
|
+
/** Ticks or clears the rows on screen only — selected rows the filters hide are left as they are. */
|
|
282
337
|
toggleSelectAllRows: () => void;
|
|
338
|
+
/** Every row, hidden ones included: the footer's way out of a selection the filters keep half out of sight. */
|
|
339
|
+
clearSelection: () => void;
|
|
340
|
+
private selectionChanged;
|
|
283
341
|
toggleColumnVisibility: (columnKey: Key) => void;
|
|
284
342
|
setWidth: (columnKey: Key, width: number) => void;
|
|
285
343
|
private _groupColumns?;
|
|
@@ -31,14 +31,14 @@ export default class GroupRowModel<TRow> {
|
|
|
31
31
|
aggregateValue(_column: ColumnModel<TRow>): AggregateValue | undefined;
|
|
32
32
|
get key(): Key;
|
|
33
33
|
parentRow?: GroupRowModel<TRow>;
|
|
34
|
-
private
|
|
34
|
+
private _cells?;
|
|
35
35
|
get cells(): GroupRowCellModel<TRow>[];
|
|
36
|
+
private cellCache;
|
|
36
37
|
/**
|
|
37
38
|
* The cells this row actually renders, each with the column it starts at. A `hidden` cell is a
|
|
38
39
|
* data column the grouping cell has absorbed into its span: no element, and nothing to navigate
|
|
39
40
|
* to — which is why a group row's cell positions and its `aria-colindex` values differ.
|
|
40
41
|
*/
|
|
41
|
-
private readonly _renderedCells;
|
|
42
42
|
get renderedCells(): {
|
|
43
43
|
cell: GroupRowCellModel<TRow>;
|
|
44
44
|
columnIndex: number;
|
|
@@ -14,6 +14,8 @@ export default class HeaderCellModel<TRow> {
|
|
|
14
14
|
*/
|
|
15
15
|
get hiddenLabel(): string | undefined;
|
|
16
16
|
get isSortable(): boolean;
|
|
17
|
+
/** Whether the cell paints its own hover pill: under `'sliding'` the header draws one for every cell. */
|
|
18
|
+
get hasHoverPill(): boolean;
|
|
17
19
|
get isSorted(): boolean;
|
|
18
20
|
get sortDirection(): SortDirection | undefined;
|
|
19
21
|
get showResizer(): boolean;
|
|
@@ -33,6 +35,11 @@ export default class HeaderCellModel<TRow> {
|
|
|
33
35
|
get ariaSort(): 'ascending' | 'descending' | 'none' | undefined;
|
|
34
36
|
/** What the resizer names itself. A separator carries no text, so it has nothing else to go on. */
|
|
35
37
|
get resizerLabel(): string;
|
|
38
|
+
/**
|
|
39
|
+
* Whether this header ends where the grid does. A resizer straddling that edge overhangs the scroller,
|
|
40
|
+
* which made every grid whose columns exactly fit scroll sideways by 3px.
|
|
41
|
+
*/
|
|
42
|
+
get isAtGridEnd(): boolean;
|
|
36
43
|
/** `aria-valuenow`: how wide the column is right now, in px. */
|
|
37
44
|
get width(): number;
|
|
38
45
|
/** `aria-valuemin`: every leaf the header covers at the narrowest the grid allows. */
|
|
@@ -54,6 +61,9 @@ export default class HeaderCellModel<TRow> {
|
|
|
54
61
|
isFirstEndPinned: boolean;
|
|
55
62
|
isLastEndPinned: boolean;
|
|
56
63
|
isSortable: boolean;
|
|
64
|
+
hasHoverPill: boolean;
|
|
65
|
+
isPillBeforeResizer: boolean;
|
|
66
|
+
isPillAfterResizer: boolean;
|
|
57
67
|
isRowNumber: boolean;
|
|
58
68
|
isFirstLeaf: boolean;
|
|
59
69
|
isLastLeaf: boolean;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every word the grid writes itself — visible text, accessible names, announcements and messages. A value
|
|
3
|
+
* with something in it is a function, because word order and plurals differ between languages and a
|
|
4
|
+
* sentence glued from pieces cannot be translated. Override any subset through `def.localeText`.
|
|
5
|
+
*/
|
|
6
|
+
export interface DataGridLocaleText {
|
|
7
|
+
/** The global search box's placeholder. */
|
|
8
|
+
searchPlaceholder: string;
|
|
9
|
+
/** The columns button's text and the panel's accessible name. */
|
|
10
|
+
columnsMenu: string;
|
|
11
|
+
/** The button's accessible name while some columns are hidden — it has to start with `columnsMenu`. */
|
|
12
|
+
columnsMenuLabel: (shown: number, total: number) => string;
|
|
13
|
+
columnsMenuSearchPlaceholder: string;
|
|
14
|
+
columnsMenuShowAll: string;
|
|
15
|
+
columnsMenuHideAll: string;
|
|
16
|
+
/** The count above the list: "6 of 8 shown". */
|
|
17
|
+
columnsMenuShown: (shown: number, total: number) => string;
|
|
18
|
+
/** What the list says when the search matches no column. */
|
|
19
|
+
columnsMenuNoMatch: (query: string) => string;
|
|
20
|
+
/** The ✕ on a grouped column's chip. */
|
|
21
|
+
stopGrouping: (column: string) => string;
|
|
22
|
+
/** The export buttons' visible text, and their accessible names. */
|
|
23
|
+
exportCsv: string;
|
|
24
|
+
exportCsvLabel: string;
|
|
25
|
+
exportExcel: string;
|
|
26
|
+
exportExcelLabel: string;
|
|
27
|
+
/** The exported file's name when there is no `fileName` and no string `title`. */
|
|
28
|
+
exportFileName: string;
|
|
29
|
+
selectAllRows: string;
|
|
30
|
+
/** The hidden names of the row-number and row-detail columns, which draw no header text. */
|
|
31
|
+
rowNumberHeader: string;
|
|
32
|
+
rowDetailHeader: string;
|
|
33
|
+
/** The grouping column's header when more than one column is grouped. */
|
|
34
|
+
groupHeader: string;
|
|
35
|
+
columnOptions: (column: string) => string;
|
|
36
|
+
resizeColumn: (column: string) => string;
|
|
37
|
+
/** A resizer's `aria-valuetext`. */
|
|
38
|
+
columnWidth: (pixels: number) => string;
|
|
39
|
+
sortAscending: string;
|
|
40
|
+
sortDescending: string;
|
|
41
|
+
clearSort: string;
|
|
42
|
+
/** The pin items name a screen side, so a right-to-left page swaps them. */
|
|
43
|
+
pinLeft: string;
|
|
44
|
+
pinRight: string;
|
|
45
|
+
unpin: string;
|
|
46
|
+
groupBy: (column: string) => string;
|
|
47
|
+
ungroupAll: string;
|
|
48
|
+
filterPlaceholder: string;
|
|
49
|
+
filterColumn: (column: string) => string;
|
|
50
|
+
clearFilter: (column: string) => string;
|
|
51
|
+
filterComparison: (column: string) => string;
|
|
52
|
+
filterValuePlaceholder: string;
|
|
53
|
+
filterFromPlaceholder: string;
|
|
54
|
+
filterToPlaceholder: string;
|
|
55
|
+
filterFrom: (column: string) => string;
|
|
56
|
+
filterTo: (column: string) => string;
|
|
57
|
+
filterSelectPlaceholder: string;
|
|
58
|
+
filterSelectSearchPlaceholder: string;
|
|
59
|
+
filterSelectClear: string;
|
|
60
|
+
filterSelectAll: string;
|
|
61
|
+
/** How a multiselect filter lists a `null` value. */
|
|
62
|
+
filterEmptyValue: string;
|
|
63
|
+
/** What an empty grid shows when there is no `noDataComponent`. */
|
|
64
|
+
noRows: string;
|
|
65
|
+
loadingRows: string;
|
|
66
|
+
selectRow: (rowNumber: number) => string;
|
|
67
|
+
selectGroupRows: (group: string) => string;
|
|
68
|
+
expandRowDetail: (rowNumber: number) => string;
|
|
69
|
+
collapseRowDetail: (rowNumber: number) => string;
|
|
70
|
+
expandTreeRow: (name: string) => string;
|
|
71
|
+
collapseTreeRow: (name: string) => string;
|
|
72
|
+
/** What a tree row with no value of its own is called in its expander's name. */
|
|
73
|
+
unnamedRow: (rowNumber: number) => string;
|
|
74
|
+
editCell: (column: string) => string;
|
|
75
|
+
/** A refused edit with no message of its own. */
|
|
76
|
+
invalidValue: string;
|
|
77
|
+
/** A pasted value the column cannot read, such as text in a number column. */
|
|
78
|
+
wrongKindOfValue: string;
|
|
79
|
+
/** The totals row's label when `def.footer` has none. */
|
|
80
|
+
footerTotal: string;
|
|
81
|
+
noColumnsTitle: string;
|
|
82
|
+
noColumnsDescription: string;
|
|
83
|
+
/** A failed fetch whose error carries no message. */
|
|
84
|
+
loadError: string;
|
|
85
|
+
retry: string;
|
|
86
|
+
rowCount: (filtered: number, total: number) => string;
|
|
87
|
+
pageRowRange: (start: number, end: number, total: number) => string;
|
|
88
|
+
/** `hidden` is how many selected rows the filters keep off screen. */
|
|
89
|
+
selectedCount: (selected: number, hidden: number) => string;
|
|
90
|
+
clearFilters: string;
|
|
91
|
+
/** A toggle: it shows the selected rows whatever the filters say, and pressing it again shows the rest. */
|
|
92
|
+
showSelected: string;
|
|
93
|
+
clearSelection: string;
|
|
94
|
+
rowsPerPage: string;
|
|
95
|
+
/** An entry in the page-size list. */
|
|
96
|
+
pageSizeOption: (size: number) => string;
|
|
97
|
+
pageNumber: string;
|
|
98
|
+
/** The text after the page box: "of 12". */
|
|
99
|
+
pageCount: (totalPages: number) => string;
|
|
100
|
+
firstPage: string;
|
|
101
|
+
previousPage: string;
|
|
102
|
+
nextPage: string;
|
|
103
|
+
lastPage: string;
|
|
104
|
+
/** What the live region says when the selection changes. */
|
|
105
|
+
selectionAnnouncement: (selected: number, total: number) => string;
|
|
106
|
+
}
|
|
107
|
+
/** The grid's own words, in English. Spread it to start a translation: `{ ...DATA_GRID_LOCALE_TEXT, clearFilters: 'Rensa filter' }`. */
|
|
108
|
+
export declare const DATA_GRID_LOCALE_TEXT: DataGridLocaleText;
|
|
@@ -57,6 +57,8 @@ export default class RangeModel<TRow> {
|
|
|
57
57
|
isCurrent(row: number, column: number): boolean;
|
|
58
58
|
/** Whether the cell is part of a marked block. A single current cell is the cursor, not a selection. */
|
|
59
59
|
isSelected(row: number, column: number): boolean;
|
|
60
|
+
/** Everything about this body row the range draws: the current column, the block's columns, and a drag. */
|
|
61
|
+
rowDigest(row: number): string;
|
|
60
62
|
/**
|
|
61
63
|
* Put the current cell here. `extend` keeps the anchor where it is, which is what makes Shift+arrow and
|
|
62
64
|
* a drag grow a rectangle instead of moving a cursor.
|
|
@@ -29,7 +29,7 @@ export default class RowModel<TRow> {
|
|
|
29
29
|
/** Whether clicking the row toggles its detail panel. */
|
|
30
30
|
get expandOnRowClick(): boolean;
|
|
31
31
|
toggleDetail: () => void;
|
|
32
|
-
private
|
|
32
|
+
private _cells?;
|
|
33
33
|
get cells(): CellModel<TRow>[];
|
|
34
34
|
/** One cell per visible column — the width the grid navigation sees for this row. */
|
|
35
35
|
get cellCount(): number;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A debounced input over a value the grid owns. When the grid's value changes to something the draft does
|
|
3
|
+
* not already say — "Clear filters" in the footer, a controlled prop — the draft takes it and any pending
|
|
4
|
+
* commit is dropped; a copy read once at mount kept showing a filter that was gone.
|
|
5
|
+
*/
|
|
6
|
+
export default function useFilterDraft<T>(committed: T, matches: (committed: T) => boolean, adopt: (committed: T) => void): {
|
|
7
|
+
debounce: (key: string, commit: () => void) => void;
|
|
8
|
+
cancel: () => void;
|
|
9
|
+
};
|