@svgrid/grid 2.6.19 → 2.6.21
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/SvGrid.controller.svelte.d.ts +1 -0
- package/dist/SvGrid.controller.svelte.js +64 -2
- package/dist/SvGrid.svelte +2 -1
- package/dist/SvGrid.types.d.ts +150 -0
- package/dist/ai.d.ts +28 -0
- package/dist/ai.js +6 -0
- package/dist/cdn/{GridMenus-B0F9iBrG.js → GridMenus-BfTAKn84.js} +1 -1
- package/dist/cdn/{GridMenus-IHK_l7m6.js → GridMenus-C3bJd7w8.js} +1 -1
- package/dist/cdn/{src-Cd0tearp.js → src-BYq-qyrp.js} +1012 -999
- package/dist/cdn/{src-B1TdiyS8.js → src-DBel9wRZ.js} +1324 -1311
- package/dist/cdn/svgrid.js +1 -1
- package/dist/cdn/svgrid.svelte-external.js +1 -1
- package/dist/cdn/validate-_CDJzgIo.js +75 -0
- package/dist/cell-formatting.d.ts +2 -0
- package/dist/cell-formatting.js +2 -0
- package/dist/chart-export.d.ts +1 -0
- package/dist/chart.d.ts +31 -5
- package/dist/chart.js +9 -3
- package/dist/core.d.ts +197 -0
- package/dist/core.js +72 -0
- package/dist/createTree.svelte.d.ts +3 -0
- package/dist/createTree.svelte.js +1 -0
- package/dist/datetime/date-core.d.ts +2 -0
- package/dist/datetime/date-restrict.d.ts +1 -0
- package/dist/datetime/timezone.d.ts +1 -0
- package/dist/dock-manager-model.d.ts +3 -0
- package/dist/dock-manager-model.js +1 -0
- package/dist/dock-model.d.ts +6 -0
- package/dist/dock-model.js +3 -0
- package/dist/editor-contract.d.ts +1 -0
- package/dist/list-option.d.ts +1 -0
- package/dist/positioning.d.ts +2 -0
- package/dist/scheduler-ical.d.ts +1 -0
- package/dist/scheduler-model.d.ts +1 -0
- package/dist/summaries.js +22 -0
- package/dist/svgrid-wrapper.types.d.ts +5 -0
- package/dist/toast-store.svelte.d.ts +4 -0
- package/dist/validate.d.ts +50 -0
- package/dist/validate.js +187 -0
- package/package.json +4 -1
- package/src/SvGrid.controller.svelte.ts +68 -2
- package/src/SvGrid.svelte +2 -1
- package/src/SvGrid.types.ts +150 -0
- package/src/ai.ts +28 -0
- package/src/cell-formatting.ts +2 -0
- package/src/chart-export.ts +1 -0
- package/src/chart.ts +31 -5
- package/src/core.ts +207 -0
- package/src/createTree.svelte.ts +3 -0
- package/src/datetime/date-core.ts +2 -0
- package/src/datetime/date-restrict.ts +1 -0
- package/src/datetime/timezone.ts +1 -0
- package/src/dock-manager-model.ts +3 -0
- package/src/dock-model.ts +6 -0
- package/src/editor-contract.ts +1 -0
- package/src/list-option.ts +1 -0
- package/src/positioning.ts +2 -0
- package/src/scheduler-ical.ts +1 -0
- package/src/scheduler-model.ts +1 -0
- package/src/summaries.ts +21 -0
- package/src/svgrid-wrapper.types.ts +5 -0
- package/src/svgrid.summaries.test.ts +217 -0
- package/src/toast-store.svelte.ts +4 -0
- package/src/validate.test.ts +207 -0
- package/src/validate.ts +269 -0
package/dist/core.d.ts
CHANGED
|
@@ -1,35 +1,74 @@
|
|
|
1
1
|
import type { SparklineConfig } from './sparkline.js';
|
|
2
|
+
/**
|
|
3
|
+
* The constraint every row type satisfies: an object keyed by string. Your own
|
|
4
|
+
* row type (`type Person = { name: string }`) is what flows through the generics
|
|
5
|
+
* below; this is only the lower bound they are declared against.
|
|
6
|
+
*/
|
|
2
7
|
export type RowData = Record<string, unknown>;
|
|
8
|
+
/**
|
|
9
|
+
* A new value, or a function that derives it from the previous one - the shape
|
|
10
|
+
* every `set*` on the grid accepts, so callers can update state without first
|
|
11
|
+
* reading it.
|
|
12
|
+
*
|
|
13
|
+
* api.setSorting([{ id: 'name', desc: false }])
|
|
14
|
+
* api.setSorting((prev) => [...prev, { id: 'age', desc: true }])
|
|
15
|
+
*/
|
|
3
16
|
export type Updater<T> = T | ((prev: T) => T);
|
|
17
|
+
/** Active sort clauses, outermost first. `desc: false` is ascending. */
|
|
4
18
|
export type SortingState = Array<{
|
|
5
19
|
id: string;
|
|
6
20
|
desc: boolean;
|
|
7
21
|
}>;
|
|
22
|
+
/**
|
|
23
|
+
* One column's filter: the column `id`, the `value` being matched, and
|
|
24
|
+
* optionally which comparison to use. `fn` defaults to the column's own type -
|
|
25
|
+
* see {@link filterFns} for the available names.
|
|
26
|
+
*/
|
|
8
27
|
export type ColumnFilter = {
|
|
9
28
|
id: string;
|
|
10
29
|
value: unknown;
|
|
11
30
|
fn?: keyof typeof filterFns;
|
|
12
31
|
};
|
|
32
|
+
/** Every active column filter. A column with no entry here is unfiltered. */
|
|
13
33
|
export type ColumnFiltersState = Array<ColumnFilter>;
|
|
34
|
+
/** Current page position. `pageIndex` is 0-based, so page 1 is index 0. */
|
|
14
35
|
export type PaginationState = {
|
|
15
36
|
pageIndex: number;
|
|
16
37
|
pageSize: number;
|
|
17
38
|
};
|
|
39
|
+
/** Column ids the rows are grouped by, outermost first. */
|
|
18
40
|
export type GroupingState = Array<string>;
|
|
41
|
+
/** Which rows are expanded, keyed by row id. Absent means collapsed. */
|
|
19
42
|
export type ExpandedState = Record<string, boolean>;
|
|
43
|
+
/** Which rows are selected, keyed by row id. Absent means unselected. */
|
|
20
44
|
export type RowSelectionState = Record<string, boolean>;
|
|
45
|
+
/**
|
|
46
|
+
* Where keyboard focus sits. The indices address the *displayed* grid (after
|
|
47
|
+
* sorting, filtering and paging), not the source data.
|
|
48
|
+
*/
|
|
21
49
|
export type ActiveCellState = {
|
|
22
50
|
rowIndex: number;
|
|
23
51
|
colIndex: number;
|
|
24
52
|
cellId: string | null;
|
|
25
53
|
};
|
|
54
|
+
/**
|
|
55
|
+
* The set of features a grid has registered, as built by {@link tableFeatures}.
|
|
56
|
+
* Deliberately open: a feature is identified by its key, so the type carries
|
|
57
|
+
* which ones are on without enumerating them.
|
|
58
|
+
*/
|
|
26
59
|
export type TableFeatures = Record<string, unknown>;
|
|
60
|
+
/** A cell's value. Unconstrained - a column can hold anything. */
|
|
27
61
|
export type CellData = unknown;
|
|
62
|
+
/** What a column's `header` render function receives. */
|
|
28
63
|
export type HeaderContext<TData extends RowData> = {
|
|
29
64
|
header: Header<TData>;
|
|
30
65
|
column: Column<TData>;
|
|
31
66
|
table: SvGrid<TData>;
|
|
32
67
|
};
|
|
68
|
+
/**
|
|
69
|
+
* What a column's `cell` render function receives. `getValue()` applies the
|
|
70
|
+
* column's accessor (`field` or `fieldFn`); `row.original` is the raw object.
|
|
71
|
+
*/
|
|
33
72
|
export type CellContext<TData extends RowData> = {
|
|
34
73
|
cell: Cell<TData>;
|
|
35
74
|
row: Row<TData>;
|
|
@@ -86,6 +125,11 @@ export type EditorContext<TData extends RowData> = CellContext<TData> & {
|
|
|
86
125
|
commit: (next?: unknown) => void;
|
|
87
126
|
cancel: () => void;
|
|
88
127
|
};
|
|
128
|
+
/**
|
|
129
|
+
* Declarative cell formatting, applied through `Intl` - number, currency,
|
|
130
|
+
* percent, date and datetime. Prefer this over a `formatter` function: it is
|
|
131
|
+
* locale-aware, and export and the clipboard reuse the same configuration.
|
|
132
|
+
*/
|
|
89
133
|
export type CellFormatConfig = {
|
|
90
134
|
type: 'number';
|
|
91
135
|
locales?: string | Array<string>;
|
|
@@ -116,12 +160,17 @@ export type CellFormatConfig = {
|
|
|
116
160
|
pattern?: string;
|
|
117
161
|
options?: Intl.DateTimeFormatOptions;
|
|
118
162
|
};
|
|
163
|
+
/**
|
|
164
|
+
* A column's custom display function, for anything {@link CellFormatConfig}
|
|
165
|
+
* cannot express. Returns a string - to render markup, use `cell` instead.
|
|
166
|
+
*/
|
|
119
167
|
export type CellFormatter<TData extends RowData> = (context: {
|
|
120
168
|
value: unknown;
|
|
121
169
|
row: Row<TData>;
|
|
122
170
|
column: Column<TData>;
|
|
123
171
|
table: SvGrid<TData>;
|
|
124
172
|
}) => string;
|
|
173
|
+
/** A header or cell slot: a literal string, or a function returning renderable content. */
|
|
125
174
|
export type ColumnDefTemplate<TContext> = string | ((context: TContext) => unknown);
|
|
126
175
|
/**
|
|
127
176
|
* How a column's value is aggregated for a group row when `columnGrouping`
|
|
@@ -310,6 +359,20 @@ export type ColumnDef<TFeatures extends TableFeatures, TData extends RowData> =
|
|
|
310
359
|
* is formatted with this column's `format` and shown in the group header.
|
|
311
360
|
*/
|
|
312
361
|
aggregate?: GroupAggregator<TData>;
|
|
362
|
+
/**
|
|
363
|
+
* What this column contributes to the grid's footer summary row (the one
|
|
364
|
+
* turned on with `summary` / `enableRowSummaries`). Takes the same
|
|
365
|
+
* aggregators as {@link aggregate}, and the result is formatted with this
|
|
366
|
+
* column's `format`.
|
|
367
|
+
*
|
|
368
|
+
* Without it the footer falls back to its default: the sum of a numeric
|
|
369
|
+
* column, `Count: N` otherwise. Set `false` to leave the cell blank, which is
|
|
370
|
+
* usually what an actions or checkbox column wants.
|
|
371
|
+
*
|
|
372
|
+
* { field: 'amount', summary: 'avg' }
|
|
373
|
+
* { id: 'actions', summary: false }
|
|
374
|
+
*/
|
|
375
|
+
summary?: GroupAggregator<TData> | false;
|
|
313
376
|
/**
|
|
314
377
|
* Render the cell as an in-cell sparkline chart. The cell value should be
|
|
315
378
|
* an array of numbers (or a comma/space separated string). Mutually
|
|
@@ -371,6 +434,12 @@ export type ColumnDef<TFeatures extends TableFeatures, TData extends RowData> =
|
|
|
371
434
|
export type GridColumnDef<TData extends RowData = RowData> = ColumnDef<TableFeatures, TData>;
|
|
372
435
|
/** An array of {@link GridColumnDef} - what you pass to `<SvGrid columns={...}>`. */
|
|
373
436
|
export type GridColumns<TData extends RowData = RowData> = Array<GridColumnDef<TData>>;
|
|
437
|
+
/**
|
|
438
|
+
* A resolved column: your {@link ColumnDef} plus everything the grid computed
|
|
439
|
+
* from it - its id, its depth under any group header, and the sort handlers a
|
|
440
|
+
* header needs. This is what you receive in render contexts; the `ColumnDef`
|
|
441
|
+
* is what you wrote.
|
|
442
|
+
*/
|
|
374
443
|
export type Column<TData extends RowData> = {
|
|
375
444
|
id: string;
|
|
376
445
|
columnDef: ColumnDef<any, TData>;
|
|
@@ -381,6 +450,11 @@ export type Column<TData extends RowData> = {
|
|
|
381
450
|
getIsSorted: () => false | 'asc' | 'desc';
|
|
382
451
|
getToggleSortingHandler: () => () => void;
|
|
383
452
|
};
|
|
453
|
+
/**
|
|
454
|
+
* One header cell. `colSpan` is how many leaf columns it covers, and
|
|
455
|
+
* `isPlaceholder` marks the empty cells that pad a group-header row so the
|
|
456
|
+
* levels line up.
|
|
457
|
+
*/
|
|
384
458
|
export type Header<TData extends RowData> = {
|
|
385
459
|
id: string;
|
|
386
460
|
isPlaceholder: boolean;
|
|
@@ -388,10 +462,12 @@ export type Header<TData extends RowData> = {
|
|
|
388
462
|
column: Column<TData>;
|
|
389
463
|
getContext: () => HeaderContext<TData>;
|
|
390
464
|
};
|
|
465
|
+
/** One row of header cells. A grid with grouped columns has several, outermost first. */
|
|
391
466
|
export type HeaderGroup<TData extends RowData> = {
|
|
392
467
|
id: string;
|
|
393
468
|
headers: Array<Header<TData>>;
|
|
394
469
|
};
|
|
470
|
+
/** One cell: the intersection of a {@link Row} and a {@link Column}. */
|
|
395
471
|
export type Cell<TData extends RowData> = {
|
|
396
472
|
id: string;
|
|
397
473
|
row: Row<TData>;
|
|
@@ -399,6 +475,13 @@ export type Cell<TData extends RowData> = {
|
|
|
399
475
|
getValue: () => unknown;
|
|
400
476
|
getContext: () => CellContext<TData>;
|
|
401
477
|
};
|
|
478
|
+
/**
|
|
479
|
+
* A row in the display model. `original` is your untouched data object;
|
|
480
|
+
* everything else is grid-computed. `index` is the position in the displayed
|
|
481
|
+
* set, so it shifts as sorting and filtering change - key on `id`, not index.
|
|
482
|
+
*
|
|
483
|
+
* Group rows and tree parents carry `subRows`; a plain data row does not.
|
|
484
|
+
*/
|
|
402
485
|
export type Row<TData extends RowData> = {
|
|
403
486
|
id: string;
|
|
404
487
|
index: number;
|
|
@@ -415,50 +498,126 @@ export type Row<TData extends RowData> = {
|
|
|
415
498
|
getAllCells: () => Array<Cell<TData>>;
|
|
416
499
|
getCellValueByColumnId: (columnId: string) => unknown;
|
|
417
500
|
};
|
|
501
|
+
/** The output of the row pipeline: the rows to display, in order. */
|
|
418
502
|
export type RowModel<TData extends RowData> = {
|
|
419
503
|
rows: Array<Row<TData>>;
|
|
420
504
|
};
|
|
505
|
+
/**
|
|
506
|
+
* The minimal reactive store behind the headless core - read `state`, write
|
|
507
|
+
* through `setState`, and `subscribe` for changes. Deliberately framework
|
|
508
|
+
* free, which is what lets the core run under plain Node.
|
|
509
|
+
*
|
|
510
|
+
* In Svelte you rarely touch this: `subscribeGrid` wraps it with fine-grained
|
|
511
|
+
* selectors so a component only re-runs for the slice it read.
|
|
512
|
+
*/
|
|
421
513
|
export type Store<T> = {
|
|
422
514
|
readonly state: T;
|
|
423
515
|
setState: (updater: (prev: T) => T) => void;
|
|
424
516
|
subscribe: (listener: () => void) => () => void;
|
|
425
517
|
};
|
|
518
|
+
/**
|
|
519
|
+
* Click-to-sort. Injected by the `sortable` shortcut.
|
|
520
|
+
*
|
|
521
|
+
* This and the five features below are opaque markers: pass the ones you want
|
|
522
|
+
* to {@link tableFeatures} and the grid wires up the matching row model. With
|
|
523
|
+
* `<SvGrid>` you rarely name them - the boolean shortcuts (`sortable`,
|
|
524
|
+
* `filterable`, `pageable`, `groupable`) inject them for you. Reach for them
|
|
525
|
+
* directly when driving the headless core, or when you want a feature on
|
|
526
|
+
* without its UI.
|
|
527
|
+
*
|
|
528
|
+
* The names match TanStack Table v9, so a features object written for it works
|
|
529
|
+
* here unchanged.
|
|
530
|
+
*/
|
|
426
531
|
export declare const rowSortingFeature: {
|
|
427
532
|
key: string;
|
|
428
533
|
};
|
|
534
|
+
/** Per-column filtering. Injected by the `filterable` shortcut. */
|
|
429
535
|
export declare const columnFilteringFeature: {
|
|
430
536
|
key: string;
|
|
431
537
|
};
|
|
538
|
+
/** Paging of the row model. Injected by the `pageable` shortcut. */
|
|
432
539
|
export declare const rowPaginationFeature: {
|
|
433
540
|
key: string;
|
|
434
541
|
};
|
|
542
|
+
/** Row grouping with aggregation. Injected by the `groupable` shortcut. */
|
|
435
543
|
export declare const columnGroupingFeature: {
|
|
436
544
|
key: string;
|
|
437
545
|
};
|
|
546
|
+
/** Row selection state (the checkbox column reads it). */
|
|
438
547
|
export declare const rowSelectionFeature: {
|
|
439
548
|
key: string;
|
|
440
549
|
};
|
|
550
|
+
/** Expand / collapse, for tree rows and master-detail. */
|
|
441
551
|
export declare const rowExpandingFeature: {
|
|
442
552
|
key: string;
|
|
443
553
|
};
|
|
554
|
+
/**
|
|
555
|
+
* Declare which features a grid uses. Identity at runtime - its whole job is to
|
|
556
|
+
* capture the exact set in the type, so `ColumnDef<typeof features, Row>` knows
|
|
557
|
+
* what is registered and anything you did not register is tree-shaken out.
|
|
558
|
+
*
|
|
559
|
+
* ```ts
|
|
560
|
+
* const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })
|
|
561
|
+
* ```
|
|
562
|
+
*
|
|
563
|
+
* Same call signature as TanStack Table v9, so a features object written for it
|
|
564
|
+
* transfers unchanged.
|
|
565
|
+
*/
|
|
444
566
|
export declare function tableFeatures<T extends TableFeatures>(features: T): T;
|
|
567
|
+
/**
|
|
568
|
+
* Built-in comparators, chosen per column by its data type. `auto` compares as
|
|
569
|
+
* text; set a column's type or supply your own comparator to override.
|
|
570
|
+
*/
|
|
445
571
|
export declare const sortFns: {
|
|
446
572
|
auto: (a: unknown, b: unknown) => number;
|
|
447
573
|
number: (a: unknown, b: unknown) => number;
|
|
448
574
|
date: (a: unknown, b: unknown) => number;
|
|
449
575
|
};
|
|
576
|
+
/**
|
|
577
|
+
* Built-in match functions, named by {@link ColumnFilter}'s `fn`.
|
|
578
|
+
* `includesString` is case-insensitive substring; `equals` is strict identity.
|
|
579
|
+
*/
|
|
450
580
|
export declare const filterFns: {
|
|
451
581
|
includesString: (value: unknown, query: string) => boolean;
|
|
452
582
|
equals: (value: unknown, query: unknown) => boolean;
|
|
453
583
|
};
|
|
584
|
+
/**
|
|
585
|
+
* One stage of the row pipeline: takes the rows produced so far and returns the
|
|
586
|
+
* next set. Stages compose in the order given to `_rowModels`, so filtering
|
|
587
|
+
* before sorting sorts only what survived the filter.
|
|
588
|
+
*/
|
|
454
589
|
export type RowModelFactory<TData extends RowData> = (args: {
|
|
455
590
|
table: SvGrid<TData>;
|
|
456
591
|
rows: Array<Row<TData>>;
|
|
457
592
|
}) => Array<Row<TData>>;
|
|
593
|
+
/**
|
|
594
|
+
* The identity stage that starts every pipeline. Always required, even when no
|
|
595
|
+
* other stage is: it is what turns your data into rows.
|
|
596
|
+
*/
|
|
458
597
|
export declare function createCoreRowModel<TData extends RowData>(): RowModelFactory<TData>;
|
|
598
|
+
/**
|
|
599
|
+
* Drops rows that fail the active {@link ColumnFiltersState}. Pairs with
|
|
600
|
+
* `columnFilteringFeature`; without it there are no filters to apply.
|
|
601
|
+
*/
|
|
459
602
|
export declare function createFilteredRowModel<TData extends RowData>(): RowModelFactory<TData>;
|
|
603
|
+
/**
|
|
604
|
+
* Narrows the rows to the current page. Put it LAST: anything after it would
|
|
605
|
+
* only ever see one page of data.
|
|
606
|
+
*/
|
|
460
607
|
export declare function createPaginatedRowModel<TData extends RowData>(): RowModelFactory<TData>;
|
|
608
|
+
/**
|
|
609
|
+
* Buckets rows by the active {@link GroupingState} and inserts a group row
|
|
610
|
+
* ahead of each bucket, carrying that bucket's aggregates.
|
|
611
|
+
*/
|
|
461
612
|
export declare function createGroupedRowModel<TData extends RowData>(): RowModelFactory<TData>;
|
|
613
|
+
/**
|
|
614
|
+
* How to read a hierarchy out of FLAT rows: each row names its parent, and the
|
|
615
|
+
* grid reconstructs the tree. Rows whose parent id matches nothing become roots
|
|
616
|
+
* rather than disappearing.
|
|
617
|
+
*
|
|
618
|
+
* For nested source data (`children: [...]`), flatten it first with
|
|
619
|
+
* {@link flattenTreeData}.
|
|
620
|
+
*/
|
|
462
621
|
export type TreeRowModelOptions = {
|
|
463
622
|
/** Field holding each row's parent id. Rows with no parent are roots. */
|
|
464
623
|
parentField: string;
|
|
@@ -481,6 +640,11 @@ export type TreeRowModelOptions = {
|
|
|
481
640
|
* data row for a full-width group banner.
|
|
482
641
|
*/
|
|
483
642
|
export declare function createTreeRowModel<TData extends RowData>(options: TreeRowModelOptions): RowModelFactory<TData>;
|
|
643
|
+
/**
|
|
644
|
+
* How to flatten NESTED source data into the parent-id shape tree rows need.
|
|
645
|
+
* `parentField` is written onto each row, so point `treeData.parentField` at
|
|
646
|
+
* the same name afterwards.
|
|
647
|
+
*/
|
|
484
648
|
export type FlattenTreeOptions = {
|
|
485
649
|
/** Field holding an array of child objects. */
|
|
486
650
|
childrenField: string;
|
|
@@ -498,8 +662,25 @@ export type FlattenTreeOptions = {
|
|
|
498
662
|
* (harmless, and callers often still want it); only the parent link is added.
|
|
499
663
|
*/
|
|
500
664
|
export declare function flattenTreeData<T extends RowData>(data: ReadonlyArray<T>, options: FlattenTreeOptions): T[];
|
|
665
|
+
/**
|
|
666
|
+
* Hides the descendants of collapsed rows. Needed for grouping, tree data and
|
|
667
|
+
* master-detail alike - all three are the same expand/collapse mechanism.
|
|
668
|
+
*/
|
|
501
669
|
export declare function createExpandedRowModel<TData extends RowData>(): RowModelFactory<TData>;
|
|
670
|
+
/**
|
|
671
|
+
* Orders rows by the active {@link SortingState}. Pass your own comparators to
|
|
672
|
+
* override the built-in {@link sortFns} - useful for locale-aware or
|
|
673
|
+
* domain-specific ordering.
|
|
674
|
+
*/
|
|
502
675
|
export declare function createSortedRowModel<TData extends RowData>(localSortFns?: typeof sortFns): RowModelFactory<TData>;
|
|
676
|
+
/**
|
|
677
|
+
* Everything {@link createSvGridCore} accepts: the data and columns, the
|
|
678
|
+
* features and row models that make up the pipeline, and an `on*Change`
|
|
679
|
+
* callback per piece of state for controlled use.
|
|
680
|
+
*
|
|
681
|
+
* `<SvGrid>` builds this for you from its props - you only construct it
|
|
682
|
+
* directly when driving the headless core.
|
|
683
|
+
*/
|
|
503
684
|
export type SvGridOptions<TFeatures extends TableFeatures, TData extends RowData> = {
|
|
504
685
|
_features: TFeatures;
|
|
505
686
|
_rowModels?: {
|
|
@@ -528,6 +709,13 @@ export type SvGridOptions<TFeatures extends TableFeatures, TData extends RowData
|
|
|
528
709
|
onRowSelectionChange?: (updater: Updater<RowSelectionState>) => void;
|
|
529
710
|
onActiveCellChange?: (updater: Updater<ActiveCellState>) => void;
|
|
530
711
|
};
|
|
712
|
+
/**
|
|
713
|
+
* The headless grid instance: the state stores plus the read methods a renderer
|
|
714
|
+
* needs (`getHeaderGroups()`, `getRowModel()`, the `set*` writers).
|
|
715
|
+
*
|
|
716
|
+
* Framework free by design - `<SvGrid>` is one renderer over this, and you can
|
|
717
|
+
* write another. See the "Why headless?" guide.
|
|
718
|
+
*/
|
|
531
719
|
export type SvGrid<TData extends RowData> = {
|
|
532
720
|
store: Store<Record<string, any>>;
|
|
533
721
|
optionsStore: Store<Record<string, any>>;
|
|
@@ -549,5 +737,14 @@ export type SvGrid<TData extends RowData> = {
|
|
|
549
737
|
getFooterGroups: () => Array<HeaderGroup<TData>>;
|
|
550
738
|
getRowModel: () => RowModel<TData>;
|
|
551
739
|
};
|
|
740
|
+
/**
|
|
741
|
+
* Build a headless grid: state, the row pipeline, and the read methods, with no
|
|
742
|
+
* DOM and no Svelte. This is the engine `<SvGrid>` renders.
|
|
743
|
+
*
|
|
744
|
+
* Most callers want `createSvGrid` (the runes-aware wrapper) or the component
|
|
745
|
+
* itself; reach for this when you are writing your own renderer or running the
|
|
746
|
+
* pipeline outside a browser.
|
|
747
|
+
*/
|
|
552
748
|
export declare function createSvGridCore<TFeatures extends TableFeatures, TData extends RowData>(options: SvGridOptions<TFeatures, TData>): SvGrid<TData>;
|
|
749
|
+
/** Narrowing helper for the many options that accept a value or a function. */
|
|
553
750
|
export declare function isFunction(value: unknown): value is (...args: Array<any>) => any;
|
package/dist/core.js
CHANGED
|
@@ -47,15 +47,49 @@ function createStore(initial) {
|
|
|
47
47
|
},
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Click-to-sort. Injected by the `sortable` shortcut.
|
|
52
|
+
*
|
|
53
|
+
* This and the five features below are opaque markers: pass the ones you want
|
|
54
|
+
* to {@link tableFeatures} and the grid wires up the matching row model. With
|
|
55
|
+
* `<SvGrid>` you rarely name them - the boolean shortcuts (`sortable`,
|
|
56
|
+
* `filterable`, `pageable`, `groupable`) inject them for you. Reach for them
|
|
57
|
+
* directly when driving the headless core, or when you want a feature on
|
|
58
|
+
* without its UI.
|
|
59
|
+
*
|
|
60
|
+
* The names match TanStack Table v9, so a features object written for it works
|
|
61
|
+
* here unchanged.
|
|
62
|
+
*/
|
|
50
63
|
export const rowSortingFeature = { key: 'rowSortingFeature' };
|
|
64
|
+
/** Per-column filtering. Injected by the `filterable` shortcut. */
|
|
51
65
|
export const columnFilteringFeature = { key: 'columnFilteringFeature' };
|
|
66
|
+
/** Paging of the row model. Injected by the `pageable` shortcut. */
|
|
52
67
|
export const rowPaginationFeature = { key: 'rowPaginationFeature' };
|
|
68
|
+
/** Row grouping with aggregation. Injected by the `groupable` shortcut. */
|
|
53
69
|
export const columnGroupingFeature = { key: 'columnGroupingFeature' };
|
|
70
|
+
/** Row selection state (the checkbox column reads it). */
|
|
54
71
|
export const rowSelectionFeature = { key: 'rowSelectionFeature' };
|
|
72
|
+
/** Expand / collapse, for tree rows and master-detail. */
|
|
55
73
|
export const rowExpandingFeature = { key: 'rowExpandingFeature' };
|
|
74
|
+
/**
|
|
75
|
+
* Declare which features a grid uses. Identity at runtime - its whole job is to
|
|
76
|
+
* capture the exact set in the type, so `ColumnDef<typeof features, Row>` knows
|
|
77
|
+
* what is registered and anything you did not register is tree-shaken out.
|
|
78
|
+
*
|
|
79
|
+
* ```ts
|
|
80
|
+
* const features = tableFeatures({ rowSortingFeature, columnFilteringFeature })
|
|
81
|
+
* ```
|
|
82
|
+
*
|
|
83
|
+
* Same call signature as TanStack Table v9, so a features object written for it
|
|
84
|
+
* transfers unchanged.
|
|
85
|
+
*/
|
|
56
86
|
export function tableFeatures(features) {
|
|
57
87
|
return features;
|
|
58
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Built-in comparators, chosen per column by its data type. `auto` compares as
|
|
91
|
+
* text; set a column's type or supply your own comparator to override.
|
|
92
|
+
*/
|
|
59
93
|
export const sortFns = {
|
|
60
94
|
auto: (a, b) => String(a).localeCompare(String(b)),
|
|
61
95
|
number: (a, b) => Number(a ?? 0) - Number(b ?? 0),
|
|
@@ -65,13 +99,25 @@ export const sortFns = {
|
|
|
65
99
|
return aa - bb;
|
|
66
100
|
},
|
|
67
101
|
};
|
|
102
|
+
/**
|
|
103
|
+
* Built-in match functions, named by {@link ColumnFilter}'s `fn`.
|
|
104
|
+
* `includesString` is case-insensitive substring; `equals` is strict identity.
|
|
105
|
+
*/
|
|
68
106
|
export const filterFns = {
|
|
69
107
|
includesString: (value, query) => String(value).toLowerCase().includes(query.toLowerCase()),
|
|
70
108
|
equals: (value, query) => value === query,
|
|
71
109
|
};
|
|
110
|
+
/**
|
|
111
|
+
* The identity stage that starts every pipeline. Always required, even when no
|
|
112
|
+
* other stage is: it is what turns your data into rows.
|
|
113
|
+
*/
|
|
72
114
|
export function createCoreRowModel() {
|
|
73
115
|
return ({ rows }) => rows;
|
|
74
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Drops rows that fail the active {@link ColumnFiltersState}. Pairs with
|
|
119
|
+
* `columnFilteringFeature`; without it there are no filters to apply.
|
|
120
|
+
*/
|
|
75
121
|
export function createFilteredRowModel() {
|
|
76
122
|
return ({ table, rows }) => {
|
|
77
123
|
const filters = table.getState().columnFilters ?? [];
|
|
@@ -89,6 +135,10 @@ export function createFilteredRowModel() {
|
|
|
89
135
|
});
|
|
90
136
|
};
|
|
91
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* Narrows the rows to the current page. Put it LAST: anything after it would
|
|
140
|
+
* only ever see one page of data.
|
|
141
|
+
*/
|
|
92
142
|
export function createPaginatedRowModel() {
|
|
93
143
|
return ({ table, rows }) => {
|
|
94
144
|
const pagination = table.getState().pagination ?? { pageIndex: 0, pageSize: rows.length || 10 };
|
|
@@ -96,6 +146,10 @@ export function createPaginatedRowModel() {
|
|
|
96
146
|
return rows.slice(start, start + pagination.pageSize);
|
|
97
147
|
};
|
|
98
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* Buckets rows by the active {@link GroupingState} and inserts a group row
|
|
151
|
+
* ahead of each bucket, carrying that bucket's aggregates.
|
|
152
|
+
*/
|
|
99
153
|
export function createGroupedRowModel() {
|
|
100
154
|
return ({ table, rows }) => {
|
|
101
155
|
const grouping = table.getState().grouping ?? [];
|
|
@@ -282,6 +336,10 @@ export function flattenTreeData(data, options) {
|
|
|
282
336
|
walk(data, null);
|
|
283
337
|
return out;
|
|
284
338
|
}
|
|
339
|
+
/**
|
|
340
|
+
* Hides the descendants of collapsed rows. Needed for grouping, tree data and
|
|
341
|
+
* master-detail alike - all three are the same expand/collapse mechanism.
|
|
342
|
+
*/
|
|
285
343
|
export function createExpandedRowModel() {
|
|
286
344
|
return ({ table, rows }) => {
|
|
287
345
|
const expanded = table.getState().expanded ?? {};
|
|
@@ -298,6 +356,11 @@ export function createExpandedRowModel() {
|
|
|
298
356
|
return flattened;
|
|
299
357
|
};
|
|
300
358
|
}
|
|
359
|
+
/**
|
|
360
|
+
* Orders rows by the active {@link SortingState}. Pass your own comparators to
|
|
361
|
+
* override the built-in {@link sortFns} - useful for locale-aware or
|
|
362
|
+
* domain-specific ordering.
|
|
363
|
+
*/
|
|
301
364
|
export function createSortedRowModel(localSortFns = sortFns) {
|
|
302
365
|
return ({ table, rows }) => {
|
|
303
366
|
const sorting = table.getState().sorting ?? [];
|
|
@@ -323,6 +386,14 @@ export function createSortedRowModel(localSortFns = sortFns) {
|
|
|
323
386
|
return sorted;
|
|
324
387
|
};
|
|
325
388
|
}
|
|
389
|
+
/**
|
|
390
|
+
* Build a headless grid: state, the row pipeline, and the read methods, with no
|
|
391
|
+
* DOM and no Svelte. This is the engine `<SvGrid>` renders.
|
|
392
|
+
*
|
|
393
|
+
* Most callers want `createSvGrid` (the runes-aware wrapper) or the component
|
|
394
|
+
* itself; reach for this when you are writing your own renderer or running the
|
|
395
|
+
* pipeline outside a browser.
|
|
396
|
+
*/
|
|
326
397
|
export function createSvGridCore(options) {
|
|
327
398
|
const internalState = {
|
|
328
399
|
sorting: [],
|
|
@@ -653,6 +724,7 @@ export function createSvGridCore(options) {
|
|
|
653
724
|
};
|
|
654
725
|
return grid;
|
|
655
726
|
}
|
|
727
|
+
/** Narrowing helper for the many options that accept a value or a function. */
|
|
656
728
|
export function isFunction(value) {
|
|
657
729
|
return typeof value === 'function';
|
|
658
730
|
}
|
|
@@ -30,6 +30,7 @@ export type TreeNode = {
|
|
|
30
30
|
* even with no children yet; the renderer loads them on first expand). */
|
|
31
31
|
lazy?: boolean;
|
|
32
32
|
};
|
|
33
|
+
/** A node's checkbox state. `'indeterminate'` means some but not all descendants are checked. */
|
|
33
34
|
export type CheckState = 'checked' | 'indeterminate' | 'unchecked';
|
|
34
35
|
/** A single visible (flattened) tree row. */
|
|
35
36
|
export type TreeRow = {
|
|
@@ -73,6 +74,7 @@ export type TreeConfig = {
|
|
|
73
74
|
/** Filter query: show only matching nodes + their ancestors, auto-expanded. */
|
|
74
75
|
filter?: () => string | undefined;
|
|
75
76
|
};
|
|
77
|
+
/** Build the headless tree model: expansion, selection and checkbox cascading, with no markup. */
|
|
76
78
|
export declare function createTree(config: TreeConfig): {
|
|
77
79
|
/** Internally-managed set of expanded node ids. */
|
|
78
80
|
readonly expanded: Set<string>;
|
|
@@ -113,4 +115,5 @@ export declare function createTree(config: TreeConfig): {
|
|
|
113
115
|
onkeydown: (e: KeyboardEvent) => void;
|
|
114
116
|
};
|
|
115
117
|
};
|
|
118
|
+
/** The headless tree instance returned by {@link createTree}. */
|
|
116
119
|
export type Tree = ReturnType<typeof createTree>;
|
|
@@ -87,6 +87,7 @@ export function sortTreeNodes(nodes, compare) {
|
|
|
87
87
|
.sort(compare)
|
|
88
88
|
.map((n) => (n.children ? { ...n, children: sortTreeNodes(n.children, compare) } : n));
|
|
89
89
|
}
|
|
90
|
+
/** Build the headless tree model: expansion, selection and checkbox cascading, with no markup. */
|
|
90
91
|
export function createTree(config) {
|
|
91
92
|
const nodes = () => config.nodes();
|
|
92
93
|
const checkable = () => config.checkable?.() ?? false;
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* - `firstDayOfWeek` is 0-6 (0 = Sunday), matching `Date.getDay()` and Smart's
|
|
10
10
|
* `firstDayOfWeek`.
|
|
11
11
|
*/
|
|
12
|
+
/** Anything the date helpers accept: a `Date`, epoch milliseconds, or a parseable string. */
|
|
12
13
|
export type DateLike = Date | number | string;
|
|
13
14
|
/** Coerce a Date | epoch-ms | parseable string to a Date, or null if invalid. */
|
|
14
15
|
export declare function toDate(value: DateLike | null | undefined): Date | null;
|
|
@@ -63,6 +64,7 @@ export declare function centuryRange(year: number): {
|
|
|
63
64
|
start: number;
|
|
64
65
|
end: number;
|
|
65
66
|
};
|
|
67
|
+
/** One cell of a month grid, including the leading and trailing days from adjacent months. */
|
|
66
68
|
export type MonthMatrixCell = {
|
|
67
69
|
date: Date;
|
|
68
70
|
/** In the displayed month (vs. leading/trailing days of adjacent months). */
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* still selectable). Mirrors Smart's calendar constraint model. Framework-free.
|
|
5
5
|
*/
|
|
6
6
|
import { type DateLike } from './date-core.js';
|
|
7
|
+
/** Which dates a picker allows: bounds, an explicit disabled set, and disabled weekdays. */
|
|
7
8
|
export type RestrictOptions = {
|
|
8
9
|
min?: DateLike | null;
|
|
9
10
|
max?: DateLike | null;
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* These functions are DST-aware and take no ambient "now" (safe for the model /
|
|
12
12
|
* headless contexts that forbid `Date.now()`).
|
|
13
13
|
*/
|
|
14
|
+
/** A wall-clock time broken into fields, as it reads in a specific time zone. */
|
|
14
15
|
export type ZoneParts = {
|
|
15
16
|
year: number;
|
|
16
17
|
month: number;
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* painting; all the surgery lives here and is unit-tested without a browser.
|
|
17
17
|
*/
|
|
18
18
|
import { type DockNode, type DockTabs, type DockPane, type DockZone, type IdGen } from './dock-model.js';
|
|
19
|
+
/** Which edge a pane docks against when dropped. */
|
|
19
20
|
export type DockSide = Exclude<DockZone, 'center'>;
|
|
20
21
|
/** A floating window: one tabs leaf shown in a movable/resizable frame. */
|
|
21
22
|
export type FloatWindow = {
|
|
@@ -40,6 +41,7 @@ export type AutoHideEntry = {
|
|
|
40
41
|
/** Fly-out panel size in px along the reveal axis. */
|
|
41
42
|
size: number;
|
|
42
43
|
};
|
|
44
|
+
/** The whole dock manager: its layout tree plus floating and pinned panes. */
|
|
43
45
|
export type DockManagerState = {
|
|
44
46
|
main: DockNode | null;
|
|
45
47
|
floating: FloatWindow[];
|
|
@@ -57,6 +59,7 @@ export type PaneLocation = {
|
|
|
57
59
|
kind: 'autoHide';
|
|
58
60
|
entryId: string;
|
|
59
61
|
};
|
|
62
|
+
/** Find a pane in the layout tree by id, returning it with its parent for mutation. */
|
|
60
63
|
export declare function locatePane(state: DockManagerState, paneId: string): PaneLocation | null;
|
|
61
64
|
/** Which surface holds a tabs leaf: 'main', a window id, or null. */
|
|
62
65
|
export declare function surfaceOfTabs(state: DockManagerState, tabsId: string): 'main' | string | null;
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* painting; all the surgery lives here and is unit-tested without a browser.
|
|
17
17
|
*/
|
|
18
18
|
import { tabs, dockInto, removePane as removePaneFromTree, removeLeaf, dockLeafToEdge, reorderPane, findTabsWithPane, allPaneIds, } from './dock-model.js';
|
|
19
|
+
/** Find a pane in the layout tree by id, returning it with its parent for mutation. */
|
|
19
20
|
export function locatePane(state, paneId) {
|
|
20
21
|
if (state.main && findTabsWithPane(state.main, paneId))
|
|
21
22
|
return { kind: 'main' };
|
package/dist/dock-model.d.ts
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* the drag gestures; all the tree surgery lives here so it is unit-testable
|
|
13
13
|
* without a browser. Modelled on Smart's `smart-layout` group/item structure.
|
|
14
14
|
*/
|
|
15
|
+
/** One dockable pane: its id, title, and the state a tab needs to render. */
|
|
15
16
|
export type DockPane = {
|
|
16
17
|
id: string;
|
|
17
18
|
title: string;
|
|
@@ -36,14 +37,19 @@ export type DockGroup = {
|
|
|
36
37
|
/** Size weight per child; parallel to `children`, normalized to sum ~1. */
|
|
37
38
|
sizes: number[];
|
|
38
39
|
};
|
|
40
|
+
/** A node in the layout tree - either a split group or a tabbed leaf. */
|
|
39
41
|
export type DockNode = DockGroup | DockTabs;
|
|
40
42
|
/** Where a dragged pane lands relative to a target leaf. */
|
|
41
43
|
export type DockZone = 'left' | 'right' | 'top' | 'bottom' | 'center';
|
|
44
|
+
/** Supplies ids for newly created nodes, so layouts stay deterministic in tests. */
|
|
42
45
|
export type IdGen = () => string;
|
|
46
|
+
/** Build a {@link DockPane}. */
|
|
43
47
|
export declare function pane(id: string, title: string, closable?: boolean): DockPane;
|
|
44
48
|
/** Largest per-pane `minSize` in a leaf (0 if none). Used by splitter clamping. */
|
|
45
49
|
export declare function leafMinSize(node: DockTabs): number;
|
|
50
|
+
/** Build a tabbed leaf holding the given panes. */
|
|
46
51
|
export declare function tabs(genId: IdGen, panes: DockPane[], active?: number): DockTabs;
|
|
52
|
+
/** Build a split group: panes or nested groups laid out in a row or column. */
|
|
47
53
|
export declare function group(genId: IdGen, direction: 'row' | 'column', children: DockNode[], sizes?: number[]): DockGroup;
|
|
48
54
|
/** Return sizes summing to 1, padded/trimmed to `count`. Even split when absent. */
|
|
49
55
|
export declare function normalizeSizes(sizes: number[] | undefined, count: number): number[];
|
package/dist/dock-model.js
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* without a browser. Modelled on Smart's `smart-layout` group/item structure.
|
|
14
14
|
*/
|
|
15
15
|
// ---- construction helpers -------------------------------------------------
|
|
16
|
+
/** Build a {@link DockPane}. */
|
|
16
17
|
export function pane(id, title, closable = true) {
|
|
17
18
|
return { id, title, closable };
|
|
18
19
|
}
|
|
@@ -20,9 +21,11 @@ export function pane(id, title, closable = true) {
|
|
|
20
21
|
export function leafMinSize(node) {
|
|
21
22
|
return node.panes.reduce((m, p) => Math.max(m, p.minSize ?? 0), 0);
|
|
22
23
|
}
|
|
24
|
+
/** Build a tabbed leaf holding the given panes. */
|
|
23
25
|
export function tabs(genId, panes, active = 0) {
|
|
24
26
|
return { type: 'tabs', id: genId(), panes, active: clampIndex(active, panes.length) };
|
|
25
27
|
}
|
|
28
|
+
/** Build a split group: panes or nested groups laid out in a row or column. */
|
|
26
29
|
export function group(genId, direction, children, sizes) {
|
|
27
30
|
return { type: 'group', id: genId(), direction, children, sizes: normalizeSizes(sizes, children.length) };
|
|
28
31
|
}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Framework-free (no Svelte, no DOM) so it can be unit-tested and reused.
|
|
11
11
|
*/
|
|
12
|
+
/** How much room a cell editor asks for, so the grid can size its overlay. */
|
|
12
13
|
export type EditorSize = 'sm' | 'md' | 'lg';
|
|
13
14
|
/**
|
|
14
15
|
* A small action button rendered inside a framed field (via `SvField`'s
|
package/dist/list-option.d.ts
CHANGED
|
@@ -48,6 +48,7 @@ export type VirtualListRow = {
|
|
|
48
48
|
opt: IndexedOption;
|
|
49
49
|
size: number;
|
|
50
50
|
};
|
|
51
|
+
/** A flattened option list plus its measurements, for virtualizing long dropdowns. */
|
|
51
52
|
export type FlatVirtualModel = {
|
|
52
53
|
/** Group headings + options in render order, each with its px height. */
|
|
53
54
|
entries: VirtualListRow[];
|