@oscarpalmer/tabela 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/components/body.component.js +1 -0
  2. package/dist/components/row.component.js +11 -8
  3. package/dist/managers/column.manager.js +9 -8
  4. package/dist/managers/data.manager.js +26 -22
  5. package/dist/managers/event.manager.js +39 -23
  6. package/dist/managers/filter.manager.js +11 -10
  7. package/dist/managers/navigation.manager.js +73 -0
  8. package/dist/managers/render.manager.js +30 -25
  9. package/dist/managers/row.manager.js +7 -7
  10. package/dist/managers/selection.manager.js +19 -21
  11. package/dist/managers/sort.manager.js +9 -8
  12. package/dist/tabela.full.js +535 -410
  13. package/dist/tabela.js +27 -9
  14. package/package.json +1 -1
  15. package/src/components/body.component.ts +2 -0
  16. package/src/components/row.component.ts +14 -9
  17. package/src/managers/column.manager.ts +11 -13
  18. package/src/managers/data.manager.ts +31 -27
  19. package/src/managers/event.manager.ts +65 -42
  20. package/src/managers/filter.manager.ts +12 -11
  21. package/src/managers/navigation.manager.ts +145 -0
  22. package/src/managers/render.manager.ts +34 -28
  23. package/src/managers/row.manager.ts +9 -14
  24. package/src/managers/selection.manager.ts +24 -30
  25. package/src/managers/sort.manager.ts +14 -14
  26. package/src/models/render.model.ts +3 -1
  27. package/src/models/tabela.model.ts +12 -0
  28. package/src/tabela.ts +34 -9
  29. package/types/components/row.component.d.ts +2 -2
  30. package/types/managers/column.manager.d.ts +4 -5
  31. package/types/managers/data.manager.d.ts +5 -6
  32. package/types/managers/event.manager.d.ts +3 -6
  33. package/types/managers/filter.manager.d.ts +3 -3
  34. package/types/managers/navigation.manager.d.ts +10 -0
  35. package/types/managers/render.manager.d.ts +4 -6
  36. package/types/managers/row.manager.d.ts +4 -5
  37. package/types/managers/selection.manager.d.ts +3 -4
  38. package/types/managers/sort.manager.d.ts +4 -4
  39. package/types/models/render.model.d.ts +2 -1
  40. package/types/models/tabela.model.d.ts +11 -0
@@ -12,6 +12,7 @@ var BodyComponent = class {
12
12
  this.elements.group = group;
13
13
  group.className += " tabela__rowgroup--body";
14
14
  group.tabIndex = 0;
15
+ group.setAttribute("data-event", "body");
15
16
  group.append(this.elements.faker);
16
17
  }
17
18
  destroy() {
@@ -9,27 +9,30 @@ function removeRow(pool, row) {
9
9
  }
10
10
  row.cells = {};
11
11
  }
12
- function renderRow(managers, row) {
13
- const element = row.element ?? managers.render.pool.rows.shift() ?? createRow();
12
+ function renderRow(state, row) {
13
+ const element = row.element ?? state.managers.render.pool.rows.shift() ?? createRow();
14
14
  row.element = element;
15
15
  element.innerHTML = "";
16
- const selected = managers.selection.items.has(row.key);
16
+ const selected = state.managers.selection.items.has(row.key);
17
+ const key = String(row.key);
17
18
  setAttributes(element, {
18
19
  "aria-selected": String(selected),
20
+ "data-active": String(state.managers.navigation.active === row.key),
19
21
  "data-event": "row",
20
- "data-key": String(row.key)
22
+ "data-key": key,
23
+ id: `tabela_${state.id}_row_${key}`
21
24
  });
22
25
  element.classList.add("tabela__row--body");
23
26
  if (selected) element.classList.add("tabela__row--selected");
24
27
  else element.classList.remove("tabela__row--selected");
25
- const columns = managers.column.items;
28
+ const columns = state.managers.column.items;
26
29
  const { length } = columns;
27
- const data = managers.data.values.objects.mapped.get(row.key);
30
+ const data = state.managers.data.values.objects.mapped.get(row.key);
28
31
  if (data == null) return;
29
32
  for (let index = 0; index < length; index += 1) {
30
33
  const { options } = columns[index];
31
- managers.render.pool.cells[options.field] ??= [];
32
- const cell = managers.render.pool.cells[columns[index].options.field].shift() ?? createCell(options.width);
34
+ state.managers.render.pool.cells[options.field] ??= [];
35
+ const cell = state.managers.render.pool.cells[columns[index].options.field].shift() ?? createCell(options.width);
33
36
  cell.textContent = String(data[options.field]);
34
37
  row.cells[options.field] = cell;
35
38
  element.append(cell);
@@ -1,18 +1,19 @@
1
1
  import { ColumnComponent } from "../components/column.component.js";
2
2
  var ColumnManager = class {
3
3
  items = [];
4
- constructor(managers, components, columns) {
5
- this.managers = managers;
6
- this.components = components;
7
- this.set(columns);
4
+ constructor(state) {
5
+ this.state = state;
6
+ this.set(state.options.columns);
8
7
  }
9
8
  destroy() {
10
9
  const { length } = this.items;
11
10
  for (let index = 0; index < length; index += 1) this.items[index].destroy();
12
- this.items.length = 0;
11
+ this.items = void 0;
12
+ this.state = void 0;
13
13
  }
14
14
  remove(value) {
15
- const { components, items, managers } = this;
15
+ const { items, state } = this;
16
+ const { components, managers } = state;
16
17
  const fields = (Array.isArray(value) ? value : [value]).filter((item) => typeof item === "string");
17
18
  const { length } = fields;
18
19
  if (length === 0) return;
@@ -28,8 +29,8 @@ var ColumnManager = class {
28
29
  managers.render.removeCells(fields);
29
30
  }
30
31
  set(columns) {
31
- const { components, items } = this;
32
- const { footer, header } = components;
32
+ const { items, state } = this;
33
+ const { footer, header } = state.components;
33
34
  items.splice(0, items.length, ...columns.map((column) => new ColumnComponent(column)));
34
35
  header.update(items);
35
36
  footer.update(items);
@@ -20,15 +20,13 @@ var DataManager = class {
20
20
  get size() {
21
21
  return this.values.keys.active?.length ?? this.values.keys.original.length;
22
22
  }
23
- constructor(managers, components, field) {
24
- this.managers = managers;
25
- this.components = components;
26
- this.field = field;
23
+ constructor(state) {
24
+ this.state = state;
27
25
  }
28
26
  async add(data, render) {
29
- const { field, values } = this;
27
+ const { state, values } = this;
30
28
  push(values.objects.array, data);
31
- values.objects.mapped = toMap(values.objects.array, field);
29
+ values.objects.mapped = toMap(values.objects.array, state.key);
32
30
  if (render) this.render();
33
31
  }
34
32
  clear() {
@@ -41,48 +39,54 @@ var DataManager = class {
41
39
  values.keys.original.length = 0;
42
40
  values.objects.array.length = 0;
43
41
  this.handlers = void 0;
42
+ this.state = void 0;
43
+ this.values = void 0;
44
44
  }
45
45
  get(active) {
46
46
  const { values } = this;
47
47
  return active ?? false ? values.keys.active?.map((key) => values.objects.mapped.get(key)) ?? [] : values.objects.array;
48
48
  }
49
+ getIndex(key) {
50
+ const { values } = this;
51
+ return (values.keys.active ?? values.keys.original).indexOf(key);
52
+ }
49
53
  async remove(items, render) {
50
- const { field, managers, values } = this;
51
- const keys = items.map((value) => isPlainObject(value) ? value[field] : value).filter((key) => values.objects.mapped.has(key));
54
+ const { state, values } = this;
55
+ const keys = items.map((value) => isPlainObject(value) ? value[state.key] : value).filter((key) => values.objects.mapped.has(key));
52
56
  const { length } = keys;
53
57
  if (length === 0) return;
54
58
  for (let keyIndex = 0; keyIndex < length; keyIndex += 1) {
55
59
  const key = keys[keyIndex];
56
60
  values.objects.mapped.delete(key);
57
- const arrayIndex = values.objects.array.findIndex((object) => object[field] === key);
61
+ const arrayIndex = values.objects.array.findIndex((object) => object[state.key] === key);
58
62
  if (arrayIndex > -1) values.objects.array.splice(arrayIndex, 1);
59
63
  values.keys.original.splice(values.keys.original.indexOf(key), 1);
60
- managers.row.remove(key);
64
+ state.managers.row.remove(key);
61
65
  }
62
66
  if (render) this.render();
63
67
  }
64
68
  render() {
65
- const { field, managers, values } = this;
66
- values.keys.original = sort(values.objects.array.map((item) => item[field]));
67
- if (Object.keys(managers.filter.items).length > 0) managers.filter.filter();
68
- else if (managers.sort.items.length > 0) managers.sort.sort();
69
- else managers.render.update(true);
69
+ const { state, values } = this;
70
+ values.keys.original = sort(values.objects.array.map((item) => item[state.key]));
71
+ if (Object.keys(state.managers.filter.items).length > 0) state.managers.filter.filter();
72
+ else if (state.managers.sort.items.length > 0) state.managers.sort.sort();
73
+ else state.managers.render.update(true);
70
74
  }
71
75
  set(data) {
72
- const { field, values } = this;
73
- values.objects.mapped = toMap(data, field);
76
+ const { state, values } = this;
77
+ values.objects.mapped = toMap(data, state.key);
74
78
  values.objects.array = data;
75
79
  this.render();
76
80
  }
77
81
  async synchronize(data, remove) {
78
- const { field, values } = this;
82
+ const { state, values } = this;
79
83
  const add = [];
80
84
  const updated = [];
81
85
  const keys = /* @__PURE__ */ new Set([]);
82
86
  const { length } = data;
83
87
  for (let index = 0; index < length; index += 1) {
84
88
  const object = data[index];
85
- const key = object[field];
89
+ const key = object[state.key];
86
90
  if (values.objects.mapped.has(key)) updated.push(object);
87
91
  else add.push(object);
88
92
  keys.add(key);
@@ -97,18 +101,18 @@ var DataManager = class {
97
101
  if (add.length > 0 || (remove ?? false)) this.render();
98
102
  }
99
103
  async update(data) {
100
- const { field, managers, values } = this;
104
+ const { state, values } = this;
101
105
  const { length } = data;
102
106
  for (let index = 0; index < length; index += 1) {
103
107
  const object = data[index];
104
- const key = object[field];
108
+ const key = object[state.key];
105
109
  const value = values.objects.mapped.get(key);
106
110
  if (value != null) {
107
111
  values.objects.mapped.set(key, {
108
112
  ...value,
109
113
  ...object
110
114
  });
111
- managers.row.update(key);
115
+ state.managers.row.update(key);
112
116
  }
113
117
  }
114
118
  }
@@ -1,34 +1,50 @@
1
1
  import { on } from "@oscarpalmer/toretto/event";
2
- import { findAncestor } from "@oscarpalmer/toretto";
2
+ import { findAncestor } from "@oscarpalmer/toretto/find";
3
3
  var EventManager = class {
4
- listener;
5
- constructor(element, managers) {
6
- this.managers = managers;
7
- this.listener = on(element, "click", (event) => {
8
- this.onClick(event);
9
- }, { passive: false });
4
+ constructor(state) {
5
+ this.state = state;
6
+ mapped.set(state.element, this);
10
7
  }
11
8
  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
- case "row":
22
- this.managers.selection.handle(event, target);
23
- break;
24
- default: break;
25
- }
9
+ mapped.delete(this.state.element);
10
+ this.state = void 0;
26
11
  }
27
12
  onSort(event, target) {
28
- const { managers } = this;
29
13
  const direction = target.getAttribute("data-sort-direction");
30
14
  const field = target.getAttribute("data-field");
31
- if (field != null) managers.sort.toggle(event, field, direction);
15
+ if (field != null) this.state.managers.sort.toggle(event, field, direction);
32
16
  }
33
17
  };
18
+ function onClick(event) {
19
+ const target = findAncestor(event, "[data-event]");
20
+ const table = findAncestor(event, ".tabela");
21
+ if (!(target instanceof HTMLElement) || !(table instanceof HTMLElement)) return;
22
+ const manager = mapped.get(table);
23
+ if (manager == null) return;
24
+ switch (target?.getAttribute("data-event")) {
25
+ case "heading":
26
+ manager.onSort(event, target);
27
+ break;
28
+ case "row":
29
+ manager.state.managers.selection.handle(event, target);
30
+ break;
31
+ default: break;
32
+ }
33
+ }
34
+ function onKeydown(event) {
35
+ const target = findAncestor(event, "[data-event]");
36
+ const table = findAncestor(event, ".tabela");
37
+ if (!(target instanceof HTMLElement) || !(table instanceof HTMLElement)) return;
38
+ const manager = mapped.get(table);
39
+ if (manager == null) return;
40
+ switch (target?.getAttribute("data-event")) {
41
+ case "body":
42
+ manager.state.managers.navigation.handle(event);
43
+ break;
44
+ default: break;
45
+ }
46
+ }
47
+ var mapped = /* @__PURE__ */ new WeakMap();
48
+ on(document, "click", onClick);
49
+ on(document, "keydown", onKeydown, { passive: false });
34
50
  export { EventManager };
@@ -10,8 +10,8 @@ var FilterManager = class {
10
10
  set: (items) => this.set(items)
11
11
  });
12
12
  items = {};
13
- constructor(managers) {
14
- this.managers = managers;
13
+ constructor(state) {
14
+ this.state = state;
15
15
  }
16
16
  add(item) {
17
17
  if (this.items[item.field] == null) this.items[item.field] = [];
@@ -27,16 +27,17 @@ var FilterManager = class {
27
27
  }
28
28
  destroy() {
29
29
  this.handlers = void 0;
30
- this.items = {};
30
+ this.items = void 0;
31
+ this.state = void 0;
31
32
  }
32
33
  filter() {
33
- const { managers } = this;
34
+ const { state } = this;
34
35
  const filtered = [];
35
36
  const filters = Object.entries(this.items);
36
- const keysLength = managers.data.values.keys.original.length;
37
+ const keysLength = state.managers.data.values.keys.original.length;
37
38
  rowLoop: for (let keyIndex = 0; keyIndex < keysLength; keyIndex += 1) {
38
- const key = managers.data.values.keys.original[keyIndex];
39
- const row = managers.data.values.objects.mapped.get(key);
39
+ const key = state.managers.data.values.keys.original[keyIndex];
40
+ const row = state.managers.data.values.objects.mapped.get(key);
40
41
  if (row == null) continue;
41
42
  filterLoop: for (let filterIndex = 0; filterIndex < filters.length; filterIndex += 1) {
42
43
  const [field, items] = filters[filterIndex];
@@ -49,9 +50,9 @@ var FilterManager = class {
49
50
  }
50
51
  filtered.push(key);
51
52
  }
52
- managers.data.values.keys.active = filtered;
53
- if (managers.sort.items.length > 0) managers.sort.sort();
54
- else managers.render.update(true, true);
53
+ state.managers.data.values.keys.active = filtered;
54
+ if (state.managers.sort.items.length > 0) state.managers.sort.sort();
55
+ else state.managers.render.update(true, true);
55
56
  }
56
57
  remove(value) {
57
58
  if (typeof value === "string") {
@@ -0,0 +1,73 @@
1
+ import { getKey } from "../helpers/misc.helpers.js";
2
+ import { isNullableOrWhitespace } from "@oscarpalmer/atoms/is";
3
+ import { clamp } from "@oscarpalmer/atoms/number";
4
+ var NavigationManager = class {
5
+ active;
6
+ constructor(state) {
7
+ this.state = state;
8
+ }
9
+ destroy() {
10
+ this.state = void 0;
11
+ }
12
+ handle(event) {
13
+ if (!allKeys.has(event.key)) return;
14
+ event.preventDefault();
15
+ const { components, id, managers } = this.state;
16
+ const activeDescendant = components.body.elements.group.getAttribute("aria-activedescendant");
17
+ const keys = managers.data.values.keys.active ?? managers.data.values.keys.original;
18
+ const { length } = keys;
19
+ let next;
20
+ if (isNullableOrWhitespace(activeDescendant)) next = getDefaultIndex(event.key, length);
21
+ else next = getIndex(event, activeDescendant, id, keys);
22
+ if (next != null) this.setActive(keys.at(next));
23
+ }
24
+ setActive(key, scroll) {
25
+ const { components, managers, options } = this.state;
26
+ this.active = key;
27
+ const active = components.body.elements.group.querySelectorAll("[data-active=\"true\"]");
28
+ for (const item of active) item.setAttribute("data-active", "false");
29
+ const row = managers.row.get(key);
30
+ if (row != null) {
31
+ row.element?.setAttribute("data-active", "true");
32
+ if (scroll ?? true) if (row.element == null) components.body.elements.group.scrollTo({
33
+ top: managers.data.getIndex(key) * options.rowHeight,
34
+ behavior: "smooth"
35
+ });
36
+ else row.element.scrollIntoView({ block: "nearest" });
37
+ }
38
+ components.body.elements.group.setAttribute("aria-activedescendant", row == null ? "" : `tabela_${this.state.id}_row_${key}`);
39
+ }
40
+ };
41
+ function getDefaultIndex(key, max) {
42
+ switch (true) {
43
+ case negativeDefaultKeys.has(key): return -1;
44
+ case key === "PageDown": return Math.min(9, max - 1);
45
+ case key === "PageUp": return max < 10 ? 0 : max - 10;
46
+ default: return 0;
47
+ }
48
+ }
49
+ function getIndex(event, active, id, keys) {
50
+ const key = getKey(active.replace(`tabela_${id}_row_`, ""));
51
+ if (key == null) return;
52
+ if (absoluteKeys.has(event.key)) return event.key === "Home" ? 0 : keys.length - 1;
53
+ return clamp(keys.indexOf(key) + getOffset(event.key), 0, keys.length - 1, true);
54
+ }
55
+ function getOffset(key) {
56
+ switch (key) {
57
+ case "ArrowDown": return 1;
58
+ case "ArrowUp": return -1;
59
+ case "PageDown": return 10;
60
+ case "PageUp": return -10;
61
+ default: return 0;
62
+ }
63
+ }
64
+ var absoluteKeys = new Set(["End", "Home"]);
65
+ var arrowKeys = new Set(["ArrowDown", "ArrowUp"]);
66
+ var negativeDefaultKeys = new Set(["ArrowUp", "End"]);
67
+ var pageKeys = new Set(["PageDown", "PageUp"]);
68
+ var allKeys = new Set([
69
+ ...absoluteKeys,
70
+ ...arrowKeys,
71
+ ...pageKeys
72
+ ]);
73
+ export { NavigationManager };
@@ -1,12 +1,12 @@
1
1
  import { removeRow, renderRow } from "../components/row.component.js";
2
2
  import { on } from "@oscarpalmer/toretto/event";
3
3
  function getRange(down) {
4
- const { components, managers } = this;
4
+ const { components, managers, options } = this.state;
5
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);
6
+ const first = Math.floor(scrollTop / options.rowHeight);
7
+ const last = Math.min((managers.data.values.keys.active?.length ?? managers.data.values.keys.original.length) - 1, Math.ceil((scrollTop + clientHeight) / options.rowHeight) - 1);
8
+ const before = Math.ceil(clientHeight / options.rowHeight) * (down ? 1 : 2);
9
+ const after = Math.ceil(clientHeight / options.rowHeight) * (down ? 2 : 1);
10
10
  const start = Math.max(0, first - before);
11
11
  return {
12
12
  end: Math.min((managers.data.values.keys.active?.length ?? managers.data.values.keys.original.length) - 1, last + after),
@@ -14,14 +14,15 @@ function getRange(down) {
14
14
  };
15
15
  }
16
16
  function onScroll() {
17
- if (!this.state.active) {
17
+ const { state } = this;
18
+ if (!state.active) {
18
19
  requestAnimationFrame(() => {
19
- const top = this.components.body.elements.group.scrollTop;
20
- this.update(top > this.state.top);
21
- this.state.active = false;
22
- this.state.top = top;
20
+ const top = state.components.body.elements.group.scrollTop;
21
+ this.update(top > state.top);
22
+ state.active = false;
23
+ state.top = top;
23
24
  });
24
- this.state.active = true;
25
+ state.active = true;
25
26
  }
26
27
  }
27
28
  var RenderManager = class {
@@ -31,15 +32,15 @@ var RenderManager = class {
31
32
  cells: {},
32
33
  rows: []
33
34
  };
34
- state = {
35
- active: false,
36
- top: 0
37
- };
35
+ state;
38
36
  visible = /* @__PURE__ */ new Map();
39
- constructor(managers, components) {
40
- this.managers = managers;
41
- this.components = components;
42
- this.listener = on(components.body.elements.group, "scroll", onScroll.bind(this));
37
+ constructor(state) {
38
+ this.listener = on(state.components.body.elements.group, "scroll", onScroll.bind(this));
39
+ this.state = {
40
+ ...state,
41
+ active: false,
42
+ top: 0
43
+ };
43
44
  }
44
45
  destroy() {
45
46
  const { listener, pool, visible } = this;
@@ -47,15 +48,18 @@ var RenderManager = class {
47
48
  visible.clear();
48
49
  pool.cells = {};
49
50
  pool.rows = [];
51
+ this.fragment = void 0;
50
52
  this.listener = void 0;
53
+ this.pool = void 0;
54
+ this.state = void 0;
51
55
  this.visible = void 0;
52
56
  }
53
57
  removeCells(fields) {
54
- const { managers, pool, visible } = this;
58
+ const { pool, state, visible } = this;
55
59
  const { length } = fields;
56
60
  for (let index = 0; index < length; index += 1) delete pool.cells[fields[index]];
57
61
  for (const [, key] of visible) {
58
- const row = managers.row.get(key);
62
+ const row = state.managers.row.get(key);
59
63
  if (row == null || row.element == null) continue;
60
64
  for (let index = 0; index < length; index += 1) {
61
65
  row.cells[fields[index]].innerHTML = "";
@@ -70,8 +74,9 @@ var RenderManager = class {
70
74
  return this.fragment;
71
75
  }
72
76
  update(down, rerender) {
73
- const { components, managers, pool, visible } = this;
74
- components.body.elements.faker.style.height = `${managers.data.size * managers.row.height}px`;
77
+ const { state, pool, visible } = this;
78
+ const { components, managers, options } = state;
79
+ components.body.elements.faker.style.height = `${managers.data.size * options.rowHeight}px`;
75
80
  const indices = /* @__PURE__ */ new Set();
76
81
  const range = getRange.call(this, down);
77
82
  for (let index = range.start; index <= range.end; index += 1) indices.add(index);
@@ -92,10 +97,10 @@ var RenderManager = class {
92
97
  const row = managers.row.get(key);
93
98
  if (row == null) continue;
94
99
  count += 1;
95
- renderRow(managers, row);
100
+ renderRow(state, row);
96
101
  visible.set(index, key);
97
102
  if (row.element != null) {
98
- row.element.style.transform = `translateY(${index * managers.row.height}px)`;
103
+ row.element.style.transform = `translateY(${index * options.rowHeight}px)`;
99
104
  fragment.append(row.element);
100
105
  }
101
106
  }
@@ -1,16 +1,16 @@
1
1
  import { RowComponent, removeRow, renderRow } from "../components/row.component.js";
2
2
  var RowManager = class {
3
3
  components = /* @__PURE__ */ new Map();
4
- height;
5
- constructor(managers, rowHeight) {
6
- this.managers = managers;
7
- this.height = rowHeight;
4
+ constructor(state) {
5
+ this.state = state;
8
6
  }
9
7
  destroy() {
10
8
  const components = [...this.components.values()];
11
9
  const { length } = components;
12
- for (let index = 0; index < length; index += 1) removeRow(this.managers.render.pool, components[index]);
10
+ for (let index = 0; index < length; index += 1) removeRow(this.state.managers.render.pool, components[index]);
13
11
  this.components.clear();
12
+ this.components = void 0;
13
+ this.state = void 0;
14
14
  }
15
15
  get(key) {
16
16
  let row = this.components.get(key);
@@ -26,13 +26,13 @@ var RowManager = class {
26
26
  remove(key) {
27
27
  const row = this.components.get(key);
28
28
  if (row != null) {
29
- removeRow(this.managers.render.pool, row);
29
+ removeRow(this.state.managers.render.pool, row);
30
30
  this.components.delete(key);
31
31
  }
32
32
  }
33
33
  update(key) {
34
34
  const row = this.components.get(key);
35
- if (row != null) renderRow(this.managers, row);
35
+ if (row != null) renderRow(this.state, row);
36
36
  }
37
37
  };
38
38
  export { RowManager };
@@ -14,10 +14,9 @@ var SelectionManager = class {
14
14
  });
15
15
  items = /* @__PURE__ */ new Set();
16
16
  last;
17
- constructor(element, managers) {
18
- this.element = element;
19
- this.managers = managers;
20
- mapped.set(element, this);
17
+ constructor(state) {
18
+ this.state = state;
19
+ mapped.set(state.element, this);
21
20
  }
22
21
  clear() {
23
22
  if (this.items.size === 0) return;
@@ -35,48 +34,47 @@ var SelectionManager = class {
35
34
  if (removed.length > 0) this.update(removed);
36
35
  }
37
36
  destroy() {
38
- mapped.delete(this.element);
37
+ mapped.delete(this.state.element);
39
38
  this.handlers = void 0;
40
- this.element = void 0;
41
39
  this.items = void 0;
40
+ this.last = void 0;
41
+ this.state = void 0;
42
42
  }
43
43
  handle(event, target) {
44
44
  const key = getKey(target.getAttribute("data-key"));
45
45
  if (key == null) return;
46
46
  const { items } = this;
47
47
  if (event.shiftKey) {
48
- if (this.last == null) {
49
- this.last = key;
50
- return;
51
- }
52
- this.range(this.last, key);
53
- this.last = key;
48
+ if (this.last == null) this.state.managers.navigation.setActive(key, false);
49
+ else this.range(this.last, key);
54
50
  return;
55
51
  }
56
52
  this.last = key;
53
+ this.state.managers.navigation.setActive(key, false);
57
54
  if (event.ctrlKey || event.metaKey) {
58
55
  if (items.has(key)) this.deselect([key]);
59
56
  else this.select([key]);
60
57
  return;
61
58
  }
62
- if (items.has(key)) if (items.size === 1) this.clear();
63
- else this.set([key]);
64
- else this.set([key]);
59
+ this.set([key]);
65
60
  }
66
61
  range(from, to) {
62
+ const { state } = this;
67
63
  const keyed = isKey(from) && isKey(to);
68
64
  const fromKey = keyed ? from : getKey(from.getAttribute("data-key"));
69
65
  const toKey = keyed ? to : getKey(to.getAttribute("data-key"));
70
66
  if (fromKey === toKey) return;
71
- const keys = this.managers.data.values.keys.active ?? this.managers.data.values.keys.original;
72
- const fromIndex = keys.indexOf(fromKey);
73
- const toIndex = keys.indexOf(toKey);
67
+ const keys = state.managers.data.values.keys.active ?? state.managers.data.values.keys.original;
68
+ const fromIndex = state.managers.data.getIndex(fromKey);
69
+ const toIndex = state.managers.data.getIndex(toKey);
74
70
  if (fromIndex === -1 || toIndex === -1) return;
75
71
  const [start, end] = fromIndex < toIndex ? [fromIndex, toIndex] : [toIndex, fromIndex];
76
72
  const selected = [];
77
73
  for (let index = start; index <= end; index += 1) selected.push(keys[index]);
78
74
  if (keyed) this.select(selected);
79
75
  else this.set(selected);
76
+ this.last = toKey;
77
+ this.state.managers.navigation.setActive(toKey, false);
80
78
  }
81
79
  select(keys) {
82
80
  const { length } = keys;
@@ -99,8 +97,8 @@ var SelectionManager = class {
99
97
  this.update(removed);
100
98
  }
101
99
  toggle() {
102
- const { items, managers } = this;
103
- const all = managers.data.values.keys.active ?? managers.data.values.keys.original;
100
+ const { items, state } = this;
101
+ const all = state.managers.data.values.keys.active ?? state.managers.data.values.keys.original;
104
102
  if (items.size === all.length) this.clear();
105
103
  else this.select(all);
106
104
  }
@@ -115,7 +113,7 @@ var SelectionManager = class {
115
113
  const { length } = items;
116
114
  for (let index = 0; index < length; index += 1) {
117
115
  const { key, removed } = items[index];
118
- const row = this.managers.row.get(key);
116
+ const row = this.state.managers.row.get(key);
119
117
  if (row == null || row.element == null) continue;
120
118
  setAttribute(row.element, "aria-selected", String(!removed));
121
119
  if (removed) row.element.classList.remove("tabela__row--selected");