@oscarpalmer/tabela 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/body.component.js +2 -15
- package/dist/components/footer.component.js +3 -3
- package/dist/components/header.component.js +2 -2
- package/dist/components/row.component.js +13 -4
- package/dist/helpers/dom.helpers.js +5 -10
- package/dist/helpers/misc.helpers.js +7 -0
- package/dist/helpers/style.helper.js +6 -0
- package/dist/managers/column.manager.js +7 -2
- package/dist/managers/data.manager.js +6 -4
- package/dist/managers/event.manager.js +6 -2
- package/dist/managers/filter.manager.js +92 -0
- package/dist/managers/{virtualization.manager.js → render.manager.js} +28 -22
- package/dist/managers/row.manager.js +9 -2
- package/dist/managers/selection.manager.js +191 -0
- package/dist/managers/sort.manager.js +17 -6
- package/dist/models/render.model.js +0 -0
- package/dist/tabela.full.js +1253 -105
- package/dist/tabela.js +19 -6
- package/package.json +1 -1
- package/src/components/body.component.ts +4 -21
- package/src/components/footer.component.ts +3 -3
- package/src/components/header.component.ts +2 -2
- package/src/components/row.component.ts +22 -7
- package/src/helpers/dom.helpers.ts +3 -10
- package/src/helpers/misc.helpers.ts +15 -0
- package/src/helpers/style.helper.ts +6 -0
- package/src/managers/column.manager.ts +9 -1
- package/src/managers/data.manager.ts +9 -5
- package/src/managers/event.manager.ts +10 -3
- package/src/managers/filter.manager.ts +154 -0
- package/src/managers/{virtualization.manager.ts → render.manager.ts} +36 -31
- package/src/managers/row.manager.ts +16 -2
- package/src/managers/selection.manager.ts +338 -0
- package/src/managers/sort.manager.ts +35 -16
- package/src/models/filter.model.ts +17 -0
- package/src/models/{virtualization.model.ts → render.model.ts} +3 -3
- package/src/models/sort.model.ts +1 -1
- package/src/models/tabela.model.ts +22 -2
- package/src/tabela.ts +28 -6
- package/types/components/row.component.d.ts +2 -2
- package/types/helpers/dom.helpers.d.ts +1 -1
- package/types/helpers/misc.helpers.d.ts +2 -0
- package/types/helpers/style.helper.d.ts +1 -0
- package/types/managers/data.manager.d.ts +1 -1
- package/types/managers/event.manager.d.ts +1 -1
- package/types/managers/filter.manager.d.ts +19 -0
- package/types/managers/{virtualization.manager.d.ts → render.manager.d.ts} +6 -6
- package/types/managers/selection.manager.d.ts +19 -0
- package/types/managers/sort.manager.d.ts +5 -2
- package/types/models/filter.model.d.ts +6 -0
- package/types/models/{virtualization.model.d.ts → render.model.d.ts} +3 -3
- package/types/models/sort.model.d.ts +1 -1
- package/types/models/tabela.model.d.ts +20 -2
- package/types/tabela.d.ts +3 -1
- /package/dist/models/{virtualization.model.js → filter.model.js} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type {Key} from '@oscarpalmer/atoms/models';
|
|
2
|
-
import {renderRow, RowComponent} from '../components/row.component';
|
|
2
|
+
import {removeRow, renderRow, RowComponent} from '../components/row.component';
|
|
3
3
|
import type {TabelaManagers} from '../models/tabela.model';
|
|
4
4
|
|
|
5
5
|
export class RowManager {
|
|
@@ -15,6 +15,14 @@ export class RowManager {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
destroy(): void {
|
|
18
|
+
const components = [...this.components.values()];
|
|
19
|
+
|
|
20
|
+
const {length} = components;
|
|
21
|
+
|
|
22
|
+
for (let index = 0; index < length; index += 1) {
|
|
23
|
+
removeRow(this.managers.render.pool, components[index]);
|
|
24
|
+
}
|
|
25
|
+
|
|
18
26
|
this.components.clear();
|
|
19
27
|
}
|
|
20
28
|
|
|
@@ -35,7 +43,13 @@ export class RowManager {
|
|
|
35
43
|
}
|
|
36
44
|
|
|
37
45
|
remove(key: Key): void {
|
|
38
|
-
this.components.
|
|
46
|
+
const row = this.components.get(key);
|
|
47
|
+
|
|
48
|
+
if (row != null) {
|
|
49
|
+
removeRow(this.managers.render.pool, row);
|
|
50
|
+
|
|
51
|
+
this.components.delete(key);
|
|
52
|
+
}
|
|
39
53
|
}
|
|
40
54
|
|
|
41
55
|
update(key: Key): void {
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
import {isKey} from '@oscarpalmer/atoms/is';
|
|
2
|
+
import type {Key} from '@oscarpalmer/atoms/models';
|
|
3
|
+
import {findAncestor, type EventPosition} from '@oscarpalmer/toretto';
|
|
4
|
+
import {setAttribute} from '@oscarpalmer/toretto/attribute';
|
|
5
|
+
import {getPosition, on} from '@oscarpalmer/toretto/event';
|
|
6
|
+
import {createElement} from '../helpers/dom.helpers';
|
|
7
|
+
import {getKey} from '../helpers/misc.helpers';
|
|
8
|
+
import {dragStyling} from '../helpers/style.helper';
|
|
9
|
+
import type {TabelaManagers, TabelaSelection} from '../models/tabela.model';
|
|
10
|
+
|
|
11
|
+
export class SelectionManager {
|
|
12
|
+
handlers = Object.freeze({
|
|
13
|
+
clear: () => this.clear(),
|
|
14
|
+
deselect: keys => this.deselect(keys),
|
|
15
|
+
select: keys => this.select(keys),
|
|
16
|
+
toggle: () => this.toggle(),
|
|
17
|
+
} as TabelaSelection);
|
|
18
|
+
|
|
19
|
+
items = new Set<Key>();
|
|
20
|
+
|
|
21
|
+
last: Key | undefined;
|
|
22
|
+
|
|
23
|
+
constructor(
|
|
24
|
+
public element: HTMLElement,
|
|
25
|
+
readonly managers: TabelaManagers,
|
|
26
|
+
) {
|
|
27
|
+
mapped.set(element, this);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
clear(): void {
|
|
31
|
+
if (this.items.size === 0) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const removed = [...this.items];
|
|
36
|
+
|
|
37
|
+
this.items.clear();
|
|
38
|
+
|
|
39
|
+
this.update(removed);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
deselect(keys: Key[]): void {
|
|
43
|
+
const {length} = keys;
|
|
44
|
+
|
|
45
|
+
const removed: Key[] = [];
|
|
46
|
+
|
|
47
|
+
for (let index = 0; index < length; index += 1) {
|
|
48
|
+
const key = keys[index];
|
|
49
|
+
|
|
50
|
+
if (this.items.delete(key)) {
|
|
51
|
+
removed.push(key);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (removed.length > 0) {
|
|
56
|
+
this.update(removed);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
destroy(): void {
|
|
61
|
+
mapped.delete(this.element);
|
|
62
|
+
|
|
63
|
+
this.handlers = undefined as never;
|
|
64
|
+
this.element = undefined as never;
|
|
65
|
+
this.items = undefined as never;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
handle(event: MouseEvent, target: HTMLElement): void {
|
|
69
|
+
const key = getKey(target.getAttribute('data-key'));
|
|
70
|
+
|
|
71
|
+
if (key == null) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const {items} = this;
|
|
76
|
+
|
|
77
|
+
if (event.shiftKey) {
|
|
78
|
+
if (this.last == null) {
|
|
79
|
+
this.last = key;
|
|
80
|
+
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
this.range(this.last, key);
|
|
85
|
+
|
|
86
|
+
this.last = key;
|
|
87
|
+
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
this.last = key;
|
|
92
|
+
|
|
93
|
+
if (event.ctrlKey || event.metaKey) {
|
|
94
|
+
if (items.has(key)) {
|
|
95
|
+
this.deselect([key]);
|
|
96
|
+
} else {
|
|
97
|
+
this.select([key]);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (items.has(key)) {
|
|
104
|
+
if (items.size === 1) {
|
|
105
|
+
this.clear();
|
|
106
|
+
} else {
|
|
107
|
+
this.set([key]);
|
|
108
|
+
}
|
|
109
|
+
} else {
|
|
110
|
+
this.set([key]);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
range(from: Key | HTMLElement, to: Key | HTMLElement): void {
|
|
115
|
+
const keyed = isKey(from) && isKey(to);
|
|
116
|
+
|
|
117
|
+
const fromKey = keyed ? (from as Key) : getKey((from as HTMLElement).getAttribute('data-key'))!;
|
|
118
|
+
const toKey = keyed ? (to as Key) : getKey((to as HTMLElement).getAttribute('data-key'))!;
|
|
119
|
+
|
|
120
|
+
if (fromKey === toKey) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const keys = this.managers.data.values.keys.active ?? this.managers.data.values.keys.original;
|
|
125
|
+
|
|
126
|
+
const fromIndex = keys.indexOf(fromKey);
|
|
127
|
+
const toIndex = keys.indexOf(toKey);
|
|
128
|
+
|
|
129
|
+
if (fromIndex === -1 || toIndex === -1) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const [start, end] = fromIndex < toIndex ? [fromIndex, toIndex] : [toIndex, fromIndex];
|
|
134
|
+
|
|
135
|
+
const selected: Key[] = [];
|
|
136
|
+
|
|
137
|
+
for (let index = start; index <= end; index += 1) {
|
|
138
|
+
selected.push(keys[index]);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (keyed) {
|
|
142
|
+
this.select(selected);
|
|
143
|
+
} else {
|
|
144
|
+
this.set(selected);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
select(keys: Key[]): void {
|
|
149
|
+
const {length} = keys;
|
|
150
|
+
|
|
151
|
+
let update = false;
|
|
152
|
+
|
|
153
|
+
for (let index = 0; index < length; index += 1) {
|
|
154
|
+
const key = keys[index];
|
|
155
|
+
|
|
156
|
+
if (!this.items.has(key)) {
|
|
157
|
+
this.items.add(key);
|
|
158
|
+
|
|
159
|
+
update = true;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (update) {
|
|
164
|
+
this.update([]);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
set(keys: Key[]): void {
|
|
169
|
+
const {items} = this;
|
|
170
|
+
|
|
171
|
+
const removed = [...items].filter(key => !keys.includes(key));
|
|
172
|
+
const added = keys.filter(key => !items.has(key));
|
|
173
|
+
|
|
174
|
+
if (removed.length === 0 && added.length === 0) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
this.items = new Set(keys);
|
|
179
|
+
|
|
180
|
+
this.update(removed);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
toggle(): void {
|
|
184
|
+
const {items, managers} = this;
|
|
185
|
+
|
|
186
|
+
const all = managers.data.values.keys.active ?? managers.data.values.keys.original;
|
|
187
|
+
|
|
188
|
+
if (items.size === all.length) {
|
|
189
|
+
this.clear();
|
|
190
|
+
} else {
|
|
191
|
+
this.select(all);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
update(removed: Key[]): void {
|
|
196
|
+
const items = [
|
|
197
|
+
...removed.map(key => ({key, removed: true})),
|
|
198
|
+
...[...this.items].map(key => ({key, removed: false})),
|
|
199
|
+
];
|
|
200
|
+
|
|
201
|
+
const {length} = items;
|
|
202
|
+
|
|
203
|
+
for (let index = 0; index < length; index += 1) {
|
|
204
|
+
const {key, removed} = items[index];
|
|
205
|
+
|
|
206
|
+
const row = this.managers.row.get(key);
|
|
207
|
+
|
|
208
|
+
if (row == null || row.element == null) {
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
setAttribute(row.element, 'aria-selected', String(!removed));
|
|
213
|
+
|
|
214
|
+
if (removed) {
|
|
215
|
+
row.element.classList.remove('tabela__row--selected');
|
|
216
|
+
} else {
|
|
217
|
+
row.element.classList.add('tabela__row--selected');
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function getPlaceholder(): HTMLElement {
|
|
224
|
+
placeholder ??= createElement(
|
|
225
|
+
'div',
|
|
226
|
+
{
|
|
227
|
+
className: 'tabela__selection--placeholder',
|
|
228
|
+
},
|
|
229
|
+
{},
|
|
230
|
+
{},
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
return placeholder;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function onMouseDown(event: MouseEvent): void {
|
|
237
|
+
if (shifted) {
|
|
238
|
+
const row = findAncestor(event.target as HTMLElement, '.tabela__row--body');
|
|
239
|
+
|
|
240
|
+
if (!(row instanceof HTMLElement)) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
startElement = row;
|
|
245
|
+
startPosition = getPosition(event)!;
|
|
246
|
+
|
|
247
|
+
dragStyling.set();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function onMouseMove(event: MouseEvent): void {
|
|
252
|
+
if (startElement == null) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const currentPosition = getPosition(event)!;
|
|
257
|
+
|
|
258
|
+
if (currentPosition == null || startPosition == null) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const element = getPlaceholder();
|
|
263
|
+
|
|
264
|
+
if (element.parentElement == null) {
|
|
265
|
+
document.body.append(element);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const {x: cX, y: cY} = currentPosition;
|
|
269
|
+
const {x: sX, y: sY} = startPosition;
|
|
270
|
+
|
|
271
|
+
const top = Math.min(cY, sY);
|
|
272
|
+
const left = Math.min(cX, sX);
|
|
273
|
+
|
|
274
|
+
const width = Math.abs(cX - sX);
|
|
275
|
+
const height = Math.abs(cY - sY);
|
|
276
|
+
|
|
277
|
+
element.style.inset = `${top}px ${window.innerWidth - left - width}px ${window.innerHeight - top - height}px ${left}px`;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function onMouseUp(event: MouseEvent): void {
|
|
281
|
+
if (startElement == null) {
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (!event.shiftKey) {
|
|
286
|
+
shifted = false;
|
|
287
|
+
|
|
288
|
+
dragStyling.remove();
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
getPlaceholder().remove();
|
|
292
|
+
|
|
293
|
+
const row = findAncestor(event.target as HTMLElement, '.tabela__row--body');
|
|
294
|
+
|
|
295
|
+
if (row instanceof HTMLElement) {
|
|
296
|
+
endElement = row;
|
|
297
|
+
|
|
298
|
+
const endTable = findAncestor(endElement, '.tabela');
|
|
299
|
+
const startTable = findAncestor(startElement, '.tabela');
|
|
300
|
+
|
|
301
|
+
if (startTable != null && startTable === endTable) {
|
|
302
|
+
mapped.get(startTable)?.range(startElement, endElement);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
endElement = undefined;
|
|
307
|
+
startElement = undefined;
|
|
308
|
+
startPosition = undefined as never;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
function onShift(event: KeyboardEvent, value: boolean): void {
|
|
312
|
+
if (event.key === 'Shift') {
|
|
313
|
+
shifted = value;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function onShiftDown(event: KeyboardEvent): void {
|
|
318
|
+
onShift(event, true);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function onShiftUp(event: KeyboardEvent): void {
|
|
322
|
+
onShift(event, false);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
const mapped = new WeakMap<Element, SelectionManager>();
|
|
326
|
+
|
|
327
|
+
let shifted = false;
|
|
328
|
+
|
|
329
|
+
let endElement: HTMLElement | undefined;
|
|
330
|
+
let placeholder: HTMLElement;
|
|
331
|
+
let startPosition: EventPosition;
|
|
332
|
+
let startElement: HTMLElement | undefined;
|
|
333
|
+
|
|
334
|
+
on(document, 'keydown', onShiftDown);
|
|
335
|
+
on(document, 'keyup', onShiftUp);
|
|
336
|
+
on(document, 'mousedown', onMouseDown);
|
|
337
|
+
on(document, 'mousemove', onMouseMove);
|
|
338
|
+
on(document, 'mouseup', onMouseUp);
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {sort} from '@oscarpalmer/atoms/array';
|
|
2
|
-
import type {Key} from '@oscarpalmer/atoms/models';
|
|
1
|
+
import {sort, type ArrayKeySorter} from '@oscarpalmer/atoms/array';
|
|
2
|
+
import type {Key, PlainObject} from '@oscarpalmer/atoms/models';
|
|
3
3
|
import {setAttribute, setAttributes} from '@oscarpalmer/toretto/attribute';
|
|
4
4
|
import type {SortDirection, SortItem} from '../models/sort.model';
|
|
5
5
|
import type {TabelaManagers, TabelaSort} from '../models/tabela.model';
|
|
6
6
|
|
|
7
7
|
export class SortManager {
|
|
8
|
-
|
|
8
|
+
handlers = Object.freeze({
|
|
9
9
|
add: (field, direction) => this.add(field, direction),
|
|
10
10
|
flip: field => this.flip(field),
|
|
11
11
|
clear: () => this.clear(),
|
|
@@ -13,7 +13,7 @@ export class SortManager {
|
|
|
13
13
|
set: items => this.set(items),
|
|
14
14
|
} satisfies TabelaSort);
|
|
15
15
|
|
|
16
|
-
readonly items:
|
|
16
|
+
readonly items: ArrayKeySorter<PlainObject>[] = [];
|
|
17
17
|
|
|
18
18
|
constructor(readonly managers: TabelaManagers) {}
|
|
19
19
|
|
|
@@ -36,14 +36,21 @@ export class SortManager {
|
|
|
36
36
|
if (event.ctrlKey || event.metaKey) {
|
|
37
37
|
this.add(field);
|
|
38
38
|
} else {
|
|
39
|
-
this.set([{
|
|
39
|
+
this.set([{field, direction: 'ascending'}]);
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
clear(): void {
|
|
44
|
-
this.items.length
|
|
44
|
+
if (this.items.length > 0) {
|
|
45
|
+
this.items.length = 0;
|
|
45
46
|
|
|
46
|
-
|
|
47
|
+
this.sort();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
destroy(): void {
|
|
52
|
+
this.handlers = undefined as never;
|
|
53
|
+
this.items.length = 0;
|
|
47
54
|
}
|
|
48
55
|
|
|
49
56
|
flip(field: string): void {
|
|
@@ -77,7 +84,11 @@ export class SortManager {
|
|
|
77
84
|
}
|
|
78
85
|
|
|
79
86
|
set(items: SortItem[]): void {
|
|
80
|
-
this.items.splice(
|
|
87
|
+
this.items.splice(
|
|
88
|
+
0,
|
|
89
|
+
this.items.length,
|
|
90
|
+
...items.map(item => ({key: item.field, direction: item.direction})),
|
|
91
|
+
);
|
|
81
92
|
|
|
82
93
|
this.sort();
|
|
83
94
|
}
|
|
@@ -85,16 +96,11 @@ export class SortManager {
|
|
|
85
96
|
sort(): void {
|
|
86
97
|
const {items, managers} = this;
|
|
87
98
|
|
|
88
|
-
managers.
|
|
89
|
-
items.length === 0
|
|
90
|
-
? undefined
|
|
91
|
-
: (sort(managers.data.values.objects.array, items).map(
|
|
92
|
-
row => row[managers.data.field],
|
|
93
|
-
) as Key[]);
|
|
99
|
+
const {length} = managers.column.items;
|
|
94
100
|
|
|
95
|
-
|
|
101
|
+
for (let index = 0; index < length; index += 1) {
|
|
102
|
+
const column = managers.column.items[index];
|
|
96
103
|
|
|
97
|
-
for (const column of managers.column.items) {
|
|
98
104
|
const sorterIndex = items.findIndex(item => item.key === column.options.field);
|
|
99
105
|
const sorterItem = items[sorterIndex];
|
|
100
106
|
|
|
@@ -110,6 +116,19 @@ export class SortManager {
|
|
|
110
116
|
sorterIndex > -1 && items.length > 1 ? sorterIndex + 1 : undefined,
|
|
111
117
|
);
|
|
112
118
|
}
|
|
119
|
+
|
|
120
|
+
managers.data.values.keys.active =
|
|
121
|
+
items.length === 0
|
|
122
|
+
? undefined
|
|
123
|
+
: (sort(
|
|
124
|
+
managers.data.values.keys.active?.map(
|
|
125
|
+
key => managers.data.values.objects.mapped.get(key)!,
|
|
126
|
+
) ??
|
|
127
|
+
managers.data.values.objects.array,
|
|
128
|
+
items,
|
|
129
|
+
).map(row => row[managers.data.field]) as Key[]);
|
|
130
|
+
|
|
131
|
+
managers.render.update(true, true);
|
|
113
132
|
}
|
|
114
133
|
|
|
115
134
|
toggle(event: MouseEvent, field: string, direction?: string | null): void {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type FilterComparison =
|
|
2
|
+
| 'contains'
|
|
3
|
+
| 'ends-with'
|
|
4
|
+
| 'equals'
|
|
5
|
+
| 'greater-than'
|
|
6
|
+
| 'greater-than-or-equal'
|
|
7
|
+
| 'less-than'
|
|
8
|
+
| 'less-than-or-equal'
|
|
9
|
+
| 'not-contains'
|
|
10
|
+
| 'not-equals'
|
|
11
|
+
| 'starts-with';
|
|
12
|
+
|
|
13
|
+
export type FilterItem = {
|
|
14
|
+
comparison: FilterComparison;
|
|
15
|
+
field: string;
|
|
16
|
+
value: unknown;
|
|
17
|
+
};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export type RenderElementPool = {
|
|
2
2
|
cells: Record<string, HTMLDivElement[]>;
|
|
3
3
|
rows: HTMLDivElement[];
|
|
4
4
|
};
|
|
5
5
|
|
|
6
|
-
export type
|
|
6
|
+
export type RenderRange = {
|
|
7
7
|
end: number;
|
|
8
8
|
start: number;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
export type
|
|
11
|
+
export type RenderState = {
|
|
12
12
|
active: boolean;
|
|
13
13
|
top: number;
|
|
14
14
|
};
|
package/src/models/sort.model.ts
CHANGED
|
@@ -5,9 +5,12 @@ import type {HeaderComponent} from '../components/header.component';
|
|
|
5
5
|
import type {ColumnManager} from '../managers/column.manager';
|
|
6
6
|
import type {DataManager} from '../managers/data.manager';
|
|
7
7
|
import type {EventManager} from '../managers/event.manager';
|
|
8
|
+
import type {FilterManager} from '../managers/filter.manager';
|
|
9
|
+
import type {RenderManager} from '../managers/render.manager';
|
|
8
10
|
import type {RowManager} from '../managers/row.manager';
|
|
11
|
+
import type {SelectionManager} from '../managers/selection.manager';
|
|
9
12
|
import type {SortManager} from '../managers/sort.manager';
|
|
10
|
-
import type {
|
|
13
|
+
import type {FilterItem} from './filter.model';
|
|
11
14
|
import type {SortDirection, SortItem} from './sort.model';
|
|
12
15
|
|
|
13
16
|
export type TabelaComponents = {
|
|
@@ -26,13 +29,30 @@ export type TabelaData = {
|
|
|
26
29
|
update(data: PlainObject[]): void;
|
|
27
30
|
};
|
|
28
31
|
|
|
32
|
+
export type TabelaFilter = {
|
|
33
|
+
add(item: FilterItem): void;
|
|
34
|
+
clear(): void;
|
|
35
|
+
remove(field: string): void;
|
|
36
|
+
remove(item: FilterItem): void;
|
|
37
|
+
set(items: FilterItem[]): void;
|
|
38
|
+
};
|
|
39
|
+
|
|
29
40
|
export type TabelaManagers = {
|
|
30
41
|
column: ColumnManager;
|
|
31
42
|
data: DataManager;
|
|
32
43
|
event: EventManager;
|
|
44
|
+
filter: FilterManager;
|
|
33
45
|
row: RowManager;
|
|
46
|
+
selection: SelectionManager;
|
|
34
47
|
sort: SortManager;
|
|
35
|
-
|
|
48
|
+
render: RenderManager;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export type TabelaSelection = {
|
|
52
|
+
clear(): void;
|
|
53
|
+
deselect(keys: Key[]): void;
|
|
54
|
+
select(keys: Key[]): void;
|
|
55
|
+
toggle(): void;
|
|
36
56
|
};
|
|
37
57
|
|
|
38
58
|
export type TabelaSort = {
|
package/src/tabela.ts
CHANGED
|
@@ -4,10 +4,19 @@ import {HeaderComponent} from './components/header.component';
|
|
|
4
4
|
import {ColumnManager} from './managers/column.manager';
|
|
5
5
|
import {DataManager} from './managers/data.manager';
|
|
6
6
|
import {EventManager} from './managers/event.manager';
|
|
7
|
+
import {FilterManager} from './managers/filter.manager';
|
|
7
8
|
import {RowManager} from './managers/row.manager';
|
|
9
|
+
import {SelectionManager} from './managers/selection.manager';
|
|
8
10
|
import {SortManager} from './managers/sort.manager';
|
|
9
|
-
import {
|
|
10
|
-
import type {
|
|
11
|
+
import {RenderManager} from './managers/render.manager';
|
|
12
|
+
import type {
|
|
13
|
+
TabelaComponents,
|
|
14
|
+
TabelaData,
|
|
15
|
+
TabelaFilter,
|
|
16
|
+
TabelaManagers,
|
|
17
|
+
TabelaSelection,
|
|
18
|
+
TabelaSort,
|
|
19
|
+
} from './models/tabela.model';
|
|
11
20
|
import type {TabelaOptions} from './models/tabela.options';
|
|
12
21
|
|
|
13
22
|
export class Tabela {
|
|
@@ -25,13 +34,19 @@ export class Tabela {
|
|
|
25
34
|
column: undefined as never,
|
|
26
35
|
data: undefined as never,
|
|
27
36
|
event: undefined as never,
|
|
37
|
+
filter: undefined as never,
|
|
38
|
+
render: undefined as never,
|
|
28
39
|
row: undefined as never,
|
|
40
|
+
selection: undefined as never,
|
|
29
41
|
sort: undefined as never,
|
|
30
|
-
virtualization: undefined as never,
|
|
31
42
|
};
|
|
32
43
|
|
|
33
44
|
readonly data: TabelaData;
|
|
34
45
|
|
|
46
|
+
readonly filter: TabelaFilter;
|
|
47
|
+
|
|
48
|
+
readonly selection: TabelaSelection;
|
|
49
|
+
|
|
35
50
|
readonly sort: TabelaSort;
|
|
36
51
|
|
|
37
52
|
get key(): string {
|
|
@@ -56,10 +71,12 @@ export class Tabela {
|
|
|
56
71
|
|
|
57
72
|
this.#managers.column = new ColumnManager(this.#managers, this.#components, options.columns);
|
|
58
73
|
this.#managers.data = new DataManager(this.#managers, this.#components, options.key);
|
|
59
|
-
this.#managers.event = new EventManager(this.#
|
|
74
|
+
this.#managers.event = new EventManager(this.#element, this.#managers);
|
|
75
|
+
this.#managers.filter = new FilterManager(this.#managers);
|
|
76
|
+
this.#managers.render = new RenderManager(this.#managers, this.#components);
|
|
60
77
|
this.#managers.row = new RowManager(this.#managers, options.rowHeight);
|
|
78
|
+
this.#managers.selection = new SelectionManager(this.#element, this.#managers);
|
|
61
79
|
this.#managers.sort = new SortManager(this.#managers);
|
|
62
|
-
this.#managers.virtualization = new VirtualizationManager(this.#managers, this.#components);
|
|
63
80
|
|
|
64
81
|
element.append(
|
|
65
82
|
this.#components.header.elements.group,
|
|
@@ -70,6 +87,8 @@ export class Tabela {
|
|
|
70
87
|
this.#managers.data.set(options.data);
|
|
71
88
|
|
|
72
89
|
this.data = this.#managers.data.handlers;
|
|
90
|
+
this.filter = this.#managers.filter.handlers;
|
|
91
|
+
this.selection = this.#managers.selection.handlers;
|
|
73
92
|
this.sort = this.#managers.sort.handlers;
|
|
74
93
|
}
|
|
75
94
|
|
|
@@ -84,8 +103,11 @@ export class Tabela {
|
|
|
84
103
|
|
|
85
104
|
managers.column.destroy();
|
|
86
105
|
managers.data.destroy();
|
|
106
|
+
managers.event.destroy();
|
|
107
|
+
managers.filter.destroy();
|
|
108
|
+
managers.render.destroy();
|
|
87
109
|
managers.row.destroy();
|
|
88
|
-
managers.
|
|
110
|
+
managers.sort.destroy();
|
|
89
111
|
|
|
90
112
|
element.innerHTML = '';
|
|
91
113
|
element.role = '';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Key } from '@oscarpalmer/atoms/models';
|
|
2
|
+
import type { RenderElementPool } from '../models/render.model';
|
|
2
3
|
import type { TabelaManagers } from '../models/tabela.model';
|
|
3
|
-
|
|
4
|
-
export declare function removeRow(pool: VirtualizationPool, row: RowComponent): void;
|
|
4
|
+
export declare function removeRow(pool: RenderElementPool, row: RowComponent): void;
|
|
5
5
|
export declare function renderRow(managers: TabelaManagers, row: RowComponent): void;
|
|
6
6
|
export declare class RowComponent {
|
|
7
7
|
readonly key: Key;
|
|
@@ -6,5 +6,5 @@ export declare function createCell(width: number, body?: boolean): HTMLDivElemen
|
|
|
6
6
|
export declare function createElement<TagName extends keyof HTMLElementTagNameMap>(tagName: TagName, properties: Partial<HTMLElementTagNameMap[TagName]>, attributes: Record<string, string>, style: Partial<CSSStyleDeclaration>): HTMLElementTagNameMap[TagName];
|
|
7
7
|
export declare function createRowGroup(): RowGroupWithRow;
|
|
8
8
|
export declare function createRowGroup(withRow: boolean): HTMLDivElement;
|
|
9
|
-
export declare function createRow(
|
|
9
|
+
export declare function createRow(): HTMLDivElement;
|
|
10
10
|
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const dragStyling: import("@oscarpalmer/toretto").StyleToggler;
|
|
@@ -5,7 +5,7 @@ export declare class DataManager {
|
|
|
5
5
|
managers: TabelaManagers;
|
|
6
6
|
components: TabelaComponents;
|
|
7
7
|
field: string;
|
|
8
|
-
|
|
8
|
+
handlers: Readonly<{
|
|
9
9
|
add: (data: PlainObject[]) => undefined;
|
|
10
10
|
clear: () => undefined;
|
|
11
11
|
get: (active: boolean | undefined) => PlainObject[];
|
|
@@ -3,7 +3,7 @@ import type { TabelaManagers } from '../models/tabela.model';
|
|
|
3
3
|
export declare class EventManager {
|
|
4
4
|
readonly managers: TabelaManagers;
|
|
5
5
|
listener: RemovableEventListener;
|
|
6
|
-
constructor(
|
|
6
|
+
constructor(element: HTMLElement, managers: TabelaManagers);
|
|
7
7
|
destroy(): void;
|
|
8
8
|
onClick(event: MouseEvent): void;
|
|
9
9
|
onSort(event: MouseEvent, target: HTMLElement): void;
|