@oscarpalmer/tabela 0.7.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 +1 -1
- package/dist/components/column.component.js +29 -9
- package/dist/components/header.component.js +1 -1
- package/dist/helpers/dom.helpers.js +6 -4
- package/dist/managers/data.manager.js +12 -9
- package/dist/managers/event.manager.js +30 -0
- package/dist/managers/sort.manager.js +83 -0
- package/dist/managers/virtualization.manager.js +2 -2
- package/dist/models/sort.model.js +0 -0
- package/dist/tabela.full.js +829 -106
- package/dist/tabela.js +8 -0
- package/package.json +1 -1
- package/src/components/body.component.ts +1 -0
- package/src/components/column.component.ts +58 -19
- package/src/components/header.component.ts +1 -1
- package/src/helpers/dom.helpers.ts +6 -0
- package/src/managers/data.manager.ts +20 -14
- package/src/managers/event.manager.ts +55 -0
- package/src/managers/sort.manager.ts +130 -0
- package/src/managers/virtualization.manager.ts +2 -2
- package/src/models/sort.model.ts +6 -0
- package/src/models/tabela.model.ts +13 -0
- package/src/tabela.ts +10 -1
- package/types/components/column.component.d.ts +9 -2
- package/types/helpers/dom.helpers.d.ts +1 -1
- package/types/managers/data.manager.d.ts +10 -2
- package/types/managers/event.manager.d.ts +10 -0
- package/types/managers/sort.manager.d.ts +23 -0
- package/types/managers/virtualization.manager.d.ts +1 -1
- package/types/models/sort.model.d.ts +5 -0
- package/types/models/tabela.model.d.ts +12 -0
- package/types/tabela.d.ts +2 -1
|
@@ -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",
|
|
@@ -1,13 +1,6 @@
|
|
|
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
5
|
constructor(options) {
|
|
13
6
|
const width = Number.parseInt(getComputedStyle(document.body).fontSize, 10) * (options.width ?? options.title.length * 1.5);
|
|
@@ -15,7 +8,34 @@ var ColumnComponent = class {
|
|
|
15
8
|
...options,
|
|
16
9
|
width
|
|
17
10
|
};
|
|
18
|
-
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;
|
|
19
19
|
}
|
|
20
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
|
+
}
|
|
21
41
|
export { ColumnComponent };
|
|
@@ -16,7 +16,7 @@ var HeaderComponent = class {
|
|
|
16
16
|
}
|
|
17
17
|
update(columns) {
|
|
18
18
|
this.elements.row.innerHTML = "";
|
|
19
|
-
this.elements.row.append(...columns.map((column) => column.
|
|
19
|
+
this.elements.row.append(...columns.map((column) => column.elements.wrapper));
|
|
20
20
|
}
|
|
21
21
|
};
|
|
22
22
|
export { HeaderComponent };
|
|
@@ -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,3 +1,4 @@
|
|
|
1
|
+
import { sort } from "@oscarpalmer/atoms/array";
|
|
1
2
|
import { toMap } from "@oscarpalmer/atoms/array/to-map";
|
|
2
3
|
import { isPlainObject } from "@oscarpalmer/atoms/is";
|
|
3
4
|
var DataManager = class {
|
|
@@ -28,8 +29,7 @@ var DataManager = class {
|
|
|
28
29
|
const { field, values } = this;
|
|
29
30
|
values.objects.array.push(...data);
|
|
30
31
|
values.objects.mapped = toMap(values.objects.array, field);
|
|
31
|
-
|
|
32
|
-
if (render) this.managers.virtualization.update(true);
|
|
32
|
+
if (render) this.render();
|
|
33
33
|
}
|
|
34
34
|
clear() {
|
|
35
35
|
if (this.values.objects.array.length > 0) this.set([]);
|
|
@@ -58,16 +58,19 @@ var DataManager = class {
|
|
|
58
58
|
values.keys.original.splice(values.keys.original.indexOf(key), 1);
|
|
59
59
|
managers.row.remove(key);
|
|
60
60
|
}
|
|
61
|
-
if (render) this.
|
|
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);
|
|
62
68
|
}
|
|
63
69
|
set(data) {
|
|
64
70
|
const { field, values } = this;
|
|
65
|
-
|
|
66
|
-
values.keys.active = void 0;
|
|
67
|
-
values.keys.original = [...mapped.keys()];
|
|
68
|
-
values.objects.mapped = mapped;
|
|
71
|
+
values.objects.mapped = toMap(data, field);
|
|
69
72
|
values.objects.array = data;
|
|
70
|
-
this.
|
|
73
|
+
this.render();
|
|
71
74
|
}
|
|
72
75
|
async synchronize(data, remove) {
|
|
73
76
|
const { field, values } = this;
|
|
@@ -89,7 +92,7 @@ var DataManager = class {
|
|
|
89
92
|
}
|
|
90
93
|
await this.update(updated);
|
|
91
94
|
if (add.length > 0) await this.add(add, false);
|
|
92
|
-
if (add.length > 0 || (remove ?? false)) this.
|
|
95
|
+
if (add.length > 0 || (remove ?? false)) this.render();
|
|
93
96
|
}
|
|
94
97
|
async update(data) {
|
|
95
98
|
const { field, managers, values } = this;
|
|
@@ -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 };
|
|
@@ -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 };
|
|
@@ -64,13 +64,13 @@ var VirtualizationManager = class {
|
|
|
64
64
|
this.fragment.replaceChildren();
|
|
65
65
|
return this.fragment;
|
|
66
66
|
}
|
|
67
|
-
update(down) {
|
|
67
|
+
update(down, rerender) {
|
|
68
68
|
const { components, managers, pool, visible } = this;
|
|
69
69
|
components.body.elements.faker.style.height = `${managers.data.size * managers.row.height}px`;
|
|
70
70
|
const indices = /* @__PURE__ */ new Set();
|
|
71
71
|
const range = getRange.call(this, down);
|
|
72
72
|
for (let index = range.start; index <= range.end; index += 1) indices.add(index);
|
|
73
|
-
let remove = false;
|
|
73
|
+
let remove = rerender ?? false;
|
|
74
74
|
for (const [index, row] of visible) {
|
|
75
75
|
if (!managers.row.has(row.key) || !indices.has(index)) remove = true;
|
|
76
76
|
if (remove) {
|
|
File without changes
|