@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.
Files changed (108) hide show
  1. package/dist/components/body.component.d.mts +10 -1
  2. package/dist/components/body.component.mjs +8 -6
  3. package/dist/components/column.component.d.mts +15 -1
  4. package/dist/components/column.component.mjs +12 -10
  5. package/dist/components/footer.component.d.mts +12 -1
  6. package/dist/components/footer.component.mjs +6 -6
  7. package/dist/components/group.component.d.mts +19 -1
  8. package/dist/components/group.component.mjs +17 -11
  9. package/dist/components/header.component.d.mts +12 -1
  10. package/dist/components/header.component.mjs +5 -5
  11. package/dist/components/row.component.d.mts +14 -1
  12. package/dist/components/row.component.mjs +21 -17
  13. package/dist/helpers/dom.helpers.d.mts +3 -3
  14. package/dist/helpers/dom.helpers.mjs +12 -11
  15. package/dist/helpers/misc.helpers.d.mts +7 -1
  16. package/dist/helpers/misc.helpers.mjs +12 -1
  17. package/dist/index.d.mts +1 -1
  18. package/dist/managers/column.manager.d.mts +16 -1
  19. package/dist/managers/column.manager.mjs +7 -7
  20. package/dist/managers/data.manager.d.mts +26 -1
  21. package/dist/managers/data.manager.mjs +122 -88
  22. package/dist/managers/event.manager.d.mts +17 -1
  23. package/dist/managers/event.manager.mjs +35 -10
  24. package/dist/managers/filter.manager.d.mts +17 -1
  25. package/dist/managers/filter.manager.mjs +43 -35
  26. package/dist/managers/group.manager.d.mts +26 -1
  27. package/dist/managers/group.manager.mjs +36 -16
  28. package/dist/managers/navigation.manager.d.mts +15 -2
  29. package/dist/managers/navigation.manager.mjs +38 -34
  30. package/dist/managers/render.manager.d.mts +18 -1
  31. package/dist/managers/render.manager.mjs +44 -31
  32. package/dist/managers/row.manager.d.mts +18 -1
  33. package/dist/managers/row.manager.mjs +1 -1
  34. package/dist/managers/selection.manager.d.mts +22 -1
  35. package/dist/managers/selection.manager.mjs +26 -23
  36. package/dist/managers/sort.manager.d.mts +22 -1
  37. package/dist/managers/sort.manager.mjs +71 -49
  38. package/dist/managers/style.manager.d.mts +8 -1
  39. package/dist/managers/style.manager.mjs +57 -25
  40. package/dist/models/body.model.d.mts +6 -1
  41. package/dist/models/column.model.d.mts +13 -2
  42. package/dist/models/data.model.d.mts +28 -2
  43. package/dist/models/dom.model.d.mts +19 -0
  44. package/dist/models/dom.model.mjs +19 -0
  45. package/dist/models/event.model.d.mts +99 -0
  46. package/dist/models/event.model.mjs +53 -0
  47. package/dist/models/filter.model.d.mts +26 -2
  48. package/dist/models/filter.model.mjs +13 -1
  49. package/dist/models/footer.model.d.mts +7 -1
  50. package/dist/models/group.model.d.mts +19 -2
  51. package/dist/models/group.model.mjs +5 -1
  52. package/dist/models/header.model.d.mts +6 -1
  53. package/dist/models/render.model.d.mts +22 -2
  54. package/dist/models/selection.model.d.mts +11 -1
  55. package/dist/models/sort.model.d.mts +19 -2
  56. package/dist/models/sort.model.mjs +5 -1
  57. package/dist/models/style.model.d.mts +27 -21
  58. package/dist/models/style.model.mjs +27 -21
  59. package/dist/models/tabela.model.d.mts +45 -1
  60. package/dist/models/tabela.options.d.mts +13 -1
  61. package/dist/tabela.d.mts +9 -8
  62. package/dist/tabela.full.mjs +1083 -574
  63. package/dist/tabela.mjs +19 -19
  64. package/package.json +2 -4
  65. package/src/components/body.component.ts +10 -7
  66. package/src/components/column.component.ts +20 -16
  67. package/src/components/footer.component.ts +7 -10
  68. package/src/components/group.component.ts +39 -13
  69. package/src/components/header.component.ts +6 -5
  70. package/src/components/row.component.ts +27 -19
  71. package/src/helpers/dom.helpers.ts +18 -22
  72. package/src/helpers/misc.helpers.ts +17 -0
  73. package/src/managers/column.manager.ts +9 -9
  74. package/src/managers/data.manager.ts +196 -107
  75. package/src/managers/event.manager.ts +69 -12
  76. package/src/managers/filter.manager.ts +70 -41
  77. package/src/managers/group.manager.ts +60 -18
  78. package/src/managers/navigation.manager.ts +46 -49
  79. package/src/managers/render.manager.ts +60 -34
  80. package/src/managers/row.manager.ts +1 -1
  81. package/src/managers/selection.manager.ts +37 -35
  82. package/src/managers/sort.manager.ts +114 -72
  83. package/src/managers/style.manager.ts +73 -25
  84. package/src/models/column.model.ts +4 -8
  85. package/src/models/data.model.ts +13 -14
  86. package/src/models/dom.model.ts +31 -0
  87. package/src/models/event.model.ts +175 -0
  88. package/src/models/filter.model.ts +22 -2
  89. package/src/models/group.model.ts +13 -0
  90. package/src/models/render.model.ts +6 -0
  91. package/src/models/sort.model.ts +11 -5
  92. package/src/models/style.model.ts +32 -20
  93. package/src/models/tabela.model.ts +1 -0
  94. package/src/tabela.ts +26 -24
  95. package/dist/body.component-_VDOpJhV.d.mts +0 -10
  96. package/dist/body.model-2iwsovAV.d.mts +0 -7
  97. package/dist/column.component-Bx46r3JI.d.mts +0 -16
  98. package/dist/column.model-D-aw4EU4.d.mts +0 -16
  99. package/dist/filter.model-7ukJrtil.d.mts +0 -16
  100. package/dist/footer.component-Curiab8j.d.mts +0 -12
  101. package/dist/footer.model-DhqoS6ds.d.mts +0 -8
  102. package/dist/group.component-Cq1YYbfJ.d.mts +0 -285
  103. package/dist/group.model-BsKFwHbt.d.mts +0 -10
  104. package/dist/header.component-BjjlpZIg.d.mts +0 -12
  105. package/dist/header.model-DN_KzUCV.d.mts +0 -7
  106. package/dist/selection.model-rwQe9fco.d.mts +0 -12
  107. package/dist/sort.model-CauImaLu.d.mts +0 -15
  108. package/dist/tabela.options-RkZvfptB.d.mts +0 -14
package/dist/tabela.mjs CHANGED
@@ -1,4 +1,5 @@
1
- import { CSS_TABELA, CSS_TABELA_TABLE } from "./models/style.model.mjs";
1
+ import { ARIA_LABEL, ATTRIBUTE_ROLE, ROLE_TABLE } from "./models/dom.model.mjs";
2
+ import { CSS_TABLE, CSS_WRAPPER } from "./models/style.model.mjs";
2
3
  import { createElement } from "./helpers/dom.helpers.mjs";
3
4
  import { BodyComponent } from "./components/body.component.mjs";
4
5
  import { FooterComponent } from "./components/footer.component.mjs";
@@ -19,7 +20,6 @@ var Tabela = class {
19
20
  #components;
20
21
  #element;
21
22
  #id = getId();
22
- #table;
23
23
  #key;
24
24
  #managers = {
25
25
  column: void 0,
@@ -34,37 +34,37 @@ var Tabela = class {
34
34
  sort: void 0,
35
35
  style: void 0
36
36
  };
37
+ #prefix = `tabela_${this.#id}_`;
37
38
  #state;
39
+ #table;
38
40
  data;
41
+ events;
39
42
  filter;
40
43
  group;
41
44
  selection;
42
45
  sort;
43
- get key() {
44
- return this.#key;
45
- }
46
46
  constructor(element, options) {
47
47
  this.#element = element;
48
48
  element.innerHTML = "";
49
- element.classList.add(CSS_TABELA);
49
+ element.classList.add(CSS_WRAPPER);
50
50
  this.#table = createElement("div", {
51
- className: CSS_TABELA_TABLE,
52
- role: "table"
53
- }, { "aria-label": options.label });
51
+ className: CSS_TABLE,
52
+ role: ROLE_TABLE
53
+ }, { [ARIA_LABEL]: options.label });
54
54
  this.#key = options.key;
55
- this.#components = {
56
- body: new BodyComponent(),
57
- footer: new FooterComponent(),
58
- header: new HeaderComponent()
59
- };
55
+ this.#components = {};
60
56
  this.#state = {
61
57
  options,
62
58
  components: this.#components,
63
59
  element: this.#table,
64
60
  id: this.#id,
65
61
  key: this.#key,
66
- managers: this.#managers
62
+ managers: this.#managers,
63
+ prefix: this.#prefix
67
64
  };
65
+ this.#components.body = new BodyComponent(this.#state);
66
+ this.#components.footer = new FooterComponent(this.#state);
67
+ this.#components.header = new HeaderComponent(this.#state);
68
68
  this.#managers.column = new ColumnManager(this.#state);
69
69
  this.#managers.data = new DataManager(this.#state);
70
70
  this.#managers.event = new EventManager(this.#state);
@@ -80,6 +80,7 @@ var Tabela = class {
80
80
  element.append(this.#table);
81
81
  this.#managers.data.set(options.data);
82
82
  this.data = this.#managers.data.handlers;
83
+ this.events = this.#managers.event.handlers;
83
84
  this.filter = this.#managers.filter.handlers;
84
85
  this.group = this.#managers.group.handlers;
85
86
  this.selection = this.#managers.selection.handlers;
@@ -105,10 +106,9 @@ var Tabela = class {
105
106
  managers.sort.destroy();
106
107
  element.innerHTML = "";
107
108
  table.innerHTML = "";
108
- table.role = "";
109
- element.classList.remove(CSS_TABELA);
110
- table.removeAttribute("aria-label");
111
- table.removeAttribute("role");
109
+ element.classList.remove(CSS_WRAPPER);
110
+ table.removeAttribute(ARIA_LABEL);
111
+ table.removeAttribute(ATTRIBUTE_ROLE);
112
112
  this.#state.components = void 0;
113
113
  this.#state.managers = void 0;
114
114
  this.#state.element = void 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oscarpalmer/tabela",
3
- "version": "0.13.0",
3
+ "version": "0.15.0",
4
4
  "description": "A modern table.",
5
5
  "keywords": [],
6
6
  "license": "MIT",
@@ -37,12 +37,10 @@
37
37
  "www:js": "vpx tsdown -c ./www/.app/js/tsdown.config.ts --watch"
38
38
  },
39
39
  "dependencies": {
40
- "@oscarpalmer/atoms": "^0.165",
40
+ "@oscarpalmer/atoms": "^0.166",
41
41
  "@oscarpalmer/toretto": "^0.41"
42
42
  },
43
43
  "devDependencies": {
44
- "@oscarpalmer/abydon": "^0.19",
45
- "@oscarpalmer/oui": "^0.19",
46
44
  "@types/node": "^25.5",
47
45
  "@vitest/coverage-istanbul": "^4.1",
48
46
  "concurrently": "^9.2",
@@ -1,10 +1,13 @@
1
1
  import {createElement, createRowGroup} from '../helpers/dom.helpers';
2
2
  import type {BodyElements} from '../models/body.model';
3
- import {CSS_TABELA_FAKER, CSS_TABELA_ROWGROUP_BODY} from '../models/style.model';
3
+ import {ATTRIBUTE_DATA_EVENT, ELEMENT_DIV} from '../models/dom.model';
4
+ import {EVENT_BODY} from '../models/event.model';
5
+ import {CSS_FAKER, CSS_ROWGROUP_BODY} from '../models/style.model';
6
+ import type {State} from '../models/tabela.model';
4
7
 
5
8
  function createFaker(): HTMLDivElement {
6
- return createElement('div', {
7
- className: CSS_TABELA_FAKER,
9
+ return createElement(ELEMENT_DIV, {
10
+ className: CSS_FAKER,
8
11
  });
9
12
  }
10
13
 
@@ -14,16 +17,16 @@ export class BodyComponent {
14
17
  group: undefined as never,
15
18
  };
16
19
 
17
- constructor() {
18
- const group = createRowGroup(false);
20
+ constructor(state: State) {
21
+ const group = createRowGroup(state.options.rowHeight, false);
19
22
 
20
23
  this.elements.group = group;
21
24
 
22
- group.className += ` ${CSS_TABELA_ROWGROUP_BODY}`;
25
+ group.className += ` ${CSS_ROWGROUP_BODY}`;
23
26
 
24
27
  group.tabIndex = 0;
25
28
 
26
- group.setAttribute('data-event', 'body');
29
+ group.setAttribute(ATTRIBUTE_DATA_EVENT, EVENT_BODY);
27
30
 
28
31
  group.append(this.elements.faker);
29
32
  }
@@ -1,10 +1,14 @@
1
1
  import {createElement} from '../helpers/dom.helpers';
2
2
  import type {Column, TabelaColumn} from '../models/column.model';
3
3
  import {
4
- CSS_TABELA_HEADING,
5
- CSS_TABELA_HEADING_CONTENT,
6
- CSS_TABELA_HEADING_SORTER,
7
- } from '../models/style.model';
4
+ ATTRIBUTE_DATA_EVENT,
5
+ ATTRIBUTE_DATA_KEY,
6
+ ATTRIBUTE_ROLE,
7
+ ELEMENT_DIV,
8
+ ROLE_COLUMNHEADER,
9
+ } from '../models/dom.model';
10
+ import {EVENT_HEADING} from '../models/event.model';
11
+ import {CSS_HEADING, CSS_HEADING_CONTENT, CSS_HEADING_SORTER} from '../models/style.model';
8
12
 
9
13
  export class ColumnComponent {
10
14
  elements: ColumnElements;
@@ -13,14 +17,14 @@ export class ColumnComponent {
13
17
  constructor(column: TabelaColumn) {
14
18
  const width =
15
19
  Number.parseInt(getComputedStyle(document.body).fontSize, 10) *
16
- (column.width ?? column.title.length * 1.5);
20
+ (column.width ?? column.label.length * 1.5);
17
21
 
18
22
  this.options = {
19
23
  ...column,
20
24
  width,
21
25
  };
22
26
 
23
- this.elements = createHeading(this.options.field, this.options.title, width);
27
+ this.elements = createHeading(this.options.key, this.options.label, width);
24
28
  }
25
29
 
26
30
  destroy(): void {
@@ -39,29 +43,29 @@ type ColumnElements = {
39
43
  wrapper: HTMLDivElement;
40
44
  };
41
45
 
42
- function createHeading(field: string, title: string, width: number): ColumnElements {
46
+ function createHeading(key: string, title: string, width: number): ColumnElements {
43
47
  const wrapper = createElement(
44
- 'div',
48
+ ELEMENT_DIV,
45
49
  {
46
- className: CSS_TABELA_HEADING,
47
- role: 'columnheader',
50
+ className: CSS_HEADING,
51
+ [ATTRIBUTE_ROLE]: ROLE_COLUMNHEADER,
48
52
  },
49
53
  {
50
- 'data-event': 'heading',
51
- 'data-field': field,
54
+ [ATTRIBUTE_DATA_EVENT]: EVENT_HEADING,
55
+ [ATTRIBUTE_DATA_KEY]: key,
52
56
  },
53
57
  {
54
58
  width: `${width}px`,
55
59
  },
56
60
  );
57
61
 
58
- const content = createElement('div', {
59
- className: CSS_TABELA_HEADING_CONTENT,
62
+ const content = createElement(ELEMENT_DIV, {
63
+ className: CSS_HEADING_CONTENT,
60
64
  textContent: title,
61
65
  });
62
66
 
63
- const sorter = createElement('div', {
64
- className: CSS_TABELA_HEADING_SORTER,
67
+ const sorter = createElement(ELEMENT_DIV, {
68
+ className: CSS_HEADING_SORTER,
65
69
  });
66
70
 
67
71
  wrapper.append(content, sorter);
@@ -1,17 +1,14 @@
1
1
  import {createCell, createRowGroup} from '../helpers/dom.helpers';
2
2
  import type {FooterElements} from '../models/footer.model';
3
- import {
4
- CSS_TABELA_CELL_FOOTER,
5
- CSS_TABELA_ROW_FOOTER,
6
- CSS_TABELA_ROWGROUP_FOOTER,
7
- } from '../models/style.model';
3
+ import {CSS_CELL_FOOTER, CSS_ROW_FOOTER, CSS_ROWGROUP_FOOTER} from '../models/style.model';
4
+ import type {State} from '../models/tabela.model';
8
5
  import type {ColumnComponent} from './column.component';
9
6
 
10
7
  export class FooterComponent {
11
8
  readonly elements: FooterElements;
12
9
 
13
- constructor() {
14
- const {group, row} = createRowGroup();
10
+ constructor(state: State) {
11
+ const {group, row} = createRowGroup(state.options.rowHeight);
15
12
 
16
13
  this.elements = {
17
14
  group,
@@ -19,8 +16,8 @@ export class FooterComponent {
19
16
  cells: [],
20
17
  };
21
18
 
22
- group.className += ` ${CSS_TABELA_ROWGROUP_FOOTER}`;
23
- row.className += ` ${CSS_TABELA_ROW_FOOTER}`;
19
+ group.className += ` ${CSS_ROWGROUP_FOOTER}`;
20
+ row.className += ` ${CSS_ROW_FOOTER}`;
24
21
  }
25
22
 
26
23
  destroy(): void {
@@ -40,7 +37,7 @@ export class FooterComponent {
40
37
  for (let index = 0; index < length; index += 1) {
41
38
  const cell = createCell(columns[index].options.width ?? 4, false);
42
39
 
43
- cell.className += ` ${CSS_TABELA_CELL_FOOTER}`;
40
+ cell.className += ` ${CSS_CELL_FOOTER}`;
44
41
  cell.innerHTML = '&nbsp;';
45
42
 
46
43
  elements.cells.push(cell);
@@ -1,8 +1,26 @@
1
1
  import {getString} from '@oscarpalmer/atoms/string';
2
2
  import {createElement} from '../helpers/dom.helpers';
3
- import type {GroupValue} from '../models/group.model';
4
- import {CSS_TABELA_ROW, CSS_TABELA_ROW_GROUP} from '../models/style.model';
3
+ import {GROUP_KEY_PREFIX, type GroupValue} from '../models/group.model';
4
+ import {
5
+ CSS_BUTTON,
6
+ CSS_BUTTON_GROUP,
7
+ CSS_CELL,
8
+ CSS_CELL_GROUP,
9
+ CSS_GROUP_SELECTED,
10
+ CSS_GROUP_TOTAL,
11
+ CSS_ROW,
12
+ CSS_ROW_GROUP,
13
+ } from '../models/style.model';
5
14
  import type {State} from '../models/tabela.model';
15
+ import {
16
+ ATTRIBUTE_DATA_EVENT,
17
+ ATTRIBUTE_DATA_KEY,
18
+ ATTRIBUTE_ROLE,
19
+ ELEMENT_DIV,
20
+ ROLE_CELL,
21
+ ROLE_ROW,
22
+ } from '../models/dom.model';
23
+ import {EVENT_GROUP, EVENT_GROUP_UPDATE} from '../models/event.model';
6
24
 
7
25
  export class GroupComponent {
8
26
  element: HTMLElement | undefined;
@@ -25,7 +43,7 @@ export class GroupComponent {
25
43
  ) {
26
44
  const stringified = getString(value);
27
45
 
28
- this.key = `group:${stringified}`;
46
+ this.key = `${GROUP_KEY_PREFIX}${stringified}`;
29
47
 
30
48
  this.value = {
31
49
  stringified,
@@ -46,19 +64,19 @@ export function removeGroup(group: GroupComponent): void {
46
64
 
47
65
  export function renderGroup(state: State, component: GroupComponent): void {
48
66
  component.element ??= createElement(
49
- 'div',
67
+ ELEMENT_DIV,
50
68
  {
51
- className: `${CSS_TABELA_ROW} ${CSS_TABELA_ROW_GROUP}`,
52
- innerHTML: `<div class="tabela__cell tabela__cell--group" role="cell">
53
- <button class="tabela__button tabela__button--group" data-event="group" data-key="tabela_${state.id}_${component.key}" type="button">
69
+ className: `${CSS_ROW} ${CSS_ROW_GROUP}`,
70
+ innerHTML: `<div class="${CSS_CELL} ${CSS_CELL_GROUP}" role="${ROLE_CELL}">
71
+ <button class="${CSS_BUTTON} ${CSS_BUTTON_GROUP}" ${ATTRIBUTE_DATA_EVENT}="${EVENT_GROUP}" ${ATTRIBUTE_DATA_KEY}="${state.prefix}_${component.key}" type="button">
54
72
  <span aria-hidden="true"></span>
55
73
  <span>Open/close</span>
56
74
  </button>
57
75
  <p>${component.label}</p>
58
- <span class="tabela__group__total">${component.total}</span>
59
- <span class="tabela__group__selected">${component.selected === 0 ? '' : component.selected}</span>
76
+ <span class="${CSS_GROUP_TOTAL}">${component.total}</span>
77
+ <span class="${CSS_GROUP_SELECTED}">${component.selected === 0 ? '' : component.selected}</span>
60
78
  </div>`,
61
- role: 'row',
79
+ [ATTRIBUTE_ROLE]: ROLE_ROW,
62
80
  },
63
81
  {},
64
82
  {
@@ -67,13 +85,13 @@ export function renderGroup(state: State, component: GroupComponent): void {
67
85
  );
68
86
  }
69
87
 
70
- export function updateGroup(state: State, component: GroupComponent): void {
88
+ export function updateGroup(state: State, component: GroupComponent, emit: boolean): void {
71
89
  if (component.element == null) {
72
90
  return;
73
91
  }
74
92
 
75
- const selected = component.element.querySelector<HTMLSpanElement>('.tabela__group__selected');
76
- const total = component.element.querySelector<HTMLSpanElement>('.tabela__group__total');
93
+ const selected = component.element.querySelector<HTMLSpanElement>(selectedSelector);
94
+ const total = component.element.querySelector<HTMLSpanElement>(totalSelector);
77
95
 
78
96
  if (selected != null) {
79
97
  selected.textContent = component.selected === 0 ? '' : String(component.selected);
@@ -82,4 +100,12 @@ export function updateGroup(state: State, component: GroupComponent): void {
82
100
  if (total != null) {
83
101
  total.textContent = String(component.total);
84
102
  }
103
+
104
+ if (emit) {
105
+ state.managers.event.emit(EVENT_GROUP_UPDATE, [component]);
106
+ }
85
107
  }
108
+
109
+ const selectedSelector = `.${CSS_GROUP_SELECTED}`;
110
+
111
+ const totalSelector = `.${CSS_GROUP_TOTAL}`;
@@ -1,18 +1,19 @@
1
1
  import {createRowGroup} from '../helpers/dom.helpers';
2
2
  import type {HeaderElements} from '../models/header.model';
3
- import {CSS_TABELA_ROW_HEADER, CSS_TABELA_ROWGROUP_HEADER} from '../models/style.model';
3
+ import {CSS_ROW_HEADER, CSS_ROWGROUP_HEADER} from '../models/style.model';
4
+ import type {State} from '../models/tabela.model';
4
5
  import type {ColumnComponent} from './column.component';
5
6
 
6
7
  export class HeaderComponent {
7
8
  readonly elements: HeaderElements;
8
9
 
9
- constructor() {
10
- const {group, row} = createRowGroup();
10
+ constructor(state: State) {
11
+ const {group, row} = createRowGroup(state.options.rowHeight);
11
12
 
12
13
  this.elements = {group, row};
13
14
 
14
- group.className += ` ${CSS_TABELA_ROWGROUP_HEADER}`;
15
- row.className += ` ${CSS_TABELA_ROW_HEADER}`;
15
+ group.className += ` ${CSS_ROWGROUP_HEADER}`;
16
+ row.className += ` ${CSS_ROW_HEADER}`;
16
17
  }
17
18
 
18
19
  destroy(): void {
@@ -3,8 +3,15 @@ import {getValue} from '@oscarpalmer/atoms/value/handle';
3
3
  import {setAttributes} from '@oscarpalmer/toretto/attribute';
4
4
  import {createCell, createRow} from '../helpers/dom.helpers';
5
5
  import type {RenderElementPool} from '../models/render.model';
6
- import {CSS_TABELA_ROW_BODY, CSS_TABELA_ROW_SELECTED} from '../models/style.model';
6
+ import {CSS_ROW_BODY, CSS_ROW_SELECTED} from '../models/style.model';
7
7
  import type {State} from '../models/tabela.model';
8
+ import {
9
+ ARIA_SELECTED,
10
+ ATTRIBUTE_DATA_ACTIVE,
11
+ ATTRIBUTE_DATA_EVENT,
12
+ ATTRIBUTE_DATA_KEY,
13
+ } from '../models/dom.model';
14
+ import {EVENT_ROW} from '../models/event.model';
8
15
 
9
16
  export function removeRow(pool: RenderElementPool, row: RowComponent): void {
10
17
  if (row.element != null) {
@@ -20,36 +27,38 @@ export function removeRow(pool: RenderElementPool, row: RowComponent): void {
20
27
  }
21
28
 
22
29
  export function renderRow(state: State, row: RowComponent): void {
23
- const element = row.element ?? state.managers.render.pool.rows.shift() ?? createRow();
30
+ const {managers, options, prefix} = state;
31
+
32
+ const element = row.element ?? managers.render.pool.rows.shift() ?? createRow(options.rowHeight);
24
33
 
25
34
  row.element = element;
26
35
 
27
36
  element.innerHTML = '';
28
37
 
29
- const selected = state.managers.selection.items.has(row.key);
38
+ const selected = managers.selection.items.has(row.key);
30
39
 
31
40
  const key = String(row.key);
32
41
 
33
42
  setAttributes(element, {
34
- 'aria-selected': String(selected),
35
- 'data-active': String(state.managers.navigation.active === row.key),
36
- 'data-event': 'row',
37
- 'data-key': key,
38
- id: `tabela_${state.id}_${key}`,
43
+ [ARIA_SELECTED]: String(selected),
44
+ [ATTRIBUTE_DATA_ACTIVE]: String(managers.navigation.active === row.key),
45
+ [ATTRIBUTE_DATA_EVENT]: EVENT_ROW,
46
+ [ATTRIBUTE_DATA_KEY]: key,
47
+ id: `${prefix}${key}`,
39
48
  });
40
49
 
41
- element.classList.add(CSS_TABELA_ROW_BODY);
50
+ element.classList.add(CSS_ROW_BODY);
42
51
 
43
52
  if (selected) {
44
- element.classList.add(CSS_TABELA_ROW_SELECTED);
53
+ element.classList.add(CSS_ROW_SELECTED);
45
54
  } else {
46
- element.classList.remove(CSS_TABELA_ROW_SELECTED);
55
+ element.classList.remove(CSS_ROW_SELECTED);
47
56
  }
48
57
 
49
- const columns = state.managers.column.items;
58
+ const columns = managers.column.items;
50
59
  const {length} = columns;
51
60
 
52
- const data = state.managers.data.state.values.mapped.get(row.key);
61
+ const data = managers.data.state.values.mapped.get(row.key);
53
62
 
54
63
  if (data == null) {
55
64
  return;
@@ -57,16 +66,15 @@ export function renderRow(state: State, row: RowComponent): void {
57
66
 
58
67
  for (let index = 0; index < length; index += 1) {
59
68
  const {options} = columns[index];
69
+ const {key, width} = options;
60
70
 
61
- state.managers.render.pool.cells[options.field] ??= [];
71
+ managers.render.pool.cells[key] ??= [];
62
72
 
63
- const cell =
64
- state.managers.render.pool.cells[columns[index].options.field].shift() ??
65
- createCell(options.width);
73
+ const cell = managers.render.pool.cells[key].shift() ?? createCell(width);
66
74
 
67
- cell.textContent = String(getValue(data, options.field));
75
+ cell.textContent = String(getValue(data, key));
68
76
 
69
- row.cells[options.field] = cell;
77
+ row.cells[key] = cell;
70
78
 
71
79
  element.append(cell);
72
80
  }
@@ -1,11 +1,7 @@
1
1
  import {setAttributes} from '@oscarpalmer/toretto/attribute';
2
2
  import {setStyles} from '@oscarpalmer/toretto/style';
3
- import {
4
- CSS_TABELA_CELL,
5
- CSS_TABELA_CELL_BODY,
6
- CSS_TABELA_ROW,
7
- CSS_TABELA_ROWGROUP,
8
- } from '../models/style.model';
3
+ import {ELEMENT_DIV, ROLE_CELL, ROLE_ROW, ROLE_ROWGROUP} from '../models/dom.model';
4
+ import {CSS_CELL, CSS_CELL_BODY, CSS_ROW, CSS_ROWGROUP} from '../models/style.model';
9
5
 
10
6
  type RowGroupWithRow = {
11
7
  group: HTMLDivElement;
@@ -14,10 +10,10 @@ type RowGroupWithRow = {
14
10
 
15
11
  export function createCell(width: number, body?: boolean): HTMLDivElement {
16
12
  const cell = createElement(
17
- 'div',
13
+ ELEMENT_DIV,
18
14
  {
19
- className: CSS_TABELA_CELL,
20
- role: 'cell',
15
+ className: CSS_CELL,
16
+ role: ROLE_CELL,
21
17
  },
22
18
  {},
23
19
  {
@@ -26,7 +22,7 @@ export function createCell(width: number, body?: boolean): HTMLDivElement {
26
22
  );
27
23
 
28
24
  if (body ?? true) {
29
- cell.classList.add(CSS_TABELA_CELL_BODY);
25
+ cell.classList.add(CSS_CELL_BODY);
30
26
  }
31
27
 
32
28
  return cell;
@@ -53,37 +49,37 @@ export function createElement<TagName extends keyof HTMLElementTagNameMap>(
53
49
  return element;
54
50
  }
55
51
 
56
- export function createRowGroup(): RowGroupWithRow;
52
+ export function createRowGroup(height: number): RowGroupWithRow;
57
53
 
58
- export function createRowGroup(withRow: boolean): HTMLDivElement;
54
+ export function createRowGroup(height: number, withRow: boolean): HTMLDivElement;
59
55
 
60
- export function createRowGroup(withRow?: boolean) {
61
- const group = createElement('div', {
62
- className: CSS_TABELA_ROWGROUP,
63
- role: 'rowgroup',
56
+ export function createRowGroup(height: number, withRow?: boolean) {
57
+ const group = createElement(ELEMENT_DIV, {
58
+ className: CSS_ROWGROUP,
59
+ role: ROLE_ROWGROUP,
64
60
  });
65
61
 
66
62
  if (!(withRow ?? true)) {
67
63
  return group;
68
64
  }
69
65
 
70
- const row = createRow();
66
+ const row = createRow(height);
71
67
 
72
68
  group.append(row);
73
69
 
74
70
  return {group, row};
75
71
  }
76
72
 
77
- export function createRow(): HTMLDivElement {
73
+ export function createRow(height: number): HTMLDivElement {
78
74
  const row = createElement(
79
- 'div',
75
+ ELEMENT_DIV,
80
76
  {
81
- className: CSS_TABELA_ROW,
82
- role: 'row',
77
+ className: CSS_ROW,
78
+ role: ROLE_ROW,
83
79
  },
84
80
  {},
85
81
  {
86
- height: '32px',
82
+ height: `${height}px`,
87
83
  },
88
84
  );
89
85
 
@@ -1,4 +1,13 @@
1
1
  import type {Key} from '@oscarpalmer/atoms/models';
2
+ import type {GroupComponent} from '../components/group.component';
3
+ import {EVENTS_NAMES, type EventName} from '../models/event.model';
4
+ import {GROUP_KEY_EXPRESSION, type TabelaGroup} from '../models/group.model';
5
+
6
+ export function getGroup(group: GroupComponent): TabelaGroup {
7
+ return {
8
+ value: group.value.original,
9
+ };
10
+ }
2
11
 
3
12
  export function getKey(value: unknown): Key | undefined {
4
13
  if (typeof value === 'number') {
@@ -12,4 +21,12 @@ export function getKey(value: unknown): Key | undefined {
12
21
  return integerExpression.test(value) ? Number.parseInt(value, 10) : value;
13
22
  }
14
23
 
24
+ export function isEvent(value: unknown): value is EventName {
25
+ return EVENTS_NAMES.has(value as EventName);
26
+ }
27
+
28
+ export function isGroupKey(key: unknown): boolean {
29
+ return typeof key === 'string' && GROUP_KEY_EXPRESSION.test(key);
30
+ }
31
+
15
32
  const integerExpression = /^\d+$/;
@@ -20,31 +20,31 @@ export class ColumnManager {
20
20
  this.state = undefined as never;
21
21
  }
22
22
 
23
- get(field: string): ColumnComponent | undefined {
24
- return this.items.find(item => item.options.field === field);
23
+ get(key: string): ColumnComponent | undefined {
24
+ return this.items.find(item => item.options.key === key);
25
25
  }
26
26
 
27
- remove(field: string): void;
27
+ remove(key: string): void;
28
28
 
29
- remove(fields: string[]): void;
29
+ remove(keys: string[]): void;
30
30
 
31
31
  remove(value: unknown): void {
32
32
  const {items, state} = this;
33
33
  const {components, managers} = state;
34
34
 
35
- const fields = (Array.isArray(value) ? value : [value]).filter(
35
+ const keys = (Array.isArray(value) ? value : [value]).filter(
36
36
  item => typeof item === 'string',
37
37
  );
38
38
 
39
- const {length} = fields;
39
+ const {length} = keys;
40
40
 
41
41
  if (length === 0) {
42
42
  return;
43
43
  }
44
44
 
45
- for (let fieldIndex = 0; fieldIndex < length; fieldIndex += 1) {
45
+ for (let keyIndex = 0; keyIndex < length; keyIndex += 1) {
46
46
  const itemIndex = items.findIndex(
47
- component => component.options.field === fields[fieldIndex],
47
+ component => component.options.key === keys[keyIndex],
48
48
  );
49
49
 
50
50
  if (itemIndex > -1) {
@@ -57,7 +57,7 @@ export class ColumnManager {
57
57
  components.header.update(items);
58
58
  components.footer.update(items);
59
59
 
60
- managers.render.removeCells(fields);
60
+ managers.render.removeCells(keys);
61
61
  }
62
62
 
63
63
  set(columns: TabelaColumn[]): void {