@oscarpalmer/tabela 0.13.0 → 0.15.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.d.mts +10 -1
- package/dist/components/body.component.mjs +8 -6
- package/dist/components/column.component.d.mts +15 -1
- package/dist/components/column.component.mjs +12 -10
- package/dist/components/footer.component.d.mts +12 -1
- package/dist/components/footer.component.mjs +6 -6
- package/dist/components/group.component.d.mts +19 -1
- package/dist/components/group.component.mjs +17 -11
- package/dist/components/header.component.d.mts +12 -1
- package/dist/components/header.component.mjs +5 -5
- package/dist/components/row.component.d.mts +14 -1
- package/dist/components/row.component.mjs +21 -17
- package/dist/helpers/dom.helpers.d.mts +3 -3
- package/dist/helpers/dom.helpers.mjs +12 -11
- package/dist/helpers/misc.helpers.d.mts +7 -1
- package/dist/helpers/misc.helpers.mjs +12 -1
- package/dist/index.d.mts +1 -1
- package/dist/managers/column.manager.d.mts +16 -1
- package/dist/managers/column.manager.mjs +7 -7
- package/dist/managers/data.manager.d.mts +26 -1
- package/dist/managers/data.manager.mjs +122 -88
- package/dist/managers/event.manager.d.mts +17 -1
- package/dist/managers/event.manager.mjs +35 -10
- package/dist/managers/filter.manager.d.mts +17 -1
- package/dist/managers/filter.manager.mjs +43 -35
- package/dist/managers/group.manager.d.mts +26 -1
- package/dist/managers/group.manager.mjs +36 -16
- package/dist/managers/navigation.manager.d.mts +15 -2
- package/dist/managers/navigation.manager.mjs +38 -34
- package/dist/managers/render.manager.d.mts +18 -1
- package/dist/managers/render.manager.mjs +44 -31
- package/dist/managers/row.manager.d.mts +18 -1
- package/dist/managers/row.manager.mjs +1 -1
- package/dist/managers/selection.manager.d.mts +22 -1
- package/dist/managers/selection.manager.mjs +26 -23
- package/dist/managers/sort.manager.d.mts +22 -1
- package/dist/managers/sort.manager.mjs +71 -49
- package/dist/managers/style.manager.d.mts +8 -1
- package/dist/managers/style.manager.mjs +57 -25
- package/dist/models/body.model.d.mts +6 -1
- package/dist/models/column.model.d.mts +13 -2
- package/dist/models/data.model.d.mts +28 -2
- package/dist/models/dom.model.d.mts +19 -0
- package/dist/models/dom.model.mjs +19 -0
- package/dist/models/event.model.d.mts +99 -0
- package/dist/models/event.model.mjs +53 -0
- package/dist/models/filter.model.d.mts +26 -2
- package/dist/models/filter.model.mjs +13 -1
- package/dist/models/footer.model.d.mts +7 -1
- package/dist/models/group.model.d.mts +19 -2
- package/dist/models/group.model.mjs +5 -1
- package/dist/models/header.model.d.mts +6 -1
- package/dist/models/render.model.d.mts +22 -2
- package/dist/models/selection.model.d.mts +11 -1
- package/dist/models/sort.model.d.mts +19 -2
- package/dist/models/sort.model.mjs +5 -1
- package/dist/models/style.model.d.mts +27 -21
- package/dist/models/style.model.mjs +27 -21
- package/dist/models/tabela.model.d.mts +45 -1
- package/dist/models/tabela.options.d.mts +13 -1
- package/dist/tabela.d.mts +9 -8
- package/dist/tabela.full.mjs +1083 -574
- package/dist/tabela.mjs +19 -19
- package/package.json +2 -4
- package/src/components/body.component.ts +10 -7
- package/src/components/column.component.ts +20 -16
- package/src/components/footer.component.ts +7 -10
- package/src/components/group.component.ts +39 -13
- package/src/components/header.component.ts +6 -5
- package/src/components/row.component.ts +27 -19
- package/src/helpers/dom.helpers.ts +18 -22
- package/src/helpers/misc.helpers.ts +17 -0
- package/src/managers/column.manager.ts +9 -9
- package/src/managers/data.manager.ts +196 -107
- package/src/managers/event.manager.ts +69 -12
- package/src/managers/filter.manager.ts +70 -41
- package/src/managers/group.manager.ts +60 -18
- package/src/managers/navigation.manager.ts +46 -49
- package/src/managers/render.manager.ts +60 -34
- package/src/managers/row.manager.ts +1 -1
- package/src/managers/selection.manager.ts +37 -35
- package/src/managers/sort.manager.ts +114 -72
- package/src/managers/style.manager.ts +73 -25
- package/src/models/column.model.ts +4 -8
- package/src/models/data.model.ts +13 -14
- package/src/models/dom.model.ts +31 -0
- package/src/models/event.model.ts +175 -0
- package/src/models/filter.model.ts +22 -2
- package/src/models/group.model.ts +13 -0
- package/src/models/render.model.ts +6 -0
- package/src/models/sort.model.ts +11 -5
- package/src/models/style.model.ts +32 -20
- package/src/models/tabela.model.ts +1 -0
- package/src/tabela.ts +26 -24
- package/dist/body.component-_VDOpJhV.d.mts +0 -10
- package/dist/body.model-2iwsovAV.d.mts +0 -7
- package/dist/column.component-Bx46r3JI.d.mts +0 -16
- package/dist/column.model-D-aw4EU4.d.mts +0 -16
- package/dist/filter.model-7ukJrtil.d.mts +0 -16
- package/dist/footer.component-Curiab8j.d.mts +0 -12
- package/dist/footer.model-DhqoS6ds.d.mts +0 -8
- package/dist/group.component-Cq1YYbfJ.d.mts +0 -285
- package/dist/group.model-BsKFwHbt.d.mts +0 -10
- package/dist/header.component-BjjlpZIg.d.mts +0 -12
- package/dist/header.model-DN_KzUCV.d.mts +0 -7
- package/dist/selection.model-rwQe9fco.d.mts +0 -12
- package/dist/sort.model-CauImaLu.d.mts +0 -15
- package/dist/tabela.options-RkZvfptB.d.mts +0 -14
|
@@ -1,34 +1,44 @@
|
|
|
1
|
+
import { EVENT_GROUP_ADD, EVENT_GROUP_CLEAR, EVENT_GROUP_REMOVE, EVENT_GROUP_TOGGLE } from "../models/event.model.mjs";
|
|
1
2
|
import { removeGroup } from "../components/group.component.mjs";
|
|
3
|
+
import { getGroup } from "../helpers/misc.helpers.mjs";
|
|
2
4
|
import { sort } from "@oscarpalmer/atoms/array";
|
|
5
|
+
import { toMap } from "@oscarpalmer/atoms/array/to-map";
|
|
3
6
|
import { toRecord } from "@oscarpalmer/atoms/array/to-record";
|
|
4
7
|
import { isNullableOrWhitespace } from "@oscarpalmer/atoms/is";
|
|
5
8
|
import { getString } from "@oscarpalmer/atoms/string";
|
|
9
|
+
import { compare } from "@oscarpalmer/atoms/value/compare";
|
|
6
10
|
//#region src/managers/group.manager.ts
|
|
7
11
|
var GroupManager = class {
|
|
8
12
|
collapsed = /* @__PURE__ */ new Set();
|
|
9
13
|
enabled = false;
|
|
10
|
-
|
|
11
|
-
handlers =
|
|
12
|
-
if (group === this.
|
|
14
|
+
key;
|
|
15
|
+
handlers = { set: (group) => {
|
|
16
|
+
if (group === this.key) return;
|
|
13
17
|
this.enabled = !isNullableOrWhitespace(group);
|
|
14
|
-
this.
|
|
18
|
+
this.key = group ?? "";
|
|
15
19
|
this.state.managers.data.set(this.state.managers.data.get());
|
|
16
|
-
} }
|
|
20
|
+
} };
|
|
17
21
|
items = [];
|
|
22
|
+
mapped = /* @__PURE__ */ new Map();
|
|
18
23
|
order = {};
|
|
19
24
|
constructor(state) {
|
|
20
25
|
this.state = state;
|
|
21
26
|
if (isNullableOrWhitespace(state.options.grouping)) return;
|
|
22
27
|
this.enabled = true;
|
|
23
|
-
this.
|
|
28
|
+
this.key = state.options.grouping;
|
|
24
29
|
}
|
|
25
|
-
add(group) {
|
|
30
|
+
add(group, emit) {
|
|
26
31
|
this.set([...this.items, group]);
|
|
32
|
+
if (emit) this.state.managers.event.emit(EVENT_GROUP_ADD, [getGroup(group)]);
|
|
27
33
|
}
|
|
28
34
|
clear() {
|
|
35
|
+
if (this.items.length === 0) return;
|
|
29
36
|
const groups = this.items.splice(0);
|
|
30
37
|
const { length } = groups;
|
|
31
|
-
for (let index = 0; index < length; index += 1) this.remove(groups[index]);
|
|
38
|
+
for (let index = 0; index < length; index += 1) this.remove(groups[index], false);
|
|
39
|
+
this.collapsed.clear();
|
|
40
|
+
this.set([]);
|
|
41
|
+
this.state.managers.event.emit(EVENT_GROUP_CLEAR);
|
|
32
42
|
}
|
|
33
43
|
destroy() {
|
|
34
44
|
const groups = this.items.splice(0);
|
|
@@ -38,34 +48,44 @@ var GroupManager = class {
|
|
|
38
48
|
this.handlers = void 0;
|
|
39
49
|
this.state = void 0;
|
|
40
50
|
}
|
|
41
|
-
|
|
51
|
+
getForKey(key) {
|
|
52
|
+
return this.mapped.get(key);
|
|
53
|
+
}
|
|
54
|
+
getForValue(value) {
|
|
42
55
|
const asString = getString(value);
|
|
43
56
|
return this.items.find((item) => item.value.stringified === asString);
|
|
44
57
|
}
|
|
45
58
|
handle(button) {
|
|
46
|
-
const
|
|
47
|
-
const group = this.
|
|
59
|
+
const key = button.dataset.key?.replace(`${this.state.prefix}_`, "");
|
|
60
|
+
const group = this.getForKey(key ?? "");
|
|
48
61
|
if (group == null) return;
|
|
49
62
|
const { collapsed, items, state } = this;
|
|
50
63
|
group.expanded = !group.expanded;
|
|
51
64
|
const index = items.indexOf(group);
|
|
52
|
-
let first = state.managers.data.state.
|
|
53
|
-
const last = items[index + 1] == null ? state.managers.data.state.
|
|
65
|
+
let first = state.managers.data.state.keys.original.indexOf(group.key) + 1;
|
|
66
|
+
const last = items[index + 1] == null ? state.managers.data.state.keys.original.length - 1 : state.managers.data.state.keys.original.indexOf(items[index + 1].key) - 1;
|
|
54
67
|
for (; first <= last; first += 1) {
|
|
55
|
-
const key = state.managers.data.state.
|
|
68
|
+
const key = state.managers.data.state.keys.original[first];
|
|
56
69
|
if (group.expanded) collapsed.delete(key);
|
|
57
70
|
else collapsed.add(key);
|
|
58
71
|
}
|
|
72
|
+
state.managers.event.emit(EVENT_GROUP_TOGGLE, {
|
|
73
|
+
collapsed: group.expanded ? [] : [getGroup(group)],
|
|
74
|
+
expanded: group.expanded ? [getGroup(group)] : []
|
|
75
|
+
});
|
|
59
76
|
if (Object.keys(state.managers.filter.items).length > 0) state.managers.filter.filter();
|
|
60
77
|
else if (state.managers.sort.items.length > 0) state.managers.sort.sort();
|
|
61
78
|
else state.managers.render.update(true, true);
|
|
62
79
|
}
|
|
63
|
-
remove(group) {
|
|
80
|
+
remove(group, update) {
|
|
64
81
|
removeGroup(group);
|
|
82
|
+
if (!update) return;
|
|
65
83
|
this.set(this.items.filter((item) => item !== group));
|
|
84
|
+
this.state.managers.event.emit(EVENT_GROUP_REMOVE, [getGroup(group)]);
|
|
66
85
|
}
|
|
67
86
|
set(items) {
|
|
68
|
-
this.items = sort(items, (
|
|
87
|
+
this.items = sort(items, (first, second) => compare(first.label, second.label));
|
|
88
|
+
this.mapped = toMap(items, (group) => group.key);
|
|
69
89
|
this.order = toRecord(items, (group) => group.value.stringified, (_, index) => index);
|
|
70
90
|
}
|
|
71
91
|
};
|
|
@@ -1,2 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { State } from "../models/tabela.model.mjs";
|
|
2
|
+
import { Key } from "@oscarpalmer/atoms/models";
|
|
3
|
+
|
|
4
|
+
//#region src/managers/navigation.manager.d.ts
|
|
5
|
+
declare class NavigationManager {
|
|
6
|
+
state: State;
|
|
7
|
+
active: Key | undefined;
|
|
8
|
+
constructor(state: State);
|
|
9
|
+
destroy(): void;
|
|
10
|
+
handle(event: KeyboardEvent): void;
|
|
11
|
+
setActive(item: Key | undefined, scroll?: boolean): void;
|
|
12
|
+
}
|
|
13
|
+
declare const attributeDataActiveTrue = "[data-active=\"true\"]";
|
|
14
|
+
//#endregion
|
|
15
|
+
export { NavigationManager, attributeDataActiveTrue };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { getKey } from "../helpers/misc.helpers.mjs";
|
|
1
|
+
import { ARIA_ACTIVEDESCENDANT, ATTRIBUTE_DATA_ACTIVE } from "../models/dom.model.mjs";
|
|
2
|
+
import { getKey, isGroupKey } from "../helpers/misc.helpers.mjs";
|
|
3
3
|
import { isNullableOrWhitespace } from "@oscarpalmer/atoms/is";
|
|
4
4
|
import { clamp } from "@oscarpalmer/atoms/number";
|
|
5
5
|
//#region src/managers/navigation.manager.ts
|
|
@@ -14,63 +14,67 @@ var NavigationManager = class {
|
|
|
14
14
|
handle(event) {
|
|
15
15
|
if (!allKeys.has(event.key)) return;
|
|
16
16
|
event.preventDefault();
|
|
17
|
-
const { components,
|
|
18
|
-
const activeDescendant = components.body.elements.group.getAttribute(
|
|
19
|
-
const {
|
|
20
|
-
const { length } =
|
|
17
|
+
const { components, managers } = this.state;
|
|
18
|
+
const activeDescendant = components.body.elements.group.getAttribute(ARIA_ACTIVEDESCENDANT);
|
|
19
|
+
const { keys } = managers.data;
|
|
20
|
+
const { length } = keys;
|
|
21
21
|
let next;
|
|
22
22
|
if (isNullableOrWhitespace(activeDescendant)) next = getDefaultIndex(event.key, length);
|
|
23
|
-
else next = getIndex(this.state, event, activeDescendant
|
|
24
|
-
if (next != null) this.setActive(
|
|
23
|
+
else next = getIndex(this.state, event, activeDescendant);
|
|
24
|
+
if (next != null) this.setActive(keys.at(next));
|
|
25
25
|
}
|
|
26
26
|
setActive(item, scroll) {
|
|
27
|
-
const { components,
|
|
27
|
+
const { components, managers, options, prefix } = this.state;
|
|
28
28
|
this.active = item;
|
|
29
|
-
const active = components.body.elements.group.querySelectorAll(
|
|
30
|
-
for (const item of active) item.setAttribute(
|
|
31
|
-
const component = item
|
|
29
|
+
const active = components.body.elements.group.querySelectorAll(attributeDataActiveTrue);
|
|
30
|
+
for (const item of active) item.setAttribute(ATTRIBUTE_DATA_ACTIVE, "false");
|
|
31
|
+
const component = isGroupKey(item) ? managers.group.getForKey(item) : managers.row.get(item, false);
|
|
32
32
|
if (component != null) {
|
|
33
|
-
component.element?.setAttribute(
|
|
33
|
+
component.element?.setAttribute(ATTRIBUTE_DATA_ACTIVE, "true");
|
|
34
34
|
if (scroll ?? true) if (component.element == null) components.body.elements.group.scrollTo({
|
|
35
35
|
top: managers.data.getIndex(item) * options.rowHeight,
|
|
36
36
|
behavior: "smooth"
|
|
37
37
|
});
|
|
38
38
|
else component.element.scrollIntoView({ block: "nearest" });
|
|
39
39
|
}
|
|
40
|
-
components.body.elements.group.setAttribute(
|
|
40
|
+
components.body.elements.group.setAttribute(ARIA_ACTIVEDESCENDANT, component == null ? "" : `${prefix}${component.key}`);
|
|
41
41
|
}
|
|
42
42
|
};
|
|
43
43
|
function getDefaultIndex(key, max) {
|
|
44
44
|
switch (true) {
|
|
45
45
|
case negativeDefaultKeys.has(key): return -1;
|
|
46
|
-
case key ===
|
|
47
|
-
case key ===
|
|
46
|
+
case key === KEY_PAGE_DOWN: return Math.min(9, max - 1);
|
|
47
|
+
case key === KEY_PAGE_UP: return max < 10 ? 0 : max - 10;
|
|
48
48
|
default: return 0;
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
function getIndex(state, event, active
|
|
52
|
-
const key = getKey(active.replace(
|
|
51
|
+
function getIndex(state, event, active) {
|
|
52
|
+
const key = getKey(active.replace(state.prefix, ""));
|
|
53
53
|
if (key == null) return;
|
|
54
|
-
if (absoluteKeys.has(event.key)) return event.key ===
|
|
55
|
-
return clamp(state.managers.data.getIndex(key) +
|
|
54
|
+
if (absoluteKeys.has(event.key)) return event.key === KEY_HOME ? 0 : state.managers.data.size - 1;
|
|
55
|
+
return clamp(state.managers.data.getIndex(key) + (offset[event.key] ?? 0), 0, state.managers.data.size - 1, true);
|
|
56
56
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
const
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
57
|
+
const KEY_ARROW_DOWN = "ArrowDown";
|
|
58
|
+
const KEY_ARROW_UP = "ArrowUp";
|
|
59
|
+
const KEY_END = "End";
|
|
60
|
+
const KEY_HOME = "Home";
|
|
61
|
+
const KEY_PAGE_DOWN = "PageDown";
|
|
62
|
+
const KEY_PAGE_UP = "PageUp";
|
|
63
|
+
const absoluteKeys = new Set([KEY_END, KEY_HOME]);
|
|
64
|
+
const arrowKeys = new Set([KEY_ARROW_DOWN, KEY_ARROW_UP]);
|
|
65
|
+
const attributeDataActiveTrue = `[${ATTRIBUTE_DATA_ACTIVE}="true"]`;
|
|
66
|
+
const negativeDefaultKeys = new Set([KEY_ARROW_UP, KEY_END]);
|
|
67
|
+
const offset = {
|
|
68
|
+
[KEY_ARROW_DOWN]: 1,
|
|
69
|
+
[KEY_ARROW_UP]: -1,
|
|
70
|
+
[KEY_PAGE_DOWN]: 10,
|
|
71
|
+
[KEY_PAGE_UP]: -10
|
|
72
|
+
};
|
|
73
|
+
const pageKeys = new Set([KEY_PAGE_DOWN, KEY_PAGE_UP]);
|
|
70
74
|
const allKeys = new Set([
|
|
71
75
|
...absoluteKeys,
|
|
72
76
|
...arrowKeys,
|
|
73
77
|
...pageKeys
|
|
74
78
|
]);
|
|
75
79
|
//#endregion
|
|
76
|
-
export { NavigationManager };
|
|
80
|
+
export { NavigationManager, attributeDataActiveTrue };
|
|
@@ -1,2 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RenderElementPool, RenderState, RenderVisible } from "../models/render.model.mjs";
|
|
2
|
+
import { State } from "../models/tabela.model.mjs";
|
|
3
|
+
import { RemovableEventListener } from "@oscarpalmer/toretto/models";
|
|
4
|
+
|
|
5
|
+
//#region src/managers/render.manager.d.ts
|
|
6
|
+
declare class RenderManager {
|
|
7
|
+
fragment: DocumentFragment;
|
|
8
|
+
listener: RemovableEventListener;
|
|
9
|
+
pool: RenderElementPool;
|
|
10
|
+
state: RenderState;
|
|
11
|
+
visible: RenderVisible;
|
|
12
|
+
constructor(state: State);
|
|
13
|
+
destroy(): void;
|
|
14
|
+
removeCells(keys: string[]): void;
|
|
15
|
+
getFragment(): DocumentFragment;
|
|
16
|
+
update(down: boolean, rerender?: boolean): void;
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
2
19
|
export { RenderManager };
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { renderGroup } from "../components/group.component.mjs";
|
|
2
|
+
import { isGroupKey } from "../helpers/misc.helpers.mjs";
|
|
2
3
|
import { removeRow, renderRow } from "../components/row.component.mjs";
|
|
3
4
|
import { on } from "@oscarpalmer/toretto/event";
|
|
4
5
|
//#region src/managers/render.manager.ts
|
|
5
6
|
function getRange(state, down) {
|
|
6
7
|
const { element, managers, options } = state;
|
|
7
8
|
const { clientHeight, scrollTop } = element;
|
|
8
|
-
const {
|
|
9
|
+
const { keys } = managers.data;
|
|
9
10
|
const firstIndex = Math.floor(scrollTop / options.rowHeight);
|
|
10
|
-
const lastIndex =
|
|
11
|
+
const lastIndex = keys.length - managers.group.collapsed.size - 1;
|
|
11
12
|
const last = Math.min(lastIndex, Math.ceil((scrollTop + clientHeight) / options.rowHeight) - 1);
|
|
12
13
|
const visible = clientHeight / options.rowHeight;
|
|
13
14
|
const before = Math.ceil(visible) * (down ? 1 : 2);
|
|
@@ -38,7 +39,10 @@ var RenderManager = class {
|
|
|
38
39
|
rows: []
|
|
39
40
|
};
|
|
40
41
|
state;
|
|
41
|
-
visible =
|
|
42
|
+
visible = {
|
|
43
|
+
indiced: /* @__PURE__ */ new Map(),
|
|
44
|
+
keys: /* @__PURE__ */ new Set()
|
|
45
|
+
};
|
|
42
46
|
constructor(state) {
|
|
43
47
|
this.listener = on(state.element, "scroll", onScroll.bind(this));
|
|
44
48
|
this.state = {
|
|
@@ -50,7 +54,8 @@ var RenderManager = class {
|
|
|
50
54
|
destroy() {
|
|
51
55
|
const { listener, pool, visible } = this;
|
|
52
56
|
listener();
|
|
53
|
-
visible.clear();
|
|
57
|
+
visible.indiced.clear();
|
|
58
|
+
visible.keys.clear();
|
|
54
59
|
const cells = Object.values(pool.cells).flat();
|
|
55
60
|
let { length } = cells;
|
|
56
61
|
for (let index = 0; index < length; index += 1) cells[index].remove();
|
|
@@ -64,18 +69,18 @@ var RenderManager = class {
|
|
|
64
69
|
this.state = void 0;
|
|
65
70
|
this.visible = void 0;
|
|
66
71
|
}
|
|
67
|
-
removeCells(
|
|
72
|
+
removeCells(keys) {
|
|
68
73
|
const { pool, state, visible } = this;
|
|
69
|
-
const { length } =
|
|
70
|
-
for (let index = 0; index < length; index += 1) delete pool.cells[
|
|
71
|
-
for (const [, key] of visible) {
|
|
72
|
-
if (key
|
|
74
|
+
const { length } = keys;
|
|
75
|
+
for (let index = 0; index < length; index += 1) delete pool.cells[keys[index]];
|
|
76
|
+
for (const [, key] of visible.indiced) {
|
|
77
|
+
if (isGroupKey(key)) continue;
|
|
73
78
|
const row = state.managers.row.get(key, false);
|
|
74
79
|
if (row == null || row.element == null) continue;
|
|
75
80
|
for (let index = 0; index < length; index += 1) {
|
|
76
|
-
row.cells[
|
|
77
|
-
row.cells[
|
|
78
|
-
delete row.cells[
|
|
81
|
+
row.cells[keys[index]].innerHTML = "";
|
|
82
|
+
row.cells[keys[index]].remove();
|
|
83
|
+
delete row.cells[keys[index]];
|
|
79
84
|
}
|
|
80
85
|
}
|
|
81
86
|
}
|
|
@@ -92,52 +97,60 @@ var RenderManager = class {
|
|
|
92
97
|
const range = getRange(state, down);
|
|
93
98
|
for (let index = range.start; index <= range.end; index += 1) indices.add(index);
|
|
94
99
|
let remove = rerender ?? false;
|
|
95
|
-
for (const [index, key] of visible) {
|
|
96
|
-
if (key
|
|
100
|
+
for (const [index, key] of visible.indiced) {
|
|
101
|
+
if (isGroupKey(key)) {
|
|
97
102
|
if (remove || !indices.has(index)) {
|
|
98
|
-
visible.delete(index);
|
|
99
|
-
|
|
103
|
+
visible.indiced.delete(index);
|
|
104
|
+
visible.keys.delete(key);
|
|
105
|
+
state.managers.group.getForKey(key)?.element?.remove();
|
|
100
106
|
}
|
|
101
107
|
continue;
|
|
102
108
|
}
|
|
103
109
|
const row = managers.row.get(key, false);
|
|
104
110
|
if (remove || row == null || !indices.has(index) || managers.group.collapsed.has(key)) {
|
|
105
|
-
visible.delete(index);
|
|
111
|
+
visible.indiced.delete(index);
|
|
112
|
+
visible.keys.delete(key);
|
|
106
113
|
if (row != null) removeRow(pool, row);
|
|
107
114
|
}
|
|
108
115
|
}
|
|
109
116
|
const fragment = this.getFragment();
|
|
110
|
-
const {
|
|
117
|
+
const { keys } = managers.data;
|
|
111
118
|
let count = 0;
|
|
112
119
|
let offset = 0;
|
|
113
120
|
for (let index = range.start; index <= range.end + offset; index += 1) {
|
|
114
|
-
if (visible.has(index)) continue;
|
|
115
|
-
const
|
|
116
|
-
if (
|
|
121
|
+
if (visible.indiced.has(index)) continue;
|
|
122
|
+
const key = keys[index];
|
|
123
|
+
if (isGroupKey(key)) {
|
|
124
|
+
const group = managers.group.getForKey(key);
|
|
125
|
+
if (group == null) continue;
|
|
117
126
|
count += 1;
|
|
118
|
-
renderGroup(state,
|
|
119
|
-
visible.set(index,
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
127
|
+
renderGroup(state, group);
|
|
128
|
+
visible.indiced.set(index, group.key);
|
|
129
|
+
visible.keys.add(group.key);
|
|
130
|
+
if (group.element != null) {
|
|
131
|
+
group.element.style.transform = `translateY(${(index - offset) * options.rowHeight}px)`;
|
|
132
|
+
fragment.append(group.element);
|
|
123
133
|
}
|
|
124
134
|
continue;
|
|
125
135
|
}
|
|
126
|
-
const row = managers.row.get(
|
|
136
|
+
const row = managers.row.get(key, true);
|
|
127
137
|
if (row == null) continue;
|
|
128
|
-
if (managers.group.collapsed.has(
|
|
138
|
+
if (managers.group.collapsed.has(key)) {
|
|
129
139
|
offset += 1;
|
|
130
140
|
continue;
|
|
131
141
|
}
|
|
132
142
|
count += 1;
|
|
133
143
|
renderRow(state, row);
|
|
134
|
-
visible.set(index,
|
|
144
|
+
visible.indiced.set(index, key);
|
|
145
|
+
visible.keys.add(key);
|
|
135
146
|
if (row.element != null) {
|
|
136
147
|
row.element.style.transform = `translateY(${(index - offset) * options.rowHeight}px)`;
|
|
137
148
|
fragment.append(row.element);
|
|
138
149
|
}
|
|
139
150
|
}
|
|
140
|
-
if (count
|
|
151
|
+
if (count === 0) return;
|
|
152
|
+
if (down) components.body.elements.group.append(fragment);
|
|
153
|
+
else components.body.elements.group.prepend(fragment);
|
|
141
154
|
}
|
|
142
155
|
};
|
|
143
156
|
//#endregion
|
|
@@ -1,2 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RowComponent } from "../components/row.component.mjs";
|
|
2
|
+
import { State } from "../models/tabela.model.mjs";
|
|
3
|
+
import { Key } from "@oscarpalmer/atoms/models";
|
|
4
|
+
|
|
5
|
+
//#region src/managers/row.manager.d.ts
|
|
6
|
+
declare class RowManager {
|
|
7
|
+
state: State;
|
|
8
|
+
components: Map<Key, RowComponent>;
|
|
9
|
+
constructor(state: State);
|
|
10
|
+
clear(): void;
|
|
11
|
+
destroy(): void;
|
|
12
|
+
get(key: Key, create: boolean): RowComponent | undefined;
|
|
13
|
+
has(key: Key): boolean;
|
|
14
|
+
remove(key: Key): void;
|
|
15
|
+
removeRow(row: RowComponent): void;
|
|
16
|
+
update(key: Key): void;
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
2
19
|
export { RowManager };
|
|
@@ -1,2 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TabelaSelection } from "../models/selection.model.mjs";
|
|
2
|
+
import { State } from "../models/tabela.model.mjs";
|
|
3
|
+
import { Key } from "@oscarpalmer/atoms/models";
|
|
4
|
+
|
|
5
|
+
//#region src/managers/selection.manager.d.ts
|
|
6
|
+
declare class SelectionManager {
|
|
7
|
+
state: State;
|
|
8
|
+
handlers: TabelaSelection;
|
|
9
|
+
items: Set<Key>;
|
|
10
|
+
last: Key | undefined;
|
|
11
|
+
constructor(state: State);
|
|
12
|
+
add(keys: Key[]): void;
|
|
13
|
+
clear(): void;
|
|
14
|
+
destroy(): void;
|
|
15
|
+
handle(event: MouseEvent, target: HTMLElement): void;
|
|
16
|
+
range(from: Key | HTMLElement, to: Key | HTMLElement): void;
|
|
17
|
+
remove(keys: Key[]): void;
|
|
18
|
+
set(keys: Key[]): void;
|
|
19
|
+
toggle(): void;
|
|
20
|
+
update(removed: Key[]): void;
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
2
23
|
export { SelectionManager };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ARIA_SELECTED, ATTRIBUTE_DATA_KEY } from "../models/dom.model.mjs";
|
|
2
|
+
import { CSS_ROW_BODY, CSS_ROW_SELECTED, CSS_SELECTION, CSS_TABLE } from "../models/style.model.mjs";
|
|
2
3
|
import { createElement } from "../helpers/dom.helpers.mjs";
|
|
3
|
-
import {
|
|
4
|
-
import { getKey } from "../helpers/misc.helpers.mjs";
|
|
4
|
+
import { getKey, isGroupKey } from "../helpers/misc.helpers.mjs";
|
|
5
5
|
import { preventSelection } from "../helpers/style.helper.mjs";
|
|
6
6
|
import { setAttribute } from "@oscarpalmer/toretto/attribute";
|
|
7
7
|
import { isKey } from "@oscarpalmer/atoms/is";
|
|
@@ -9,13 +9,13 @@ import { getPosition, on } from "@oscarpalmer/toretto/event";
|
|
|
9
9
|
import { findAncestor } from "@oscarpalmer/toretto/find";
|
|
10
10
|
//#region src/managers/selection.manager.ts
|
|
11
11
|
var SelectionManager = class {
|
|
12
|
-
handlers =
|
|
12
|
+
handlers = {
|
|
13
13
|
add: (keys) => this.add(keys),
|
|
14
14
|
clear: () => this.clear(),
|
|
15
15
|
remove: (keys) => this.remove(keys),
|
|
16
16
|
set: (keys) => this.set(keys),
|
|
17
17
|
toggle: () => this.toggle()
|
|
18
|
-
}
|
|
18
|
+
};
|
|
19
19
|
items = /* @__PURE__ */ new Set();
|
|
20
20
|
last;
|
|
21
21
|
constructor(state) {
|
|
@@ -48,7 +48,7 @@ var SelectionManager = class {
|
|
|
48
48
|
this.state = void 0;
|
|
49
49
|
}
|
|
50
50
|
handle(event, target) {
|
|
51
|
-
const key = getKey(target.getAttribute(
|
|
51
|
+
const key = getKey(target.getAttribute(ATTRIBUTE_DATA_KEY));
|
|
52
52
|
if (key == null) return;
|
|
53
53
|
const { items } = this;
|
|
54
54
|
if (event.shiftKey) {
|
|
@@ -68,18 +68,18 @@ var SelectionManager = class {
|
|
|
68
68
|
range(from, to) {
|
|
69
69
|
const { state } = this;
|
|
70
70
|
const keyed = isKey(from) && isKey(to);
|
|
71
|
-
const fromKey = keyed ? from : getKey(from.getAttribute(
|
|
72
|
-
const toKey = keyed ? to : getKey(to.getAttribute(
|
|
71
|
+
const fromKey = keyed ? from : getKey(from.getAttribute(ATTRIBUTE_DATA_KEY));
|
|
72
|
+
const toKey = keyed ? to : getKey(to.getAttribute(ATTRIBUTE_DATA_KEY));
|
|
73
73
|
if (fromKey === toKey) return;
|
|
74
|
-
const {
|
|
74
|
+
const { keys } = state.managers.data;
|
|
75
75
|
const fromIndex = state.managers.data.getIndex(fromKey);
|
|
76
76
|
const toIndex = state.managers.data.getIndex(toKey);
|
|
77
77
|
if (fromIndex === -1 || toIndex === -1) return;
|
|
78
78
|
const [start, end] = fromIndex < toIndex ? [fromIndex, toIndex] : [toIndex, fromIndex];
|
|
79
79
|
const selected = [];
|
|
80
80
|
for (let index = start; index <= end; index += 1) {
|
|
81
|
-
const
|
|
82
|
-
if (!(
|
|
81
|
+
const key = keys[index];
|
|
82
|
+
if (!isGroupKey(key)) selected.push(key);
|
|
83
83
|
}
|
|
84
84
|
if (keyed) this.add(selected);
|
|
85
85
|
else this.set(selected);
|
|
@@ -105,9 +105,9 @@ var SelectionManager = class {
|
|
|
105
105
|
}
|
|
106
106
|
toggle() {
|
|
107
107
|
const { items, state } = this;
|
|
108
|
-
const
|
|
109
|
-
if (items.size ===
|
|
110
|
-
else this.set(
|
|
108
|
+
const { keys } = state.managers.data;
|
|
109
|
+
if (items.size === keys.length - state.managers.group.items.length) this.clear();
|
|
110
|
+
else this.set(keys.filter((key) => !isGroupKey(key)));
|
|
111
111
|
}
|
|
112
112
|
update(removed) {
|
|
113
113
|
const { state } = this;
|
|
@@ -123,19 +123,19 @@ var SelectionManager = class {
|
|
|
123
123
|
const { key, removed } = items[index];
|
|
124
124
|
const element = state.managers.row.get(key, false)?.element;
|
|
125
125
|
if (element == null) continue;
|
|
126
|
-
setAttribute(element,
|
|
127
|
-
if (removed) element.classList.remove(
|
|
128
|
-
else element.classList.add(
|
|
126
|
+
setAttribute(element, ARIA_SELECTED, String(!removed));
|
|
127
|
+
if (removed) element.classList.remove(CSS_ROW_SELECTED);
|
|
128
|
+
else element.classList.add(CSS_ROW_SELECTED);
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
};
|
|
132
132
|
function getPlaceholder() {
|
|
133
|
-
placeholder ??= createElement("div", { className:
|
|
133
|
+
placeholder ??= createElement("div", { className: CSS_SELECTION });
|
|
134
134
|
return placeholder;
|
|
135
135
|
}
|
|
136
136
|
function onMouseDown(event) {
|
|
137
137
|
if (shifted) {
|
|
138
|
-
const row = findAncestor(event.target, `.${
|
|
138
|
+
const row = findAncestor(event.target, `.${CSS_ROW_BODY}`);
|
|
139
139
|
if (!(row instanceof HTMLElement)) return;
|
|
140
140
|
startElement = row;
|
|
141
141
|
startPosition = getPosition(event);
|
|
@@ -163,11 +163,11 @@ function onMouseUp(event) {
|
|
|
163
163
|
preventSelection.remove();
|
|
164
164
|
}
|
|
165
165
|
getPlaceholder().remove();
|
|
166
|
-
const row = findAncestor(event.target,
|
|
166
|
+
const row = findAncestor(event.target, bodyRowSelector);
|
|
167
167
|
if (row instanceof HTMLElement) {
|
|
168
168
|
endElement = row;
|
|
169
|
-
const endTable = findAncestor(endElement,
|
|
170
|
-
const startTable = findAncestor(startElement,
|
|
169
|
+
const endTable = findAncestor(endElement, tableSelector);
|
|
170
|
+
const startTable = findAncestor(startElement, tableSelector);
|
|
171
171
|
if (startTable != null && startTable === endTable) mapped.get(startTable)?.range(startElement, endElement);
|
|
172
172
|
}
|
|
173
173
|
endElement = void 0;
|
|
@@ -175,7 +175,7 @@ function onMouseUp(event) {
|
|
|
175
175
|
startPosition = void 0;
|
|
176
176
|
}
|
|
177
177
|
function onShift(event, value) {
|
|
178
|
-
if (event.key ===
|
|
178
|
+
if (event.key === KEY_SHIFT) shifted = value;
|
|
179
179
|
}
|
|
180
180
|
function onShiftDown(event) {
|
|
181
181
|
onShift(event, true);
|
|
@@ -183,7 +183,10 @@ function onShiftDown(event) {
|
|
|
183
183
|
function onShiftUp(event) {
|
|
184
184
|
onShift(event, false);
|
|
185
185
|
}
|
|
186
|
+
const KEY_SHIFT = "Shift";
|
|
186
187
|
const mapped = /* @__PURE__ */ new WeakMap();
|
|
188
|
+
const bodyRowSelector = `.${CSS_ROW_BODY}`;
|
|
189
|
+
const tableSelector = `.${CSS_TABLE}`;
|
|
187
190
|
let shifted = false;
|
|
188
191
|
let endElement;
|
|
189
192
|
let placeholder;
|
|
@@ -1,2 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DataValue } from "../models/data.model.mjs";
|
|
2
|
+
import { TabelaSort, TabelaSortDirection, TabelaSortItem } from "../models/sort.model.mjs";
|
|
3
|
+
import { State } from "../models/tabela.model.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/managers/sort.manager.d.ts
|
|
6
|
+
declare class SortManager {
|
|
7
|
+
state: State;
|
|
8
|
+
handlers: TabelaSort;
|
|
9
|
+
items: TabelaSortItem[];
|
|
10
|
+
constructor(state: State);
|
|
11
|
+
add(key: string, direction?: TabelaSortDirection): void;
|
|
12
|
+
addOrSet(event: MouseEvent, key: string): void;
|
|
13
|
+
clear(): void;
|
|
14
|
+
destroy(): void;
|
|
15
|
+
flip(key: string): void;
|
|
16
|
+
remove(key: string): void;
|
|
17
|
+
set(items: TabelaSortItem[], set: boolean): void;
|
|
18
|
+
sort(): void;
|
|
19
|
+
toggle(event: MouseEvent, key: string, direction?: string | null): void;
|
|
20
|
+
}
|
|
21
|
+
declare function sortWithGroups(state: State, data: DataValue[], sorters: TabelaSortItem[]): DataValue[];
|
|
22
|
+
//#endregion
|
|
2
23
|
export { SortManager, sortWithGroups };
|