@oscarpalmer/tabela 0.6.0 → 0.8.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 -3
- package/dist/components/column.component.js +31 -12
- package/dist/components/footer.component.js +1 -2
- package/dist/components/header.component.js +2 -3
- package/dist/components/row.component.js +7 -7
- package/dist/helpers/dom.helpers.js +6 -4
- package/dist/managers/column.manager.js +16 -15
- package/dist/managers/data.manager.js +99 -15
- package/dist/managers/event.manager.js +30 -0
- package/dist/managers/row.manager.js +13 -3
- package/dist/managers/sort.manager.js +83 -0
- package/dist/managers/virtualization.manager.js +39 -32
- package/dist/models/sort.model.js +0 -0
- package/dist/models/tabela.model.js +0 -0
- package/dist/tabela.full.js +1003 -161
- package/dist/tabela.js +44 -22
- package/package.json +3 -3
- package/src/components/body.component.ts +2 -2
- package/src/components/column.component.ts +58 -23
- package/src/components/footer.component.ts +1 -2
- package/src/components/header.component.ts +2 -3
- package/src/components/row.component.ts +10 -8
- package/src/helpers/dom.helpers.ts +6 -0
- package/src/managers/column.manager.ts +17 -20
- package/src/managers/data.manager.ts +167 -20
- package/src/managers/event.manager.ts +55 -0
- package/src/managers/row.manager.ts +19 -3
- package/src/managers/sort.manager.ts +130 -0
- package/src/managers/virtualization.manager.ts +56 -35
- package/src/models/sort.model.ts +6 -0
- package/src/models/tabela.model.ts +44 -0
- package/src/tabela.ts +56 -40
- package/types/components/body.component.d.ts +1 -3
- package/types/components/column.component.d.ts +10 -5
- package/types/components/footer.component.d.ts +1 -3
- package/types/components/header.component.d.ts +1 -3
- package/types/components/row.component.d.ts +3 -3
- package/types/helpers/dom.helpers.d.ts +1 -1
- package/types/managers/column.manager.d.ts +5 -4
- package/types/managers/data.manager.d.ts +23 -6
- package/types/managers/event.manager.d.ts +10 -0
- package/types/managers/row.manager.d.ts +6 -3
- package/types/managers/sort.manager.d.ts +23 -0
- package/types/managers/virtualization.manager.d.ts +6 -4
- package/types/models/sort.model.d.ts +5 -0
- package/types/models/tabela.model.d.ts +40 -0
- package/types/tabela.d.ts +5 -23
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createElement, createRowGroup } from "../helpers/dom.helpers.js";
|
|
2
2
|
import { setStyles } from "@oscarpalmer/toretto/style";
|
|
3
3
|
function createFaker() {
|
|
4
|
-
return createElement("div", {}, {
|
|
4
|
+
return createElement("div", {}, {}, {
|
|
5
5
|
height: "0",
|
|
6
6
|
inset: "0 auto auto 0",
|
|
7
7
|
opacity: "0",
|
|
@@ -15,8 +15,7 @@ var BodyComponent = class {
|
|
|
15
15
|
faker: createFaker(),
|
|
16
16
|
group: void 0
|
|
17
17
|
};
|
|
18
|
-
constructor(
|
|
19
|
-
this.tabela = tabela;
|
|
18
|
+
constructor() {
|
|
20
19
|
const group = createRowGroup(false);
|
|
21
20
|
this.elements.group = group;
|
|
22
21
|
group.className += " tabela__rowgroup-body";
|
|
@@ -1,22 +1,41 @@
|
|
|
1
1
|
import { createElement } from "../helpers/dom.helpers.js";
|
|
2
|
-
function createHeading(title, width) {
|
|
3
|
-
return createElement("div", {
|
|
4
|
-
className: "tabela__heading",
|
|
5
|
-
role: "columnheader",
|
|
6
|
-
textContent: title
|
|
7
|
-
}, { width: `${width}px` });
|
|
8
|
-
}
|
|
9
2
|
var ColumnComponent = class {
|
|
10
|
-
|
|
3
|
+
elements;
|
|
11
4
|
options;
|
|
12
|
-
constructor(
|
|
13
|
-
|
|
14
|
-
const width = Number.parseInt(getComputedStyle(tabela.element).fontSize, 10) * (options.width ?? options.title.length * 1.5);
|
|
5
|
+
constructor(options) {
|
|
6
|
+
const width = Number.parseInt(getComputedStyle(document.body).fontSize, 10) * (options.width ?? options.title.length * 1.5);
|
|
15
7
|
this.options = {
|
|
16
8
|
...options,
|
|
17
9
|
width
|
|
18
10
|
};
|
|
19
|
-
this.
|
|
11
|
+
this.elements = createHeading(options.field, options.title, width);
|
|
12
|
+
}
|
|
13
|
+
destroy() {
|
|
14
|
+
this.elements.content.remove();
|
|
15
|
+
this.elements.wrapper.remove();
|
|
16
|
+
this.elements.sorter.remove();
|
|
17
|
+
this.elements = void 0;
|
|
18
|
+
this.options = void 0;
|
|
20
19
|
}
|
|
21
20
|
};
|
|
21
|
+
function createHeading(field, title, width) {
|
|
22
|
+
const wrapper = createElement("div", {
|
|
23
|
+
className: "tabela__heading",
|
|
24
|
+
role: "columnheader"
|
|
25
|
+
}, {
|
|
26
|
+
"data-event": "heading",
|
|
27
|
+
"data-field": field
|
|
28
|
+
}, { width: `${width}px` });
|
|
29
|
+
const content = createElement("div", {
|
|
30
|
+
className: "tabela__heading__content",
|
|
31
|
+
textContent: title
|
|
32
|
+
}, {}, {});
|
|
33
|
+
const sorter = createElement("div", { className: "tabela__heading__sorter" }, {}, {});
|
|
34
|
+
wrapper.append(content, sorter);
|
|
35
|
+
return {
|
|
36
|
+
content,
|
|
37
|
+
sorter,
|
|
38
|
+
wrapper
|
|
39
|
+
};
|
|
40
|
+
}
|
|
22
41
|
export { ColumnComponent };
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { createRowGroup } from "../helpers/dom.helpers.js";
|
|
2
2
|
var HeaderComponent = class {
|
|
3
3
|
elements;
|
|
4
|
-
constructor(
|
|
5
|
-
this.tabela = tabela;
|
|
4
|
+
constructor() {
|
|
6
5
|
const { group, row } = createRowGroup();
|
|
7
6
|
this.elements = {
|
|
8
7
|
group,
|
|
@@ -17,7 +16,7 @@ var HeaderComponent = class {
|
|
|
17
16
|
}
|
|
18
17
|
update(columns) {
|
|
19
18
|
this.elements.row.innerHTML = "";
|
|
20
|
-
this.elements.row.append(...columns.map((column) => column.
|
|
19
|
+
this.elements.row.append(...columns.map((column) => column.elements.wrapper));
|
|
21
20
|
}
|
|
22
21
|
};
|
|
23
22
|
export { HeaderComponent };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createCell, createRow } from "../helpers/dom.helpers.js";
|
|
2
|
-
function removeRow(
|
|
2
|
+
function removeRow(pool, row) {
|
|
3
3
|
if (row.element != null) {
|
|
4
4
|
row.element.innerHTML = "";
|
|
5
5
|
pool.rows.push(row.element);
|
|
@@ -8,19 +8,19 @@ function removeRow(row, pool) {
|
|
|
8
8
|
}
|
|
9
9
|
row.cells = {};
|
|
10
10
|
}
|
|
11
|
-
function renderRow(
|
|
12
|
-
const element = row.element ?? pool.rows.shift() ?? createRow();
|
|
11
|
+
function renderRow(managers, row) {
|
|
12
|
+
const element = row.element ?? managers.virtualization.pool.rows.shift() ?? createRow();
|
|
13
13
|
row.element = element;
|
|
14
14
|
element.dataset.key = String(row.key);
|
|
15
15
|
element.innerHTML = "";
|
|
16
|
-
const columns =
|
|
16
|
+
const columns = managers.column.items;
|
|
17
17
|
const { length } = columns;
|
|
18
|
-
const data =
|
|
18
|
+
const data = managers.data.values.objects.mapped.get(row.key);
|
|
19
19
|
if (data == null) return;
|
|
20
20
|
for (let index = 0; index < length; index += 1) {
|
|
21
21
|
const { options } = columns[index];
|
|
22
|
-
pool.cells[options.field] ??= [];
|
|
23
|
-
const cell = pool.cells[columns[index].options.field].shift() ?? createCell(options.width);
|
|
22
|
+
managers.virtualization.pool.cells[options.field] ??= [];
|
|
23
|
+
const cell = managers.virtualization.pool.cells[columns[index].options.field].shift() ?? createCell(options.width);
|
|
24
24
|
cell.textContent = String(data[options.field]);
|
|
25
25
|
row.cells[options.field] = cell;
|
|
26
26
|
element.append(cell);
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { setStyles } from "@oscarpalmer/toretto/style";
|
|
2
|
+
import { setAttributes } from "@oscarpalmer/toretto/attribute";
|
|
2
3
|
function createCell(width, body) {
|
|
3
4
|
const cell = createElement("div", {
|
|
4
5
|
className: "tabela__cell",
|
|
5
6
|
role: "cell"
|
|
6
|
-
}, { width: `${width}px` });
|
|
7
|
+
}, {}, { width: `${width}px` });
|
|
7
8
|
if (body ?? true) cell.classList.add("tabela__cell-body");
|
|
8
9
|
return cell;
|
|
9
10
|
}
|
|
10
|
-
function createElement(tagName, properties, style) {
|
|
11
|
+
function createElement(tagName, properties, attributes, style) {
|
|
11
12
|
const element = document.createElement(tagName);
|
|
12
13
|
const keys = Object.keys(properties);
|
|
13
14
|
for (const key of keys) element[key] = properties[key];
|
|
15
|
+
setAttributes(element, attributes);
|
|
14
16
|
setStyles(element, style);
|
|
15
17
|
return element;
|
|
16
18
|
}
|
|
@@ -18,7 +20,7 @@ function createRowGroup(withRow) {
|
|
|
18
20
|
const group = createElement("div", {
|
|
19
21
|
className: "tabela__rowgroup",
|
|
20
22
|
role: "rowgroup"
|
|
21
|
-
}, {});
|
|
23
|
+
}, {}, {});
|
|
22
24
|
if (!(withRow ?? true)) return group;
|
|
23
25
|
const row = createRow(false);
|
|
24
26
|
group.append(row);
|
|
@@ -31,7 +33,7 @@ function createRow(withStyle) {
|
|
|
31
33
|
const row = createElement("div", {
|
|
32
34
|
className: "tabela__row",
|
|
33
35
|
role: "row"
|
|
34
|
-
}, {});
|
|
36
|
+
}, {}, {});
|
|
35
37
|
if (withStyle ?? true) setStyles(row, {
|
|
36
38
|
inset: "0 auto auto 0",
|
|
37
39
|
position: "absolute"
|
|
@@ -1,32 +1,33 @@
|
|
|
1
1
|
import { ColumnComponent } from "../components/column.component.js";
|
|
2
2
|
var ColumnManager = class {
|
|
3
|
-
|
|
4
|
-
constructor(
|
|
5
|
-
this.
|
|
3
|
+
items = [];
|
|
4
|
+
constructor(managers, components, columns) {
|
|
5
|
+
this.managers = managers;
|
|
6
|
+
this.components = components;
|
|
6
7
|
this.set(columns);
|
|
7
8
|
}
|
|
8
9
|
destroy() {
|
|
9
|
-
this.
|
|
10
|
+
this.items.length = 0;
|
|
10
11
|
}
|
|
11
12
|
remove(value) {
|
|
12
|
-
const { components,
|
|
13
|
+
const { components, items, managers } = this;
|
|
13
14
|
const fields = (Array.isArray(value) ? value : [value]).filter((item) => typeof item === "string");
|
|
14
15
|
const { length } = fields;
|
|
15
16
|
if (length === 0) return;
|
|
16
17
|
for (let fieldIndex = 0; fieldIndex < length; fieldIndex += 1) {
|
|
17
|
-
const
|
|
18
|
-
if (
|
|
18
|
+
const itemIndex = items.findIndex((component) => component.options.field === fields[fieldIndex]);
|
|
19
|
+
if (itemIndex > -1) items.splice(itemIndex, 1);
|
|
19
20
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
components.header.update(items);
|
|
22
|
+
components.footer.update(items);
|
|
23
|
+
managers.virtualization.removeCells(fields);
|
|
23
24
|
}
|
|
24
25
|
set(columns) {
|
|
25
|
-
const { components,
|
|
26
|
-
const { footer, header } =
|
|
27
|
-
|
|
28
|
-
header.update(
|
|
29
|
-
footer.update(
|
|
26
|
+
const { components, items } = this;
|
|
27
|
+
const { footer, header } = components;
|
|
28
|
+
items.splice(0, items.length, ...columns.map((column) => new ColumnComponent(column)));
|
|
29
|
+
header.update(items);
|
|
30
|
+
footer.update(items);
|
|
30
31
|
}
|
|
31
32
|
};
|
|
32
33
|
export { ColumnManager };
|
|
@@ -1,19 +1,38 @@
|
|
|
1
|
+
import { sort } from "@oscarpalmer/atoms/array";
|
|
1
2
|
import { toMap } from "@oscarpalmer/atoms/array/to-map";
|
|
3
|
+
import { isPlainObject } from "@oscarpalmer/atoms/is";
|
|
2
4
|
var DataManager = class {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
+
handlers = Object.freeze({
|
|
6
|
+
add: (data) => void this.add(data, true),
|
|
7
|
+
clear: () => void this.clear(),
|
|
8
|
+
get: (active) => this.get(active),
|
|
9
|
+
remove: (items) => void this.remove(items, true),
|
|
10
|
+
synchronize: (data, remove) => void this.synchronize(data, remove),
|
|
11
|
+
update: (data) => void this.update(data)
|
|
12
|
+
});
|
|
13
|
+
values = {
|
|
14
|
+
keys: { original: [] },
|
|
15
|
+
objects: {
|
|
16
|
+
mapped: /* @__PURE__ */ new Map(),
|
|
17
|
+
array: []
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
get size() {
|
|
5
21
|
return this.values.keys.active?.length ?? this.values.keys.original.length;
|
|
6
22
|
}
|
|
7
|
-
constructor(
|
|
8
|
-
this.
|
|
9
|
-
|
|
10
|
-
this.
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
23
|
+
constructor(managers, components, field) {
|
|
24
|
+
this.managers = managers;
|
|
25
|
+
this.components = components;
|
|
26
|
+
this.field = field;
|
|
27
|
+
}
|
|
28
|
+
async add(data, render) {
|
|
29
|
+
const { field, values } = this;
|
|
30
|
+
values.objects.array.push(...data);
|
|
31
|
+
values.objects.mapped = toMap(values.objects.array, field);
|
|
32
|
+
if (render) this.render();
|
|
33
|
+
}
|
|
34
|
+
clear() {
|
|
35
|
+
if (this.values.objects.array.length > 0) this.set([]);
|
|
17
36
|
}
|
|
18
37
|
destroy() {
|
|
19
38
|
const { values } = this;
|
|
@@ -22,9 +41,74 @@ var DataManager = class {
|
|
|
22
41
|
values.keys.original.length = 0;
|
|
23
42
|
values.objects.array.length = 0;
|
|
24
43
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
44
|
+
get(active) {
|
|
45
|
+
const { values } = this;
|
|
46
|
+
return active ?? false ? values.keys.active?.map((key) => values.objects.mapped.get(key)) ?? [] : values.objects.array;
|
|
47
|
+
}
|
|
48
|
+
async remove(items, render) {
|
|
49
|
+
const { field, managers, values } = this;
|
|
50
|
+
const keys = items.map((value) => isPlainObject(value) ? value[field] : value).filter((key) => values.objects.mapped.has(key));
|
|
51
|
+
const { length } = keys;
|
|
52
|
+
if (length === 0) return;
|
|
53
|
+
for (let keyIndex = 0; keyIndex < length; keyIndex += 1) {
|
|
54
|
+
const key = keys[keyIndex];
|
|
55
|
+
values.objects.mapped.delete(key);
|
|
56
|
+
const arrayIndex = values.objects.array.findIndex((object) => object[field] === key);
|
|
57
|
+
if (arrayIndex > -1) values.objects.array.splice(arrayIndex, 1);
|
|
58
|
+
values.keys.original.splice(values.keys.original.indexOf(key), 1);
|
|
59
|
+
managers.row.remove(key);
|
|
60
|
+
}
|
|
61
|
+
if (render) this.render();
|
|
62
|
+
}
|
|
63
|
+
render() {
|
|
64
|
+
const { field, managers, values } = this;
|
|
65
|
+
values.keys.original = sort(values.objects.array.map((item) => item[field]));
|
|
66
|
+
if (managers.sort.items.length > 0) managers.sort.sort();
|
|
67
|
+
else managers.virtualization.update(true);
|
|
68
|
+
}
|
|
69
|
+
set(data) {
|
|
70
|
+
const { field, values } = this;
|
|
71
|
+
values.objects.mapped = toMap(data, field);
|
|
72
|
+
values.objects.array = data;
|
|
73
|
+
this.render();
|
|
74
|
+
}
|
|
75
|
+
async synchronize(data, remove) {
|
|
76
|
+
const { field, values } = this;
|
|
77
|
+
const add = [];
|
|
78
|
+
const updated = [];
|
|
79
|
+
const keys = /* @__PURE__ */ new Set([]);
|
|
80
|
+
const { length } = data;
|
|
81
|
+
for (let index = 0; index < length; index += 1) {
|
|
82
|
+
const object = data[index];
|
|
83
|
+
const key = object[field];
|
|
84
|
+
if (values.objects.mapped.has(key)) updated.push(object);
|
|
85
|
+
else add.push(object);
|
|
86
|
+
keys.add(key);
|
|
87
|
+
}
|
|
88
|
+
if (keys.size === 0) return;
|
|
89
|
+
if (remove ?? false) {
|
|
90
|
+
const toRemove = values.keys.original.filter((key) => !keys.has(key));
|
|
91
|
+
if (toRemove.length > 0) await this.remove(toRemove, false);
|
|
92
|
+
}
|
|
93
|
+
await this.update(updated);
|
|
94
|
+
if (add.length > 0) await this.add(add, false);
|
|
95
|
+
if (add.length > 0 || (remove ?? false)) this.render();
|
|
96
|
+
}
|
|
97
|
+
async update(data) {
|
|
98
|
+
const { field, managers, values } = this;
|
|
99
|
+
const { length } = data;
|
|
100
|
+
for (let index = 0; index < length; index += 1) {
|
|
101
|
+
const object = data[index];
|
|
102
|
+
const key = object[field];
|
|
103
|
+
const value = values.objects.mapped.get(key);
|
|
104
|
+
if (value != null) {
|
|
105
|
+
values.objects.mapped.set(key, {
|
|
106
|
+
...value,
|
|
107
|
+
...object
|
|
108
|
+
});
|
|
109
|
+
managers.row.update(key);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
28
112
|
}
|
|
29
113
|
};
|
|
30
114
|
export { DataManager };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { on } from "@oscarpalmer/toretto/event";
|
|
2
|
+
import { findAncestor } from "@oscarpalmer/toretto";
|
|
3
|
+
var EventManager = class {
|
|
4
|
+
listener;
|
|
5
|
+
constructor(managers, element) {
|
|
6
|
+
this.managers = managers;
|
|
7
|
+
on(element, "click", (event) => {
|
|
8
|
+
this.onClick(event);
|
|
9
|
+
}, { passive: false });
|
|
10
|
+
}
|
|
11
|
+
destroy() {
|
|
12
|
+
this.listener();
|
|
13
|
+
}
|
|
14
|
+
onClick(event) {
|
|
15
|
+
const target = findAncestor(event, "[data-event]");
|
|
16
|
+
if (!(target instanceof HTMLElement)) return;
|
|
17
|
+
switch (target?.getAttribute("data-event")) {
|
|
18
|
+
case "heading":
|
|
19
|
+
this.onSort(event, target);
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
onSort(event, target) {
|
|
24
|
+
const { managers } = this;
|
|
25
|
+
const direction = target.getAttribute("data-sort-direction");
|
|
26
|
+
const field = target.getAttribute("data-field");
|
|
27
|
+
if (field != null) managers.sort.toggle(event, field, direction);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
export { EventManager };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { RowComponent } from "../components/row.component.js";
|
|
1
|
+
import { RowComponent, renderRow } from "../components/row.component.js";
|
|
2
2
|
var RowManager = class {
|
|
3
3
|
components = /* @__PURE__ */ new Map();
|
|
4
4
|
height;
|
|
5
|
-
constructor(
|
|
6
|
-
this.
|
|
5
|
+
constructor(managers, rowHeight) {
|
|
6
|
+
this.managers = managers;
|
|
7
7
|
this.height = rowHeight;
|
|
8
8
|
}
|
|
9
9
|
destroy() {
|
|
@@ -17,5 +17,15 @@ var RowManager = class {
|
|
|
17
17
|
}
|
|
18
18
|
return row;
|
|
19
19
|
}
|
|
20
|
+
has(key) {
|
|
21
|
+
return this.components.has(key);
|
|
22
|
+
}
|
|
23
|
+
remove(key) {
|
|
24
|
+
this.components.delete(key);
|
|
25
|
+
}
|
|
26
|
+
update(key) {
|
|
27
|
+
const row = this.components.get(key);
|
|
28
|
+
if (row != null) renderRow(this.managers, row);
|
|
29
|
+
}
|
|
20
30
|
};
|
|
21
31
|
export { RowManager };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { setAttribute, setAttributes } from "@oscarpalmer/toretto/attribute";
|
|
2
|
+
import { sort } from "@oscarpalmer/atoms/array";
|
|
3
|
+
var SortManager = class {
|
|
4
|
+
handlers = Object.freeze({
|
|
5
|
+
add: (field, direction) => this.add(field, direction),
|
|
6
|
+
flip: (field) => this.flip(field),
|
|
7
|
+
clear: () => this.clear(),
|
|
8
|
+
remove: (field) => this.remove(field),
|
|
9
|
+
set: (items) => this.set(items)
|
|
10
|
+
});
|
|
11
|
+
items = [];
|
|
12
|
+
constructor(managers) {
|
|
13
|
+
this.managers = managers;
|
|
14
|
+
}
|
|
15
|
+
add(field, direction) {
|
|
16
|
+
if (this.items.findIndex((item) => item.key === field) > -1) return;
|
|
17
|
+
this.items.push({
|
|
18
|
+
key: field,
|
|
19
|
+
direction: direction ?? "ascending"
|
|
20
|
+
});
|
|
21
|
+
this.sort();
|
|
22
|
+
}
|
|
23
|
+
addOrSet(event, field) {
|
|
24
|
+
if (event.ctrlKey || event.metaKey) this.add(field);
|
|
25
|
+
else this.set([{
|
|
26
|
+
key: field,
|
|
27
|
+
direction: "ascending"
|
|
28
|
+
}]);
|
|
29
|
+
}
|
|
30
|
+
clear() {
|
|
31
|
+
this.items.length = 0;
|
|
32
|
+
this.sort();
|
|
33
|
+
}
|
|
34
|
+
flip(field) {
|
|
35
|
+
const item = this.items.find((item) => item.key === field);
|
|
36
|
+
if (item == null) return;
|
|
37
|
+
item.direction = item.direction === "ascending" ? "descending" : "ascending";
|
|
38
|
+
this.sort();
|
|
39
|
+
}
|
|
40
|
+
remove(field) {
|
|
41
|
+
const index = this.items.findIndex((item) => item.key === field);
|
|
42
|
+
if (index > -1) {
|
|
43
|
+
this.items.splice(index, 1);
|
|
44
|
+
this.sort();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
removeOrClear(event, field) {
|
|
48
|
+
if (event.ctrlKey || event.metaKey) this.remove(field);
|
|
49
|
+
else this.clear();
|
|
50
|
+
}
|
|
51
|
+
set(items) {
|
|
52
|
+
this.items.splice(0, this.items.length, ...items);
|
|
53
|
+
this.sort();
|
|
54
|
+
}
|
|
55
|
+
sort() {
|
|
56
|
+
const { items, managers } = this;
|
|
57
|
+
managers.data.values.keys.active = items.length === 0 ? void 0 : sort(managers.data.values.objects.array, items).map((row) => row[managers.data.field]);
|
|
58
|
+
managers.virtualization.update(true, true);
|
|
59
|
+
for (const column of managers.column.items) {
|
|
60
|
+
const sorterIndex = items.findIndex((item) => item.key === column.options.field);
|
|
61
|
+
const sorterItem = items[sorterIndex];
|
|
62
|
+
setAttributes(column.elements.wrapper, {
|
|
63
|
+
"aria-sort": sorterItem == null ? "none" : items.length > 1 ? "other" : sorterItem.direction,
|
|
64
|
+
"data-sort-direction": sorterItem == null ? void 0 : sorterItem.direction
|
|
65
|
+
});
|
|
66
|
+
setAttribute(column.elements.sorter, "data-sort-position", sorterIndex > -1 && items.length > 1 ? sorterIndex + 1 : void 0);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
toggle(event, field, direction) {
|
|
70
|
+
switch (direction) {
|
|
71
|
+
case "ascending":
|
|
72
|
+
this.flip(field);
|
|
73
|
+
return;
|
|
74
|
+
case "descending":
|
|
75
|
+
this.removeOrClear(event, field);
|
|
76
|
+
return;
|
|
77
|
+
default:
|
|
78
|
+
this.addOrSet(event, field);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
export { SortManager };
|
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
import { removeRow, renderRow } from "../components/row.component.js";
|
|
2
2
|
import { on } from "@oscarpalmer/toretto/event";
|
|
3
|
-
function getRange(
|
|
4
|
-
const { components, managers } =
|
|
5
|
-
const {
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const before = Math.ceil(clientHeight / rows.height) * (down ? 1 : 2);
|
|
11
|
-
const after = Math.ceil(clientHeight / rows.height) * (down ? 2 : 1);
|
|
3
|
+
function getRange(down) {
|
|
4
|
+
const { components, managers } = this;
|
|
5
|
+
const { clientHeight, scrollTop } = components.body.elements.group;
|
|
6
|
+
const first = Math.floor(scrollTop / managers.row.height);
|
|
7
|
+
const last = Math.min(managers.data.values.keys.active?.length ?? managers.data.values.keys.original.length - 1, Math.ceil((scrollTop + clientHeight) / managers.row.height) - 1);
|
|
8
|
+
const before = Math.ceil(clientHeight / managers.row.height) * (down ? 1 : 2);
|
|
9
|
+
const after = Math.ceil(clientHeight / managers.row.height) * (down ? 2 : 1);
|
|
12
10
|
const start = Math.max(0, first - before);
|
|
13
11
|
return {
|
|
14
|
-
end: Math.min(data.length - 1, last + after),
|
|
12
|
+
end: Math.min(managers.data.values.keys.active?.length ?? managers.data.values.keys.original.length - 1, last + after),
|
|
15
13
|
start
|
|
16
14
|
};
|
|
17
15
|
}
|
|
18
16
|
function onScroll() {
|
|
19
17
|
if (!this.state.active) {
|
|
20
18
|
requestAnimationFrame(() => {
|
|
21
|
-
const top = this.
|
|
19
|
+
const top = this.components.body.elements.group.scrollTop;
|
|
22
20
|
this.update(top > this.state.top);
|
|
23
21
|
this.state.active = false;
|
|
24
22
|
this.state.top = top;
|
|
@@ -38,14 +36,15 @@ var VirtualizationManager = class {
|
|
|
38
36
|
top: 0
|
|
39
37
|
};
|
|
40
38
|
visible = /* @__PURE__ */ new Map();
|
|
41
|
-
constructor(
|
|
42
|
-
this.
|
|
43
|
-
this.
|
|
39
|
+
constructor(managers, components) {
|
|
40
|
+
this.managers = managers;
|
|
41
|
+
this.components = components;
|
|
42
|
+
this.listener = on(components.body.elements.group, "scroll", onScroll.bind(this));
|
|
44
43
|
}
|
|
45
44
|
destroy() {
|
|
46
45
|
this.listener();
|
|
47
46
|
for (const [index, row] of this.visible) {
|
|
48
|
-
removeRow(
|
|
47
|
+
removeRow(this.pool, row);
|
|
49
48
|
this.visible.delete(index);
|
|
50
49
|
}
|
|
51
50
|
this.pool.cells = {};
|
|
@@ -60,33 +59,41 @@ var VirtualizationManager = class {
|
|
|
60
59
|
delete row.cells[fields[index]];
|
|
61
60
|
}
|
|
62
61
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
getFragment() {
|
|
63
|
+
this.fragment ??= document.createDocumentFragment();
|
|
64
|
+
this.fragment.replaceChildren();
|
|
65
|
+
return this.fragment;
|
|
66
|
+
}
|
|
67
|
+
update(down, rerender) {
|
|
68
|
+
const { components, managers, pool, visible } = this;
|
|
69
|
+
components.body.elements.faker.style.height = `${managers.data.size * managers.row.height}px`;
|
|
66
70
|
const indices = /* @__PURE__ */ new Set();
|
|
67
|
-
const range = getRange(
|
|
71
|
+
const range = getRange.call(this, down);
|
|
68
72
|
for (let index = range.start; index <= range.end; index += 1) indices.add(index);
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
73
|
+
let remove = rerender ?? false;
|
|
74
|
+
for (const [index, row] of visible) {
|
|
75
|
+
if (!managers.row.has(row.key) || !indices.has(index)) remove = true;
|
|
76
|
+
if (remove) {
|
|
77
|
+
visible.delete(index);
|
|
78
|
+
removeRow(pool, row);
|
|
79
|
+
}
|
|
72
80
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const keys = tabela.managers.data.values.keys.active ?? tabela.managers.data.values.keys.original;
|
|
81
|
+
const fragment = this.getFragment();
|
|
82
|
+
const keys = managers.data.values.keys.active ?? managers.data.values.keys.original;
|
|
76
83
|
let count = 0;
|
|
77
84
|
for (let index = range.start; index <= range.end; index += 1) {
|
|
78
|
-
if (
|
|
79
|
-
const row =
|
|
85
|
+
if (visible.has(index)) continue;
|
|
86
|
+
const row = managers.row.get(keys[index]);
|
|
80
87
|
if (row == null) continue;
|
|
81
88
|
count += 1;
|
|
82
|
-
renderRow(
|
|
83
|
-
|
|
89
|
+
renderRow(managers, row);
|
|
90
|
+
visible.set(index, row);
|
|
84
91
|
if (row.element != null) {
|
|
85
|
-
row.element.style.transform = `translateY(${index *
|
|
86
|
-
|
|
92
|
+
row.element.style.transform = `translateY(${index * managers.row.height}px)`;
|
|
93
|
+
fragment.append(row.element);
|
|
87
94
|
}
|
|
88
95
|
}
|
|
89
|
-
if (count > 0)
|
|
96
|
+
if (count > 0) components.body.elements.group[down ? "append" : "prepend"](fragment);
|
|
90
97
|
}
|
|
91
98
|
};
|
|
92
99
|
export { VirtualizationManager };
|
|
File without changes
|
|
File without changes
|