@vueye-table/core 3.0.0-alpha.1
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/LICENSE +21 -0
- package/README.md +30 -0
- package/dist/index.d.ts +554 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1207 -0
- package/dist/index.js.map +1 -0
- package/package.json +53 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Brahim Boussadjra and vueye-table contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# @vueye-table/core
|
|
2
|
+
|
|
3
|
+
The framework-independent engine behind vueye-table: typed column definitions, searching,
|
|
4
|
+
filtering, stable multi-column sorting, pagination, selection, column visibility and order,
|
|
5
|
+
editing with undo, spreadsheet addressing, clipboard text, and CSV export. No DOM, no Node.js,
|
|
6
|
+
no framework.
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
pnpm add @vueye-table/core
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { createTable } from "@vueye-table/core";
|
|
14
|
+
|
|
15
|
+
const table = createTable({
|
|
16
|
+
data: users,
|
|
17
|
+
columns: [
|
|
18
|
+
{ id: "name.first", header: "First name" },
|
|
19
|
+
{ id: "age", align: "end" },
|
|
20
|
+
],
|
|
21
|
+
initialState: { pagination: { page: 1, pageSize: 20 } },
|
|
22
|
+
onStateChange: (state) => console.log(state.sorting),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
table.search("ada");
|
|
26
|
+
table.toggleSort("age");
|
|
27
|
+
const { rows, pageCount, issues } = table.getSnapshot();
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
See the [repository README](https://github.com/boussadjra/vueye-table#readme) for every layer.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,554 @@
|
|
|
1
|
+
//#region src/path.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Dotted property paths.
|
|
4
|
+
*
|
|
5
|
+
* A column addresses nested data with a path such as `"address.city"`. The types below give every
|
|
6
|
+
* such path its value type, and the functions read and write through a path without mutating.
|
|
7
|
+
*/
|
|
8
|
+
type Leaf = string | number | boolean | bigint | symbol | null | undefined | Date | readonly unknown[] | ((...args: never[]) => unknown);
|
|
9
|
+
type Depth = [never, 0, 1, 2, 3];
|
|
10
|
+
/** Every dotted path into `T`, four levels deep. Arrays, dates, and functions are leaves. */
|
|
11
|
+
type DeepKeys<T, TDepth extends number = 4> = [TDepth] extends [never] ? never : T extends Leaf ? never : { [K in keyof T & string]: K | (NonNullable<T[K]> extends Leaf ? never : `${K}.${DeepKeys<NonNullable<T[K]>, Depth[TDepth]>}`); }[keyof T & string];
|
|
12
|
+
/** The value found at `TPath` in `T`. A nullable step makes the result possibly `undefined`. */
|
|
13
|
+
type PathValue<T, TPath extends string> = TPath extends `${infer THead}.${infer TRest}` ? THead extends keyof T ? PathValue<NonNullable<T[THead]>, TRest> | (undefined extends T[THead] ? undefined : never) : undefined : TPath extends keyof T ? T[TPath] : undefined;
|
|
14
|
+
/** Read the value at a dotted path, or `undefined` when a step is missing. */
|
|
15
|
+
declare function getPath(source: unknown, path: string): unknown;
|
|
16
|
+
/**
|
|
17
|
+
* Return a copy of `source` with `value` at `path`. Only the objects along the path are copied;
|
|
18
|
+
* everything else is shared. Missing steps are created as plain objects.
|
|
19
|
+
*/
|
|
20
|
+
declare function setPath<T>(source: T, path: string, value: unknown): T;
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/column.d.ts
|
|
23
|
+
type ColumnAlign = "start" | "center" | "end";
|
|
24
|
+
/** How typed or pasted text becomes a value when a column has no `parse`. */
|
|
25
|
+
type ColumnType = "text" | "number" | "boolean" | "date";
|
|
26
|
+
/** A range filter value, inclusive at both ends. Either end may be left open. */
|
|
27
|
+
interface RangeFilter {
|
|
28
|
+
readonly min?: number | string | Date | undefined;
|
|
29
|
+
readonly max?: number | string | Date | undefined;
|
|
30
|
+
}
|
|
31
|
+
/** Options shared by path columns and computed columns. */
|
|
32
|
+
interface ColumnOptions<TRow, TValue> {
|
|
33
|
+
/** Header text. Defaults to the id made readable: `"createdAt"` becomes `"Created at"`. */
|
|
34
|
+
readonly header?: string | undefined;
|
|
35
|
+
readonly align?: ColumnAlign | undefined;
|
|
36
|
+
/** Width in pixels. */
|
|
37
|
+
readonly width?: number | undefined;
|
|
38
|
+
readonly minWidth?: number | undefined;
|
|
39
|
+
/** Whether a user may sort by this column. Defaults to `true`. */
|
|
40
|
+
readonly sortable?: boolean | undefined;
|
|
41
|
+
/** Whether the free-text search looks at this column. Defaults to `true`. */
|
|
42
|
+
readonly searchable?: boolean | undefined;
|
|
43
|
+
/** Hidden until a user shows it. */
|
|
44
|
+
readonly hidden?: boolean | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* How text becomes a value. Defaults to the type of the cell's current value, or of another
|
|
47
|
+
* row's value when the cell is empty.
|
|
48
|
+
*/
|
|
49
|
+
readonly type?: ColumnType | undefined;
|
|
50
|
+
/** Whether cells of this column accept edits. A function decides per row. */
|
|
51
|
+
readonly editable?: boolean | ((row: TRow) => boolean) | undefined;
|
|
52
|
+
/** Order two values; the engine flips the sign for descending sorts. */
|
|
53
|
+
readonly compare?: ((left: TValue, right: TValue) => number) | undefined;
|
|
54
|
+
/** Decide whether a row passes this column's filter value. */
|
|
55
|
+
readonly filter?: ((value: TValue, filterValue: unknown, row: TRow) => boolean) | undefined;
|
|
56
|
+
/** Turn a value into the text a cell shows, searches, copies, and exports. */
|
|
57
|
+
readonly format?: ((value: TValue, row: TRow) => string) | undefined;
|
|
58
|
+
/**
|
|
59
|
+
* Turn typed or pasted text into a value. Throw to reject the input. Defaults to reading the
|
|
60
|
+
* column's `type`.
|
|
61
|
+
*/
|
|
62
|
+
readonly parse?: ((input: string, row: TRow) => TValue) | undefined;
|
|
63
|
+
/** Free-form data for renderers. The engine never reads it. */
|
|
64
|
+
readonly meta?: Readonly<Record<string, unknown>> | undefined;
|
|
65
|
+
}
|
|
66
|
+
/** A column that reads `row[id]`, following dots into nested objects. */
|
|
67
|
+
interface PathColumnDef<TRow, TPath extends string> extends ColumnOptions<TRow, PathValue<TRow, TPath>> {
|
|
68
|
+
readonly id: TPath;
|
|
69
|
+
readonly accessor?: undefined;
|
|
70
|
+
readonly setValue?: undefined;
|
|
71
|
+
}
|
|
72
|
+
/** A column whose value is computed from the row. It is editable only with `setValue`. */
|
|
73
|
+
interface ComputedColumnDef<TRow, TValue = unknown> extends ColumnOptions<TRow, TValue> {
|
|
74
|
+
readonly id: string;
|
|
75
|
+
readonly accessor: (row: TRow) => TValue;
|
|
76
|
+
/** Return a copy of `row` carrying `value`. Without it the column is read-only. */
|
|
77
|
+
readonly setValue?: ((row: TRow, value: TValue) => TRow) | undefined;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* One column definition. A path column is discriminated by its literal id, so `format`,
|
|
81
|
+
* `compare`, and `parse` receive the value type found at that path.
|
|
82
|
+
*/
|
|
83
|
+
type ColumnDef<TRow> = { [TPath in DeepKeys<TRow>]: PathColumnDef<TRow, TPath>; }[DeepKeys<TRow>] | ComputedColumnDef<TRow, any>;
|
|
84
|
+
/**
|
|
85
|
+
* A column definition for any row type, for props and containers that accept every table.
|
|
86
|
+
*/
|
|
87
|
+
type AnyColumnDef = ColumnDef<any>;
|
|
88
|
+
/** Declare columns for a row type with full inference, outside a table. */
|
|
89
|
+
declare function defineColumns<TRow>(columns: readonly ColumnDef<TRow>[]): readonly ColumnDef<TRow>[];
|
|
90
|
+
/**
|
|
91
|
+
* A column resolved against its defaults. Renderers read these; they never read definitions.
|
|
92
|
+
*/
|
|
93
|
+
interface TableColumn<TRow> {
|
|
94
|
+
readonly id: string;
|
|
95
|
+
readonly header: string;
|
|
96
|
+
readonly align: ColumnAlign;
|
|
97
|
+
readonly width: number | undefined;
|
|
98
|
+
readonly minWidth: number | undefined;
|
|
99
|
+
readonly sortable: boolean;
|
|
100
|
+
readonly searchable: boolean;
|
|
101
|
+
readonly initiallyHidden: boolean;
|
|
102
|
+
readonly meta: Readonly<Record<string, unknown>>;
|
|
103
|
+
readonly definition: ColumnDef<TRow>;
|
|
104
|
+
getValue(row: TRow): unknown;
|
|
105
|
+
format(value: unknown, row: TRow): string;
|
|
106
|
+
compare(left: unknown, right: unknown): number;
|
|
107
|
+
matches(value: unknown, filterValue: unknown, row: TRow): boolean;
|
|
108
|
+
isEditable(row: TRow): boolean;
|
|
109
|
+
/**
|
|
110
|
+
* Parse text into a value, or report why it could not be read. `sample` is a value from another
|
|
111
|
+
* row, used to tell the column's type when this cell is empty.
|
|
112
|
+
*/
|
|
113
|
+
parse(input: string, row: TRow, sample?: unknown): ParseResult;
|
|
114
|
+
/** Return a copy of `row` carrying `value`, or `undefined` for a read-only column. */
|
|
115
|
+
setValue(row: TRow, value: unknown): TRow | undefined;
|
|
116
|
+
}
|
|
117
|
+
/** The outcome of reading text into a cell value. */
|
|
118
|
+
type ParseResult = {
|
|
119
|
+
readonly ok: true;
|
|
120
|
+
readonly value: unknown;
|
|
121
|
+
} | {
|
|
122
|
+
readonly ok: false;
|
|
123
|
+
readonly message: string;
|
|
124
|
+
};
|
|
125
|
+
/** Order any two values: empty last, then numbers, dates, booleans, and text naturally. */
|
|
126
|
+
declare function compareValues(left: unknown, right: unknown): number;
|
|
127
|
+
/**
|
|
128
|
+
* Text for a value: empty for `null` and `undefined`, ISO for dates, comma-joined for arrays, and
|
|
129
|
+
* JSON for other objects. The result never depends on the runtime's locale, so server and client
|
|
130
|
+
* render the same text.
|
|
131
|
+
*/
|
|
132
|
+
declare function formatValue(value: unknown): string;
|
|
133
|
+
/**
|
|
134
|
+
* The default column filter:
|
|
135
|
+
*
|
|
136
|
+
* - an empty filter value (`undefined`, `null`, `""`, `[]`) lets every row through;
|
|
137
|
+
* - an array keeps rows whose value is one of its items;
|
|
138
|
+
* - `{ min, max }` keeps values inside the inclusive range; a bound given as text is read as a
|
|
139
|
+
* number or a date when the value is one, and an empty bound leaves that end open;
|
|
140
|
+
* - text keeps rows whose shown text contains it, ignoring case;
|
|
141
|
+
* - anything else keeps rows whose value is identical.
|
|
142
|
+
*/
|
|
143
|
+
declare function matchesFilter(value: unknown, filterValue: unknown, display: string): boolean;
|
|
144
|
+
/** The column type a value suggests, or `undefined` for an empty value. */
|
|
145
|
+
declare function typeOf(value: unknown): ColumnType | undefined;
|
|
146
|
+
/** Read text as a column type. Empty text is `null` for every type but text. */
|
|
147
|
+
declare function parseAs(input: string, type: ColumnType): ParseResult;
|
|
148
|
+
/** Resolve a definition against its defaults. */
|
|
149
|
+
declare function resolveColumn<TRow>(definition: ColumnDef<TRow>): TableColumn<TRow>;
|
|
150
|
+
//#endregion
|
|
151
|
+
//#region src/delimited.d.ts
|
|
152
|
+
/** Write a matrix of text as delimited lines joined with `\n`. */
|
|
153
|
+
declare function toDelimited(matrix: readonly (readonly string[])[], delimiter?: string): string;
|
|
154
|
+
/**
|
|
155
|
+
* Read delimited text into a matrix. Accepts `\n` and `\r\n`, quoted fields with doubled quotes
|
|
156
|
+
* and embedded line breaks, and ignores one trailing line break.
|
|
157
|
+
*/
|
|
158
|
+
declare function parseDelimited(text: string, delimiter?: string): string[][];
|
|
159
|
+
//#endregion
|
|
160
|
+
//#region src/grid.d.ts
|
|
161
|
+
/**
|
|
162
|
+
* Spreadsheet addressing and selection.
|
|
163
|
+
*
|
|
164
|
+
* A cell is addressed by its position in what is shown: the row index on the current page and the
|
|
165
|
+
* column index among visible columns. A selection is an anchor, where it started, and a focus,
|
|
166
|
+
* where it is now; the rectangle between them is the selected range.
|
|
167
|
+
*/
|
|
168
|
+
interface CellPosition {
|
|
169
|
+
readonly row: number;
|
|
170
|
+
readonly column: number;
|
|
171
|
+
}
|
|
172
|
+
interface CellRange {
|
|
173
|
+
readonly top: number;
|
|
174
|
+
readonly left: number;
|
|
175
|
+
readonly bottom: number;
|
|
176
|
+
readonly right: number;
|
|
177
|
+
}
|
|
178
|
+
interface GridSelection {
|
|
179
|
+
readonly anchor: CellPosition;
|
|
180
|
+
readonly focus: CellPosition;
|
|
181
|
+
}
|
|
182
|
+
/** The size of the addressable grid. */
|
|
183
|
+
interface GridBounds {
|
|
184
|
+
readonly rows: number;
|
|
185
|
+
readonly columns: number;
|
|
186
|
+
}
|
|
187
|
+
type GridDirection = "up" | "down" | "left" | "right";
|
|
188
|
+
interface MoveOptions {
|
|
189
|
+
/** Keep the anchor and move only the focus, growing or shrinking the range. */
|
|
190
|
+
readonly extend?: boolean | undefined;
|
|
191
|
+
/** Jump to the edge of the grid in that direction. */
|
|
192
|
+
readonly toEdge?: boolean | undefined;
|
|
193
|
+
}
|
|
194
|
+
declare function clampPosition(position: CellPosition, bounds: GridBounds): CellPosition;
|
|
195
|
+
/** A selection of one cell. */
|
|
196
|
+
declare function selectCell(position: CellPosition): GridSelection;
|
|
197
|
+
/** Move the focus one step, or to the edge, staying inside the bounds. */
|
|
198
|
+
declare function moveSelection(selection: GridSelection, direction: GridDirection, bounds: GridBounds, options?: MoveOptions): GridSelection;
|
|
199
|
+
/** The rectangle a selection covers. */
|
|
200
|
+
declare function selectionRange(selection: GridSelection): CellRange;
|
|
201
|
+
declare function rangeContains(range: CellRange, position: CellPosition): boolean;
|
|
202
|
+
/** `0` is `"A"`, `25` is `"Z"`, `26` is `"AA"`. */
|
|
203
|
+
declare function columnLabel(index: number): string;
|
|
204
|
+
/** `{ row: 2, column: 1 }` is `"B3"`. */
|
|
205
|
+
declare function toA1(position: CellPosition): string;
|
|
206
|
+
/** `"B3"` is `{ row: 2, column: 1 }`. Returns `undefined` for anything else. */
|
|
207
|
+
declare function fromA1(reference: string): CellPosition | undefined;
|
|
208
|
+
/** The keys of a keyboard event that grid navigation reads. */
|
|
209
|
+
interface GridKey {
|
|
210
|
+
readonly key: string;
|
|
211
|
+
readonly shiftKey?: boolean | undefined;
|
|
212
|
+
readonly ctrlKey?: boolean | undefined;
|
|
213
|
+
readonly metaKey?: boolean | undefined;
|
|
214
|
+
readonly altKey?: boolean | undefined;
|
|
215
|
+
}
|
|
216
|
+
/** What a key press asks a grid to do while no cell is being edited. */
|
|
217
|
+
type GridCommand = {
|
|
218
|
+
readonly type: "move";
|
|
219
|
+
readonly direction: GridDirection;
|
|
220
|
+
readonly options: MoveOptions;
|
|
221
|
+
} | {
|
|
222
|
+
readonly type: "edit";
|
|
223
|
+
readonly initial?: string | undefined;
|
|
224
|
+
} | {
|
|
225
|
+
readonly type: "clear";
|
|
226
|
+
} | {
|
|
227
|
+
readonly type: "selectAll";
|
|
228
|
+
} | {
|
|
229
|
+
readonly type: "undo";
|
|
230
|
+
} | {
|
|
231
|
+
readonly type: "redo";
|
|
232
|
+
} | {
|
|
233
|
+
readonly type: "cancel";
|
|
234
|
+
};
|
|
235
|
+
/**
|
|
236
|
+
* Map a key press to a grid command, spreadsheet style: arrows move (Shift extends, Ctrl or Cmd
|
|
237
|
+
* jumps to the edge), Tab moves across, Home and End reach the row's ends, Enter or F2 edit,
|
|
238
|
+
* a printable character starts editing with that character, Delete and Backspace clear, Escape
|
|
239
|
+
* collapses the selection, and Ctrl or Cmd with A, Z, Y select all, undo, and redo.
|
|
240
|
+
*/
|
|
241
|
+
declare function gridCommand(event: GridKey): GridCommand | undefined;
|
|
242
|
+
//#endregion
|
|
243
|
+
//#region src/undo-stack.d.ts
|
|
244
|
+
/**
|
|
245
|
+
* An undo stack of batches. Recording a batch clears whatever could be redone, and the stack
|
|
246
|
+
* keeps at most `limit` batches, dropping the oldest.
|
|
247
|
+
*/
|
|
248
|
+
interface UndoStack<TEntry> {
|
|
249
|
+
readonly canUndo: boolean;
|
|
250
|
+
readonly canRedo: boolean;
|
|
251
|
+
record(entry: TEntry): void;
|
|
252
|
+
/** Take the most recent batch to undo, if any. */
|
|
253
|
+
undo(): TEntry | undefined;
|
|
254
|
+
/** Take the most recently undone batch to redo, if any. */
|
|
255
|
+
redo(): TEntry | undefined;
|
|
256
|
+
clear(): void;
|
|
257
|
+
}
|
|
258
|
+
declare function createUndoStack<TEntry>(limit?: number): UndoStack<TEntry>;
|
|
259
|
+
//#endregion
|
|
260
|
+
//#region src/humanize.d.ts
|
|
261
|
+
/**
|
|
262
|
+
* Turn a column id into a readable header: `"name.first_name"` becomes `"Name first name"` and
|
|
263
|
+
* `"createdAt"` becomes `"Created at"`.
|
|
264
|
+
*/
|
|
265
|
+
declare function humanize(id: string): string;
|
|
266
|
+
//#endregion
|
|
267
|
+
//#region src/infer.d.ts
|
|
268
|
+
/**
|
|
269
|
+
* Columns for data that has none declared: one path column per leaf of the first `sample` rows,
|
|
270
|
+
* nested objects flattened into dotted paths, in first-seen order.
|
|
271
|
+
*/
|
|
272
|
+
declare function inferColumns<TRow>(rows: readonly TRow[], sample?: number): readonly ColumnDef<TRow>[];
|
|
273
|
+
//#endregion
|
|
274
|
+
//#region src/state.d.ts
|
|
275
|
+
/** A stable identity for a row, read from the row itself or produced by a function. */
|
|
276
|
+
type RowKey = string | number;
|
|
277
|
+
type SortDirection = "asc" | "desc";
|
|
278
|
+
/** One level of a sort. Several rules sort by the first, then break ties with the next. */
|
|
279
|
+
interface SortRule {
|
|
280
|
+
readonly column: string;
|
|
281
|
+
readonly direction: SortDirection;
|
|
282
|
+
}
|
|
283
|
+
/** Pages are counted from 1. */
|
|
284
|
+
interface PaginationState {
|
|
285
|
+
readonly page: number;
|
|
286
|
+
readonly pageSize: number;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Everything a user can change about a table, as plain serializable data.
|
|
290
|
+
*
|
|
291
|
+
* Being plain data, the state can be stored, restored, sent to a server that sorts and pages, or
|
|
292
|
+
* written to the URL with a library such as QueryWeave.
|
|
293
|
+
*/
|
|
294
|
+
interface TableState {
|
|
295
|
+
readonly sorting: readonly SortRule[];
|
|
296
|
+
/** Free text matched against every searchable column. */
|
|
297
|
+
readonly search: string;
|
|
298
|
+
/** Filter value per column id, interpreted by that column's `filter`. */
|
|
299
|
+
readonly filters: Readonly<Record<string, unknown>>;
|
|
300
|
+
readonly pagination: PaginationState;
|
|
301
|
+
readonly selection: readonly RowKey[];
|
|
302
|
+
readonly hiddenColumns: readonly string[];
|
|
303
|
+
/** Column ids in display order. Columns missing from the list keep their definition order. */
|
|
304
|
+
readonly columnOrder: readonly string[];
|
|
305
|
+
}
|
|
306
|
+
/** A partial state, as accepted by `setState` and `initialState`. */
|
|
307
|
+
type TableStatePatch = { readonly [K in keyof TableState]?: TableState[K] | undefined; };
|
|
308
|
+
declare const DEFAULT_PAGE_SIZE = 10;
|
|
309
|
+
//#endregion
|
|
310
|
+
//#region src/issues.d.ts
|
|
311
|
+
/** Every problem the engine can report. The union grows in minor versions. */
|
|
312
|
+
type TableIssueCode = "duplicate_row_key" | "unknown_column" | "invalid_page_size" | "unknown_row" | "read_only_cell" | "invalid_value";
|
|
313
|
+
/**
|
|
314
|
+
* A problem the engine recovered from. Invalid input is never dropped silently: the engine falls
|
|
315
|
+
* back to something safe and reports what it did here.
|
|
316
|
+
*/
|
|
317
|
+
interface TableIssue {
|
|
318
|
+
readonly code: TableIssueCode;
|
|
319
|
+
readonly message: string;
|
|
320
|
+
readonly column?: string | undefined;
|
|
321
|
+
readonly rowKey?: RowKey | undefined;
|
|
322
|
+
}
|
|
323
|
+
//#endregion
|
|
324
|
+
//#region src/row.d.ts
|
|
325
|
+
/**
|
|
326
|
+
* One row of data as the engine sees it: its key, its position in the source data, and cached
|
|
327
|
+
* access to each column's value and text.
|
|
328
|
+
*/
|
|
329
|
+
interface TableRow<TRow> {
|
|
330
|
+
readonly key: RowKey;
|
|
331
|
+
/** Position in the data the table was given. */
|
|
332
|
+
readonly index: number;
|
|
333
|
+
readonly original: TRow;
|
|
334
|
+
getValue(columnId: string): unknown;
|
|
335
|
+
/** The formatted text of a cell, as shown, searched, copied, and exported. */
|
|
336
|
+
getDisplay(columnId: string): string;
|
|
337
|
+
}
|
|
338
|
+
//#endregion
|
|
339
|
+
//#region src/pipeline.d.ts
|
|
340
|
+
/**
|
|
341
|
+
* Keep rows that pass every column filter and contain every search term in at least one
|
|
342
|
+
* searchable column.
|
|
343
|
+
*/
|
|
344
|
+
declare function filterRows<TRow>(rows: readonly TableRow<TRow>[], columns: readonly TableColumn<TRow>[], search: string, filters: Readonly<Record<string, unknown>>): readonly TableRow<TRow>[];
|
|
345
|
+
/** Sort rows by each rule in turn. The sort is stable: ties keep their incoming order. */
|
|
346
|
+
declare function sortRows<TRow>(rows: readonly TableRow<TRow>[], columns: readonly TableColumn<TRow>[], sorting: readonly SortRule[]): readonly TableRow<TRow>[];
|
|
347
|
+
/** The number of pages for a row count. An empty table still has one page. */
|
|
348
|
+
declare function countPages(rowCount: number, pageSize: number): number;
|
|
349
|
+
/** Clamp a page into `1..pageCount`. */
|
|
350
|
+
declare function clampPage(page: number, pageCount: number): number;
|
|
351
|
+
/** The rows on one page. `pagination.page` must already be clamped. */
|
|
352
|
+
declare function paginateRows<TRow>(rows: readonly TableRow<TRow>[], pagination: PaginationState): readonly TableRow<TRow>[];
|
|
353
|
+
/** A page number, or a gap between page numbers. */
|
|
354
|
+
type PageItem = {
|
|
355
|
+
readonly type: "page";
|
|
356
|
+
readonly page: number;
|
|
357
|
+
readonly current: boolean;
|
|
358
|
+
} | {
|
|
359
|
+
readonly type: "gap";
|
|
360
|
+
readonly key: string;
|
|
361
|
+
};
|
|
362
|
+
/**
|
|
363
|
+
* The page buttons to show: always the first and last page, `siblings` pages on each side of the
|
|
364
|
+
* current one, and a gap wherever pages are skipped. A gap never hides a single page.
|
|
365
|
+
*/
|
|
366
|
+
declare function paginationItems(page: number, pageCount: number, siblings?: number): readonly PageItem[];
|
|
367
|
+
//#endregion
|
|
368
|
+
//#region src/table.d.ts
|
|
369
|
+
type SelectionMode = "none" | "single" | "multiple";
|
|
370
|
+
/** Which rows "select all" covers: the current page, or every row that passes the filters. */
|
|
371
|
+
type SelectScope = "page" | "all";
|
|
372
|
+
interface TableOptions<TRow> {
|
|
373
|
+
readonly data: readonly TRow[];
|
|
374
|
+
readonly columns: readonly ColumnDef<TRow>[];
|
|
375
|
+
/**
|
|
376
|
+
* How to identify a row: a path into it, or a function. Defaults to `id` when rows have one and
|
|
377
|
+
* to the row's position otherwise.
|
|
378
|
+
*/
|
|
379
|
+
readonly rowKey?: DeepKeys<TRow> | ((row: TRow, index: number) => RowKey) | undefined;
|
|
380
|
+
readonly initialState?: TableStatePatch | undefined;
|
|
381
|
+
/** Defaults to `"multiple"`. */
|
|
382
|
+
readonly selectionMode?: SelectionMode | undefined;
|
|
383
|
+
/** Defaults to `"all"`. */
|
|
384
|
+
readonly selectScope?: SelectScope | undefined;
|
|
385
|
+
/**
|
|
386
|
+
* The data is one page that a server has already searched, filtered, sorted, and paginated
|
|
387
|
+
* with the current state. The table only presents it; `rowCount` gives the total.
|
|
388
|
+
*/
|
|
389
|
+
readonly manual?: boolean | undefined;
|
|
390
|
+
/** The total number of rows across all pages, for `manual` tables. */
|
|
391
|
+
readonly rowCount?: number | undefined;
|
|
392
|
+
/** Called after every state change a table operation makes, not after `setState`. */
|
|
393
|
+
readonly onStateChange?: ((state: TableState, previous: TableState) => void) | undefined;
|
|
394
|
+
/** Called with the new data after an edit, a paste, an undo, or a redo. */
|
|
395
|
+
readonly onDataChange?: ((data: readonly TRow[], changes: readonly CellChange<TRow>[]) => void) | undefined;
|
|
396
|
+
/** Called with the reasons whenever an edit, a paste, or a clear refuses some cells. */
|
|
397
|
+
readonly onEditIssues?: ((issues: readonly TableIssue[]) => void) | undefined;
|
|
398
|
+
/** The most edit batches `undo` can reach. Defaults to 100. */
|
|
399
|
+
readonly historyLimit?: number | undefined;
|
|
400
|
+
}
|
|
401
|
+
type SelectionCoverage = "none" | "some" | "all";
|
|
402
|
+
interface SortInfo {
|
|
403
|
+
readonly direction: SortDirection;
|
|
404
|
+
/** 0 for the first rule, 1 for the next, and so on. */
|
|
405
|
+
readonly priority: number;
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Everything a renderer needs, computed from the data, the columns, and the state. A snapshot is
|
|
409
|
+
* frozen and replaced on each change, so comparing snapshots by identity detects a change.
|
|
410
|
+
*/
|
|
411
|
+
interface TableSnapshot<TRow> {
|
|
412
|
+
readonly state: TableState;
|
|
413
|
+
/** Visible columns in display order. */
|
|
414
|
+
readonly columns: readonly TableColumn<TRow>[];
|
|
415
|
+
/** Every column in display order, hidden ones included. */
|
|
416
|
+
readonly allColumns: readonly TableColumn<TRow>[];
|
|
417
|
+
/** Rows on the current page. */
|
|
418
|
+
readonly rows: readonly TableRow<TRow>[];
|
|
419
|
+
/** Rows on every page, filtered and sorted. For `manual` tables this is the current page. */
|
|
420
|
+
readonly processedRows: readonly TableRow<TRow>[];
|
|
421
|
+
/** The current page, clamped into range. */
|
|
422
|
+
readonly page: number;
|
|
423
|
+
readonly pageSize: number;
|
|
424
|
+
readonly pageCount: number;
|
|
425
|
+
/** Rows that pass the search and filters. */
|
|
426
|
+
readonly rowCount: number;
|
|
427
|
+
/** Rows before searching and filtering. */
|
|
428
|
+
readonly totalRowCount: number;
|
|
429
|
+
/** The 1-based position of the first row on this page, or 0 when there are no rows. */
|
|
430
|
+
readonly pageStart: number;
|
|
431
|
+
/** The 1-based position of the last row on this page, or 0 when there are no rows. */
|
|
432
|
+
readonly pageEnd: number;
|
|
433
|
+
readonly pageItems: readonly PageItem[];
|
|
434
|
+
readonly canPreviousPage: boolean;
|
|
435
|
+
readonly canNextPage: boolean;
|
|
436
|
+
readonly selectionMode: SelectionMode;
|
|
437
|
+
readonly selectedCount: number;
|
|
438
|
+
/** How much of the current page is selected. */
|
|
439
|
+
readonly pageSelection: SelectionCoverage;
|
|
440
|
+
/** How much of the select-all scope is selected. */
|
|
441
|
+
readonly allSelection: SelectionCoverage;
|
|
442
|
+
readonly canUndo: boolean;
|
|
443
|
+
readonly canRedo: boolean;
|
|
444
|
+
readonly issues: readonly TableIssue[];
|
|
445
|
+
isSelected(key: RowKey): boolean;
|
|
446
|
+
getSort(columnId: string): SortInfo | undefined;
|
|
447
|
+
getColumn(columnId: string): TableColumn<TRow> | undefined;
|
|
448
|
+
getRow(key: RowKey): TableRow<TRow> | undefined;
|
|
449
|
+
}
|
|
450
|
+
/** An edit given as a value of the column's type. */
|
|
451
|
+
interface CellValueEdit {
|
|
452
|
+
readonly rowKey: RowKey;
|
|
453
|
+
readonly column: string;
|
|
454
|
+
readonly value: unknown;
|
|
455
|
+
}
|
|
456
|
+
/** An edit given as text, read by the column's `parse`, as typed or pasted. */
|
|
457
|
+
interface CellInputEdit {
|
|
458
|
+
readonly rowKey: RowKey;
|
|
459
|
+
readonly column: string;
|
|
460
|
+
readonly input: string;
|
|
461
|
+
}
|
|
462
|
+
type CellEdit = CellValueEdit | CellInputEdit;
|
|
463
|
+
interface CellChange<TRow> {
|
|
464
|
+
readonly rowKey: RowKey;
|
|
465
|
+
readonly column: string;
|
|
466
|
+
readonly previous: unknown;
|
|
467
|
+
readonly value: unknown;
|
|
468
|
+
/** The row after the change. */
|
|
469
|
+
readonly row: TRow;
|
|
470
|
+
}
|
|
471
|
+
type EditStatus = "applied" | "partial" | "rejected" | "unchanged";
|
|
472
|
+
/**
|
|
473
|
+
* The outcome of a batch of edits. `partial` means some edits applied and others were refused;
|
|
474
|
+
* each refusal is in `issues`.
|
|
475
|
+
*/
|
|
476
|
+
interface EditResult<TRow> {
|
|
477
|
+
readonly status: EditStatus;
|
|
478
|
+
readonly changes: readonly CellChange<TRow>[];
|
|
479
|
+
readonly issues: readonly TableIssue[];
|
|
480
|
+
}
|
|
481
|
+
interface ExportOptions {
|
|
482
|
+
/** Defaults to `"csv"`. */
|
|
483
|
+
readonly format?: "csv" | "tsv" | undefined;
|
|
484
|
+
/** Column ids to export. Defaults to the visible columns. */
|
|
485
|
+
readonly columns?: readonly string[] | undefined;
|
|
486
|
+
/** Export only the current page. Defaults to every filtered row. */
|
|
487
|
+
readonly pageOnly?: boolean | undefined;
|
|
488
|
+
/** Defaults to `true`. */
|
|
489
|
+
readonly headers?: boolean | undefined;
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* A data table: data, columns, and state, with named operations to change them. It knows nothing
|
|
493
|
+
* about rendering; a framework binding subscribes to it and draws each snapshot.
|
|
494
|
+
*/
|
|
495
|
+
interface DataTable<TRow> {
|
|
496
|
+
getSnapshot(): TableSnapshot<TRow>;
|
|
497
|
+
getState(): TableState;
|
|
498
|
+
/** Called after every change with the new snapshot. Returns the unsubscribe function. */
|
|
499
|
+
subscribe(listener: (snapshot: TableSnapshot<TRow>) => void): () => void;
|
|
500
|
+
/** Replace part of the state from outside, without calling `onStateChange`. */
|
|
501
|
+
setState(patch: TableStatePatch): void;
|
|
502
|
+
/** Replace the data. The undo stack is cleared unless the data is the table's own. */
|
|
503
|
+
setData(data: readonly TRow[]): void;
|
|
504
|
+
setColumns(columns: readonly ColumnDef<TRow>[]): void;
|
|
505
|
+
/** Update the total row count of a `manual` table. */
|
|
506
|
+
setRowCount(rowCount: number): void;
|
|
507
|
+
/** Cycle a column through ascending, descending, and unsorted. */
|
|
508
|
+
toggleSort(columnId: string, options?: {
|
|
509
|
+
readonly multi?: boolean | undefined;
|
|
510
|
+
}): void;
|
|
511
|
+
/** Sort by one column, or clear it with `undefined`. */
|
|
512
|
+
sort(columnId: string, direction: SortDirection | undefined, options?: {
|
|
513
|
+
readonly multi?: boolean | undefined;
|
|
514
|
+
}): void;
|
|
515
|
+
clearSorting(): void;
|
|
516
|
+
search(text: string): void;
|
|
517
|
+
/** Set a column's filter value; an empty value removes the filter. */
|
|
518
|
+
filter(columnId: string, value: unknown): void;
|
|
519
|
+
clearFilters(): void;
|
|
520
|
+
goToPage(page: number): void;
|
|
521
|
+
nextPage(): void;
|
|
522
|
+
previousPage(): void;
|
|
523
|
+
/** Change the page size, keeping the first row of the current page in view. */
|
|
524
|
+
setPageSize(pageSize: number): void;
|
|
525
|
+
select(keys: readonly RowKey[]): void;
|
|
526
|
+
deselect(keys: readonly RowKey[]): void;
|
|
527
|
+
toggleRow(key: RowKey, selected?: boolean): void;
|
|
528
|
+
/** Select every row in the scope, or clear them when all are already selected. */
|
|
529
|
+
toggleAll(scope?: SelectScope): void;
|
|
530
|
+
clearSelection(): void;
|
|
531
|
+
/** The selected rows that are present in the data. */
|
|
532
|
+
getSelectedRows(): readonly TableRow<TRow>[];
|
|
533
|
+
toggleColumn(columnId: string, visible?: boolean): void;
|
|
534
|
+
moveColumn(columnId: string, toIndex: number): void;
|
|
535
|
+
edit(edits: CellEdit | readonly CellEdit[]): EditResult<TRow>;
|
|
536
|
+
undo(): boolean;
|
|
537
|
+
redo(): boolean;
|
|
538
|
+
/** The text of a range of shown cells, tab-separated like a spreadsheet clipboard. */
|
|
539
|
+
copy(range: CellRange): string;
|
|
540
|
+
/** Paste tab-separated text with its top-left cell at `origin`, clipped to the grid. */
|
|
541
|
+
paste(origin: CellPosition, text: string): EditResult<TRow>;
|
|
542
|
+
/** Empty every editable cell in a range. */
|
|
543
|
+
clear(range: CellRange): EditResult<TRow>;
|
|
544
|
+
exportRows(options?: ExportOptions): string;
|
|
545
|
+
/** Return to the initial state. */
|
|
546
|
+
reset(): void;
|
|
547
|
+
/** Drop every listener. */
|
|
548
|
+
destroy(): void;
|
|
549
|
+
}
|
|
550
|
+
/** Create a data table. */
|
|
551
|
+
declare function createTable<TRow>(options: TableOptions<TRow>): DataTable<TRow>;
|
|
552
|
+
//#endregion
|
|
553
|
+
export { type AnyColumnDef, type CellChange, type CellEdit, type CellInputEdit, type CellPosition, type CellRange, type CellValueEdit, type ColumnAlign, type ColumnDef, type ColumnOptions, type ColumnType, type ComputedColumnDef, DEFAULT_PAGE_SIZE, type DataTable, type DeepKeys, type EditResult, type EditStatus, type ExportOptions, type GridBounds, type GridCommand, type GridDirection, type GridKey, type GridSelection, type MoveOptions, type PageItem, type PaginationState, type ParseResult, type PathColumnDef, type PathValue, type RangeFilter, type RowKey, type SelectScope, type SelectionCoverage, type SelectionMode, type SortDirection, type SortInfo, type SortRule, type TableColumn, type TableIssue, type TableIssueCode, type TableOptions, type TableRow, type TableSnapshot, type TableState, type TableStatePatch, type UndoStack, clampPage, clampPosition, columnLabel, compareValues, countPages, createTable, createUndoStack, defineColumns, filterRows, formatValue, fromA1, getPath, gridCommand, humanize, inferColumns, matchesFilter, moveSelection, paginateRows, paginationItems, parseAs, parseDelimited, rangeContains, resolveColumn, selectCell, selectionRange, setPath, sortRows, toA1, toDelimited, typeOf };
|
|
554
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/path.ts","../src/column.ts","../src/delimited.ts","../src/grid.ts","../src/undo-stack.ts","../src/humanize.ts","../src/infer.ts","../src/state.ts","../src/issues.ts","../src/row.ts","../src/pipeline.ts","../src/table.ts"],"mappings":"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"}
|