@r2digisolutions/ui 0.21.3 → 0.22.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.
Files changed (36) hide show
  1. package/dist/components/container/DataTable/DataTable.svelte +380 -0
  2. package/dist/components/container/DataTable/DataTable.svelte.d.ts +51 -0
  3. package/dist/components/container/DataTable/components/Cell.svelte +90 -0
  4. package/dist/components/container/DataTable/components/Cell.svelte.d.ts +30 -0
  5. package/dist/components/container/DataTable/components/ColumnVisibilityToggle.svelte +118 -0
  6. package/dist/components/container/DataTable/components/ColumnVisibilityToggle.svelte.d.ts +10 -0
  7. package/dist/components/container/DataTable/components/ContextMenu.svelte +203 -0
  8. package/dist/components/container/DataTable/components/ContextMenu.svelte.d.ts +21 -0
  9. package/dist/components/container/DataTable/components/FilterPanel.svelte +195 -0
  10. package/dist/components/container/DataTable/components/FilterPanel.svelte.d.ts +10 -0
  11. package/dist/components/container/DataTable/components/Pagination.svelte +59 -0
  12. package/dist/components/container/DataTable/components/Pagination.svelte.d.ts +11 -0
  13. package/dist/components/container/DataTable/components/QuickFilters.svelte +38 -0
  14. package/dist/components/container/DataTable/components/QuickFilters.svelte.d.ts +8 -0
  15. package/dist/components/container/DataTable/core/DataTableManager.svelte.d.ts +39 -0
  16. package/dist/components/container/DataTable/core/DataTableManager.svelte.js +245 -0
  17. package/dist/components/container/DataTable/core/filters/types.d.ts +18 -0
  18. package/dist/components/container/DataTable/core/filters/types.js +1 -0
  19. package/dist/components/container/DataTable/core/filters/utils.d.ts +3 -0
  20. package/dist/components/container/DataTable/core/filters/utils.js +43 -0
  21. package/dist/components/container/DataTable/core/types.d.ts +101 -0
  22. package/dist/components/container/DataTable/core/types.js +1 -0
  23. package/dist/components/container/DataTable/core/utils.d.ts +5 -0
  24. package/dist/components/container/DataTable/core/utils.js +66 -0
  25. package/dist/components/container/index.d.ts +2 -0
  26. package/dist/components/container/index.js +2 -0
  27. package/dist/components/ui/Card/Card.svelte +8 -8
  28. package/dist/components/ui/Card/CardContent.svelte +11 -3
  29. package/dist/components/ui/Card/CardContent.svelte.d.ts +8 -10
  30. package/dist/components/ui/Card/CardFooter.svelte +12 -2
  31. package/dist/components/ui/Card/CardFooter.svelte.d.ts +7 -3
  32. package/dist/components/ui/Card/CardHeader.svelte +10 -2
  33. package/dist/components/ui/Card/CardHeader.svelte.d.ts +7 -3
  34. package/dist/index.d.ts +1 -0
  35. package/dist/index.js +1 -0
  36. package/package.json +27 -27
@@ -0,0 +1,203 @@
1
+ <script module lang="ts">
2
+ export type Entry = {
3
+ id: string;
4
+ label?: string;
5
+ shortcut?: string;
6
+ onClick?: () => void;
7
+ disabled?: boolean;
8
+ children?: Entry[];
9
+ kind?: 'item' | 'divider' | 'label';
10
+ };
11
+ </script>
12
+
13
+ <script lang="ts">
14
+ type Props = {
15
+ items?: Entry[];
16
+ x?: number;
17
+ y?: number;
18
+ open?: boolean;
19
+ title?: string;
20
+ searchable?: boolean;
21
+ context?: any;
22
+ };
23
+ let {
24
+ items = [],
25
+ x = 0,
26
+ y = 0,
27
+ open = $bindable(false),
28
+ title = '',
29
+ searchable = true,
30
+ context = null
31
+ }: Props = $props();
32
+
33
+ let stack = $state<{ label: string; items: Entry[] }[]>([]);
34
+ let q = $state('');
35
+
36
+ const current = $derived(stack.length ? stack[stack.length - 1] : { label: title, items });
37
+
38
+ function close() {
39
+ open = false;
40
+ stack = [];
41
+ q = '';
42
+ }
43
+
44
+ function hasChildren(it: Entry) {
45
+ return !!(it.children && it.children.length);
46
+ }
47
+
48
+ function clickItem(it: Entry) {
49
+ if (it.disabled) return;
50
+ if (hasChildren(it)) {
51
+ stack.push({ label: it.label ?? '', items: it.children! });
52
+ q = '';
53
+ return;
54
+ }
55
+ if (it.kind !== 'divider' && it.kind !== 'label') {
56
+ it.onClick?.();
57
+ close();
58
+ }
59
+ }
60
+
61
+ function matches(it: Entry, query: string): boolean {
62
+ if (it.kind === 'divider') return true;
63
+ const lbl = (it.label ?? '').toLowerCase();
64
+ if (lbl.includes(query)) return true;
65
+ if (hasChildren(it)) return it.children!.some((c) => matches(c, query));
66
+ return false;
67
+ }
68
+
69
+ const filtered = $derived.by(() => {
70
+ const list = current.items ?? [];
71
+ const query = q.trim().toLowerCase();
72
+ let arr = query ? list.filter((it) => matches(it, query)) : list.slice();
73
+
74
+ // limpiar divisores (sin duplicados, ni al principio/fin)
75
+ const out: Entry[] = [];
76
+ let prevDiv = false;
77
+ for (const it of arr) {
78
+ if (it.kind === 'divider') {
79
+ if (out.length === 0 || prevDiv) continue;
80
+ prevDiv = true;
81
+ out.push(it);
82
+ } else {
83
+ prevDiv = false;
84
+ out.push(it);
85
+ }
86
+ }
87
+ if (out.length && out[out.length - 1].kind === 'divider') out.pop();
88
+ return out;
89
+ });
90
+
91
+ function back() {
92
+ if (stack.length) {
93
+ stack.pop();
94
+ q = '';
95
+ }
96
+ }
97
+
98
+ function onKey(e: KeyboardEvent) {
99
+ if (e.key === 'Escape') {
100
+ if (stack.length) back();
101
+ else close();
102
+ } else if (e.key === 'Backspace' && q === '' && stack.length) {
103
+ back();
104
+ }
105
+ }
106
+
107
+ $effect(() => {
108
+ if (!open) return;
109
+ const handler = (e: KeyboardEvent) => onKey(e);
110
+ document.addEventListener('keydown', handler);
111
+ return () => document.removeEventListener('keydown', handler);
112
+ });
113
+ </script>
114
+
115
+ {#if open}
116
+ <div
117
+ role="dialog"
118
+ class="fixed inset-0 z-40"
119
+ onclick={() => close()}
120
+ oncontextmenu={(e) => e.preventDefault()}
121
+ aria-modal="true"
122
+ tabindex="0"
123
+ />
124
+
125
+ <div
126
+ class="fixed z-50 w-72 rounded-2xl bg-white p-2 shadow-xl ring-1 ring-black/5 dark:bg-gray-900"
127
+ style={`left:${x}px; top:${y}px`}
128
+ oncontextmenu={(e) => e.preventDefault()}
129
+ >
130
+ <div class="flex items-center gap-1 px-1 py-1">
131
+ {#if stack.length > 0}
132
+ <button
133
+ class="rounded-lg p-1 hover:bg-gray-100 dark:hover:bg-gray-800"
134
+ role="dialog"
135
+ aria-label="Atrás"
136
+ onclick={back}
137
+ >
138
+ <svg
139
+ width="16"
140
+ height="16"
141
+ viewBox="0 0 24 24"
142
+ fill="none"
143
+ stroke="currentColor"
144
+ stroke-width="2"
145
+ stroke-linecap="round"
146
+ stroke-linejoin="round"><polyline points="15 18 9 12 15 6" /></svg
147
+ >
148
+ </button>
149
+ {/if}
150
+ <div class="min-w-0 flex-1 truncate px-1 text-xs font-medium opacity-70">
151
+ {current.label || title}
152
+ </div>
153
+ {#if searchable}
154
+ <input
155
+ class="w-28 rounded-lg border border-gray-200 px-2 py-1 text-xs dark:border-gray-800 dark:bg-gray-950"
156
+ placeholder="Buscar…"
157
+ bind:value={q}
158
+ />
159
+ {/if}
160
+ </div>
161
+
162
+ <div
163
+ class="max-h-72 overflow-auto rounded-xl border border-gray-200 p-1 dark:border-gray-800 dark:bg-gray-950"
164
+ >
165
+ {#each filtered as it}
166
+ {#if it.kind === 'divider'}
167
+ <div class="my-1 border-t border-gray-200 dark:border-gray-800"></div>
168
+ {:else if it.kind === 'label'}
169
+ <div class="px-3 py-1 text-[11px] tracking-wide uppercase opacity-60">{it.label}</div>
170
+ {:else}
171
+ <button
172
+ class="flex w-full items-center justify-between gap-3 px-3 py-2 text-left text-sm hover:bg-gray-100 disabled:opacity-50 dark:hover:bg-gray-800"
173
+ role="dialog"
174
+ disabled={it.disabled}
175
+ onclick={() => clickItem(it)}
176
+ >
177
+ <span class="truncate">{it.label}</span>
178
+ <span class="flex items-center gap-2">
179
+ {#if it.shortcut}
180
+ <kbd class="rounded bg-gray-100 px-1 text-[10px] dark:bg-gray-800"
181
+ >{it.shortcut}</kbd
182
+ >
183
+ {/if}
184
+ {#if hasChildren(it)}
185
+ <svg
186
+ width="14"
187
+ height="14"
188
+ viewBox="0 0 24 24"
189
+ class="opacity-60"
190
+ fill="none"
191
+ stroke="currentColor"
192
+ stroke-width="2"
193
+ stroke-linecap="round"
194
+ stroke-linejoin="round"><polyline points="9 18 15 12 9 6" /></svg
195
+ >
196
+ {/if}
197
+ </span>
198
+ </button>
199
+ {/if}
200
+ {/each}
201
+ </div>
202
+ </div>
203
+ {/if}
@@ -0,0 +1,21 @@
1
+ export type Entry = {
2
+ id: string;
3
+ label?: string;
4
+ shortcut?: string;
5
+ onClick?: () => void;
6
+ disabled?: boolean;
7
+ children?: Entry[];
8
+ kind?: 'item' | 'divider' | 'label';
9
+ };
10
+ type Props = {
11
+ items?: Entry[];
12
+ x?: number;
13
+ y?: number;
14
+ open?: boolean;
15
+ title?: string;
16
+ searchable?: boolean;
17
+ context?: any;
18
+ };
19
+ declare const ContextMenu: import("svelte").Component<Props, {}, "open">;
20
+ type ContextMenu = ReturnType<typeof ContextMenu>;
21
+ export default ContextMenu;
@@ -0,0 +1,195 @@
1
+ <script lang="ts">
2
+ import Input from '@UI/Input/Input.svelte';
3
+ import type { FilterField } from '../core/filters/types';
4
+ import { buildFilterDefs } from '../core/filters/utils';
5
+ import Checkbox from '@UI/Checkbox/Checkbox.svelte';
6
+ import Button from '@UI/buttons/Button.svelte';
7
+ import { Check, X } from 'lucide-svelte';
8
+
9
+ interface Props {
10
+ fields: FilterField<any>[];
11
+ values?: Record<string, any>;
12
+ onapply?: (defs: any[], values: Record<string, any>) => void;
13
+ onclear?: () => void;
14
+ }
15
+
16
+ const { fields, values = $bindable<Record<string, any>>({}), onapply, onclear }: Props = $props();
17
+
18
+ let open = $state(false);
19
+
20
+ const count = $derived(
21
+ Object.values(values).reduce(
22
+ (n, v) =>
23
+ n +
24
+ (v == null || v === ''
25
+ ? 0
26
+ : Array.isArray(v)
27
+ ? v.length > 0
28
+ ? 1
29
+ : 0
30
+ : typeof v === 'object'
31
+ ? v.min != null || v.max != null
32
+ ? 1
33
+ : 0
34
+ : 1),
35
+ 0
36
+ )
37
+ );
38
+ function setValue(id: string, v: any) {
39
+ values[id] = v;
40
+ }
41
+ function toggleArray(id: string, v: any) {
42
+ const arr = Array.isArray(values[id]) ? [...values[id]] : [];
43
+ const i = arr.findIndex((x) => x === v);
44
+ if (i >= 0) arr.splice(i, 1);
45
+ else arr.push(v);
46
+ values[id] = arr;
47
+ }
48
+ function apply() {
49
+ const defs = buildFilterDefs(fields, values);
50
+ onapply?.(defs, values);
51
+ open = false;
52
+ }
53
+ function clear() {
54
+ for (const k of Object.keys(values)) delete values[k];
55
+ onclear?.();
56
+ }
57
+ </script>
58
+
59
+ <div class="relative">
60
+ <button
61
+ class="inline-flex cursor-pointer items-center gap-2 rounded-xl border border-gray-200 px-3 py-2 text-sm hover:bg-gray-50 dark:border-gray-800 dark:hover:bg-gray-900"
62
+ onclick={() => (open = !open)}
63
+ >
64
+ <svg
65
+ width="16"
66
+ height="16"
67
+ viewBox="0 0 24 24"
68
+ fill="none"
69
+ stroke="currentColor"
70
+ stroke-width="2"><polygon points="3 5 21 5 14 13 14 19 10 21 10 13 3 5" /></svg
71
+ >
72
+ Filtros
73
+ {#if count > 0}
74
+ <span class="rounded bg-purple-600 px-1 text-[11px] text-white">{count}</span>
75
+ {/if}
76
+ </button>
77
+ {#if open}
78
+ <div
79
+ role="dialog"
80
+ class="fixed inset-0 z-40"
81
+ onclick={() => (open = false)}
82
+ oncontextmenu={(e) => e.preventDefault()}
83
+ aria-modal="true"
84
+ tabindex="0"
85
+ />
86
+ <div
87
+ class="absolute z-50 mt-2 w-80 rounded-2xl border border-gray-200 bg-white p-4 shadow-xl ring-1 ring-black/5 dark:border-gray-800 dark:bg-gray-900"
88
+ >
89
+ <div class="mb-3 text-sm font-medium">Filtros</div>
90
+ <div class="space-y-3">
91
+ {#each fields as f}
92
+ {#if f.type === 'text'}
93
+ <Input
94
+ label={f.label}
95
+ type="text"
96
+ placeholder={f.placeholder}
97
+ value={values[f.id]}
98
+ onchange={(e) => (values[f.id] = e)}
99
+ />
100
+ {:else if f.type === 'number'}
101
+ <Input
102
+ label={f.label}
103
+ type="number"
104
+ min={f.min}
105
+ max={f.max}
106
+ step={f.step}
107
+ value={values[f.id]}
108
+ onchange={(e) => (values[f.id] = e)}
109
+ />
110
+ {:else if f.type === 'date'}
111
+ <Input
112
+ label={f.label}
113
+ type="date"
114
+ value={values[f.id]}
115
+ onchange={(e) => (values[f.id] = e)}
116
+ />
117
+ {:else if f.type === 'checkbox'}
118
+ <Checkbox checked={values[f.id]} label={f.label} onchange={(e) => (values[f.id] = e)} />
119
+ {:else if f.type === 'select'}
120
+ <div>
121
+ <label class="mb-1 block text-xs opacity-70">{f.label}</label>
122
+ <select
123
+ class="w-full rounded-xl border border-gray-200 px-3 py-2 dark:border-gray-800"
124
+ bind:value={values[f.id]}
125
+ >
126
+ <option value="">Todos</option>
127
+ {#each f.options ?? [] as opt}
128
+ <option value={opt.value}>{opt.label}</option>
129
+ {/each}
130
+ </select>
131
+ </div>
132
+ {:else if f.type === 'multiselect'}
133
+ <div>
134
+ <label class="mb-1 block text-xs opacity-70">{f.label}</label>
135
+ <div class="max-h-40 overflow-auto rounded-xl border p-2">
136
+ {#each f.options ?? [] as opt}
137
+ <Checkbox
138
+ checked={(values[f.id] ?? []).includes(opt.value)}
139
+ onchange={() => toggleArray(f.id, opt.value)}
140
+ label={opt.label}
141
+ />
142
+ {/each}
143
+ </div>
144
+ </div>
145
+ {:else if f.type === 'range'}
146
+ <div>
147
+ <label class="mb-1 block text-xs opacity-70">{f.label}</label>
148
+ <div class="grid grid-cols-2 gap-2">
149
+ <Input
150
+ type="number"
151
+ placeholder="Min"
152
+ min={f.min}
153
+ max={f.max}
154
+ step={f.step}
155
+ value={values[f.id]?.min ?? 0}
156
+ onchange={(e) => (values[f.id].min = e)}
157
+ />
158
+ <Input
159
+ type="number"
160
+ placeholder="Max"
161
+ min={f.min}
162
+ max={f.max}
163
+ step={f.step}
164
+ value={values[f.id]?.max ?? 0}
165
+ onchange={(e) => (values[f.id].max = e)}
166
+ />
167
+ </div>
168
+ </div>
169
+ {:else if f.type === 'rating'}
170
+ <div>
171
+ <label class="mb-1 block text-xs opacity-70">{f.label}</label>
172
+ <select class="w-full rounded-xl border px-3 py-2" bind:value={values[f.id]}>
173
+ <option value="">Cualquiera</option>
174
+ <option value="4">4+</option>
175
+ <option value="3">3+</option>
176
+ <option value="2">2+</option>
177
+ <option value="1">1+</option>
178
+ </select>
179
+ </div>
180
+ {/if}
181
+ {/each}
182
+ </div>
183
+ <div class="mt-4 flex gap-2">
184
+ <Button variant="outline" onclick={() => clear()}>
185
+ <X class="h-4 w-4" />
186
+ Limpiar
187
+ </Button>
188
+ <Button onclick={() => apply()}>
189
+ <Check class="h-4 w-4" />
190
+ Aplicar
191
+ </Button>
192
+ </div>
193
+ </div>
194
+ {/if}
195
+ </div>
@@ -0,0 +1,10 @@
1
+ import type { FilterField } from '../core/filters/types';
2
+ interface Props {
3
+ fields: FilterField<any>[];
4
+ values?: Record<string, any>;
5
+ onapply?: (defs: any[], values: Record<string, any>) => void;
6
+ onclear?: () => void;
7
+ }
8
+ declare const FilterPanel: import("svelte").Component<Props, {}, "values">;
9
+ type FilterPanel = ReturnType<typeof FilterPanel>;
10
+ export default FilterPanel;
@@ -0,0 +1,59 @@
1
+ <script lang="ts">
2
+ import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-svelte';
3
+
4
+ interface Props {
5
+ page: number;
6
+ perPage: number;
7
+ total: number;
8
+ perPageOptions?: number[];
9
+ onchange?: (p: number) => void;
10
+ onperpage?: (n: number) => void;
11
+ }
12
+
13
+ let {
14
+ page,
15
+ perPage = $bindable(10),
16
+ total,
17
+ perPageOptions = [10, 20, 50, 100],
18
+ onchange,
19
+ onperpage
20
+ }: Props = $props();
21
+
22
+ const totalPages = $derived(Math.max(1, Math.ceil(total / perPage)));
23
+
24
+ function go(n: number) {
25
+ if (n < 1 || n > totalPages) return;
26
+ onchange?.(n);
27
+ }
28
+ </script>
29
+
30
+ <div class="flex flex-col items-center justify-between gap-3 sm:flex-row">
31
+ <div class="text-sm opacity-70">Página {page} de {totalPages} — {total} filas</div>
32
+ <div class="flex items-center gap-2">
33
+ <select
34
+ class="rounded-xl border border-gray-200 px-2 py-1 pr-6 dark:border-gray-800"
35
+ bind:value={perPage}
36
+ onchange={(e) => onperpage?.(Number((e.target as HTMLSelectElement).value))}
37
+ >
38
+ {#each perPageOptions as n}<option value={n}>{n} / pág</option>{/each}
39
+ </select>
40
+ <div class="inline-flex overflow-hidden rounded-xl border border-gray-200 dark:border-gray-800">
41
+ <button
42
+ class="flex items-center gap-2 px-3 py-1.5 disabled:opacity-40"
43
+ disabled={page <= 1}
44
+ onclick={() => go(page - 1)}
45
+ >
46
+ <ChevronLeftIcon class="h-4 w-4" />
47
+ Prev
48
+ </button>
49
+ <button
50
+ class="flex items-center gap-2 px-3 py-1.5 disabled:opacity-40"
51
+ disabled={page >= totalPages}
52
+ onclick={() => go(page + 1)}
53
+ >
54
+ Next
55
+ <ChevronRightIcon class="h-4 w-4" />
56
+ </button>
57
+ </div>
58
+ </div>
59
+ </div>
@@ -0,0 +1,11 @@
1
+ interface Props {
2
+ page: number;
3
+ perPage: number;
4
+ total: number;
5
+ perPageOptions?: number[];
6
+ onchange?: (p: number) => void;
7
+ onperpage?: (n: number) => void;
8
+ }
9
+ declare const Pagination: import("svelte").Component<Props, {}, "perPage">;
10
+ type Pagination = ReturnType<typeof Pagination>;
11
+ export default Pagination;
@@ -0,0 +1,38 @@
1
+ <script lang="ts">
2
+ import type { FilterDef } from '../core/types';
3
+
4
+ interface Props {
5
+ filters: FilterDef<any>[];
6
+ onapply: (filters: FilterDef<any>[]) => void;
7
+ }
8
+
9
+ const { filters, onapply }: Props = $props();
10
+
11
+ let text = $state('');
12
+
13
+ function submit() {
14
+ const base = filters.filter((f) => f.meta?.kind !== 'quick');
15
+ const q: FilterDef<any> = {
16
+ id: 'q',
17
+ label: 'Búsqueda',
18
+ op: 'contains',
19
+ value: text,
20
+ meta: { kind: 'quick', column: 'all' }
21
+ };
22
+ onapply([...base, q]);
23
+ }
24
+ </script>
25
+
26
+ <div class="flex items-center gap-2">
27
+ <input
28
+ class="w-64 rounded-xl border px-3 py-2"
29
+ placeholder="Buscar…"
30
+ bind:value={text}
31
+ onkeydown={(e) => e.key === 'Enter' && submit()}
32
+ />
33
+ <button
34
+ type="button"
35
+ class="rounded-xl bg-black px-3 py-2 text-white dark:bg-white dark:text-black"
36
+ onclick={submit}>Aplicar</button
37
+ >
38
+ </div>
@@ -0,0 +1,8 @@
1
+ import type { FilterDef } from '../core/types';
2
+ interface Props {
3
+ filters: FilterDef<any>[];
4
+ onapply: (filters: FilterDef<any>[]) => void;
5
+ }
6
+ declare const QuickFilters: import("svelte").Component<Props, {}, "">;
7
+ type QuickFilters = ReturnType<typeof QuickFilters>;
8
+ export default QuickFilters;
@@ -0,0 +1,39 @@
1
+ import { SvelteSet } from 'svelte/reactivity';
2
+ import type { TableOptions, TableState, VisibilityPlan } from './types.js';
3
+ export declare class DataTableManager<T extends {
4
+ id?: any;
5
+ } = any> {
6
+ options: TableOptions<T>;
7
+ state: TableState<T>;
8
+ measured: Record<string, number>;
9
+ reservedWidth: number;
10
+ forcedVisible: SvelteSet<string>;
11
+ forcedHidden: SvelteSet<string>;
12
+ expanded: SvelteSet<any>;
13
+ lastWidth: number | null;
14
+ constructor(opts: TableOptions<T>);
15
+ setMeasuredWidths(map: Record<string, number>): void;
16
+ get columns(): import("./types.js").ColumnDef<T>[];
17
+ getColumn(id: string): import("./types.js").ColumnDef<T>;
18
+ isExpanded(id: any): boolean;
19
+ toggleExpand(id: any): void;
20
+ setColumnVisibility(id: string, show: boolean): void;
21
+ setReservedWidth(n: number): void;
22
+ clearColumnOverrides(): void;
23
+ visibilityPlan(containerWidth: number): VisibilityPlan;
24
+ private mergeWithOverrides;
25
+ applyVisibility(plan: VisibilityPlan): void;
26
+ reflowForWidth(width: number): void;
27
+ reflow(): void;
28
+ setPerPage(n: number): Promise<void>;
29
+ setPage(p: number): Promise<void>;
30
+ setSort(id: string): Promise<void>;
31
+ setFilters(filters: typeof this.state.filters): Promise<void>;
32
+ clearFilters(): Promise<void>;
33
+ toggleSelect(rowId: any): void;
34
+ clearSelection(): void;
35
+ selectAllCurrentPage(getId?: (row: T) => any): void;
36
+ load(): Promise<void>;
37
+ private loadRemote;
38
+ private loadLocal;
39
+ }