@spaethtech/svelte-ui 0.18.0 → 0.18.1-dev.88.f4b29b6
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.
|
@@ -223,6 +223,9 @@ examples):
|
|
|
223
223
|
the query, filters via **`matchesRow(row, ast)`** (the in-memory AST evaluator: cmp/and/or/not/
|
|
224
224
|
match/in/range/search, honouring column `id`/`searchable`/`sortKey`), then sorts + paginates. Only a
|
|
225
225
|
remote/DB backend needs to compile the AST itself; do NOT hand-roll a "strip `$` + substring" filter.
|
|
226
|
+
`createGrid` also takes **`selectableRow: (row) => boolean`** — rows returning `false` are locked out
|
|
227
|
+
of selection (disabled checkbox, excluded from select-all, never in `grid.selected`), so
|
|
228
|
+
`bulkActions(selected)` never sees them; don't filter locked ids in the handler.
|
|
226
229
|
· **`Pagination`** (standalone
|
|
227
230
|
pager styled like the DataTable footer: tinted band, per-page `Select`, range total, and a
|
|
228
231
|
`First·Prev·[page]/N·Next·Last` stepper whose indicator is an editable `NumberInput` quick-jump;
|
|
@@ -9,6 +9,9 @@ export type GridOptions<T> = {
|
|
|
9
9
|
perPageOptions?: number[];
|
|
10
10
|
initialQuery?: string;
|
|
11
11
|
initialSort?: Sort | null;
|
|
12
|
+
/** Per-row selection lock. Return `false` to make a row non-selectable: its checkbox is disabled,
|
|
13
|
+
* it's excluded from select-all, and `toggleRow`/`selected` never include it. Default: all selectable. */
|
|
14
|
+
selectableRow?: (row: T) => boolean;
|
|
12
15
|
};
|
|
13
16
|
/**
|
|
14
17
|
* Shared, reactive controller for a data table. Implements {@link DataSet} (so any `<Query>` can
|
|
@@ -20,6 +23,7 @@ export declare class DataGrid<T> implements DataSet {
|
|
|
20
23
|
readonly fetch: FetchFn<T>;
|
|
21
24
|
readonly getRowId: (row: T) => string;
|
|
22
25
|
readonly perPageOptions: number[];
|
|
26
|
+
readonly selectableRow: (row: T) => boolean;
|
|
23
27
|
query: string;
|
|
24
28
|
applied: string;
|
|
25
29
|
error: string | null;
|
|
@@ -43,6 +47,10 @@ export declare class DataGrid<T> implements DataSet {
|
|
|
43
47
|
setPage(p: number): void;
|
|
44
48
|
setPerPage(n: number): void;
|
|
45
49
|
get pageIds(): string[];
|
|
50
|
+
/** Whether a row may be selected (per `selectableRow`); unknown ids default selectable. */
|
|
51
|
+
isRowSelectable(id: string): boolean;
|
|
52
|
+
/** Current-page ids that are actually selectable — the set select-all operates over. */
|
|
53
|
+
get selectableIds(): string[];
|
|
46
54
|
isSelected(id: string): boolean;
|
|
47
55
|
toggleRow(id: string): void;
|
|
48
56
|
get allSelected(): boolean;
|
|
@@ -10,6 +10,7 @@ export class DataGrid {
|
|
|
10
10
|
fetch;
|
|
11
11
|
getRowId;
|
|
12
12
|
perPageOptions;
|
|
13
|
+
selectableRow;
|
|
13
14
|
query = $state("");
|
|
14
15
|
applied = $state("");
|
|
15
16
|
error = $state(null);
|
|
@@ -25,6 +26,7 @@ export class DataGrid {
|
|
|
25
26
|
this.columns = opts.columns;
|
|
26
27
|
this.fetch = opts.fetch;
|
|
27
28
|
this.getRowId = opts.getRowId ?? ((r) => String(r.id));
|
|
29
|
+
this.selectableRow = opts.selectableRow ?? (() => true);
|
|
28
30
|
this.perPage = opts.perPage ?? 25;
|
|
29
31
|
this.perPageOptions = opts.perPageOptions ?? [10, 25, 50, 100];
|
|
30
32
|
this.sort = opts.initialSort ?? null;
|
|
@@ -86,24 +88,35 @@ export class DataGrid {
|
|
|
86
88
|
get pageIds() {
|
|
87
89
|
return this.rows.map((r) => this.getRowId(r));
|
|
88
90
|
}
|
|
91
|
+
/** Whether a row may be selected (per `selectableRow`); unknown ids default selectable. */
|
|
92
|
+
isRowSelectable(id) {
|
|
93
|
+
const row = this.rows.find((r) => this.getRowId(r) === id);
|
|
94
|
+
return row === undefined ? true : this.selectableRow(row);
|
|
95
|
+
}
|
|
96
|
+
/** Current-page ids that are actually selectable — the set select-all operates over. */
|
|
97
|
+
get selectableIds() {
|
|
98
|
+
return this.rows.filter((r) => this.selectableRow(r)).map((r) => this.getRowId(r));
|
|
99
|
+
}
|
|
89
100
|
isSelected(id) {
|
|
90
101
|
return this.selected.has(id);
|
|
91
102
|
}
|
|
92
103
|
toggleRow(id) {
|
|
104
|
+
if (!this.isRowSelectable(id))
|
|
105
|
+
return; // locked rows never enter `selected`
|
|
93
106
|
if (this.selected.has(id))
|
|
94
107
|
this.selected.delete(id);
|
|
95
108
|
else
|
|
96
109
|
this.selected.add(id);
|
|
97
110
|
}
|
|
98
111
|
get allSelected() {
|
|
99
|
-
const ids = this.
|
|
112
|
+
const ids = this.selectableIds;
|
|
100
113
|
return ids.length > 0 && ids.every((id) => this.selected.has(id));
|
|
101
114
|
}
|
|
102
115
|
get someSelected() {
|
|
103
|
-
return this.
|
|
116
|
+
return this.selectableIds.some((id) => this.selected.has(id)) && !this.allSelected;
|
|
104
117
|
}
|
|
105
118
|
toggleAll() {
|
|
106
|
-
const ids = this.
|
|
119
|
+
const ids = this.selectableIds;
|
|
107
120
|
if (this.allSelected)
|
|
108
121
|
ids.forEach((id) => this.selected.delete(id));
|
|
109
122
|
else
|
package/docs/components.md
CHANGED
|
@@ -384,6 +384,10 @@ Config-driven, responsive 12-column data table over a `DataGrid`.
|
|
|
384
384
|
- **`rowActions` per row**: return `null`/`undefined`/`[]` for a row with no actions — the kebab still
|
|
385
385
|
renders (the tail column stays aligned across rows) but is **disabled**, rather than opening an empty
|
|
386
386
|
or all-greyed menu. Return items to enable it.
|
|
387
|
+
- **Per-row selection lock**: pass **`selectableRow: (row) => boolean`** to `createGrid`. Rows where it
|
|
388
|
+
returns `false` get a disabled checkbox, are excluded from select-all (`toggleAll`/`allSelected`/
|
|
389
|
+
`someSelected` operate only over selectable rows), and can never enter `grid.selected` — so
|
|
390
|
+
`bulkActions(selected)` never sees them (no need to re-filter in the handler). Default: all selectable.
|
|
387
391
|
- **Links in an expandable table**: wrap only the **text** in `<a>` inside your `cell` snippet (not the
|
|
388
392
|
whole cell). The cell is a flex box, so a plain inline `<a>text</a>` is text-width — the rest of the
|
|
389
393
|
cell stays an expand/collapse target. Row-click already ignores clicks on `a`/`button`/`input`/…, so
|
package/docs/usage.md
CHANGED