@ssa-ui-kit/core 3.26.4 → 3.27.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/dist/ai/source-map.md +100 -37
- package/dist/components/Calendar/Calendar.d.ts +11 -3
- package/dist/components/Calendar/CalendarContext.d.ts +12 -1
- package/dist/components/Calendar/components/CalendarToolbar.d.ts +5 -1
- package/dist/components/Calendar/components/DayView.d.ts +4 -2
- package/dist/components/Calendar/components/TimeZoneSelect.d.ts +14 -0
- package/dist/components/Calendar/consts.d.ts +14 -1
- package/dist/components/Calendar/styles.d.ts +37 -1
- package/dist/components/Calendar/types.d.ts +93 -5
- package/dist/components/Calendar/utils.d.ts +35 -5
- package/dist/components/DataTable/DataTable.d.ts +79 -0
- package/dist/components/DataTable/DataTableColumnPicker.d.ts +66 -0
- package/dist/components/DataTable/ExpanderCell.d.ts +10 -0
- package/dist/components/DataTable/SelectionCell.d.ts +25 -0
- package/dist/components/DataTable/index.d.ts +4 -0
- package/dist/components/DataTable/styles.d.ts +47 -0
- package/dist/components/DataTable/types.d.ts +378 -0
- package/dist/components/DataTable/useColumnReorder.d.ts +31 -0
- package/dist/components/DataTable/useDataTableModel.d.ts +36 -0
- package/dist/components/DataTable/utils.d.ts +82 -0
- package/dist/components/NestedTable/WithNestedTableRow.d.ts +4 -0
- package/dist/components/NestedTable/components/NestedTable.d.ts +4 -0
- package/dist/components/NestedTable/components/NestedTableCell.d.ts +4 -0
- package/dist/components/NestedTable/components/NestedTableCellHeader.d.ts +4 -0
- package/dist/components/NestedTable/components/NestedTableRow.d.ts +4 -0
- package/dist/components/Table/ColumnFreezeMenu.d.ts +11 -1
- package/dist/components/Table/ColumnMenu.d.ts +30 -0
- package/dist/components/Table/Table.d.ts +4 -4
- package/dist/components/Table/types.d.ts +77 -6
- package/dist/components/TableCellHeader/TableCellHeader.d.ts +1 -1
- package/dist/components/TableCellHeader/types.d.ts +14 -5
- package/dist/components/index.d.ts +2 -0
- package/dist/index.js +2615 -565
- package/dist/index.mjs +2615 -566
- package/dist/tsbuildcache +1 -1
- package/package.json +6 -5
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { DataTableProps } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* DataTable - A table driven by data: give it rows and column definitions
|
|
4
|
+
* and it renders, sorts and lays out the columns itself.
|
|
5
|
+
*
|
|
6
|
+
* Use it for interactive data tables. For a static table whose markup you
|
|
7
|
+
* want to write by hand, use `Table` and its row and cell components, which
|
|
8
|
+
* this is built from.
|
|
9
|
+
*
|
|
10
|
+
* ### Sorting
|
|
11
|
+
*
|
|
12
|
+
* Mark a column `sortable` and clicking its header reports a new sort through
|
|
13
|
+
* `onSortChange`: ascending first, then toggling. By default the table only
|
|
14
|
+
* reports it, expecting the server to send the rows back sorted, and passes
|
|
15
|
+
* the column's `sortKey` along for the request. Give the column a `sortFn` to
|
|
16
|
+
* sort the rows in the browser instead.
|
|
17
|
+
*
|
|
18
|
+
* ### Column layout
|
|
19
|
+
*
|
|
20
|
+
* Widths, frozen columns, order and hidden columns live in one
|
|
21
|
+
* `DataTableColumnState`, keyed by column id. Read it from
|
|
22
|
+
* `onColumnStateChange`, store it, and pass it back through
|
|
23
|
+
* `defaultColumnState` to remember a user's layout.
|
|
24
|
+
*
|
|
25
|
+
* With `reorderableColumns` the user can move columns, by dragging the grip
|
|
26
|
+
* in the header or from the header menu. A column only moves among columns
|
|
27
|
+
* frozen to the same edge, or among the unfrozen ones.
|
|
28
|
+
*
|
|
29
|
+
* ### Nested rows
|
|
30
|
+
*
|
|
31
|
+
* `getSubRows` nests rows under rows, to any depth, with an expand button
|
|
32
|
+
* per parent; `expandedRowIds` or `defaultExpanded` say which are open.
|
|
33
|
+
*
|
|
34
|
+
* ### Selection and hidden columns
|
|
35
|
+
*
|
|
36
|
+
* `selectionMode` adds a checkbox (or radio) column; the selection is a list
|
|
37
|
+
* of row ids, reported through `onSelectionChange`. `hideableColumns` adds
|
|
38
|
+
* "Hide column" to the header menu, and `DataTableColumnPicker` brings
|
|
39
|
+
* hidden columns back.
|
|
40
|
+
*
|
|
41
|
+
* @category Components
|
|
42
|
+
* @subcategory Data Display
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```tsx
|
|
46
|
+
* const columns: DataTableColumn<Employee>[] = [
|
|
47
|
+
* { id: 'name', header: 'Name', cell: (row) => row.name, sortable: true },
|
|
48
|
+
* { id: 'role', header: 'Role', cell: (row) => row.role },
|
|
49
|
+
* ];
|
|
50
|
+
*
|
|
51
|
+
* <DataTable
|
|
52
|
+
* data={employees}
|
|
53
|
+
* columns={columns}
|
|
54
|
+
* sort={sort}
|
|
55
|
+
* onSortChange={(next, sortKey) => {
|
|
56
|
+
* setSort(next);
|
|
57
|
+
* refetch({ sortBy: sortKey, descending: next?.direction === 'desc' });
|
|
58
|
+
* }}
|
|
59
|
+
* isLoading={isFetching}
|
|
60
|
+
* />
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```tsx
|
|
65
|
+
* // Resizable, freezable columns whose layout is remembered
|
|
66
|
+
* <DataTable
|
|
67
|
+
* data={rows}
|
|
68
|
+
* columns={columns}
|
|
69
|
+
* resizableColumns
|
|
70
|
+
* freezeControls
|
|
71
|
+
* defaultColumnState={loadLayout()}
|
|
72
|
+
* onColumnStateChange={saveLayout}
|
|
73
|
+
* />
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* @see {@link Table} - the building blocks, for hand-written tables
|
|
77
|
+
*/
|
|
78
|
+
declare const DataTable: <Row>(props: DataTableProps<Row>) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
79
|
+
export default DataTable;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { DataTableColumn, DataTableColumnState } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Props of {@link DataTableColumnPicker}.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```tsx
|
|
8
|
+
* <DataTableColumnPicker
|
|
9
|
+
* columns={columns}
|
|
10
|
+
* columnState={columnState}
|
|
11
|
+
* onColumnStateChange={setColumnState}
|
|
12
|
+
* />
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export interface DataTableColumnPickerProps<Row> {
|
|
16
|
+
/** The same columns the table gets. */
|
|
17
|
+
columns: DataTableColumn<Row>[];
|
|
18
|
+
/** The table's column state, as passed to its `columnState`. */
|
|
19
|
+
columnState?: Partial<DataTableColumnState>;
|
|
20
|
+
/** Called with the whole new column state when a column is shown or hidden. */
|
|
21
|
+
onColumnStateChange: (columnState: DataTableColumnState) => void;
|
|
22
|
+
/**
|
|
23
|
+
* Text of the button that opens the list.
|
|
24
|
+
* @default 'Columns'
|
|
25
|
+
*/
|
|
26
|
+
label?: ReactNode;
|
|
27
|
+
/** Class name of the button. */
|
|
28
|
+
className?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* DataTableColumnPicker - A button that opens a checklist of a
|
|
32
|
+
* {@link DataTable}'s columns, to show or hide each one.
|
|
33
|
+
*
|
|
34
|
+
* Place it wherever the page keeps its table controls, such as next to the
|
|
35
|
+
* filters, and share a controlled `columnState` between it and the table.
|
|
36
|
+
* Columns are listed in display order. Columns with `hideable: false` stay
|
|
37
|
+
* checked and cannot be cleared, and neither can the last one shown.
|
|
38
|
+
*
|
|
39
|
+
* @category Components
|
|
40
|
+
* @subcategory Data Display
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```tsx
|
|
44
|
+
* const [columnState, setColumnState] = useState<Partial<DataTableColumnState>>({});
|
|
45
|
+
*
|
|
46
|
+
* <DataTableColumnPicker
|
|
47
|
+
* columns={columns}
|
|
48
|
+
* columnState={columnState}
|
|
49
|
+
* onColumnStateChange={setColumnState}
|
|
50
|
+
* />
|
|
51
|
+
* <DataTable
|
|
52
|
+
* data={rows}
|
|
53
|
+
* columns={columns}
|
|
54
|
+
* columnState={columnState}
|
|
55
|
+
* onColumnStateChange={setColumnState}
|
|
56
|
+
* />
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @see {@link DataTable} - `hideableColumns` adds "Hide column" to its header menu
|
|
60
|
+
*
|
|
61
|
+
* @accessibility
|
|
62
|
+
* - The list is a multi-select listbox: arrows move, Space or Enter toggles
|
|
63
|
+
* - Escape closes it and returns focus to the button
|
|
64
|
+
*/
|
|
65
|
+
export declare const DataTableColumnPicker: <Row>({ columns, columnState, onColumnStateChange, label, className, }: DataTableColumnPickerProps<Row>) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
66
|
+
export default DataTableColumnPicker;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** The empty header above the expand buttons. */
|
|
2
|
+
export declare const ExpanderHeaderCell: () => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
3
|
+
interface ExpanderCellProps {
|
|
4
|
+
hasChildren: boolean;
|
|
5
|
+
isExpanded: boolean;
|
|
6
|
+
onToggle: () => void;
|
|
7
|
+
}
|
|
8
|
+
/** A row's expand/collapse button, or nothing for a row without children. */
|
|
9
|
+
export declare const ExpanderCell: ({ hasChildren, isExpanded, onToggle, }: ExpanderCellProps) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { DataTableSelectionMode } from './types';
|
|
2
|
+
interface SelectionHeaderCellProps {
|
|
3
|
+
mode: Exclude<DataTableSelectionMode, 'none'>;
|
|
4
|
+
checked: boolean;
|
|
5
|
+
indeterminate: boolean;
|
|
6
|
+
disabled: boolean;
|
|
7
|
+
onToggle: () => void;
|
|
8
|
+
}
|
|
9
|
+
/** The header of the selection column: select-all, or a label for radios. */
|
|
10
|
+
export declare const SelectionHeaderCell: ({ mode, checked, indeterminate, disabled, onToggle, }: SelectionHeaderCellProps) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
11
|
+
interface SelectionCellProps {
|
|
12
|
+
mode: Exclude<DataTableSelectionMode, 'none'>;
|
|
13
|
+
/** Groups the radios of one table. */
|
|
14
|
+
name: string;
|
|
15
|
+
rowId: string;
|
|
16
|
+
label: string;
|
|
17
|
+
checked: boolean;
|
|
18
|
+
/** Some of the rows below are selected, not all. */
|
|
19
|
+
indeterminate?: boolean;
|
|
20
|
+
disabled: boolean;
|
|
21
|
+
onChange: (checked: boolean) => void;
|
|
22
|
+
}
|
|
23
|
+
/** A row's checkbox or radio. */
|
|
24
|
+
export declare const SelectionCell: ({ mode, name, rowId, label, checked, indeterminate, disabled, onChange, }: SelectionCellProps) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Theme } from '@emotion/react';
|
|
2
|
+
export declare const root: import("@emotion/react").SerializedStyles;
|
|
3
|
+
/** A header button that looks like the header text it wraps. */
|
|
4
|
+
export declare const sortButton: (theme: Theme) => import("@emotion/react").SerializedStyles;
|
|
5
|
+
export declare const headerLabel: import("@emotion/react").SerializedStyles;
|
|
6
|
+
/** Rows stay readable but plainly stale while a re-fetch is in flight. */
|
|
7
|
+
export declare const busyBody: import("@emotion/react").SerializedStyles;
|
|
8
|
+
export declare const clickableRow: (theme: Theme) => import("@emotion/react").SerializedStyles;
|
|
9
|
+
export declare const stateCell: (theme: Theme) => import("@emotion/react").SerializedStyles;
|
|
10
|
+
/**
|
|
11
|
+
* Every header cell. Relative so the grip, the menu and the drop line have
|
|
12
|
+
* something to sit against; a frozen header keeps its sticky position, whose
|
|
13
|
+
* rule in TableBase is the more specific one.
|
|
14
|
+
*/
|
|
15
|
+
export declare const header: (theme: Theme) => import("@emotion/react").SerializedStyles;
|
|
16
|
+
/** Room on the right for the menu, so long header text never runs under it. */
|
|
17
|
+
export declare const headerWithMenu: import("@emotion/react").SerializedStyles;
|
|
18
|
+
/**
|
|
19
|
+
* Pinned to the right edge of the header, clear of the resize handle, so it
|
|
20
|
+
* lines up from column to column whatever the header text.
|
|
21
|
+
*/
|
|
22
|
+
export declare const headerMenu: import("@emotion/react").SerializedStyles;
|
|
23
|
+
/**
|
|
24
|
+
* Sits in the cell's left padding, so showing it never moves the header
|
|
25
|
+
* text. Hidden until the header is hovered, like the column menu.
|
|
26
|
+
*/
|
|
27
|
+
export declare const grip: import("@emotion/react").SerializedStyles;
|
|
28
|
+
/** The checkbox or radio column: narrow, its control centred. */
|
|
29
|
+
export declare const selectionCell: import("@emotion/react").SerializedStyles;
|
|
30
|
+
export declare const selectedRow: (theme: Theme) => import("@emotion/react").SerializedStyles;
|
|
31
|
+
export declare const visuallyHidden: import("@emotion/react").SerializedStyles;
|
|
32
|
+
/** The expand/collapse column. */
|
|
33
|
+
export declare const expanderCell: import("@emotion/react").SerializedStyles;
|
|
34
|
+
export declare const expanderButton: (theme: Theme) => import("@emotion/react").SerializedStyles;
|
|
35
|
+
/**
|
|
36
|
+
* A row given a `background` by getRowProps. The colour arrives as a custom
|
|
37
|
+
* property, so every tinted row shares this one class whatever its colour.
|
|
38
|
+
* Layered over white: frozen cells must stay opaque. Hover and selection
|
|
39
|
+
* rules come later or weigh more, so they paint over it.
|
|
40
|
+
*/
|
|
41
|
+
export declare const tintedRow: import("@emotion/react").SerializedStyles;
|
|
42
|
+
/** A row with children, as NestedTable draws its group rows. */
|
|
43
|
+
export declare const parentRow: (theme: Theme) => import("@emotion/react").SerializedStyles;
|
|
44
|
+
/** A tinted row with children: the row's tint over the parent grey. */
|
|
45
|
+
export declare const tintedParentRow: (theme: Theme) => import("@emotion/react").SerializedStyles;
|
|
46
|
+
/** A selected row with children: the selected tint over the parent grey. */
|
|
47
|
+
export declare const selectedParentRow: (theme: Theme) => import("@emotion/react").SerializedStyles;
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
import { CSSProperties, KeyboardEvent, MouseEvent, ReactNode, Ref } from 'react';
|
|
2
|
+
import { ColumnResizeMode } from '../Table/types';
|
|
3
|
+
/** Direction of a {@link DataTableSort}. */
|
|
4
|
+
export type DataTableSortDirection = 'asc' | 'desc';
|
|
5
|
+
/**
|
|
6
|
+
* How many rows of a {@link DataTable} the user can select: `multiple` adds a
|
|
7
|
+
* checkbox column with a select-all checkbox, `single` a radio column.
|
|
8
|
+
*/
|
|
9
|
+
export type DataTableSelectionMode = 'none' | 'single' | 'multiple';
|
|
10
|
+
/**
|
|
11
|
+
* Attributes a {@link DataTable} adds to one body row or cell, returned by
|
|
12
|
+
* `getRowProps` on the table or `getCellProps` on a column. For styling a row
|
|
13
|
+
* or cell from its data.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* getRowProps: (row) => ({
|
|
18
|
+
* className: row.excluded ? 'excluded' : undefined,
|
|
19
|
+
* background: row.awaitingReply ? 'rgba(242, 136, 142, 0.08)' : undefined,
|
|
20
|
+
* })
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export interface DataTableElementProps {
|
|
24
|
+
/** Added to the element's class names. */
|
|
25
|
+
className?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Inline style of the element. On a row, a `background` here is hidden by
|
|
28
|
+
* the cells, which paint their own; use the `background` field instead.
|
|
29
|
+
*/
|
|
30
|
+
style?: CSSProperties;
|
|
31
|
+
/**
|
|
32
|
+
* A colour painted over the cells, such as a translucent tint. Laid over
|
|
33
|
+
* white, so frozen cells stay opaque. On a row, the hover and selected
|
|
34
|
+
* states show over it; on a cell, it stays.
|
|
35
|
+
*/
|
|
36
|
+
background?: string;
|
|
37
|
+
/** `data-*` attributes, for CSS or tests. */
|
|
38
|
+
[dataAttribute: `data-${string}`]: string | number | boolean | undefined;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The column a {@link DataTable} is sorted by. One column at a time; `null`
|
|
42
|
+
* when the rows are in the order they were given.
|
|
43
|
+
*/
|
|
44
|
+
export interface DataTableSort {
|
|
45
|
+
/** `id` of the sorted column. */
|
|
46
|
+
columnId: string;
|
|
47
|
+
direction: DataTableSortDirection;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* One column of a {@link DataTable}.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```tsx
|
|
54
|
+
* const columns: DataTableColumn<Employee>[] = [
|
|
55
|
+
* { id: 'name', header: 'Name', cell: (row) => row.name, sortable: true },
|
|
56
|
+
* { id: 'salary', header: 'Salary', cell: (row) => fmt(row.salary), align: 'right' },
|
|
57
|
+
* ];
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export interface DataTableColumn<Row> {
|
|
61
|
+
/**
|
|
62
|
+
* Stable, unique id. Column state (order, widths, frozen, hidden) and the
|
|
63
|
+
* sort refer to columns by it, so it must not change between renders.
|
|
64
|
+
*/
|
|
65
|
+
id: string;
|
|
66
|
+
/** Header cell content. */
|
|
67
|
+
header: ReactNode;
|
|
68
|
+
/**
|
|
69
|
+
* Body cell content for a row. `rowIndex` is the row's position as shown,
|
|
70
|
+
* after sorting, not its index in `data`.
|
|
71
|
+
*/
|
|
72
|
+
cell: (row: Row, rowIndex: number) => ReactNode;
|
|
73
|
+
/**
|
|
74
|
+
* Text alignment of the header and body cells.
|
|
75
|
+
* @default 'left'
|
|
76
|
+
*/
|
|
77
|
+
align?: 'left' | 'center' | 'right';
|
|
78
|
+
/**
|
|
79
|
+
* Whether clicking the header sorts by this column.
|
|
80
|
+
* @default false
|
|
81
|
+
*/
|
|
82
|
+
sortable?: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* The name the server knows this column by, when it differs from `id`.
|
|
85
|
+
* Handed to `onSortChange` as its second argument.
|
|
86
|
+
* @default id
|
|
87
|
+
*/
|
|
88
|
+
sortKey?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Sorts the rows in the browser while this column is the sorted one.
|
|
91
|
+
* Without it, sorting only reports the new sort through `onSortChange` and
|
|
92
|
+
* the rows are expected to arrive sorted, which is right for server data.
|
|
93
|
+
*
|
|
94
|
+
* Compare ascending; the table reverses the result for `desc`.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* sortFn: (a, b) => a.name.localeCompare(b.name)
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
sortFn?: (a: Row, b: Row) => number;
|
|
102
|
+
/**
|
|
103
|
+
* Starting width in pixels, used until the user resizes the column or
|
|
104
|
+
* `columnState.widths` says otherwise. Columns without one are measured on
|
|
105
|
+
* first layout.
|
|
106
|
+
*/
|
|
107
|
+
width?: number;
|
|
108
|
+
/**
|
|
109
|
+
* Narrowest the user can resize this column to, in pixels. Overrides the
|
|
110
|
+
* table's `minColumnWidth`.
|
|
111
|
+
*/
|
|
112
|
+
minWidth?: number;
|
|
113
|
+
/**
|
|
114
|
+
* Widest the user can resize this column to, in pixels. Overrides the
|
|
115
|
+
* table's `maxColumnWidth`.
|
|
116
|
+
*/
|
|
117
|
+
maxWidth?: number;
|
|
118
|
+
/**
|
|
119
|
+
* Class name, style, background or data attributes for this column's body
|
|
120
|
+
* cell in a given row, such as colouring a cell by its value. Header cells
|
|
121
|
+
* are not affected.
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```ts
|
|
125
|
+
* getCellProps: (row) => ({ background: heatColor(row.score) })
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
getCellProps?: (row: Row, rowIndex: number) => DataTableElementProps;
|
|
129
|
+
/**
|
|
130
|
+
* Whether the user can resize this column, in a table with
|
|
131
|
+
* `resizableColumns`. Turn it off for actions or checkbox columns.
|
|
132
|
+
* @default true
|
|
133
|
+
*/
|
|
134
|
+
resizable?: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Whether the header offers the freeze menu, in a table with
|
|
137
|
+
* `freezeControls`. The column can still be frozen through `columnState`.
|
|
138
|
+
* @default true
|
|
139
|
+
*/
|
|
140
|
+
freezable?: boolean;
|
|
141
|
+
/**
|
|
142
|
+
* Whether the user can move this column, in a table with
|
|
143
|
+
* `reorderableColumns`. A column that cannot move keeps its place, and the
|
|
144
|
+
* others move past it.
|
|
145
|
+
* @default true
|
|
146
|
+
*/
|
|
147
|
+
reorderable?: boolean;
|
|
148
|
+
/**
|
|
149
|
+
* Whether the user can hide this column, from its header menu in a table
|
|
150
|
+
* with `hideableColumns`, or from `DataTableColumnPicker`. The column can
|
|
151
|
+
* still be hidden through `columnState`.
|
|
152
|
+
* @default true
|
|
153
|
+
*/
|
|
154
|
+
hideable?: boolean;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Everything about a {@link DataTable}'s columns the user can change, keyed
|
|
158
|
+
* by column id, so it survives columns being added, removed or reordered.
|
|
159
|
+
* Store it whole to remember a user's layout.
|
|
160
|
+
*/
|
|
161
|
+
export interface DataTableColumnState {
|
|
162
|
+
/**
|
|
163
|
+
* Column ids in display order. Columns missing from it follow, in the
|
|
164
|
+
* order of `columns`.
|
|
165
|
+
*/
|
|
166
|
+
order: string[];
|
|
167
|
+
/** Width in pixels per column id. */
|
|
168
|
+
widths: Record<string, number>;
|
|
169
|
+
/** Column ids frozen to each edge. */
|
|
170
|
+
frozen: {
|
|
171
|
+
start: string[];
|
|
172
|
+
end: string[];
|
|
173
|
+
};
|
|
174
|
+
/** Ids of columns that are not shown. */
|
|
175
|
+
hidden: string[];
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Props of {@link DataTable}.
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```tsx
|
|
182
|
+
* <DataTable data={rows} columns={columns} />
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
export interface DataTableProps<Row> {
|
|
186
|
+
/** Rows to show, in the order to show them unless a column sorts them. */
|
|
187
|
+
data: Row[];
|
|
188
|
+
/**
|
|
189
|
+
* Column definitions. Every `id` must be unique. Need not be memoised:
|
|
190
|
+
* the table only rebuilds its model when the columns' ids or sort settings
|
|
191
|
+
* change, and always renders with the latest `header` and `cell`.
|
|
192
|
+
*/
|
|
193
|
+
columns: DataTableColumn<Row>[];
|
|
194
|
+
/**
|
|
195
|
+
* Stable id of a row, for rows whose id is not in an `id` field, such as
|
|
196
|
+
* `employeeId` or a key built from several fields. Rows are keyed by it
|
|
197
|
+
* and selection and expanded state refer to it.
|
|
198
|
+
*
|
|
199
|
+
* Without it, a row's own `id` (string or number) is used. Rows without
|
|
200
|
+
* either are keyed by position, children under their parent (`"2.0"`),
|
|
201
|
+
* which remounts cells whenever the order changes.
|
|
202
|
+
* @default (row) => String(row.id)
|
|
203
|
+
*/
|
|
204
|
+
getRowId?: (row: Row, index: number) => string;
|
|
205
|
+
/**
|
|
206
|
+
* Column layout, for the controlled case. Partial values are filled in
|
|
207
|
+
* with defaults. Hold it in state and update it from
|
|
208
|
+
* `onColumnStateChange`.
|
|
209
|
+
*/
|
|
210
|
+
columnState?: Partial<DataTableColumnState>;
|
|
211
|
+
/** Starting column layout, for the uncontrolled case. */
|
|
212
|
+
defaultColumnState?: Partial<DataTableColumnState>;
|
|
213
|
+
/**
|
|
214
|
+
* Called whenever the user changes the layout: on every frame of a resize
|
|
215
|
+
* drag, when moving or hiding a column, and when freezing or unfreezing. Not called for widths the table
|
|
216
|
+
* measures itself on first layout.
|
|
217
|
+
*/
|
|
218
|
+
onColumnStateChange?: (columnState: DataTableColumnState) => void;
|
|
219
|
+
/**
|
|
220
|
+
* Lets the user resize columns by dragging the right edge of the header.
|
|
221
|
+
* @default false
|
|
222
|
+
*/
|
|
223
|
+
resizableColumns?: boolean;
|
|
224
|
+
/**
|
|
225
|
+
* How a resize spends width. `fit` keeps the table's width: the resizable
|
|
226
|
+
* columns to the right share the change, in proportion to their widths.
|
|
227
|
+
* `expand` grows or shrinks the table instead, so it scrolls sideways.
|
|
228
|
+
* @default 'fit'
|
|
229
|
+
*/
|
|
230
|
+
columnResizeMode?: ColumnResizeMode;
|
|
231
|
+
/**
|
|
232
|
+
* Narrowest a column can be resized to, in pixels. A column's own
|
|
233
|
+
* `minWidth` wins.
|
|
234
|
+
* @default 64
|
|
235
|
+
*/
|
|
236
|
+
minColumnWidth?: number;
|
|
237
|
+
/**
|
|
238
|
+
* Widest a column can be resized to, in pixels. A column's own `maxWidth`
|
|
239
|
+
* wins. Unbounded when omitted.
|
|
240
|
+
*/
|
|
241
|
+
maxColumnWidth?: number;
|
|
242
|
+
/**
|
|
243
|
+
* Gives every header a menu to freeze its column to either edge.
|
|
244
|
+
* @default false
|
|
245
|
+
*/
|
|
246
|
+
freezeControls?: boolean;
|
|
247
|
+
/**
|
|
248
|
+
* Lets the user move columns: by dragging the grip at the left of the
|
|
249
|
+
* header, or with "Move left" and "Move right" in the header menu. A column
|
|
250
|
+
* moves only among columns frozen to the same edge, or among the unfrozen
|
|
251
|
+
* ones. The order is kept in `columnState.order`.
|
|
252
|
+
* @default false
|
|
253
|
+
*/
|
|
254
|
+
reorderableColumns?: boolean;
|
|
255
|
+
/**
|
|
256
|
+
* Adds "Hide column" to the header menu. The last visible column cannot be
|
|
257
|
+
* hidden. Hidden columns are kept in `columnState.hidden`; bring them back
|
|
258
|
+
* with `DataTableColumnPicker`.
|
|
259
|
+
* @default false
|
|
260
|
+
*/
|
|
261
|
+
hideableColumns?: boolean;
|
|
262
|
+
/**
|
|
263
|
+
* Keeps the header in view while the rows scroll. Give the table a height
|
|
264
|
+
* limit through `maxHeight`.
|
|
265
|
+
* @default false
|
|
266
|
+
*/
|
|
267
|
+
stickyHeader?: boolean;
|
|
268
|
+
/**
|
|
269
|
+
* Tallest the table gets before it scrolls vertically. Any CSS value.
|
|
270
|
+
* Unbounded when omitted, so only horizontal overflow scrolls.
|
|
271
|
+
*/
|
|
272
|
+
maxHeight?: string | number;
|
|
273
|
+
/** Sorted column, for the controlled case. `null` for none. */
|
|
274
|
+
sort?: DataTableSort | null;
|
|
275
|
+
/** Starting sort, for the uncontrolled case. */
|
|
276
|
+
defaultSort?: DataTableSort | null;
|
|
277
|
+
/**
|
|
278
|
+
* Called when a sortable header is clicked. A column starts ascending and
|
|
279
|
+
* toggles between ascending and descending after that. The second argument
|
|
280
|
+
* is the column's `sortKey` (its `id` without one), ready for a request.
|
|
281
|
+
*/
|
|
282
|
+
onSortChange?: (sort: DataTableSort | null, sortKey: string | null) => void;
|
|
283
|
+
/**
|
|
284
|
+
* Marks the table busy. Rows already shown stay, dimmed, so a re-fetch
|
|
285
|
+
* after sorting does not make the table jump; with no rows yet,
|
|
286
|
+
* `loadingState` is shown instead.
|
|
287
|
+
* @default false
|
|
288
|
+
*/
|
|
289
|
+
isLoading?: boolean;
|
|
290
|
+
/**
|
|
291
|
+
* Shown in place of the rows while loading with none to show.
|
|
292
|
+
* @default 'Loading…'
|
|
293
|
+
*/
|
|
294
|
+
loadingState?: ReactNode;
|
|
295
|
+
/**
|
|
296
|
+
* Shown in place of the rows when there are none.
|
|
297
|
+
* @default 'No results'
|
|
298
|
+
*/
|
|
299
|
+
emptyState?: ReactNode;
|
|
300
|
+
/**
|
|
301
|
+
* Called when a row is clicked, or when Enter is pressed on a focused row;
|
|
302
|
+
* rows become focusable when this is set. Clicks on a button, link, input
|
|
303
|
+
* or menu inside the row keep their own behaviour.
|
|
304
|
+
*
|
|
305
|
+
* Screen readers do not announce a row as actionable, so also give the
|
|
306
|
+
* row a link or button in a cell when the action matters.
|
|
307
|
+
*/
|
|
308
|
+
onRowClick?: (row: Row, event: MouseEvent<HTMLTableRowElement> | KeyboardEvent<HTMLTableRowElement>) => void;
|
|
309
|
+
/**
|
|
310
|
+
* Class name, style, background or data attributes for a body row, such as
|
|
311
|
+
* tinting rows that need attention. Each row also carries `data-row-id`.
|
|
312
|
+
*
|
|
313
|
+
* @example
|
|
314
|
+
* ```ts
|
|
315
|
+
* getRowProps: (row) => (row.excluded ? { className: 'excluded' } : {})
|
|
316
|
+
* ```
|
|
317
|
+
*/
|
|
318
|
+
getRowProps?: (row: Row, rowIndex: number) => DataTableElementProps;
|
|
319
|
+
/**
|
|
320
|
+
* Children of a row, shown nested under it, to any depth. Rows with
|
|
321
|
+
* children get an expand button in a column at the start, and their own
|
|
322
|
+
* styling; children are indented. A sorted column sorts the children of
|
|
323
|
+
* each row among themselves.
|
|
324
|
+
*
|
|
325
|
+
* @example
|
|
326
|
+
* ```ts
|
|
327
|
+
* getSubRows: (team) => team.members
|
|
328
|
+
* ```
|
|
329
|
+
*/
|
|
330
|
+
getSubRows?: (row: Row) => Row[] | undefined;
|
|
331
|
+
/** Ids of the expanded rows, for the controlled case. */
|
|
332
|
+
expandedRowIds?: string[];
|
|
333
|
+
/**
|
|
334
|
+
* Which rows start expanded, for the uncontrolled case: `true` for all,
|
|
335
|
+
* including rows that arrive later, or a list of ids.
|
|
336
|
+
* @default false
|
|
337
|
+
*/
|
|
338
|
+
defaultExpanded?: boolean | string[];
|
|
339
|
+
/** Called with the ids of the expanded rows whenever the user changes them. */
|
|
340
|
+
onExpandedChange?: (expandedRowIds: string[]) => void;
|
|
341
|
+
/**
|
|
342
|
+
* Lets the user select rows: `multiple` adds a checkbox column whose header
|
|
343
|
+
* checkbox selects or clears the rows shown, `single` a radio column.
|
|
344
|
+
* With `getSubRows`, selecting a row selects everything under it, and a
|
|
345
|
+
* row with some of its children selected shows a partial check.
|
|
346
|
+
* Selection is kept as row ids (see `getRowId`), so rows selected on
|
|
347
|
+
* another page stay selected.
|
|
348
|
+
* @default 'none'
|
|
349
|
+
*/
|
|
350
|
+
selectionMode?: DataTableSelectionMode;
|
|
351
|
+
/** Ids of the selected rows, for the controlled case. */
|
|
352
|
+
selectedRowIds?: string[];
|
|
353
|
+
/** Ids of the rows selected at first, for the uncontrolled case. */
|
|
354
|
+
defaultSelectedRowIds?: string[];
|
|
355
|
+
/** Called with the ids of the selected rows whenever the user changes them. */
|
|
356
|
+
onSelectionChange?: (selectedRowIds: string[]) => void;
|
|
357
|
+
/**
|
|
358
|
+
* Whether a row can be selected. Rows that cannot get a disabled checkbox
|
|
359
|
+
* and are skipped by the header checkbox.
|
|
360
|
+
*
|
|
361
|
+
* With `getSubRows`, a row that cannot be selected but has rows below it
|
|
362
|
+
* that can keeps an enabled checkbox, which selects those rows. Its own id
|
|
363
|
+
* is never in the selection, even when its checkbox shows checked.
|
|
364
|
+
*/
|
|
365
|
+
isRowSelectable?: (row: Row) => boolean;
|
|
366
|
+
/**
|
|
367
|
+
* Accessible name of a row's selection checkbox, such as the person's
|
|
368
|
+
* name. Without it the row is named by its position.
|
|
369
|
+
* @default (row, rowIndex) => `Select row ${rowIndex + 1}`
|
|
370
|
+
*/
|
|
371
|
+
getRowLabel?: (row: Row, rowIndex: number) => string;
|
|
372
|
+
/** Rendered below the table, such as `Pagination`. */
|
|
373
|
+
footer?: ReactNode;
|
|
374
|
+
/** Class name of the outer container. */
|
|
375
|
+
className?: string;
|
|
376
|
+
/** Forwarded to the `table` element. */
|
|
377
|
+
ref?: Ref<HTMLTableElement>;
|
|
378
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { PointerEvent, RefObject } from 'react';
|
|
2
|
+
/** A drag in progress: the column held, and the column it would drop on. */
|
|
3
|
+
export interface ColumnDrag {
|
|
4
|
+
id: string;
|
|
5
|
+
overId: string | null;
|
|
6
|
+
}
|
|
7
|
+
interface UseColumnReorderOptions {
|
|
8
|
+
tableRef: RefObject<HTMLTableElement | null>;
|
|
9
|
+
/** Whether `id` may be dropped where `targetId` is. */
|
|
10
|
+
canDrop: (id: string, targetId: string) => boolean;
|
|
11
|
+
onDrop: (id: string, targetId: string) => void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Drag-to-reorder for header grips. The pointer is captured by the grip, and
|
|
15
|
+
* the drop target is whichever header cell is under it horizontally, so the
|
|
16
|
+
* pointer can wander above or below the header. Escape cancels.
|
|
17
|
+
*
|
|
18
|
+
* State changes only when the target does, not on every move, so a drag
|
|
19
|
+
* re-renders the table a handful of times rather than once per frame.
|
|
20
|
+
*/
|
|
21
|
+
export declare const useColumnReorder: ({ tableRef, canDrop, onDrop, }: UseColumnReorderOptions) => {
|
|
22
|
+
drag: ColumnDrag | null;
|
|
23
|
+
getGripProps: (id: string) => {
|
|
24
|
+
onPointerDown: (event: PointerEvent<HTMLElement>) => void;
|
|
25
|
+
onPointerMove: (event: PointerEvent<HTMLElement>) => void;
|
|
26
|
+
onPointerUp: () => void;
|
|
27
|
+
onPointerCancel: () => void;
|
|
28
|
+
onLostPointerCapture: () => void;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { DataTableColumn, DataTableColumnState, DataTableSort } from './types';
|
|
2
|
+
interface UseDataTableModelOptions<Row> {
|
|
3
|
+
data: Row[];
|
|
4
|
+
columns: DataTableColumn<Row>[];
|
|
5
|
+
getRowId?: (row: Row, index: number) => string;
|
|
6
|
+
getSubRows?: (row: Row) => Row[] | undefined;
|
|
7
|
+
/** Ids of the expanded rows, or `true` for all of them. */
|
|
8
|
+
expanded: true | string[];
|
|
9
|
+
columnState: DataTableColumnState;
|
|
10
|
+
sort: DataTableSort | null;
|
|
11
|
+
}
|
|
12
|
+
/** A visible row, in display order, with what rendering needs. */
|
|
13
|
+
export interface DataTableModelRow<Row> {
|
|
14
|
+
id: string;
|
|
15
|
+
original: Row;
|
|
16
|
+
/** 0 for a top-level row, 1 for its children, and so on. */
|
|
17
|
+
depth: number;
|
|
18
|
+
hasChildren: boolean;
|
|
19
|
+
isExpanded: boolean;
|
|
20
|
+
}
|
|
21
|
+
/** Where a row sits in the tree, expanded or not. */
|
|
22
|
+
export interface DataTableTreeNode<Row> {
|
|
23
|
+
original: Row;
|
|
24
|
+
parentId?: string;
|
|
25
|
+
childIds: string[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Turns the public props into rows and columns in display order. The only
|
|
29
|
+
* place TanStack Table is used, so it never reaches the public API.
|
|
30
|
+
*/
|
|
31
|
+
export declare const useDataTableModel: <Row>({ data, columns, getRowId, getSubRows, expanded, columnState, sort, }: UseDataTableModelOptions<Row>) => {
|
|
32
|
+
visibleColumns: DataTableColumn<Row>[];
|
|
33
|
+
rows: DataTableModelRow<Row>[];
|
|
34
|
+
tree: Map<string, DataTableTreeNode<Row>>;
|
|
35
|
+
};
|
|
36
|
+
export {};
|