@oscarpalmer/tabela 0.12.0 → 0.13.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 (160) hide show
  1. package/dist/body.component-_VDOpJhV.d.mts +10 -0
  2. package/dist/body.model-2iwsovAV.d.mts +7 -0
  3. package/dist/column.component-Bx46r3JI.d.mts +16 -0
  4. package/dist/column.model-D-aw4EU4.d.mts +16 -0
  5. package/dist/components/body.component.d.mts +2 -0
  6. package/dist/components/{body.component.js → body.component.mjs} +6 -3
  7. package/dist/components/column.component.d.mts +2 -0
  8. package/dist/components/{column.component.js → column.component.mjs} +8 -5
  9. package/dist/components/footer.component.d.mts +2 -0
  10. package/dist/components/{footer.component.js → footer.component.mjs} +7 -4
  11. package/dist/components/group.component.d.mts +2 -0
  12. package/dist/components/group.component.mjs +51 -0
  13. package/dist/components/header.component.d.mts +2 -0
  14. package/dist/components/{header.component.js → header.component.mjs} +6 -3
  15. package/dist/components/row.component.d.mts +2 -0
  16. package/dist/components/{row.component.js → row.component.mjs} +11 -7
  17. package/dist/filter.model-7ukJrtil.d.mts +16 -0
  18. package/dist/footer.component-Curiab8j.d.mts +12 -0
  19. package/dist/footer.model-DhqoS6ds.d.mts +8 -0
  20. package/dist/group.component-Cq1YYbfJ.d.mts +285 -0
  21. package/dist/group.model-BsKFwHbt.d.mts +10 -0
  22. package/dist/header.component-BjjlpZIg.d.mts +12 -0
  23. package/dist/header.model-DN_KzUCV.d.mts +7 -0
  24. package/dist/helpers/dom.helpers.d.mts +12 -0
  25. package/dist/helpers/{dom.helpers.js → dom.helpers.mjs} +13 -9
  26. package/dist/helpers/misc.helpers.d.mts +6 -0
  27. package/dist/helpers/{misc.helpers.js → misc.helpers.mjs} +3 -1
  28. package/dist/helpers/style.helper.d.mts +6 -0
  29. package/dist/helpers/style.helper.mjs +8 -0
  30. package/dist/index.d.mts +7 -0
  31. package/dist/{index.js → index.mjs} +3 -1
  32. package/dist/managers/column.manager.d.mts +2 -0
  33. package/dist/managers/{column.manager.js → column.manager.mjs} +6 -1
  34. package/dist/managers/data.manager.d.mts +2 -0
  35. package/dist/managers/data.manager.mjs +222 -0
  36. package/dist/managers/event.manager.d.mts +2 -0
  37. package/dist/managers/{event.manager.js → event.manager.mjs} +9 -8
  38. package/dist/managers/filter.manager.d.mts +2 -0
  39. package/dist/managers/{filter.manager.js → filter.manager.mjs} +23 -14
  40. package/dist/managers/group.manager.d.mts +2 -0
  41. package/dist/managers/group.manager.mjs +73 -0
  42. package/dist/managers/navigation.manager.d.mts +2 -0
  43. package/dist/managers/{navigation.manager.js → navigation.manager.mjs} +27 -24
  44. package/dist/managers/render.manager.d.mts +2 -0
  45. package/dist/managers/{render.manager.js → render.manager.mjs} +35 -26
  46. package/dist/managers/row.manager.d.mts +2 -0
  47. package/dist/managers/{row.manager.js → row.manager.mjs} +18 -11
  48. package/dist/managers/selection.manager.d.mts +2 -0
  49. package/dist/managers/{selection.manager.js → selection.manager.mjs} +32 -28
  50. package/dist/managers/sort.manager.d.mts +2 -0
  51. package/dist/managers/{sort.manager.js → sort.manager.mjs} +12 -9
  52. package/dist/managers/style.manager.d.mts +2 -0
  53. package/dist/managers/style.manager.mjs +149 -0
  54. package/dist/models/body.model.d.mts +2 -0
  55. package/dist/models/body.model.mjs +1 -0
  56. package/dist/models/column.model.d.mts +2 -0
  57. package/dist/models/column.model.mjs +1 -0
  58. package/dist/models/data.model.d.mts +2 -0
  59. package/dist/models/data.model.mjs +1 -0
  60. package/dist/models/filter.model.d.mts +2 -0
  61. package/dist/models/filter.model.mjs +1 -0
  62. package/dist/models/footer.model.d.mts +2 -0
  63. package/dist/models/footer.model.mjs +1 -0
  64. package/dist/models/group.model.d.mts +2 -0
  65. package/dist/models/group.model.mjs +1 -0
  66. package/dist/models/header.model.d.mts +2 -0
  67. package/dist/models/header.model.mjs +1 -0
  68. package/dist/models/render.model.d.mts +2 -0
  69. package/dist/models/render.model.mjs +1 -0
  70. package/dist/models/selection.model.d.mts +2 -0
  71. package/dist/models/selection.model.mjs +1 -0
  72. package/dist/models/sort.model.d.mts +2 -0
  73. package/dist/models/sort.model.mjs +1 -0
  74. package/dist/models/style.model.d.mts +23 -0
  75. package/dist/models/style.model.mjs +23 -0
  76. package/dist/models/tabela.model.d.mts +2 -0
  77. package/dist/models/tabela.model.mjs +1 -0
  78. package/dist/models/tabela.options.d.mts +2 -0
  79. package/dist/models/tabela.options.mjs +1 -0
  80. package/dist/selection.model-rwQe9fco.d.mts +12 -0
  81. package/dist/sort.model-CauImaLu.d.mts +15 -0
  82. package/dist/tabela.d.mts +21 -0
  83. package/dist/{tabela.full.js → tabela.full.mjs} +1073 -756
  84. package/dist/tabela.mjs +126 -0
  85. package/dist/tabela.options-RkZvfptB.d.mts +14 -0
  86. package/package.json +45 -37
  87. package/src/components/body.component.ts +4 -3
  88. package/src/components/column.component.ts +13 -18
  89. package/src/components/footer.component.ts +8 -3
  90. package/src/components/group.component.ts +48 -6
  91. package/src/components/header.component.ts +3 -2
  92. package/src/components/row.component.ts +8 -6
  93. package/src/helpers/dom.helpers.ts +21 -19
  94. package/src/helpers/style.helper.ts +1 -1
  95. package/src/managers/column.manager.ts +4 -0
  96. package/src/managers/data.manager.ts +170 -100
  97. package/src/managers/event.manager.ts +9 -10
  98. package/src/managers/filter.manager.ts +23 -12
  99. package/src/managers/group.manager.ts +63 -11
  100. package/src/managers/navigation.manager.ts +23 -22
  101. package/src/managers/render.manager.ts +43 -29
  102. package/src/managers/row.manager.ts +21 -9
  103. package/src/managers/selection.manager.ts +28 -21
  104. package/src/managers/sort.manager.ts +22 -20
  105. package/src/managers/style.manager.ts +156 -0
  106. package/src/models/data.model.ts +11 -8
  107. package/src/models/group.model.ts +6 -2
  108. package/src/models/style.model.ts +39 -0
  109. package/src/models/tabela.model.ts +10 -8
  110. package/src/tabela.ts +65 -33
  111. package/dist/components/group.component.js +0 -28
  112. package/dist/helpers/style.helper.js +0 -6
  113. package/dist/managers/data.manager.js +0 -181
  114. package/dist/managers/group.manager.js +0 -46
  115. package/dist/models/body.model.js +0 -0
  116. package/dist/models/column.model.js +0 -0
  117. package/dist/models/data.model.js +0 -0
  118. package/dist/models/filter.model.js +0 -0
  119. package/dist/models/footer.model.js +0 -0
  120. package/dist/models/group.model.js +0 -0
  121. package/dist/models/header.model.js +0 -0
  122. package/dist/models/render.model.js +0 -0
  123. package/dist/models/selection.model.js +0 -0
  124. package/dist/models/sort.model.js +0 -0
  125. package/dist/models/tabela.model.js +0 -0
  126. package/dist/models/tabela.options.js +0 -0
  127. package/dist/tabela.js +0 -105
  128. package/types/components/body.component.d.ts +0 -6
  129. package/types/components/column.component.d.ts +0 -13
  130. package/types/components/footer.component.d.ts +0 -8
  131. package/types/components/group.component.d.ts +0 -14
  132. package/types/components/header.component.d.ts +0 -8
  133. package/types/components/row.component.d.ts +0 -11
  134. package/types/helpers/dom.helpers.d.ts +0 -10
  135. package/types/helpers/misc.helpers.d.ts +0 -2
  136. package/types/helpers/style.helper.d.ts +0 -1
  137. package/types/index.d.ts +0 -4
  138. package/types/managers/column.manager.d.ts +0 -12
  139. package/types/managers/data.manager.d.ts +0 -29
  140. package/types/managers/event.manager.d.ts +0 -7
  141. package/types/managers/filter.manager.d.ts +0 -19
  142. package/types/managers/group.manager.d.ts +0 -17
  143. package/types/managers/navigation.manager.d.ts +0 -10
  144. package/types/managers/render.manager.d.ts +0 -17
  145. package/types/managers/row.manager.d.ts +0 -13
  146. package/types/managers/selection.manager.d.ts +0 -24
  147. package/types/managers/sort.manager.d.ts +0 -28
  148. package/types/models/body.model.d.ts +0 -4
  149. package/types/models/column.model.d.ts +0 -13
  150. package/types/models/data.model.d.ts +0 -24
  151. package/types/models/filter.model.d.ts +0 -13
  152. package/types/models/footer.model.d.ts +0 -5
  153. package/types/models/group.model.d.ts +0 -4
  154. package/types/models/header.model.d.ts +0 -4
  155. package/types/models/render.model.d.ts +0 -13
  156. package/types/models/selection.model.d.ts +0 -8
  157. package/types/models/sort.model.d.ts +0 -12
  158. package/types/models/tabela.model.d.ts +0 -39
  159. package/types/models/tabela.options.d.ts +0 -10
  160. package/types/tabela.d.ts +0 -15
@@ -1,4 +1,89 @@
1
- function compact$1(array, strict) {
1
+ //#region node_modules/@oscarpalmer/toretto/dist/internal/is.mjs
2
+ /**
3
+ * Is the value an event target?
4
+ * @param value Value to check
5
+ * @returns `true` if it's an event target, otherwise `false`
6
+ */
7
+ function isEventTarget(value) {
8
+ return typeof value === "object" && value != null && typeof value.addEventListener === "function" && typeof value.removeEventListener === "function" && typeof value.dispatchEvent === "function";
9
+ }
10
+ /**
11
+ * Is the value an HTML or SVG element?
12
+ * @param value Value to check
13
+ * @returns `true` if it's an HTML or SVG element, otherwise `false`
14
+ */
15
+ function isHTMLOrSVGElement(value) {
16
+ return value instanceof HTMLElement || value instanceof SVGElement;
17
+ }
18
+ new Set([
19
+ Node.ELEMENT_NODE,
20
+ Node.TEXT_NODE,
21
+ Node.PROCESSING_INSTRUCTION_NODE,
22
+ Node.COMMENT_NODE,
23
+ Node.DOCUMENT_TYPE_NODE
24
+ ]);
25
+ //#endregion
26
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/is.mjs
27
+ /**
28
+ * Is the value a constructor function?
29
+ * @param value Value to check
30
+ * @returns `true` if the value is a constructor function, otherwise `false`
31
+ */
32
+ function isConstructor(value) {
33
+ return typeof value === "function" && value.prototype?.constructor === value;
34
+ }
35
+ /**
36
+ * Is the value a key?
37
+ * @param value Value to check
38
+ * @returns `true` if the value is a `Key` _(`number` or `string`)_, otherwise `false`
39
+ */
40
+ function isKey(value) {
41
+ return typeof value === "number" || typeof value === "string";
42
+ }
43
+ /**
44
+ * Is the value a number?
45
+ * @param value Value to check
46
+ * @returns `true` if the value is a `number`, otherwise `false`
47
+ */
48
+ function isNumber(value) {
49
+ return typeof value === "number" && !Number.isNaN(value);
50
+ }
51
+ /**
52
+ * Is the value a plain object?
53
+ * @param value Value to check
54
+ * @returns `true` if the value is a plain object, otherwise `false`
55
+ */
56
+ function isPlainObject(value) {
57
+ if (value === null || typeof value !== "object") return false;
58
+ if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
59
+ const prototype = Object.getPrototypeOf(value);
60
+ return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
61
+ }
62
+ /**
63
+ * Is the value a typed array?
64
+ * @param value Value to check
65
+ * @returns `true` if the value is a typed array, otherwise `false`
66
+ */
67
+ function isTypedArray(value) {
68
+ TYPED_ARRAYS ??= new Set([
69
+ Int8Array,
70
+ Uint8Array,
71
+ Uint8ClampedArray,
72
+ Int16Array,
73
+ Uint16Array,
74
+ Int32Array,
75
+ Uint32Array,
76
+ Float32Array,
77
+ Float64Array,
78
+ BigInt64Array,
79
+ BigUint64Array
80
+ ]);
81
+ return TYPED_ARRAYS.has(value?.constructor);
82
+ }
83
+ let TYPED_ARRAYS;
84
+ //#endregion
85
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/array/compact.mjs
86
+ function compact(array, strict) {
2
87
  if (!Array.isArray(array)) return [];
3
88
  if (strict === true) return array.filter(Boolean);
4
89
  const { length } = array;
@@ -9,56 +94,143 @@ function compact$1(array, strict) {
9
94
  }
10
95
  return compacted;
11
96
  }
97
+ //#endregion
98
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/string.mjs
12
99
  /**
13
100
  * Get the string value from any value
14
101
  * @param value Original value
15
102
  * @returns String representation of the value
16
103
  */
17
- function getString$1(value) {
104
+ function getString(value) {
18
105
  if (typeof value === "string") return value;
19
106
  if (value == null) return "";
20
- if (typeof value === "function") return getString$1(value());
107
+ if (typeof value === "function") return getString(value());
21
108
  if (typeof value !== "object") return String(value);
22
109
  const asString = String(value.valueOf?.() ?? value);
23
110
  return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
24
111
  }
112
+ function ignoreKey(key) {
113
+ return EXPRESSION_IGNORED.test(key);
114
+ }
25
115
  /**
26
116
  * Join an array of values into a string
27
117
  * @param value Array of values
28
118
  * @param delimiter Delimiter to use between values
29
119
  * @returns Joined string
30
120
  */
31
- function join$1(value, delimiter) {
32
- return compact$1(value).map(getString$1).join(typeof delimiter === "string" ? delimiter : "");
121
+ function join(value, delimiter) {
122
+ return compact(value).map(getString).join(typeof delimiter === "string" ? delimiter : "");
33
123
  }
34
124
  /**
35
125
  * Split a string into words _(and other readable parts)_
36
126
  * @param value Original string
37
127
  * @returns Array of words found in the string
38
128
  */
39
- function words$1(value) {
40
- return typeof value === "string" ? value.match(EXPRESSION_WORDS$1) ?? [] : [];
129
+ function words(value) {
130
+ return typeof value === "string" ? value.match(EXPRESSION_WORDS) ?? [] : [];
41
131
  }
42
- var EXPRESSION_WORDS$1 = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
132
+ const EXPRESSION_IGNORED = /(^|\.)(__proto__|constructor|prototype)(\.|$)/i;
133
+ const EXPRESSION_WORDS = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
134
+ //#endregion
135
+ //#region node_modules/@oscarpalmer/atoms/dist/is.mjs
43
136
  /**
44
- * Is the value a number?
137
+ * Is the value `undefined`, `null`, or a whitespace-only string?
45
138
  * @param value Value to check
46
- * @returns `true` if the value is a `number`, otherwise `false`
139
+ * @returns `true` if the value is nullable or a whitespace-only string, otherwise `false`
47
140
  */
48
- function isNumber$1(value) {
49
- return typeof value === "number" && !Number.isNaN(value);
141
+ function isNullableOrWhitespace(value) {
142
+ return value == null || EXPRESSION_WHITESPACE.test(getString(value));
143
+ }
144
+ const EXPRESSION_WHITESPACE = /^\s*$/;
145
+ //#endregion
146
+ //#region node_modules/@oscarpalmer/toretto/dist/internal/element-value.mjs
147
+ function setElementValue(element, first, second, third, callback) {
148
+ if (!isHTMLOrSVGElement(element)) return;
149
+ if (typeof first === "string") setElementValues(element, first, second, third, callback);
150
+ else if (isAttribute(first)) setElementValues(element, first.name, first.value, third, callback);
151
+ }
152
+ function setElementValues(element, first, second, third, callback) {
153
+ if (!isHTMLOrSVGElement(element)) return;
154
+ if (typeof first === "string") {
155
+ callback(element, first, second, third);
156
+ return;
157
+ }
158
+ const isArray = Array.isArray(first);
159
+ if (!isArray && !(typeof first === "object" && first !== null)) return;
160
+ const entries = isArray ? first : Object.entries(first).map(([name, value]) => ({
161
+ name,
162
+ value
163
+ }));
164
+ const { length } = entries;
165
+ for (let index = 0; index < length; index += 1) {
166
+ const entry = entries[index];
167
+ if (typeof entry === "object" && typeof entry?.name === "string") callback(element, entry.name, entry.value, third);
168
+ }
169
+ }
170
+ function updateElementValue(element, key, value, set, remove, isBoolean, json) {
171
+ if (isBoolean ? value == null : isNullableOrWhitespace(value)) remove.call(element, key);
172
+ else set.call(element, key, json ? JSON.stringify(value) : String(value));
173
+ }
174
+ //#endregion
175
+ //#region node_modules/@oscarpalmer/toretto/dist/internal/attribute.mjs
176
+ function isAttribute(value) {
177
+ return value instanceof Attr || isPlainObject(value) && typeof value.name === "string" && "value" in value;
178
+ }
179
+ function updateAttribute(element, name, value, dispatch) {
180
+ const normalizedName = name.toLowerCase();
181
+ const isBoolean = booleanAttributesSet.has(normalizedName);
182
+ const next = isBoolean ? value === true || typeof value === "string" && (value === "" || value.toLowerCase() === normalizedName) : value == null ? "" : value;
183
+ if (name in element) updateProperty(element, normalizedName, next, dispatch);
184
+ updateElementValue(element, name, isBoolean ? next ? "" : null : value, element.setAttribute, element.removeAttribute, isBoolean, false);
185
+ }
186
+ function updateProperty(element, name, value, dispatch) {
187
+ if (Object.is(element[name], value)) return;
188
+ element[name] = value;
189
+ const event = dispatch !== false && elementEvents[element.tagName]?.[name];
190
+ if (typeof event === "string") element.dispatchEvent(new Event(event, { bubbles: true }));
50
191
  }
51
192
  /**
52
- * Is the value a plain object?
53
- * @param value Value to check
54
- * @returns `true` if the value is a plain object, otherwise `false`
193
+ * List of boolean attributes
55
194
  */
56
- function isPlainObject$1(value) {
57
- if (value === null || typeof value !== "object") return false;
58
- if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
59
- const prototype = Object.getPrototypeOf(value);
60
- return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
61
- }
195
+ const booleanAttributes = Object.freeze([
196
+ "async",
197
+ "autofocus",
198
+ "autoplay",
199
+ "checked",
200
+ "controls",
201
+ "default",
202
+ "defer",
203
+ "disabled",
204
+ "formnovalidate",
205
+ "hidden",
206
+ "inert",
207
+ "ismap",
208
+ "itemscope",
209
+ "loop",
210
+ "multiple",
211
+ "muted",
212
+ "nomodule",
213
+ "novalidate",
214
+ "open",
215
+ "playsinline",
216
+ "readonly",
217
+ "required",
218
+ "reversed",
219
+ "selected"
220
+ ]);
221
+ const booleanAttributesSet = new Set(booleanAttributes);
222
+ const elementEvents = {
223
+ DETAILS: { open: "toggle" },
224
+ INPUT: {
225
+ checked: "change",
226
+ value: "input"
227
+ },
228
+ SELECT: { value: "change" },
229
+ TEXTAREA: { value: "input" }
230
+ };
231
+ document.createElement("form");
232
+ //#endregion
233
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/number.mjs
62
234
  /**
63
235
  * Clamp a number between a minimum and maximum value
64
236
  * @param value Value to clamp
@@ -67,29 +239,59 @@ function isPlainObject$1(value) {
67
239
  * @param loop If `true`, the value will loop around when smaller than the minimum or larger than the maximum _(defaults to `false`)_
68
240
  * @returns Clamped value
69
241
  */
70
- function clamp$1(value, minimum, maximum, loop) {
242
+ function clamp(value, minimum, maximum, loop) {
71
243
  if (![
72
244
  value,
73
245
  minimum,
74
246
  maximum
75
- ].every(isNumber$1)) return NaN;
247
+ ].every(isNumber)) return NaN;
76
248
  if (value < minimum) return loop === true ? maximum : minimum;
77
249
  return value > maximum ? loop === true ? minimum : maximum : value;
78
250
  }
79
- function getSizedMaximum$1(first, second) {
251
+ /**
252
+ * Get the number value from an unknown value _(based on Lodash)_
253
+ * @param value Original value
254
+ * @returns Original value as a number, or `NaN` if the value is unable to be parsed
255
+ */
256
+ function getNumber(value) {
257
+ if (typeof value === "number") return value;
258
+ if (typeof value === "bigint" || typeof value === "boolean") return Number(value);
259
+ if (value == null || typeof value === "symbol") return NaN;
260
+ if (typeof value === "function") return getNumber(value());
261
+ let parsed = value.valueOf();
262
+ if (typeof parsed === "object") parsed = parsed.toString();
263
+ if (typeof parsed !== "string") return getNumber(parsed);
264
+ const trimmed = parsed.trim();
265
+ if (trimmed.length === 0) return NaN;
266
+ if (EXPRESSION_ZEROISH.test(parsed)) return 0;
267
+ const isBinary = EXPRESSION_BINARY.test(trimmed);
268
+ if (isBinary || EXPRESSION_OCTAL.test(trimmed)) return Number.parseInt(trimmed.slice(2), isBinary ? 2 : OCTAL_VALUE);
269
+ return Number(EXPRESSION_HEX.test(trimmed) ? trimmed : trimmed.replace(EXPRESSION_UNDERSCORE, ""));
270
+ }
271
+ const EXPRESSION_BINARY = /^0b[01]+$/i;
272
+ const EXPRESSION_HEX = /^0x[0-9a-f]+$/i;
273
+ const EXPRESSION_OCTAL = /^0o[0-7]+$/i;
274
+ const EXPRESSION_UNDERSCORE = /_/g;
275
+ const EXPRESSION_ZEROISH = /^\s*0+\s*$/;
276
+ const OCTAL_VALUE = 8;
277
+ //#endregion
278
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/sized.mjs
279
+ function getSizedMaximum(first, second) {
80
280
  let actual;
81
281
  if (typeof first === "number") actual = first;
82
- else actual = typeof second === "number" ? second : MAXIMUM_DEFAULT$1;
83
- return clamp$1(actual, 1, MAXIMUM_ABSOLUTE$1);
282
+ else actual = typeof second === "number" ? second : MAXIMUM_DEFAULT;
283
+ return clamp(actual, 1, MAXIMUM_ABSOLUTE);
84
284
  }
85
- var MAXIMUM_ABSOLUTE$1 = 16777216;
86
- var MAXIMUM_DEFAULT$1 = 1048576;
285
+ const MAXIMUM_ABSOLUTE = 16777216;
286
+ const MAXIMUM_DEFAULT = 1048576;
287
+ //#endregion
288
+ //#region node_modules/@oscarpalmer/atoms/dist/sized/map.mjs
87
289
  /**
88
290
  * A Map with a maximum size
89
291
  *
90
292
  * Behavior is similar to a _LRU_-cache, where the least recently used entries are removed
91
293
  */
92
- var SizedMap$1 = class extends Map {
294
+ var SizedMap = class extends Map {
93
295
  /**
94
296
  * The maximum size of the Map
95
297
  */
@@ -104,7 +306,7 @@ var SizedMap$1 = class extends Map {
104
306
  return this.#maximumSize;
105
307
  }
106
308
  constructor(first, second) {
107
- const maximum = getSizedMaximum$1(first, second);
309
+ const maximum = getSizedMaximum(first, second);
108
310
  super();
109
311
  this.#maximumSize = maximum;
110
312
  if (Array.isArray(first)) {
@@ -130,7 +332,9 @@ var SizedMap$1 = class extends Map {
130
332
  return super.set(key, value);
131
333
  }
132
334
  };
133
- var Memoized$1 = class {
335
+ //#endregion
336
+ //#region node_modules/@oscarpalmer/atoms/dist/function/memoize.mjs
337
+ var Memoized = class {
134
338
  #state;
135
339
  /**
136
340
  * Maximum cache size
@@ -145,9 +349,9 @@ var Memoized$1 = class {
145
349
  return this.#state.cache?.size ?? NaN;
146
350
  }
147
351
  constructor(callback, options) {
148
- const cache = new SizedMap$1(options.cacheSize);
352
+ const cache = new SizedMap(options.cacheSize);
149
353
  const getter = (...parameters) => {
150
- const key = options.cacheKey?.(...parameters) ?? (parameters.length === 1 ? parameters[0] : join$1(parameters.map(getString$1), "_"));
354
+ const key = options.cacheKey?.(...parameters) ?? (parameters.length === 1 ? parameters[0] : join(parameters.map(getString), SEPARATOR));
151
355
  if (cache.has(key)) return cache.get(key);
152
356
  const value = callback(...parameters);
153
357
  cache.set(key, value);
@@ -206,11 +410,11 @@ var Memoized$1 = class {
206
410
  return this.#state.getter(...parameters);
207
411
  }
208
412
  };
209
- function getMemoizationOptions$1(input) {
210
- const { cacheKey, cacheSize } = isPlainObject$1(input) ? input : {};
413
+ function getMemoizationOptions(input) {
414
+ const { cacheKey, cacheSize } = isPlainObject(input) ? input : {};
211
415
  return {
212
416
  cacheKey: typeof cacheKey === "function" ? cacheKey : void 0,
213
- cacheSize: typeof cacheSize === "number" && cacheSize > 0 ? cacheSize : DEFAULT_CACHE_SIZE$1
417
+ cacheSize: typeof cacheSize === "number" && cacheSize > 0 ? cacheSize : DEFAULT_CACHE_SIZE
214
418
  };
215
419
  }
216
420
  /**
@@ -219,17 +423,20 @@ function getMemoizationOptions$1(input) {
219
423
  * @param options Memoization options
220
424
  * @returns Memoized instance
221
425
  */
222
- function memoize$1(callback, options) {
223
- return new Memoized$1(callback, getMemoizationOptions$1(options));
426
+ function memoize(callback, options) {
427
+ return new Memoized(callback, getMemoizationOptions(options));
224
428
  }
225
- var DEFAULT_CACHE_SIZE$1 = 1024;
429
+ const DEFAULT_CACHE_SIZE = 1024;
430
+ const SEPARATOR = "_";
431
+ //#endregion
432
+ //#region node_modules/@oscarpalmer/atoms/dist/string/case.mjs
226
433
  /**
227
434
  * Convert a string to camel case _(thisIsCamelCase)_
228
435
  * @param value String to convert
229
436
  * @returns Camel-cased string
230
437
  */
231
438
  function camelCase(value) {
232
- return toCase("camel", value, true, false);
439
+ return toCase(CASE_CAMEL, value, true, false);
233
440
  }
234
441
  /**
235
442
  * Capitalize the first letter of a string _(and lowercase the rest)_
@@ -238,11 +445,11 @@ function camelCase(value) {
238
445
  */
239
446
  function capitalize(value) {
240
447
  if (typeof value !== "string" || value.length === 0) return "";
241
- memoizedCapitalize ??= memoize$1((v) => v.length === 1 ? v.toLocaleUpperCase() : `${v.charAt(0).toLocaleUpperCase()}${v.slice(1).toLocaleLowerCase()}`);
448
+ memoizedCapitalize ??= memoize((v) => v.length === 1 ? v.toLocaleUpperCase() : `${v.charAt(0).toLocaleUpperCase()}${v.slice(1).toLocaleLowerCase()}`);
242
449
  return memoizedCapitalize.run(value);
243
450
  }
244
451
  function toCase(type, value, capitalizeAny, capitalizeFirst) {
245
- caseMemoizers[type] ??= memoize$1(toCaseCallback.bind({
452
+ caseMemoizers[type] ??= memoize(toCaseCallback.bind({
246
453
  type,
247
454
  capitalizeAny,
248
455
  capitalizeFirst
@@ -253,11 +460,11 @@ function toCaseCallback(value) {
253
460
  if (typeof value !== "string") return "";
254
461
  if (value.length < 1) return value;
255
462
  const { capitalizeAny, capitalizeFirst, type } = this;
256
- const parts = words$1(value);
463
+ const parts = words(value);
257
464
  const partsLength = parts.length;
258
465
  const cased = [];
259
466
  for (let partIndex = 0; partIndex < partsLength; partIndex += 1) {
260
- const items = parts[partIndex].replace(EXPRESSION_ACRONYM, (full, one, two, three) => three === "s" ? full : `${one}-${two}${three}`).replace(EXPRESSION_CAMEL_CASE, REPLACEMENT_CAMEL_CASE).split("-");
467
+ const items = parts[partIndex].replace(EXPRESSION_ACRONYM, (full, one, two, three) => three === S ? full : `${one}-${two}${three}`).replace(EXPRESSION_CAMEL_CASE, REPLACEMENT_CAMEL_CASE).split("-");
261
468
  const itemsLength = items.length;
262
469
  const partResult = [];
263
470
  let itemCount = 0;
@@ -268,21 +475,31 @@ function toCaseCallback(value) {
268
475
  else partResult.push(capitalize(item));
269
476
  itemCount += 1;
270
477
  }
271
- cased.push(join$1(partResult, delimiters[type]));
272
- }
273
- return join$1(cased, delimiters[type]);
274
- }
275
- var caseMemoizers = {};
276
- var delimiters = {
277
- camel: "",
278
- kebab: "-",
279
- pascal: "",
280
- snake: "_"
478
+ cased.push(join(partResult, delimiters[type]));
479
+ }
480
+ return join(cased, delimiters[type]);
481
+ }
482
+ const CASE_CAMEL = "camel";
483
+ const CASE_KEBAB = "kebab";
484
+ const CASE_PASCAL = "pascal";
485
+ const CASE_SNAKE = "snake";
486
+ const DELIMTER_EMPTY = "";
487
+ const DELIMITER_HYPHEN = "-";
488
+ const DELIMITER_UNDERSCORE = "_";
489
+ const EXPRESSION_CAMEL_CASE = /(\p{Ll})(\p{Lu})/gu;
490
+ const EXPRESSION_ACRONYM = /(\p{Lu}*)(\p{Lu})(\p{Ll}+)/gu;
491
+ const REPLACEMENT_CAMEL_CASE = "$1-$2";
492
+ const S = "s";
493
+ const caseMemoizers = {};
494
+ const delimiters = {
495
+ [CASE_CAMEL]: DELIMTER_EMPTY,
496
+ [CASE_KEBAB]: DELIMITER_HYPHEN,
497
+ [CASE_PASCAL]: DELIMTER_EMPTY,
498
+ [CASE_SNAKE]: DELIMITER_UNDERSCORE
281
499
  };
282
- var EXPRESSION_CAMEL_CASE = /(\p{Ll})(\p{Lu})/gu;
283
- var EXPRESSION_ACRONYM = /(\p{Lu}*)(\p{Lu})(\p{Ll}+)/gu;
284
- var REPLACEMENT_CAMEL_CASE = "$1-$2";
285
- var memoizedCapitalize;
500
+ let memoizedCapitalize;
501
+ //#endregion
502
+ //#region node_modules/@oscarpalmer/toretto/dist/internal/get-value.mjs
286
503
  function getBoolean(value, defaultValue) {
287
504
  return typeof value === "boolean" ? value : defaultValue ?? false;
288
505
  }
@@ -290,127 +507,16 @@ function getStyleValue(element, property, computed) {
290
507
  const name = camelCase(property);
291
508
  return computed ? getComputedStyle(element)[name] : element.style[name];
292
509
  }
293
- /**
294
- * Is the value an event target?
295
- * @param value Value to check
296
- * @returns `true` if it's an event target, otherwise `false`
297
- */
298
- function isEventTarget(value) {
299
- return typeof value === "object" && value != null && typeof value.addEventListener === "function" && typeof value.removeEventListener === "function" && typeof value.dispatchEvent === "function";
300
- }
301
- /**
302
- * Is the value an HTML or SVG element?
303
- * @param value Value to check
304
- * @returns `true` if it's an HTML or SVG element, otherwise `false`
305
- */
306
- function isHTMLOrSVGElement(value) {
307
- return value instanceof HTMLElement || value instanceof SVGElement;
308
- }
309
- new Set([
310
- Node.ELEMENT_NODE,
311
- Node.TEXT_NODE,
312
- Node.PROCESSING_INSTRUCTION_NODE,
313
- Node.COMMENT_NODE,
314
- Node.DOCUMENT_TYPE_NODE
315
- ]);
316
- /**
317
- * Is the value `undefined`, `null`, or a whitespace-only string?
318
- * @param value Value to check
319
- * @returns `true` if the value is nullable or a whitespace-only string, otherwise `false`
320
- */
321
- function isNullableOrWhitespace$1(value) {
322
- return value == null || EXPRESSION_WHITESPACE$1.test(getString$1(value));
323
- }
324
- var EXPRESSION_WHITESPACE$1 = /^\s*$/;
325
- function setElementValue(element, first, second, third, callback) {
326
- if (!isHTMLOrSVGElement(element)) return;
327
- if (typeof first === "string") setElementValues(element, first, second, third, callback);
328
- else if (isAttribute(first)) setElementValues(element, first.name, first.value, third, callback);
329
- }
330
- function setElementValues(element, first, second, third, callback) {
331
- if (!isHTMLOrSVGElement(element)) return;
332
- if (typeof first === "string") {
333
- callback(element, first, second, third);
334
- return;
335
- }
336
- const isArray = Array.isArray(first);
337
- if (!isArray && !(typeof first === "object" && first !== null)) return;
338
- const entries = isArray ? first : Object.entries(first).map(([name, value]) => ({
339
- name,
340
- value
341
- }));
342
- const { length } = entries;
343
- for (let index = 0; index < length; index += 1) {
344
- const entry = entries[index];
345
- if (typeof entry === "object" && typeof entry?.name === "string") callback(element, entry.name, entry.value, third);
346
- }
347
- }
348
- function updateElementValue(element, key, value, set, remove, isBoolean, json) {
349
- if (isBoolean ? value == null : isNullableOrWhitespace$1(value)) remove.call(element, key);
350
- else set.call(element, key, json ? JSON.stringify(value) : String(value));
351
- }
352
- function isAttribute(value) {
353
- return value instanceof Attr || isPlainObject$1(value) && typeof value.name === "string" && "value" in value;
354
- }
355
- function updateAttribute(element, name, value, dispatch) {
356
- const normalizedName = name.toLowerCase();
357
- const isBoolean = booleanAttributesSet.has(normalizedName);
358
- const next = isBoolean ? value === true || typeof value === "string" && (value === "" || value.toLowerCase() === normalizedName) : value == null ? "" : value;
359
- if (name in element) updateProperty(element, normalizedName, next, dispatch);
360
- updateElementValue(element, name, isBoolean ? next ? "" : null : value, element.setAttribute, element.removeAttribute, isBoolean, false);
361
- }
362
- function updateProperty(element, name, value, dispatch) {
363
- if (Object.is(element[name], value)) return;
364
- element[name] = value;
365
- const event = dispatch !== false && elementEvents[element.tagName]?.[name];
366
- if (typeof event === "string") element.dispatchEvent(new Event(event, { bubbles: true }));
367
- }
368
- /**
369
- * List of boolean attributes
370
- */
371
- const booleanAttributes = Object.freeze([
372
- "async",
373
- "autofocus",
374
- "autoplay",
375
- "checked",
376
- "controls",
377
- "default",
378
- "defer",
379
- "disabled",
380
- "formnovalidate",
381
- "hidden",
382
- "inert",
383
- "ismap",
384
- "itemscope",
385
- "loop",
386
- "multiple",
387
- "muted",
388
- "nomodule",
389
- "novalidate",
390
- "open",
391
- "playsinline",
392
- "readonly",
393
- "required",
394
- "reversed",
395
- "selected"
396
- ]);
397
- var booleanAttributesSet = new Set(booleanAttributes);
398
- var elementEvents = {
399
- DETAILS: { open: "toggle" },
400
- INPUT: {
401
- checked: "change",
402
- value: "input"
403
- },
404
- SELECT: { value: "change" },
405
- TEXTAREA: { value: "input" }
406
- };
407
- document.createElement("form");
510
+ //#endregion
511
+ //#region node_modules/@oscarpalmer/toretto/dist/attribute/set.mjs
408
512
  function setAttribute(element, first, second, third) {
409
513
  setElementValue(element, first, second, third, updateAttribute);
410
514
  }
411
515
  function setAttributes(element, attributes, dispatch) {
412
516
  setElementValues(element, attributes, null, dispatch, updateAttribute);
413
517
  }
518
+ //#endregion
519
+ //#region node_modules/@oscarpalmer/toretto/dist/style.mjs
414
520
  /**
415
521
  * Get styles from an element
416
522
  * @param element Element to get the styles from
@@ -475,27 +581,52 @@ function updateStyleProperty(element, key, value) {
475
581
  this.style[property] = "";
476
582
  }, false, false);
477
583
  }
584
+ //#endregion
585
+ //#region src/models/style.model.ts
586
+ const CSS_TABELA = "tabela";
587
+ const CSS_TABELA_CELL = "tabela__cell";
588
+ const CSS_TABELA_CELL_BODY = "tabela__cell--body";
589
+ const CSS_TABELA_CELL_FOOTER = "tabela__cell--footer";
590
+ const CSS_TABELA_FAKER = "tabela__faker";
591
+ const CSS_TABELA_HEADING = "tabela__heading";
592
+ const CSS_TABELA_HEADING_CONTENT = "tabela__heading__content";
593
+ const CSS_TABELA_HEADING_SORTER = "tabela__heading__sorter";
594
+ const CSS_TABELA_ROW = "tabela__row";
595
+ const CSS_TABELA_ROW_BODY = "tabela__row--body";
596
+ const CSS_TABELA_ROW_FOOTER = "tabela__row--footer";
597
+ const CSS_TABELA_ROW_GROUP = "tabela__row--group tabela__group";
598
+ const CSS_TABELA_ROW_HEADER = "tabela__row--header";
599
+ const CSS_TABELA_ROW_SELECTED = "tabela__row--selected";
600
+ const CSS_TABELA_ROWGROUP = "tabela__rowgroup";
601
+ const CSS_TABELA_ROWGROUP_BODY = "tabela__rowgroup--body";
602
+ const CSS_TABELA_ROWGROUP_FOOTER = "tabela__rowgroup--footer";
603
+ const CSS_TABELA_ROWGROUP_HEADER = "tabela__rowgroup--header";
604
+ const CSS_TABELA_SELECTION = "tabela__selection";
605
+ const CSS_TABELA_TABLE = "tabela__table";
606
+ //#endregion
607
+ //#region src/helpers/dom.helpers.ts
478
608
  function createCell(width, body) {
479
609
  const cell = createElement("div", {
480
- className: "tabela__cell",
610
+ className: CSS_TABELA_CELL,
481
611
  role: "cell"
482
612
  }, {}, { width: `${width}px` });
483
- if (body ?? true) cell.classList.add("tabela__cell--body");
613
+ if (body ?? true) cell.classList.add(CSS_TABELA_CELL_BODY);
484
614
  return cell;
485
615
  }
486
616
  function createElement(tagName, properties, attributes, style) {
487
617
  const element = document.createElement(tagName);
488
- const keys = Object.keys(properties);
489
- for (const key of keys) element[key] = properties[key];
490
- setAttributes(element, attributes);
491
- setStyles(element, style);
618
+ const props = properties ?? {};
619
+ const keys = Object.keys(props);
620
+ for (const key of keys) element[key] = props[key];
621
+ setAttributes(element, attributes ?? {});
622
+ setStyles(element, style ?? {});
492
623
  return element;
493
624
  }
494
625
  function createRowGroup(withRow) {
495
626
  const group = createElement("div", {
496
- className: "tabela__rowgroup",
627
+ className: CSS_TABELA_ROWGROUP,
497
628
  role: "rowgroup"
498
- }, {}, {});
629
+ });
499
630
  if (!(withRow ?? true)) return group;
500
631
  const row = createRow();
501
632
  group.append(row);
@@ -506,12 +637,14 @@ function createRowGroup(withRow) {
506
637
  }
507
638
  function createRow() {
508
639
  return createElement("div", {
509
- className: "tabela__row",
640
+ className: CSS_TABELA_ROW,
510
641
  role: "row"
511
642
  }, {}, { height: "32px" });
512
643
  }
644
+ //#endregion
645
+ //#region src/components/body.component.ts
513
646
  function createFaker() {
514
- return createElement("div", { className: "tabela__faker" }, {}, {});
647
+ return createElement("div", { className: CSS_TABELA_FAKER });
515
648
  }
516
649
  var BodyComponent = class {
517
650
  elements = {
@@ -521,7 +654,7 @@ var BodyComponent = class {
521
654
  constructor() {
522
655
  const group = createRowGroup(false);
523
656
  this.elements.group = group;
524
- group.className += " tabela__rowgroup--body";
657
+ group.className += ` ${CSS_TABELA_ROWGROUP_BODY}`;
525
658
  group.tabIndex = 0;
526
659
  group.setAttribute("data-event", "body");
527
660
  group.append(this.elements.faker);
@@ -531,6 +664,8 @@ var BodyComponent = class {
531
664
  this.elements.group = void 0;
532
665
  }
533
666
  };
667
+ //#endregion
668
+ //#region src/components/footer.component.ts
534
669
  var FooterComponent = class {
535
670
  elements;
536
671
  constructor() {
@@ -540,8 +675,8 @@ var FooterComponent = class {
540
675
  row,
541
676
  cells: []
542
677
  };
543
- group.className += " tabela__rowgroup--footer";
544
- row.className += " tabela__row--footer";
678
+ group.className += ` ${CSS_TABELA_ROWGROUP_FOOTER}`;
679
+ row.className += ` ${CSS_TABELA_ROW_FOOTER}`;
545
680
  }
546
681
  destroy() {
547
682
  this.elements.cells.length = 0;
@@ -555,13 +690,15 @@ var FooterComponent = class {
555
690
  elements.row.innerHTML = "";
556
691
  for (let index = 0; index < length; index += 1) {
557
692
  const cell = createCell(columns[index].options.width ?? 4, false);
558
- cell.className += " tabela__cell--footer";
693
+ cell.className += ` ${CSS_TABELA_CELL_FOOTER}`;
559
694
  cell.innerHTML = "&nbsp;";
560
695
  elements.cells.push(cell);
561
696
  elements.row.append(cell);
562
697
  }
563
698
  }
564
699
  };
700
+ //#endregion
701
+ //#region src/components/header.component.ts
565
702
  var HeaderComponent = class {
566
703
  elements;
567
704
  constructor() {
@@ -570,8 +707,8 @@ var HeaderComponent = class {
570
707
  group,
571
708
  row
572
709
  };
573
- group.className += " tabela__rowgroup--header";
574
- row.className += " tabela__row--header";
710
+ group.className += ` ${CSS_TABELA_ROWGROUP_HEADER}`;
711
+ row.className += ` ${CSS_TABELA_ROW_HEADER}`;
575
712
  }
576
713
  destroy() {
577
714
  this.elements.group = void 0;
@@ -582,6 +719,8 @@ var HeaderComponent = class {
582
719
  this.elements.row.append(...columns.map((column) => column.elements.wrapper));
583
720
  }
584
721
  };
722
+ //#endregion
723
+ //#region src/components/column.component.ts
585
724
  var ColumnComponent = class {
586
725
  elements;
587
726
  options;
@@ -603,17 +742,17 @@ var ColumnComponent = class {
603
742
  };
604
743
  function createHeading(field, title, width) {
605
744
  const wrapper = createElement("div", {
606
- className: "tabela__heading",
745
+ className: CSS_TABELA_HEADING,
607
746
  role: "columnheader"
608
747
  }, {
609
748
  "data-event": "heading",
610
749
  "data-field": field
611
750
  }, { width: `${width}px` });
612
751
  const content = createElement("div", {
613
- className: "tabela__heading__content",
752
+ className: CSS_TABELA_HEADING_CONTENT,
614
753
  textContent: title
615
- }, {}, {});
616
- const sorter = createElement("div", { className: "tabela__heading__sorter" }, {}, {});
754
+ });
755
+ const sorter = createElement("div", { className: CSS_TABELA_HEADING_SORTER });
617
756
  wrapper.append(content, sorter);
618
757
  return {
619
758
  content,
@@ -621,6 +760,8 @@ function createHeading(field, title, width) {
621
760
  wrapper
622
761
  };
623
762
  }
763
+ //#endregion
764
+ //#region src/managers/column.manager.ts
624
765
  var ColumnManager = class {
625
766
  items = [];
626
767
  constructor(state) {
@@ -633,6 +774,9 @@ var ColumnManager = class {
633
774
  this.items = void 0;
634
775
  this.state = void 0;
635
776
  }
777
+ get(field) {
778
+ return this.items.find((item) => item.options.field === field);
779
+ }
636
780
  remove(value) {
637
781
  const { items, state } = this;
638
782
  const { components, managers } = state;
@@ -658,6 +802,31 @@ var ColumnManager = class {
658
802
  footer.update(items);
659
803
  }
660
804
  };
805
+ //#endregion
806
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/array/chunk.mjs
807
+ /**
808
+ * Chunk an array into smaller arrays
809
+ * @param array Array to chunk
810
+ * @param size Size of each chunk _(minimum is `1`, maximum is `5000`; defaults to `5000`)_
811
+ * @returns Array of arrays
812
+ */
813
+ function chunk(array, size) {
814
+ if (!Array.isArray(array)) return [];
815
+ if (array.length === 0) return [];
816
+ const { length } = array;
817
+ const actualSize = typeof size === "number" && size > 0 && size <= MAX_SIZE ? size : MAX_SIZE;
818
+ if (length <= actualSize) return [array];
819
+ const chunks = [];
820
+ let index = 0;
821
+ while (index < length) {
822
+ chunks.push(array.slice(index, index + actualSize));
823
+ index += actualSize;
824
+ }
825
+ return chunks;
826
+ }
827
+ const MAX_SIZE = 5e3;
828
+ //#endregion
829
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/array/callbacks.mjs
661
830
  function getArrayCallback(value) {
662
831
  switch (typeof value) {
663
832
  case "function": return value;
@@ -673,6 +842,8 @@ function getArrayCallbacks(bool, key, value) {
673
842
  value: getArrayCallback(value)
674
843
  };
675
844
  }
845
+ //#endregion
846
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/array/find.mjs
676
847
  function findValues(type, array, parameters, mapper) {
677
848
  const result = {
678
849
  matched: [],
@@ -715,106 +886,14 @@ function getParameters(original) {
715
886
  value: length === 1 && typeof original[0] !== "function" ? original[0] : original[1]
716
887
  };
717
888
  }
718
- var UNIQUE_THRESHOLD = 100;
719
- function filter(array, ...parameters) {
720
- return findValues("all", array, parameters).matched;
721
- }
722
- filter.remove = removeFiltered;
723
- function removeFiltered(array, ...parameters) {
724
- return findValues("all", array, parameters).notMatched;
725
- }
726
- /**
727
- * Is the value a constructor function?
728
- * @param value Value to check
729
- * @returns `true` if the value is a constructor function, otherwise `false`
730
- */
731
- function isConstructor(value) {
732
- return typeof value === "function" && value.prototype?.constructor === value;
733
- }
734
- /**
735
- * Is the value a key?
736
- * @param value Value to check
737
- * @returns `true` if the value is a `Key` _(`number` or `string`)_, otherwise `false`
738
- */
739
- function isKey(value) {
740
- return typeof value === "number" || typeof value === "string";
741
- }
742
- /**
743
- * Is the value a number?
744
- * @param value Value to check
745
- * @returns `true` if the value is a `number`, otherwise `false`
746
- */
747
- function isNumber(value) {
748
- return typeof value === "number" && !Number.isNaN(value);
749
- }
750
- /**
751
- * Is the value a plain object?
752
- * @param value Value to check
753
- * @returns `true` if the value is a plain object, otherwise `false`
754
- */
755
- function isPlainObject(value) {
756
- if (value === null || typeof value !== "object") return false;
757
- if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
758
- const prototype = Object.getPrototypeOf(value);
759
- return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
760
- }
761
- /**
762
- * Is the value a typed array?
763
- * @param value Value to check
764
- * @returns `true` if the value is a typed array, otherwise `false`
765
- */
766
- function isTypedArray(value) {
767
- TYPED_ARRAYS ??= new Set([
768
- Int8Array,
769
- Uint8Array,
770
- Uint8ClampedArray,
771
- Int16Array,
772
- Uint16Array,
773
- Int32Array,
774
- Uint32Array,
775
- Float32Array,
776
- Float64Array,
777
- BigInt64Array,
778
- BigUint64Array
779
- ]);
780
- return TYPED_ARRAYS.has(value?.constructor);
781
- }
782
- var TYPED_ARRAYS;
783
- /**
784
- * Chunk an array into smaller arrays
785
- * @param array Array to chunk
786
- * @param size Size of each chunk _(minimum is `1`, maximum is `5000`; defaults to `5000`)_
787
- * @returns Array of arrays
788
- */
789
- function chunk(array, size) {
790
- if (!Array.isArray(array)) return [];
791
- if (array.length === 0) return [];
792
- const { length } = array;
793
- const actualSize = typeof size === "number" && size > 0 && size <= MAX_SIZE ? size : MAX_SIZE;
794
- if (length <= actualSize) return [array];
795
- const chunks = [];
796
- let index = 0;
797
- while (index < length) {
798
- chunks.push(array.slice(index, index + actualSize));
799
- index += actualSize;
800
- }
801
- return chunks;
802
- }
803
- var MAX_SIZE = 5e3;
804
- function compact(array, strict) {
805
- if (!Array.isArray(array)) return [];
806
- if (strict === true) return array.filter(Boolean);
807
- const { length } = array;
808
- const compacted = [];
809
- for (let index = 0; index < length; index += 1) {
810
- const item = array[index];
811
- if (item != null) compacted.push(item);
812
- }
813
- return compacted;
814
- }
889
+ const UNIQUE_THRESHOLD = 100;
890
+ //#endregion
891
+ //#region node_modules/@oscarpalmer/atoms/dist/array/select.mjs
815
892
  function select(array, ...parameters) {
816
893
  return findValues("all", array, parameters, parameters.pop()).matched;
817
894
  }
895
+ //#endregion
896
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/math/aggregate.mjs
818
897
  function aggregate(type, array, key) {
819
898
  const length = Array.isArray(array) ? array.length : 0;
820
899
  if (length === 0) return {
@@ -853,43 +932,14 @@ function getAggregated(type, array, key) {
853
932
  const aggregated = aggregate(type, array, key);
854
933
  return aggregated.count > 0 ? aggregated.value : NaN;
855
934
  }
856
- var aggregators = {
935
+ const aggregators = {
857
936
  average: calculateSum,
858
937
  max: (current, value, notNumber) => notNumber || value > current ? value : current,
859
938
  min: (current, value, notNumber) => notNumber || value < current ? value : current,
860
939
  sum: calculateSum
861
940
  };
862
- /**
863
- * Get the string value from any value
864
- * @param value Original value
865
- * @returns String representation of the value
866
- */
867
- function getString(value) {
868
- if (typeof value === "string") return value;
869
- if (value == null) return "";
870
- if (typeof value === "function") return getString(value());
871
- if (typeof value !== "object") return String(value);
872
- const asString = String(value.valueOf?.() ?? value);
873
- return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
874
- }
875
- /**
876
- * Join an array of values into a string
877
- * @param value Array of values
878
- * @param delimiter Delimiter to use between values
879
- * @returns Joined string
880
- */
881
- function join(value, delimiter) {
882
- return compact(value).map(getString).join(typeof delimiter === "string" ? delimiter : "");
883
- }
884
- /**
885
- * Split a string into words _(and other readable parts)_
886
- * @param value Original string
887
- * @returns Array of words found in the string
888
- */
889
- function words(value) {
890
- return typeof value === "string" ? value.match(EXPRESSION_WORDS) ?? [] : [];
891
- }
892
- var EXPRESSION_WORDS = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
941
+ //#endregion
942
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/value/handlers.mjs
893
943
  function getCompareHandlers(owner, options) {
894
944
  const { get, register, unregister } = getHandlers(owner, options);
895
945
  return {
@@ -923,6 +973,9 @@ function getHandlers(owner, options) {
923
973
  function isConstructable(value) {
924
974
  return typeof value === "object" && value !== null;
925
975
  }
976
+ //#endregion
977
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/value/compare.mjs
978
+ const COMPARE_NAME = "compare";
926
979
  /**
927
980
  * Compare two values _(for sorting purposes)_
928
981
  * @param first First value
@@ -955,7 +1008,7 @@ compare.handlers = getCompareHandlers(compare, {
955
1008
  callback: (first, second, compareStrings) => {
956
1009
  if (compareStrings) return getString(first).localeCompare(getString(second));
957
1010
  },
958
- method: "compare"
1011
+ method: COMPARE_NAME
959
1012
  });
960
1013
  compare.register = registerComparator;
961
1014
  compare.unregister = unregisterComparator;
@@ -977,7 +1030,7 @@ function unregisterComparator(constructor) {
977
1030
  function compareNumbers(first, second) {
978
1031
  const firstNumber = Number(first);
979
1032
  const secondNumber = Number(second);
980
- if (firstNumber === secondNumber) return 0;
1033
+ if (Object.is(firstNumber, secondNumber)) return 0;
981
1034
  return firstNumber > secondNumber ? 1 : -1;
982
1035
  }
983
1036
  function compareSymbols(first, second) {
@@ -993,12 +1046,14 @@ function getComparisonParts(value) {
993
1046
  if (Array.isArray(value)) return value;
994
1047
  return typeof value === "object" ? [value] : words(getString(value));
995
1048
  }
996
- var comparators$1 = {
1049
+ const comparators$1 = {
997
1050
  bigint: compareNumbers,
998
1051
  boolean: compareNumbers,
999
1052
  number: compareNumbers,
1000
1053
  symbol: compareSymbols
1001
1054
  };
1055
+ //#endregion
1056
+ //#region node_modules/@oscarpalmer/atoms/dist/array/sort.mjs
1002
1057
  function getCallback(value, key, forObject) {
1003
1058
  if (key != null) return;
1004
1059
  if (forObject && typeof value.value === "function") return value.value;
@@ -1031,7 +1086,7 @@ function getSorter(value, modifier) {
1031
1086
  function sort(array, first, second) {
1032
1087
  if (!Array.isArray(array)) return [];
1033
1088
  if (array.length < 2) return array;
1034
- const modifier = (first === true || second === true ? "desc" : "asc") === "asc" ? 1 : -1;
1089
+ const modifier = (first === true || second === true ? "descending" : "ascending") === "ascending" ? 1 : -1;
1035
1090
  const sorters = (Array.isArray(first) ? first : [first]).map((item) => getSorter(item, modifier)).filter((sorter) => sorter != null).filter((current, index, filtered) => filtered.findIndex((next) => next.identifier === current.identifier) === index);
1036
1091
  const { length } = sorters;
1037
1092
  if (length === 0) return array.sort((firstItem, secondItem) => compare(firstItem, secondItem) * modifier);
@@ -1056,6 +1111,8 @@ function sort(array, first, second) {
1056
1111
  return 0;
1057
1112
  });
1058
1113
  }
1114
+ //#endregion
1115
+ //#region node_modules/@oscarpalmer/atoms/dist/array/to-map.mjs
1059
1116
  function getMapValues(array, first, second, arrays) {
1060
1117
  if (!Array.isArray(array)) return /* @__PURE__ */ new Map();
1061
1118
  const { length } = array;
@@ -1080,6 +1137,8 @@ toMap.arrays = toMapArrays;
1080
1137
  function toMapArrays(array, first, second) {
1081
1138
  return getMapValues(array, first, second, true);
1082
1139
  }
1140
+ //#endregion
1141
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/array/group.mjs
1083
1142
  function groupValues(array, key, value, arrays) {
1084
1143
  if (!Array.isArray(array) || array.length === 0) return {};
1085
1144
  const { length } = array;
@@ -1097,6 +1156,8 @@ function groupValues(array, key, value, arrays) {
1097
1156
  }
1098
1157
  return record;
1099
1158
  }
1159
+ //#endregion
1160
+ //#region node_modules/@oscarpalmer/atoms/dist/array/to-record.mjs
1100
1161
  function toRecord(array, first, second) {
1101
1162
  return groupValues(array, first, second, false);
1102
1163
  }
@@ -1104,31 +1165,199 @@ toRecord.arrays = toRecordArrays;
1104
1165
  function toRecordArrays(array, first, second) {
1105
1166
  return groupValues(array, first, second, true);
1106
1167
  }
1168
+ //#endregion
1169
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/function/timer.mjs
1170
+ function getInterval(value) {
1171
+ return typeof value === "number" && value > 0 ? value : 0;
1172
+ }
1173
+ function getTimer(type, callback, time) {
1174
+ const interval = getInterval(time);
1175
+ function run(now) {
1176
+ start ??= now;
1177
+ if (interval === 0 || now - start >= interval - OFFSET) {
1178
+ if (throttle) start = now;
1179
+ callback(...args);
1180
+ } else frame = requestAnimationFrame(run);
1181
+ }
1182
+ const throttle = type === TIMER_THROTTLE;
1183
+ let args;
1184
+ let frame;
1185
+ let start;
1186
+ const timer = (...parameters) => {
1187
+ timer.cancel();
1188
+ args = parameters;
1189
+ frame = requestAnimationFrame(run);
1190
+ };
1191
+ timer.cancel = () => {
1192
+ cancelAnimationFrame(frame);
1193
+ };
1194
+ return timer;
1195
+ }
1196
+ const OFFSET = 5;
1197
+ const TIMER_THROTTLE = "throttle";
1198
+ const TIMER_WAIT = "wait";
1199
+ //#endregion
1200
+ //#region node_modules/@oscarpalmer/atoms/dist/promise/models.mjs
1201
+ const PROMISE_ABORT_EVENT = "abort";
1202
+ const PROMISE_ABORT_OPTIONS = { once: true };
1203
+ //#endregion
1204
+ //#region node_modules/@oscarpalmer/atoms/dist/promise/helpers.mjs
1205
+ function getNumberOrDefault(value) {
1206
+ return typeof value === "number" && value > 0 ? value : 0;
1207
+ }
1208
+ function getPromiseOptions(input) {
1209
+ if (typeof input === "number") return { time: getNumberOrDefault(input) };
1210
+ if (input instanceof AbortSignal) return {
1211
+ signal: input,
1212
+ time: 0
1213
+ };
1214
+ const options = typeof input === "object" && input !== null ? input : {};
1215
+ return {
1216
+ signal: options.signal instanceof AbortSignal ? options.signal : void 0,
1217
+ time: getNumberOrDefault(options.time)
1218
+ };
1219
+ }
1220
+ //#endregion
1221
+ //#region node_modules/@oscarpalmer/atoms/dist/promise/misc.mjs
1222
+ function settlePromise(aborter, settler, value, signal) {
1223
+ signal?.removeEventListener(PROMISE_ABORT_EVENT, aborter);
1224
+ settler(value);
1225
+ }
1226
+ //#endregion
1227
+ //#region node_modules/@oscarpalmer/atoms/dist/promise/delay.mjs
1228
+ function delay(options) {
1229
+ const { signal, time } = getPromiseOptions(options);
1230
+ if (signal?.aborted ?? false) return Promise.reject(signal.reason);
1231
+ function abort() {
1232
+ timer.cancel();
1233
+ rejector(signal.reason);
1234
+ }
1235
+ const timer = getTimer(TIMER_WAIT, () => {
1236
+ settlePromise(abort, resolver, void 0, signal);
1237
+ }, time);
1238
+ signal?.addEventListener(PROMISE_ABORT_EVENT, abort, PROMISE_ABORT_OPTIONS);
1239
+ let rejector;
1240
+ let resolver;
1241
+ return new Promise((resolve, reject) => {
1242
+ rejector = reject;
1243
+ resolver = resolve;
1244
+ if (time === 0) settlePromise(abort, resolve, void 0, signal);
1245
+ else timer();
1246
+ });
1247
+ }
1248
+ //#endregion
1249
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/value/misc.mjs
1250
+ function findKey(needle, haystack) {
1251
+ const keys = Object.keys(haystack);
1252
+ const index = keys.map((key) => key.toLowerCase()).indexOf(needle.toLowerCase());
1253
+ return index > -1 ? keys[index] : needle;
1254
+ }
1255
+ function getNestedValue(data, path, ignoreCase) {
1256
+ if (typeof data !== "object" || data === null || typeof path !== "string" || path.trim().length === 0) return {
1257
+ exists: false,
1258
+ value: void 0
1259
+ };
1260
+ const shouldIgnoreCase = ignoreCase === true;
1261
+ const paths = getPaths(path, shouldIgnoreCase);
1262
+ if (typeof paths === "string") return handleValue(data, paths, null, true, shouldIgnoreCase);
1263
+ const { length } = paths;
1264
+ let current = data;
1265
+ for (let index = 0; index < length; index += 1) {
1266
+ const part = paths[index];
1267
+ const handled = handleValue(current, part, null, true, shouldIgnoreCase);
1268
+ if (!handled.exists) return handled;
1269
+ current = handled.value;
1270
+ }
1271
+ return {
1272
+ exists: true,
1273
+ value: current
1274
+ };
1275
+ }
1276
+ function getPaths(path, lowercase) {
1277
+ const normalized = lowercase ? path.toLowerCase() : path;
1278
+ if (!EXPRESSION_NESTED.test(normalized)) return normalized;
1279
+ return normalized.replace(EXPRESSION_BRACKET, ".$1").replace(EXPRESSION_DOTS, "").split(".");
1280
+ }
1281
+ function handleValue(data, path, value, get, ignoreCase) {
1282
+ if (typeof data === "object" && data !== null && !ignoreKey(path)) {
1283
+ const key = ignoreCase ? findKey(path, data) : path;
1284
+ if (get) return {
1285
+ exists: key in data,
1286
+ value: data[key]
1287
+ };
1288
+ data[key] = typeof value === "function" ? value(data[key]) : value;
1289
+ }
1290
+ if (get) return {
1291
+ exists: false,
1292
+ value: void 0
1293
+ };
1294
+ }
1295
+ const EXPRESSION_BRACKET = /\[(\w+)\]/g;
1296
+ const EXPRESSION_DOTS = /^\.|\.$/g;
1297
+ const EXPRESSION_NESTED = /\.|\[\w+\]/;
1298
+ //#endregion
1299
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/value/get.mjs
1300
+ function getValue(data, path, ignoreCase) {
1301
+ return getNestedValue(data, path, ignoreCase === true).value;
1302
+ }
1303
+ //#endregion
1304
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/value/has.mjs
1305
+ function hasValue(data, path, ignoreCase) {
1306
+ return getNestedValue(data, path, ignoreCase === true).exists;
1307
+ }
1308
+ hasValue.get = getWithHasValue;
1309
+ function getWithHasValue(data, path, ignoreCase) {
1310
+ return getNestedValue(data, path, ignoreCase === true);
1311
+ }
1312
+ //#endregion
1313
+ //#region src/components/group.component.ts
1107
1314
  var GroupComponent = class {
1108
1315
  element;
1109
1316
  expanded = true;
1110
1317
  filtered = 0;
1318
+ key;
1111
1319
  selected = 0;
1112
1320
  total = 0;
1113
- constructor(key, label, value) {
1114
- this.key = key;
1321
+ value;
1322
+ constructor(label, value) {
1115
1323
  this.label = label;
1116
- this.value = value;
1324
+ const stringified = getString(value);
1325
+ this.key = `group:${stringified}`;
1326
+ this.value = {
1327
+ stringified,
1328
+ original: value
1329
+ };
1117
1330
  }
1118
1331
  };
1332
+ function removeGroup(group) {
1333
+ if (group.element == null) return;
1334
+ group.element.innerHTML = "";
1335
+ group.element.remove();
1336
+ }
1119
1337
  function renderGroup(state, component) {
1120
1338
  component.element ??= createElement("div", {
1121
- className: "tabela__row tabela__row--group",
1339
+ className: `${CSS_TABELA_ROW} ${CSS_TABELA_ROW_GROUP}`,
1122
1340
  innerHTML: `<div class="tabela__cell tabela__cell--group" role="cell">
1123
- <button class="tabela__button tabela__button--group" data-event="group" data-key="${component.key}" type="button">
1341
+ <button class="tabela__button tabela__button--group" data-event="group" data-key="tabela_${state.id}_${component.key}" type="button">
1124
1342
  <span aria-hidden="true"></span>
1125
1343
  <span>Open/close</span>
1126
1344
  </button>
1127
1345
  <p>${component.label}</p>
1346
+ <span class="tabela__group__total">${component.total}</span>
1347
+ <span class="tabela__group__selected">${component.selected === 0 ? "" : component.selected}</span>
1128
1348
  </div>`,
1129
1349
  role: "row"
1130
1350
  }, {}, { height: `${state.options.rowHeight}px` });
1131
1351
  }
1352
+ function updateGroup(state, component) {
1353
+ if (component.element == null) return;
1354
+ const selected = component.element.querySelector(".tabela__group__selected");
1355
+ const total = component.element.querySelector(".tabela__group__total");
1356
+ if (selected != null) selected.textContent = component.selected === 0 ? "" : String(component.selected);
1357
+ if (total != null) total.textContent = String(component.total);
1358
+ }
1359
+ //#endregion
1360
+ //#region src/managers/sort.manager.ts
1132
1361
  var SortManager = class {
1133
1362
  handlers = Object.freeze({
1134
1363
  add: (field, direction) => this.add(field, direction),
@@ -1204,7 +1433,7 @@ var SortManager = class {
1204
1433
  });
1205
1434
  setAttribute(column.elements.sorter, "data-sort-position", sorterIndex > -1 && items.length > 1 ? sorterIndex + 1 : void 0);
1206
1435
  }
1207
- state.managers.data.values.keys.active = items.length === 0 ? void 0 : getSortedKeys(state, items);
1436
+ state.managers.data.state.items.active = items.length === 0 ? void 0 : getSortedItems(state, items);
1208
1437
  state.managers.render.update(true, true);
1209
1438
  }
1210
1439
  toggle(event, field, direction) {
@@ -1221,16 +1450,16 @@ var SortManager = class {
1221
1450
  }
1222
1451
  }
1223
1452
  };
1224
- function getSortedKeys(state, sorters) {
1225
- const data = state.managers.data.values.keys.active?.map((key) => key instanceof GroupComponent ? key : state.managers.data.values.objects.mapped.get(key)) ?? state.managers.data.values.objects.array.slice();
1226
- if (!state.managers.group.enabled) return sort(data, sorters).map((item) => item[state.key]);
1227
- return sortWithGroups(state, data, sorters).map((item) => item instanceof GroupComponent ? item : item[state.key]);
1453
+ function getSortedItems(state, sorters) {
1454
+ const data = state.managers.data.state.items.active?.map((key) => key instanceof GroupComponent ? key : state.managers.data.state.values.mapped.get(key)) ?? state.managers.data.state.values.array.slice();
1455
+ if (!state.managers.group.enabled) return sort(data, sorters).map((item) => getValue(item, state.key));
1456
+ return sortWithGroups(state, data, sorters).map((item) => item instanceof GroupComponent ? item : getValue(item, state.key));
1228
1457
  }
1229
1458
  function sortWithGroups(state, data, sorters) {
1230
1459
  const { length } = sorters;
1231
1460
  return data.sort((first, second) => {
1232
- const firstValue = first instanceof GroupComponent ? first.value : first[state.managers.group.field];
1233
- const secondValue = second instanceof GroupComponent ? second.value : second[state.managers.group.field];
1461
+ const firstValue = first instanceof GroupComponent ? first.value.stringified : getValue(first, state.managers.group.field);
1462
+ const secondValue = second instanceof GroupComponent ? second.value.stringified : getValue(second, state.managers.group.field);
1234
1463
  const firstOrder = state.managers.group.order[firstValue];
1235
1464
  const secondOrder = state.managers.group.order[secondValue];
1236
1465
  const groupComparison = compare(firstOrder, secondOrder);
@@ -1240,21 +1469,14 @@ function sortWithGroups(state, data, sorters) {
1240
1469
  if (firstIsGroup || secondIsGroup) return firstIsGroup && secondIsGroup ? 0 : firstIsGroup ? -1 : 1;
1241
1470
  for (let index = 0; index < length; index += 1) {
1242
1471
  const sorter = sorters[index];
1243
- const comparison = compare(first[sorter.key], second[sorter.key]);
1472
+ const comparison = compare(getValue(first, sorter.key), getValue(second, sorter.key));
1244
1473
  if (comparison !== 0) return comparison * (sorter.direction === "ascending" ? 1 : -1);
1245
1474
  }
1246
1475
  return 0;
1247
1476
  });
1248
1477
  }
1249
- /**
1250
- * Is the value `undefined`, `null`, or a whitespace-only string?
1251
- * @param value Value to check
1252
- * @returns `true` if the value is nullable or a whitespace-only string, otherwise `false`
1253
- */
1254
- function isNullableOrWhitespace(value) {
1255
- return value == null || EXPRESSION_WHITESPACE.test(getString(value));
1256
- }
1257
- var EXPRESSION_WHITESPACE = /^\s*$/;
1478
+ //#endregion
1479
+ //#region src/managers/data.manager.ts
1258
1480
  var DataManager = class {
1259
1481
  handlers = Object.freeze({
1260
1482
  add: (data) => void this.add(data, true),
@@ -1264,148 +1486,185 @@ var DataManager = class {
1264
1486
  synchronize: (data, remove) => void this.synchronize(data, remove),
1265
1487
  update: (data) => void this.update(data)
1266
1488
  });
1267
- values = {
1268
- keys: { original: [] },
1269
- objects: {
1270
- mapped: /* @__PURE__ */ new Map(),
1271
- array: []
1272
- }
1273
- };
1274
- get keys() {
1275
- return this.values.keys.active ?? this.values.keys.original;
1489
+ state;
1490
+ get items() {
1491
+ return this.state.items.active ?? this.state.items.original;
1276
1492
  }
1277
1493
  get size() {
1278
- return this.keys.length;
1494
+ return this.items.length;
1279
1495
  }
1280
1496
  constructor(state) {
1281
- this.state = state;
1497
+ this.state = {
1498
+ ...state,
1499
+ items: { original: [] },
1500
+ values: {
1501
+ array: [],
1502
+ mapped: /* @__PURE__ */ new Map()
1503
+ }
1504
+ };
1282
1505
  }
1283
1506
  async add(data, render) {
1284
- const { state, values } = this;
1285
- const { length } = data;
1507
+ const { state } = this;
1508
+ const groups = [];
1286
1509
  const updates = [];
1510
+ let groupColumn;
1511
+ let { length } = data;
1287
1512
  for (let index = 0; index < length; index += 1) {
1288
1513
  const item = data[index];
1289
- const key = item[state.key];
1290
- if (values.objects.mapped.has(key)) {
1514
+ const key = getValue(item, state.key);
1515
+ if (state.values.mapped.has(key)) {
1291
1516
  updates.push(item);
1292
1517
  continue;
1293
1518
  }
1294
- values.objects.array.push(item);
1295
- values.objects.mapped.set(key, item);
1519
+ state.values.array.push(item);
1520
+ state.values.mapped.set(key, item);
1296
1521
  if (!state.managers.group.enabled) continue;
1297
- const groupKey = item[state.managers.group.field];
1298
- let group = state.managers.group.get(groupKey);
1522
+ const groupValue = getValue(item, state.managers.group.field);
1523
+ let group = state.managers.group.get(groupValue);
1299
1524
  if (group == null) {
1300
- group = new GroupComponent(String(groupKey), String(groupKey), groupKey);
1301
- values.objects.array.push(group);
1525
+ groupColumn ??= state.managers.column.get(state.managers.group.field);
1526
+ group = new GroupComponent(`${groupColumn?.options.title ?? state.managers.group.field}: ${groupValue}`, groupValue);
1527
+ state.values.array.push(group);
1302
1528
  state.managers.group.add(group);
1303
1529
  }
1304
1530
  if (!group.expanded) state.managers.group.collapsed.add(key);
1305
1531
  group.total += 1;
1532
+ groups.push(group);
1306
1533
  }
1534
+ length = groups.length;
1535
+ for (let index = 0; index < length; index += 1) updateGroup(state, groups[index]);
1307
1536
  if (updates.length > 0) this.update(updates);
1308
1537
  else if (render) this.render();
1309
1538
  }
1310
1539
  clear() {
1311
- if (this.values.objects.array.length > 0) this.set([]);
1540
+ if (this.state.values.array.length > 0) this.removeItems([], true, true);
1312
1541
  }
1313
1542
  destroy() {
1314
- const { values } = this;
1315
- values.objects.mapped.clear();
1316
- values.keys.active = void 0;
1317
- values.keys.original.length = 0;
1318
- values.objects.array.length = 0;
1543
+ const { state } = this;
1544
+ state.values.mapped.clear();
1545
+ state.items.active = void 0;
1546
+ state.items.original.length = 0;
1547
+ state.values.array.length = 0;
1319
1548
  this.handlers = void 0;
1320
1549
  this.state = void 0;
1321
- this.values = void 0;
1322
1550
  }
1323
1551
  get(active) {
1324
- const { values } = this;
1325
- return active ?? false ? select(values.keys.active ?? [], (key) => !(key instanceof GroupComponent), (key) => values.objects.mapped.get(key)) : values.objects.array.filter((item) => !(item instanceof GroupComponent));
1552
+ const { state } = this;
1553
+ return active ?? false ? select(state.items.active ?? [], (key) => !(key instanceof GroupComponent), (key) => state.values.mapped.get(key)) : state.values.array.filter((item) => !(item instanceof GroupComponent));
1326
1554
  }
1327
- getIndex(key) {
1328
- return this.keys.indexOf(key);
1555
+ getIndex(item) {
1556
+ if (item instanceof GroupComponent) return this.items.indexOf(item);
1557
+ return this.items.findIndex((value) => value instanceof GroupComponent ? value.key === item : value === item);
1329
1558
  }
1330
1559
  async remove(items, render) {
1331
- const { state, values } = this;
1332
- const keys = items.map((value) => isPlainObject(value) ? value[state.key] : value).filter((key) => values.objects.mapped.has(key));
1560
+ const { state } = this;
1561
+ const keys = items.map((value) => isPlainObject(value) ? getValue(value, state.key) : value);
1333
1562
  const { length } = keys;
1334
- if (length === 0) return;
1335
- for (let keyIndex = 0; keyIndex < length; keyIndex += 1) {
1336
- const key = keys[keyIndex];
1337
- values.objects.mapped.delete(key);
1338
- const arrayIndex = values.objects.array.findIndex((item) => !(item instanceof GroupComponent) && item[state.key] === key);
1339
- let item;
1340
- if (arrayIndex > -1) [item] = values.objects.array.splice(arrayIndex, 1);
1341
- values.keys.original.splice(values.keys.original.indexOf(key), 1);
1342
- state.managers.row.remove(key);
1343
- if (!state.managers.group.enabled || item == null) continue;
1344
- state.managers.group.collapsed.delete(key);
1345
- const groupKey = item[state.managers.group.field];
1346
- const group = state.managers.group.get(groupKey);
1347
- if (group == null) continue;
1348
- group.total -= 1;
1349
- if (group.total > 0) continue;
1350
- const groupIndex = values.objects.array.findIndex((item) => item instanceof GroupComponent && item.value === groupKey);
1351
- if (groupIndex > -1) values.objects.array.splice(groupIndex, 1);
1352
- state.managers.group.remove(group);
1563
+ if (length > 0) return this.removeItems(keys, false, render === true);
1564
+ }
1565
+ async removeItems(items, clear, render) {
1566
+ const { state } = this;
1567
+ if (clear) {
1568
+ state.items.active = void 0;
1569
+ state.items.original = [];
1570
+ state.values.array = [];
1571
+ state.values.mapped.clear();
1572
+ state.managers.row.clear();
1573
+ if (state.managers.group.enabled) state.managers.group.clear();
1574
+ return this.render();
1575
+ }
1576
+ const groups = [];
1577
+ const chunked = chunk(items);
1578
+ const chunkedLength = chunked.length;
1579
+ for (let chunkedIndex = 0; chunkedIndex < chunkedLength; chunkedIndex += 1) {
1580
+ const chunk = chunked[chunkedIndex];
1581
+ const chunkLength = chunk.length;
1582
+ for (let itemIndex = 0; itemIndex < chunkLength; itemIndex += 1) {
1583
+ const item = chunk[itemIndex];
1584
+ const dataIndex = state.items.original.indexOf(item);
1585
+ let dataValue;
1586
+ [dataValue] = state.values.array.splice(dataIndex, 1);
1587
+ state.items.original.splice(dataIndex, 1);
1588
+ state.managers.row.remove(item);
1589
+ state.values.mapped.delete(item);
1590
+ if (!state.managers.group.enabled || item instanceof GroupComponent) continue;
1591
+ state.managers.group.collapsed.delete(item);
1592
+ const groupKey = getValue(dataValue, state.managers.group.field);
1593
+ const group = state.managers.group.get(groupKey);
1594
+ if (group == null) continue;
1595
+ group.total -= 1;
1596
+ if (group.total > 0) {
1597
+ groups.push(group);
1598
+ continue;
1599
+ }
1600
+ let groupIndex = groups.indexOf(group);
1601
+ if (groupIndex > -1) groups.splice(groupIndex, 1);
1602
+ groupIndex = state.values.array.indexOf(group);
1603
+ if (groupIndex > -1) {
1604
+ state.items.original.splice(groupIndex, 1);
1605
+ state.values.array.splice(groupIndex, 1);
1606
+ }
1607
+ state.managers.group.remove(group);
1608
+ if (items.length >= 1e4) await delay(25);
1609
+ }
1353
1610
  }
1354
- if (render) this.render();
1611
+ const { length } = groups;
1612
+ for (let index = 0; index < length; index += 1) updateGroup(state, groups[index]);
1613
+ if (render) return this.render();
1355
1614
  }
1356
1615
  render() {
1357
- const { state, values } = this;
1358
- if (state.managers.group.enabled) sortWithGroups(state, values.objects.array, [{
1616
+ const { state } = this;
1617
+ if (state.managers.group.enabled) sortWithGroups(state, state.values.array, [{
1359
1618
  direction: "ascending",
1360
1619
  key: state.key
1361
1620
  }]);
1362
- else sort(values.objects.array, [{
1621
+ else sort(state.values.array, [{
1363
1622
  direction: "ascending",
1364
1623
  key: state.key
1365
1624
  }]);
1366
- values.keys.original = values.objects.array.map((item) => item instanceof GroupComponent ? item : item[state.key]);
1367
- values.objects.mapped = toMap(values.objects.array.filter((item) => !(item instanceof GroupComponent)), (item) => item[state.key]);
1625
+ state.items.original = state.values.array.map((item) => item instanceof GroupComponent ? item : getValue(item, state.key));
1626
+ state.values.mapped = toMap(state.values.array.filter((item) => !(item instanceof GroupComponent)), (item) => getValue(item, state.key));
1368
1627
  if (Object.keys(state.managers.filter.items).length > 0) state.managers.filter.filter();
1369
1628
  else if (state.managers.sort.items.length > 0) state.managers.sort.sort();
1370
1629
  else state.managers.render.update(true, true);
1371
1630
  }
1372
1631
  set(data) {
1373
- const { state, values } = this;
1632
+ const { state } = this;
1374
1633
  const array = data.slice();
1375
1634
  if (state.managers.group.enabled) {
1635
+ const column = state.managers.column.get(state.managers.group.field);
1376
1636
  const grouped = toRecord.arrays(data, state.managers.group.field);
1377
1637
  const entries = Object.entries(grouped);
1378
1638
  const { length } = entries;
1379
1639
  const groups = [];
1380
1640
  for (let index = 0; index < length; index += 1) {
1381
1641
  const [value, items] = entries[index];
1382
- const key = String(value);
1383
- const group = new GroupComponent(key, key, value);
1642
+ const group = new GroupComponent(`${column?.options.title ?? state.managers.group.field}: ${value}`, value);
1384
1643
  group.total = items.length;
1385
1644
  groups.push(group);
1386
1645
  array.push(group);
1387
1646
  }
1388
1647
  state.managers.group.set(groups);
1389
1648
  }
1390
- values.objects.array = array;
1649
+ state.values.array = array;
1391
1650
  this.render();
1392
1651
  }
1393
1652
  async synchronize(data, remove) {
1394
- const { state, values } = this;
1653
+ const { state } = this;
1395
1654
  const add = [];
1396
1655
  const updated = [];
1397
1656
  const keys = /* @__PURE__ */ new Set([]);
1398
1657
  const { length } = data;
1399
1658
  for (let index = 0; index < length; index += 1) {
1400
1659
  const object = data[index];
1401
- const key = object[state.key];
1402
- if (values.objects.mapped.has(key)) updated.push(object);
1660
+ const key = getValue(object, state.key);
1661
+ if (state.values.mapped.has(key)) updated.push(object);
1403
1662
  else add.push(object);
1404
1663
  keys.add(key);
1405
1664
  }
1406
1665
  if (keys.size === 0) return;
1407
1666
  if (remove ?? false) {
1408
- const toRemove = values.keys.original.filter((key) => !(key instanceof GroupComponent) && !keys.has(key));
1667
+ const toRemove = state.items.original.filter((key) => !(key instanceof GroupComponent) && !keys.has(key));
1409
1668
  if (toRemove.length > 0) await this.remove(toRemove, false);
1410
1669
  }
1411
1670
  await this.update(updated);
@@ -1413,14 +1672,14 @@ var DataManager = class {
1413
1672
  if (add.length > 0 || (remove ?? false)) this.render();
1414
1673
  }
1415
1674
  async update(data) {
1416
- const { state, values } = this;
1675
+ const { state } = this;
1417
1676
  const { length } = data;
1418
1677
  for (let index = 0; index < length; index += 1) {
1419
1678
  const object = data[index];
1420
- const key = object[state.key];
1421
- const value = values.objects.mapped.get(key);
1679
+ const key = getValue(object, state.key);
1680
+ const value = state.values.mapped.get(key);
1422
1681
  if (value != null) {
1423
- values.objects.mapped.set(key, {
1682
+ state.values.mapped.set(key, {
1424
1683
  ...value,
1425
1684
  ...object
1426
1685
  });
@@ -1429,6 +1688,8 @@ var DataManager = class {
1429
1688
  }
1430
1689
  }
1431
1690
  };
1691
+ //#endregion
1692
+ //#region node_modules/@oscarpalmer/toretto/dist/event/delegation.mjs
1432
1693
  function addDelegatedHandler(doc, type, name, passive) {
1433
1694
  if (DELEGATED.has(name)) return;
1434
1695
  DELEGATED.add(name);
@@ -1480,11 +1741,11 @@ function removeDelegatedListener(target, name, listener) {
1480
1741
  if (handlers.size === 0) target[name] = void 0;
1481
1742
  return true;
1482
1743
  }
1483
- var DELEGATED = /* @__PURE__ */ new Set();
1484
- var EVENT_PREFIX = "@";
1485
- var EVENT_SUFFIX_ACTIVE = ":active";
1486
- var EVENT_SUFFIX_PASSIVE = ":passive";
1487
- var EVENT_TYPES = new Set([
1744
+ const DELEGATED = /* @__PURE__ */ new Set();
1745
+ const EVENT_PREFIX = "@";
1746
+ const EVENT_SUFFIX_ACTIVE = ":active";
1747
+ const EVENT_SUFFIX_PASSIVE = ":passive";
1748
+ const EVENT_TYPES = new Set([
1488
1749
  "beforeinput",
1489
1750
  "click",
1490
1751
  "dblclick",
@@ -1508,12 +1769,16 @@ var EVENT_TYPES = new Set([
1508
1769
  "touchmove",
1509
1770
  "touchstart"
1510
1771
  ]);
1511
- var HANDLER_ACTIVE = delegatedEventHandler.bind(false);
1512
- var HANDLER_PASSIVE = delegatedEventHandler.bind(true);
1772
+ const HANDLER_ACTIVE = delegatedEventHandler.bind(false);
1773
+ const HANDLER_PASSIVE = delegatedEventHandler.bind(true);
1774
+ //#endregion
1775
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/function/misc.mjs
1513
1776
  /**
1514
1777
  * A function that does nothing, which can be useful, I guess…
1515
1778
  */
1516
1779
  function noop() {}
1780
+ //#endregion
1781
+ //#region node_modules/@oscarpalmer/toretto/dist/event/index.mjs
1517
1782
  function createEventOptions(options) {
1518
1783
  return {
1519
1784
  capture: getBoolean(options?.capture),
@@ -1553,6 +1818,8 @@ function on(target, type, listener, options) {
1553
1818
  target.removeEventListener(type, listener, extended);
1554
1819
  };
1555
1820
  }
1821
+ //#endregion
1822
+ //#region node_modules/@oscarpalmer/toretto/dist/find/relative.mjs
1556
1823
  function findAncestor(origin, selector) {
1557
1824
  const element = getElement(origin);
1558
1825
  if (element == null || selector == null) return null;
@@ -1573,6 +1840,8 @@ function getElement(origin) {
1573
1840
  if (origin instanceof Element) return origin;
1574
1841
  return origin instanceof Event && origin.target instanceof Element ? origin.target : void 0;
1575
1842
  }
1843
+ //#endregion
1844
+ //#region src/managers/event.manager.ts
1576
1845
  var EventManager = class {
1577
1846
  constructor(state) {
1578
1847
  this.state = state;
@@ -1590,7 +1859,7 @@ var EventManager = class {
1590
1859
  };
1591
1860
  function onClick(event) {
1592
1861
  const target = findAncestor(event, "[data-event]");
1593
- const table = findAncestor(event, ".tabela");
1862
+ const table = findAncestor(event, ".tabela__table");
1594
1863
  if (!(target instanceof HTMLElement) || !(table instanceof HTMLElement)) return;
1595
1864
  const manager = mapped$1.get(table);
1596
1865
  if (manager == null) return;
@@ -1609,210 +1878,21 @@ function onClick(event) {
1609
1878
  }
1610
1879
  function onKeydown(event) {
1611
1880
  const target = findAncestor(event, "[data-event]");
1612
- const table = findAncestor(event, ".tabela");
1881
+ const table = findAncestor(event, ".tabela__table");
1613
1882
  if (!(target instanceof HTMLElement) || !(table instanceof HTMLElement)) return;
1614
1883
  const manager = mapped$1.get(table);
1615
1884
  if (manager == null) return;
1616
- switch (target?.getAttribute("data-event")) {
1617
- case "body":
1618
- manager.state.managers.navigation.handle(event);
1619
- break;
1620
- default: break;
1885
+ if (event.key === " ") {
1886
+ event.preventDefault();
1887
+ return;
1621
1888
  }
1889
+ manager.state.managers.navigation.handle(event);
1622
1890
  }
1623
1891
  const mapped$1 = /* @__PURE__ */ new WeakMap();
1624
1892
  on(document, "click", onClick);
1625
1893
  on(document, "keydown", onKeydown, { passive: false });
1626
- /**
1627
- * Clamp a number between a minimum and maximum value
1628
- * @param value Value to clamp
1629
- * @param minimum Minimum value
1630
- * @param maximum Maximum value
1631
- * @param loop If `true`, the value will loop around when smaller than the minimum or larger than the maximum _(defaults to `false`)_
1632
- * @returns Clamped value
1633
- */
1634
- function clamp(value, minimum, maximum, loop) {
1635
- if (![
1636
- value,
1637
- minimum,
1638
- maximum
1639
- ].every(isNumber)) return NaN;
1640
- if (value < minimum) return loop === true ? maximum : minimum;
1641
- return value > maximum ? loop === true ? minimum : maximum : value;
1642
- }
1643
- /**
1644
- * Get the number value from an unknown value _(based on Lodash)_
1645
- * @param value Original value
1646
- * @returns Original value as a number, or `NaN` if the value is unable to be parsed
1647
- */
1648
- function getNumber(value) {
1649
- if (typeof value === "number") return value;
1650
- if (typeof value === "bigint" || typeof value === "boolean") return Number(value);
1651
- if (value == null || typeof value === "symbol") return NaN;
1652
- if (typeof value === "function") return getNumber(value());
1653
- let parsed = value.valueOf();
1654
- if (typeof parsed === "object") parsed = parsed.toString();
1655
- if (typeof parsed !== "string") return getNumber(parsed);
1656
- const trimmed = parsed.trim();
1657
- if (trimmed.length === 0) return NaN;
1658
- if (EXPRESSION_ZEROISH.test(parsed)) return 0;
1659
- const isBinary = EXPRESSION_BINARY.test(trimmed);
1660
- if (isBinary || EXPRESSION_OCTAL.test(trimmed)) return Number.parseInt(trimmed.slice(2), isBinary ? 2 : OCTAL_VALUE);
1661
- return Number(EXPRESSION_HEX.test(trimmed) ? trimmed : trimmed.replace(EXPRESSION_UNDERSCORE, ""));
1662
- }
1663
- var EXPRESSION_BINARY = /^0b[01]+$/i;
1664
- var EXPRESSION_HEX = /^0x[0-9a-f]+$/i;
1665
- var EXPRESSION_OCTAL = /^0o[0-7]+$/i;
1666
- var EXPRESSION_UNDERSCORE = /_/g;
1667
- var EXPRESSION_ZEROISH = /^\s*0+\s*$/;
1668
- var OCTAL_VALUE = 8;
1669
- function getSizedMaximum(first, second) {
1670
- let actual;
1671
- if (typeof first === "number") actual = first;
1672
- else actual = typeof second === "number" ? second : MAXIMUM_DEFAULT;
1673
- return clamp(actual, 1, MAXIMUM_ABSOLUTE);
1674
- }
1675
- var MAXIMUM_ABSOLUTE = 16777216;
1676
- var MAXIMUM_DEFAULT = 1048576;
1677
- /**
1678
- * A Map with a maximum size
1679
- *
1680
- * Behavior is similar to a _LRU_-cache, where the least recently used entries are removed
1681
- */
1682
- var SizedMap = class extends Map {
1683
- /**
1684
- * The maximum size of the Map
1685
- */
1686
- #maximumSize;
1687
- /**
1688
- * Is the Map full?
1689
- */
1690
- get full() {
1691
- return this.size >= this.#maximumSize;
1692
- }
1693
- get maximum() {
1694
- return this.#maximumSize;
1695
- }
1696
- constructor(first, second) {
1697
- const maximum = getSizedMaximum(first, second);
1698
- super();
1699
- this.#maximumSize = maximum;
1700
- if (Array.isArray(first)) {
1701
- const { length } = first;
1702
- if (length <= maximum) for (let index = 0; index < length; index += 1) this.set(...first[index]);
1703
- else for (let index = 0; index < maximum; index += 1) this.set(...first[length - maximum + index]);
1704
- }
1705
- }
1706
- /**
1707
- * @inheritdoc
1708
- */
1709
- get(key) {
1710
- const value = super.get(key);
1711
- if (value !== void 0 || this.has(key)) this.set(key, value);
1712
- return value;
1713
- }
1714
- /**
1715
- * @inheritdoc
1716
- */
1717
- set(key, value) {
1718
- if (this.has(key)) this.delete(key);
1719
- else if (this.size >= this.#maximumSize) this.delete(this.keys().next().value);
1720
- return super.set(key, value);
1721
- }
1722
- };
1723
- var Memoized = class {
1724
- #state;
1725
- /**
1726
- * Maximum cache size
1727
- */
1728
- get maximum() {
1729
- return this.#state.cache?.maximum ?? NaN;
1730
- }
1731
- /**
1732
- * Current cache size
1733
- */
1734
- get size() {
1735
- return this.#state.cache?.size ?? NaN;
1736
- }
1737
- constructor(callback, options) {
1738
- const cache = new SizedMap(options.cacheSize);
1739
- const getter = (...parameters) => {
1740
- const key = options.cacheKey?.(...parameters) ?? (parameters.length === 1 ? parameters[0] : join(parameters.map(getString), "_"));
1741
- if (cache.has(key)) return cache.get(key);
1742
- const value = callback(...parameters);
1743
- cache.set(key, value);
1744
- return value;
1745
- };
1746
- this.#state = {
1747
- cache,
1748
- getter
1749
- };
1750
- }
1751
- /**
1752
- * Clear the cache
1753
- */
1754
- clear() {
1755
- this.#state.cache?.clear();
1756
- }
1757
- /**
1758
- * Delete a result from the cache
1759
- * @param key Key to delete
1760
- * @returns `true` if the key existed and was removed, otherwise `false`
1761
- */
1762
- delete(key) {
1763
- return this.#state.cache?.delete(key) ?? false;
1764
- }
1765
- /**
1766
- * Destroy the instance _(clearing its cache and removing its callback)_
1767
- */
1768
- destroy() {
1769
- this.#state.cache?.clear();
1770
- this.#state.cache = void 0;
1771
- this.#state.getter = void 0;
1772
- }
1773
- /**
1774
- * Get a result from the cache
1775
- * @param key Key to get
1776
- * @returns Cached result or `undefined` if it does not exist
1777
- */
1778
- get(key) {
1779
- return this.#state.cache?.get(key);
1780
- }
1781
- /**
1782
- * Does the result exist?
1783
- * @param key Key to check
1784
- * @returns `true` if the result exists, otherwise `false`
1785
- */
1786
- has(key) {
1787
- return this.#state.cache?.has(key) ?? false;
1788
- }
1789
- /**
1790
- * Run the callback with the provided parameters
1791
- * @param parameters Parameters to pass to the callback
1792
- * @returns Cached or computed _(then cached)_ result
1793
- */
1794
- run(...parameters) {
1795
- if (this.#state.cache == null || this.#state.getter == null) throw new Error("The Memoized instance has been destroyed");
1796
- return this.#state.getter(...parameters);
1797
- }
1798
- };
1799
- function getMemoizationOptions(input) {
1800
- const { cacheKey, cacheSize } = isPlainObject(input) ? input : {};
1801
- return {
1802
- cacheKey: typeof cacheKey === "function" ? cacheKey : void 0,
1803
- cacheSize: typeof cacheSize === "number" && cacheSize > 0 ? cacheSize : DEFAULT_CACHE_SIZE
1804
- };
1805
- }
1806
- /**
1807
- * Memoize a function, caching and retrieving results based on the first parameter
1808
- * @param callback Callback to memoize
1809
- * @param options Memoization options
1810
- * @returns Memoized instance
1811
- */
1812
- function memoize(callback, options) {
1813
- return new Memoized(callback, getMemoizationOptions(options));
1814
- }
1815
- var DEFAULT_CACHE_SIZE = 1024;
1894
+ //#endregion
1895
+ //#region node_modules/@oscarpalmer/atoms/dist/string/match.mjs
1816
1896
  /**
1817
1897
  * Check if a string ends with a specified substring
1818
1898
  * @param haystack String to look in
@@ -1821,7 +1901,7 @@ var DEFAULT_CACHE_SIZE = 1024;
1821
1901
  * @returns `true` if the string ends with the given substring, otherwise `false`
1822
1902
  */
1823
1903
  function endsWith(haystack, needle, ignoreCase) {
1824
- return match("endsWith", haystack, needle, ignoreCase === true);
1904
+ return match(MATCH_ENDS_WITH, haystack, needle, ignoreCase === true);
1825
1905
  }
1826
1906
  /**
1827
1907
  * Check if a string includes a specified substring
@@ -1831,7 +1911,7 @@ function endsWith(haystack, needle, ignoreCase) {
1831
1911
  * @returns `true` if the string includes the given substring, otherwise `false`
1832
1912
  */
1833
1913
  function includes(haystack, needle, ignoreCase) {
1834
- return match("includes", haystack, needle, ignoreCase === true);
1914
+ return match(MATCH_INCLUDES, haystack, needle, ignoreCase === true);
1835
1915
  }
1836
1916
  function match(type, haystack, needle, ignoreCase) {
1837
1917
  if (typeof haystack !== "string" || typeof needle !== "string") return false;
@@ -1849,9 +1929,14 @@ function matchCallback(haystack, needle, ignoreCase) {
1849
1929
  * @returns `true` if the string starts with the given substring, otherwise `false`
1850
1930
  */
1851
1931
  function startsWith(haystack, needle, ignoreCase) {
1852
- return match("startsWith", haystack, needle, ignoreCase === true);
1853
- }
1854
- var matchMemoizers = {};
1932
+ return match(MATCH_STARTS_WITH, haystack, needle, ignoreCase === true);
1933
+ }
1934
+ const MATCH_ENDS_WITH = "endsWith";
1935
+ const MATCH_INCLUDES = "includes";
1936
+ const MATCH_STARTS_WITH = "startsWith";
1937
+ const matchMemoizers = {};
1938
+ //#endregion
1939
+ //#region node_modules/@oscarpalmer/atoms/dist/internal/value/equal.mjs
1855
1940
  function equal(first, second, options) {
1856
1941
  return equalValue(first, second, getEqualOptions(options));
1857
1942
  }
@@ -1948,9 +2033,9 @@ function equalValue(first, second, options) {
1948
2033
  case first instanceof ArrayBuffer && second instanceof ArrayBuffer: return equalArrayBuffer(first, second, options);
1949
2034
  case first instanceof Date && second instanceof Date: return Object.is(Number(first), Number(second));
1950
2035
  case first instanceof DataView && second instanceof DataView: return equalDataView(first, second, options);
1951
- case first instanceof Error && second instanceof Error: return equalProperties(first, second, ["name", "message"], options);
2036
+ case first instanceof Error && second instanceof Error: return equalProperties(first, second, ERROR_PROPERTIES, options);
1952
2037
  case first instanceof Map && second instanceof Map: return equalMap(first, second, options);
1953
- case first instanceof RegExp && second instanceof RegExp: return equalProperties(first, second, ["source", "flags"], options);
2038
+ case first instanceof RegExp && second instanceof RegExp: return equalProperties(first, second, EXPRESSION_PROPERTIES, options);
1954
2039
  case first instanceof Set && second instanceof Set: return equalSet(first, second, options);
1955
2040
  case Array.isArray(first) && Array.isArray(second): return equalArray(first, second, options);
1956
2041
  case isPlainObject(first) && isPlainObject(second): return equalPlainObject(first, second, options);
@@ -2017,8 +2102,12 @@ function getEqualOptions(input) {
2017
2102
  options.relaxedNullish = input.relaxedNullish === true;
2018
2103
  return options;
2019
2104
  }
2020
- var ARRAY_PEEK_PERCENTAGE = 10;
2021
- var ARRAY_THRESHOLD = 100;
2105
+ const ARRAY_PEEK_PERCENTAGE = 10;
2106
+ const ARRAY_THRESHOLD = 100;
2107
+ const ERROR_PROPERTIES = ["name", "message"];
2108
+ const EXPRESSION_PROPERTIES = ["source", "flags"];
2109
+ //#endregion
2110
+ //#region src/managers/filter.manager.ts
2022
2111
  var FilterManager = class {
2023
2112
  handlers = Object.freeze({
2024
2113
  add: (item) => this.add(item),
@@ -2032,7 +2121,7 @@ var FilterManager = class {
2032
2121
  }
2033
2122
  add(item) {
2034
2123
  if (this.items[item.field] == null) this.items[item.field] = [];
2035
- else if (this.items[item.field].findIndex((existing) => equal(existing, item)) !== -1) return;
2124
+ else if (this.items[item.field].findIndex((existing) => equal(existing, item)) > -1) return;
2036
2125
  this.items[item.field].push(item);
2037
2126
  this.filter();
2038
2127
  }
@@ -2051,14 +2140,14 @@ var FilterManager = class {
2051
2140
  const { state } = this;
2052
2141
  const filtered = [];
2053
2142
  const filters = Object.entries(this.items);
2054
- const keysLength = state.managers.data.values.keys.original.length;
2055
- rowLoop: for (let keyIndex = 0; keyIndex < keysLength; keyIndex += 1) {
2056
- const key = state.managers.data.values.keys.original[keyIndex];
2057
- if (key instanceof GroupComponent) {
2058
- filtered.push(key);
2143
+ const itemsLength = state.managers.data.state.items.original.length;
2144
+ rowLoop: for (let itemIndex = 0; itemIndex < itemsLength; itemIndex += 1) {
2145
+ const item = state.managers.data.state.items.original[itemIndex];
2146
+ if (item instanceof GroupComponent) {
2147
+ filtered.push(item);
2059
2148
  continue;
2060
2149
  }
2061
- const row = state.managers.data.values.objects.mapped.get(key);
2150
+ const row = state.managers.data.state.values.mapped.get(item);
2062
2151
  if (row == null) continue;
2063
2152
  filterLoop: for (let filterIndex = 0; filterIndex < filters.length; filterIndex += 1) {
2064
2153
  const [field, items] = filters[filterIndex];
@@ -2069,16 +2158,23 @@ var FilterManager = class {
2069
2158
  }
2070
2159
  continue rowLoop;
2071
2160
  }
2072
- filtered.push(key);
2161
+ filtered.push(item);
2073
2162
  }
2074
- state.managers.data.values.keys.active = filtered;
2163
+ state.managers.data.state.items.active = filtered;
2075
2164
  if (state.managers.sort.items.length > 0) state.managers.sort.sort();
2076
2165
  else state.managers.render.update(true, true);
2077
2166
  }
2078
2167
  remove(value) {
2079
2168
  if (typeof value === "string") {
2080
2169
  if (this.items[value] == null) return;
2081
- this.items = {};
2170
+ const keyed = {};
2171
+ const filters = Object.keys(this.items);
2172
+ const { length } = filters;
2173
+ for (let index = 0; index < length; index += 1) {
2174
+ const field = filters[index];
2175
+ if (field !== value) keyed[field] = this.items[field];
2176
+ }
2177
+ this.items = keyed;
2082
2178
  } else {
2083
2179
  const { field } = value;
2084
2180
  if (this.items[field] == null) return;
@@ -2111,10 +2207,18 @@ const comparators = {
2111
2207
  "starts-with": (row, filter) => startsWith(getString(row), getString(filter), true)
2112
2208
  };
2113
2209
  const equalizer = equal.initialize({ ignoreCase: true });
2210
+ //#endregion
2211
+ //#region src/managers/group.manager.ts
2114
2212
  var GroupManager = class {
2115
2213
  collapsed = /* @__PURE__ */ new Set();
2116
2214
  enabled = false;
2117
2215
  field;
2216
+ handlers = Object.freeze({ set: (group) => {
2217
+ if (group === this.field) return;
2218
+ this.enabled = !isNullableOrWhitespace(group);
2219
+ this.field = group ?? "";
2220
+ this.state.managers.data.set(this.state.managers.data.get());
2221
+ } });
2118
2222
  items = [];
2119
2223
  order = {};
2120
2224
  constructor(state) {
@@ -2126,39 +2230,60 @@ var GroupManager = class {
2126
2230
  add(group) {
2127
2231
  this.set([...this.items, group]);
2128
2232
  }
2233
+ clear() {
2234
+ const groups = this.items.splice(0);
2235
+ const { length } = groups;
2236
+ for (let index = 0; index < length; index += 1) this.remove(groups[index]);
2237
+ }
2238
+ destroy() {
2239
+ const groups = this.items.splice(0);
2240
+ const { length } = groups;
2241
+ for (let index = 0; index < length; index += 1) removeGroup(groups[index]);
2242
+ this.collapsed.clear();
2243
+ this.handlers = void 0;
2244
+ this.state = void 0;
2245
+ }
2129
2246
  get(value) {
2130
- return this.items.find((item) => item.value === value);
2247
+ const asString = getString(value);
2248
+ return this.items.find((item) => item.value.stringified === asString);
2131
2249
  }
2132
2250
  handle(button) {
2133
- const key = button.dataset.key;
2134
- const group = this.get(key);
2251
+ const value = button.dataset.key?.replace(`tabela_${this.state.id}_group:`, "");
2252
+ const group = this.get(value);
2135
2253
  if (group == null) return;
2136
2254
  const { collapsed, items, state } = this;
2137
2255
  group.expanded = !group.expanded;
2138
2256
  const index = items.indexOf(group);
2139
- let first = state.managers.data.values.keys.original.indexOf(items[index]) + 1;
2140
- const last = items[index + 1] == null ? state.managers.data.keys.length - 1 : state.managers.data.values.keys.original.indexOf(items[index + 1]) - 1;
2257
+ let first = state.managers.data.state.items.original.indexOf(items[index]) + 1;
2258
+ const last = items[index + 1] == null ? state.managers.data.state.items.original.length - 1 : state.managers.data.state.items.original.indexOf(items[index + 1]) - 1;
2141
2259
  for (; first <= last; first += 1) {
2142
- const key = state.managers.data.values.keys.original[first];
2260
+ const key = state.managers.data.state.items.original[first];
2143
2261
  if (group.expanded) collapsed.delete(key);
2144
2262
  else collapsed.add(key);
2145
2263
  }
2146
- state.managers.render.update(true, true);
2264
+ if (Object.keys(state.managers.filter.items).length > 0) state.managers.filter.filter();
2265
+ else if (state.managers.sort.items.length > 0) state.managers.sort.sort();
2266
+ else state.managers.render.update(true, true);
2147
2267
  }
2148
2268
  remove(group) {
2269
+ removeGroup(group);
2149
2270
  this.set(this.items.filter((item) => item !== group));
2150
2271
  }
2151
2272
  set(items) {
2152
2273
  this.items = sort(items, (item) => item.label);
2153
- this.order = toRecord(items, "value", (_, index) => index);
2274
+ this.order = toRecord(items, (group) => group.value.stringified, (_, index) => index);
2154
2275
  }
2155
2276
  };
2277
+ //#endregion
2278
+ //#region src/helpers/misc.helpers.ts
2156
2279
  function getKey(value) {
2157
2280
  if (typeof value === "number") return value;
2158
2281
  if (typeof value !== "string") return;
2159
2282
  return integerExpression.test(value) ? Number.parseInt(value, 10) : value;
2160
2283
  }
2161
2284
  const integerExpression = /^\d+$/;
2285
+ //#endregion
2286
+ //#region src/managers/navigation.manager.ts
2162
2287
  var NavigationManager = class {
2163
2288
  active;
2164
2289
  constructor(state) {
@@ -2172,28 +2297,28 @@ var NavigationManager = class {
2172
2297
  event.preventDefault();
2173
2298
  const { components, id, managers } = this.state;
2174
2299
  const activeDescendant = components.body.elements.group.getAttribute("aria-activedescendant");
2175
- const { keys } = managers.data;
2176
- const { length } = keys;
2300
+ const { items } = managers.data;
2301
+ const { length } = items;
2177
2302
  let next;
2178
2303
  if (isNullableOrWhitespace(activeDescendant)) next = getDefaultIndex(event.key, length);
2179
- else next = getIndex(event, activeDescendant, id, keys);
2180
- if (next != null) this.setActive(keys.at(next));
2304
+ else next = getIndex(this.state, event, activeDescendant, id);
2305
+ if (next != null) this.setActive(items.at(next));
2181
2306
  }
2182
- setActive(key, scroll) {
2183
- const { components, managers, options } = this.state;
2184
- this.active = key;
2307
+ setActive(item, scroll) {
2308
+ const { components, id, managers, options } = this.state;
2309
+ this.active = item;
2185
2310
  const active = components.body.elements.group.querySelectorAll("[data-active=\"true\"]");
2186
2311
  for (const item of active) item.setAttribute("data-active", "false");
2187
- const row = managers.row.get(key);
2188
- if (row != null) {
2189
- row.element?.setAttribute("data-active", "true");
2190
- if (scroll ?? true) if (row.element == null) components.body.elements.group.scrollTo({
2191
- top: managers.data.getIndex(key) * options.rowHeight,
2312
+ const component = item instanceof GroupComponent ? item : managers.row.get(item, false);
2313
+ if (component != null) {
2314
+ component.element?.setAttribute("data-active", "true");
2315
+ if (scroll ?? true) if (component.element == null) components.body.elements.group.scrollTo({
2316
+ top: managers.data.getIndex(item) * options.rowHeight,
2192
2317
  behavior: "smooth"
2193
2318
  });
2194
- else row.element.scrollIntoView({ block: "nearest" });
2319
+ else component.element.scrollIntoView({ block: "nearest" });
2195
2320
  }
2196
- components.body.elements.group.setAttribute("aria-activedescendant", row == null ? "" : `tabela_${this.state.id}_row_${key}`);
2321
+ components.body.elements.group.setAttribute("aria-activedescendant", component == null ? "" : `tabela_${id}_${component.key}`);
2197
2322
  }
2198
2323
  };
2199
2324
  function getDefaultIndex(key, max) {
@@ -2204,11 +2329,11 @@ function getDefaultIndex(key, max) {
2204
2329
  default: return 0;
2205
2330
  }
2206
2331
  }
2207
- function getIndex(event, active, id, keys) {
2208
- const key = getKey(active.replace(`tabela_${id}_row_`, ""));
2332
+ function getIndex(state, event, active, id) {
2333
+ const key = getKey(active.replace(`tabela_${id}_`, ""));
2209
2334
  if (key == null) return;
2210
- if (absoluteKeys.has(event.key)) return event.key === "Home" ? 0 : keys.length - 1;
2211
- return clamp(keys.indexOf(key) + getOffset(event.key), 0, keys.length - 1, true);
2335
+ if (absoluteKeys.has(event.key)) return event.key === "Home" ? 0 : state.managers.data.size - 1;
2336
+ return clamp(state.managers.data.getIndex(key) + getOffset(event.key), 0, state.managers.data.size - 1, true);
2212
2337
  }
2213
2338
  function getOffset(key) {
2214
2339
  switch (key) {
@@ -2228,6 +2353,8 @@ const allKeys = new Set([
2228
2353
  ...arrowKeys,
2229
2354
  ...pageKeys
2230
2355
  ]);
2356
+ //#endregion
2357
+ //#region src/components/row.component.ts
2231
2358
  function removeRow(pool, row) {
2232
2359
  if (row.element != null) {
2233
2360
  row.element.innerHTML = "";
@@ -2248,20 +2375,20 @@ function renderRow(state, row) {
2248
2375
  "data-active": String(state.managers.navigation.active === row.key),
2249
2376
  "data-event": "row",
2250
2377
  "data-key": key,
2251
- id: `tabela_${state.id}_row_${key}`
2378
+ id: `tabela_${state.id}_${key}`
2252
2379
  });
2253
- element.classList.add("tabela__row--body");
2254
- if (selected) element.classList.add("tabela__row--selected");
2255
- else element.classList.remove("tabela__row--selected");
2380
+ element.classList.add(CSS_TABELA_ROW_BODY);
2381
+ if (selected) element.classList.add(CSS_TABELA_ROW_SELECTED);
2382
+ else element.classList.remove(CSS_TABELA_ROW_SELECTED);
2256
2383
  const columns = state.managers.column.items;
2257
2384
  const { length } = columns;
2258
- const data = state.managers.data.values.objects.mapped.get(row.key);
2385
+ const data = state.managers.data.state.values.mapped.get(row.key);
2259
2386
  if (data == null) return;
2260
2387
  for (let index = 0; index < length; index += 1) {
2261
2388
  const { options } = columns[index];
2262
2389
  state.managers.render.pool.cells[options.field] ??= [];
2263
2390
  const cell = state.managers.render.pool.cells[columns[index].options.field].shift() ?? createCell(options.width);
2264
- cell.textContent = String(data[options.field]);
2391
+ cell.textContent = String(getValue(data, options.field));
2265
2392
  row.cells[options.field] = cell;
2266
2393
  element.append(cell);
2267
2394
  }
@@ -2273,17 +2400,21 @@ var RowComponent = class {
2273
2400
  this.key = key;
2274
2401
  }
2275
2402
  };
2403
+ //#endregion
2404
+ //#region src/managers/render.manager.ts
2276
2405
  function getRange(state, down) {
2277
- const { components, managers, options } = state;
2278
- const { clientHeight, scrollTop } = components.body.elements.group;
2279
- const { keys } = managers.data;
2280
- const first = Math.floor(scrollTop / options.rowHeight);
2281
- const last = Math.min(keys.length - managers.group.collapsed.size - 1, Math.ceil((scrollTop + clientHeight) / options.rowHeight) - 1);
2282
- const before = Math.ceil(clientHeight / options.rowHeight) * (down ? 1 : 2);
2283
- const after = Math.ceil(clientHeight / options.rowHeight) * (down ? 2 : 1);
2284
- const start = Math.max(0, first - before);
2406
+ const { element, managers, options } = state;
2407
+ const { clientHeight, scrollTop } = element;
2408
+ const { items } = managers.data;
2409
+ const firstIndex = Math.floor(scrollTop / options.rowHeight);
2410
+ const lastIndex = items.length - managers.group.collapsed.size - 1;
2411
+ const last = Math.min(lastIndex, Math.ceil((scrollTop + clientHeight) / options.rowHeight) - 1);
2412
+ const visible = clientHeight / options.rowHeight;
2413
+ const before = Math.ceil(visible) * (down ? 1 : 2);
2414
+ const after = Math.ceil(visible) * (down ? 2 : 1);
2415
+ const start = Math.max(0, firstIndex - before);
2285
2416
  return {
2286
- end: Math.min(keys.length - managers.group.collapsed.size - 1, last + after),
2417
+ end: Math.min(lastIndex, last + after),
2287
2418
  start
2288
2419
  };
2289
2420
  }
@@ -2291,7 +2422,7 @@ function onScroll() {
2291
2422
  const { state } = this;
2292
2423
  if (!state.active) {
2293
2424
  requestAnimationFrame(() => {
2294
- const top = state.components.body.elements.group.scrollTop;
2425
+ const top = state.element.scrollTop;
2295
2426
  this.update(top > state.top);
2296
2427
  state.active = false;
2297
2428
  state.top = top;
@@ -2309,7 +2440,7 @@ var RenderManager = class {
2309
2440
  state;
2310
2441
  visible = /* @__PURE__ */ new Map();
2311
2442
  constructor(state) {
2312
- this.listener = on(state.components.body.elements.group, "scroll", onScroll.bind(this));
2443
+ this.listener = on(state.element, "scroll", onScroll.bind(this));
2313
2444
  this.state = {
2314
2445
  ...state,
2315
2446
  active: false,
@@ -2320,6 +2451,11 @@ var RenderManager = class {
2320
2451
  const { listener, pool, visible } = this;
2321
2452
  listener();
2322
2453
  visible.clear();
2454
+ const cells = Object.values(pool.cells).flat();
2455
+ let { length } = cells;
2456
+ for (let index = 0; index < length; index += 1) cells[index].remove();
2457
+ length = pool.rows.length;
2458
+ for (let index = 0; index < length; index += 1) pool.rows[index].remove();
2323
2459
  pool.cells = {};
2324
2460
  pool.rows = [];
2325
2461
  this.fragment = void 0;
@@ -2334,7 +2470,7 @@ var RenderManager = class {
2334
2470
  for (let index = 0; index < length; index += 1) delete pool.cells[fields[index]];
2335
2471
  for (const [, key] of visible) {
2336
2472
  if (key instanceof GroupComponent) continue;
2337
- const row = state.managers.row.get(key);
2473
+ const row = state.managers.row.get(key, false);
2338
2474
  if (row == null || row.element == null) continue;
2339
2475
  for (let index = 0; index < length; index += 1) {
2340
2476
  row.cells[fields[index]].innerHTML = "";
@@ -2364,38 +2500,38 @@ var RenderManager = class {
2364
2500
  }
2365
2501
  continue;
2366
2502
  }
2367
- const row = managers.row.get(key);
2503
+ const row = managers.row.get(key, false);
2368
2504
  if (remove || row == null || !indices.has(index) || managers.group.collapsed.has(key)) {
2369
2505
  visible.delete(index);
2370
2506
  if (row != null) removeRow(pool, row);
2371
2507
  }
2372
2508
  }
2373
2509
  const fragment = this.getFragment();
2374
- const { keys } = managers.data;
2510
+ const { items } = managers.data;
2375
2511
  let count = 0;
2376
2512
  let offset = 0;
2377
2513
  for (let index = range.start; index <= range.end + offset; index += 1) {
2378
2514
  if (visible.has(index)) continue;
2379
- const key = keys[index];
2380
- if (key instanceof GroupComponent) {
2515
+ const item = items[index];
2516
+ if (item instanceof GroupComponent) {
2381
2517
  count += 1;
2382
- renderGroup(state, key);
2383
- visible.set(index, key);
2384
- if (key.element != null) {
2385
- key.element.style.transform = `translateY(${(index - offset) * options.rowHeight}px)`;
2386
- fragment.append(key.element);
2518
+ renderGroup(state, item);
2519
+ visible.set(index, item);
2520
+ if (item.element != null) {
2521
+ item.element.style.transform = `translateY(${(index - offset) * options.rowHeight}px)`;
2522
+ fragment.append(item.element);
2387
2523
  }
2388
2524
  continue;
2389
2525
  }
2390
- const row = managers.row.get(key);
2526
+ const row = managers.row.get(item, true);
2391
2527
  if (row == null) continue;
2392
- if (managers.group.collapsed.has(key)) {
2528
+ if (managers.group.collapsed.has(item)) {
2393
2529
  offset += 1;
2394
2530
  continue;
2395
2531
  }
2396
2532
  count += 1;
2397
2533
  renderRow(state, row);
2398
- visible.set(index, key);
2534
+ visible.set(index, item);
2399
2535
  if (row.element != null) {
2400
2536
  row.element.style.transform = `translateY(${(index - offset) * options.rowHeight}px)`;
2401
2537
  fragment.append(row.element);
@@ -2404,22 +2540,28 @@ var RenderManager = class {
2404
2540
  if (count > 0) components.body.elements.group[down ? "append" : "prepend"](fragment);
2405
2541
  }
2406
2542
  };
2543
+ //#endregion
2544
+ //#region src/managers/row.manager.ts
2407
2545
  var RowManager = class {
2408
2546
  components = /* @__PURE__ */ new Map();
2409
2547
  constructor(state) {
2410
2548
  this.state = state;
2411
2549
  }
2550
+ clear() {
2551
+ const { components } = this;
2552
+ const rows = [...components.values()];
2553
+ const { length } = rows;
2554
+ for (let index = 0; index < length; index += 1) this.removeRow(rows[index]);
2555
+ components.clear();
2556
+ }
2412
2557
  destroy() {
2413
- const components = [...this.components.values()];
2414
- const { length } = components;
2415
- for (let index = 0; index < length; index += 1) removeRow(this.state.managers.render.pool, components[index]);
2416
- this.components.clear();
2558
+ this.clear();
2417
2559
  this.components = void 0;
2418
2560
  this.state = void 0;
2419
2561
  }
2420
- get(key) {
2562
+ get(key, create) {
2421
2563
  let row = this.components.get(key);
2422
- if (row == null) {
2564
+ if (row == null && create) {
2423
2565
  row = new RowComponent(key);
2424
2566
  this.components.set(key, row);
2425
2567
  }
@@ -2430,20 +2572,25 @@ var RowManager = class {
2430
2572
  }
2431
2573
  remove(key) {
2432
2574
  const row = this.components.get(key);
2433
- if (row != null) {
2434
- removeRow(this.state.managers.render.pool, row);
2435
- this.components.delete(key);
2436
- }
2575
+ if (row != null) this.removeRow(row);
2576
+ }
2577
+ removeRow(row) {
2578
+ if (row.element != null) removeRow(this.state.managers.render.pool, row);
2579
+ this.components.delete(row.key);
2437
2580
  }
2438
2581
  update(key) {
2439
2582
  const row = this.components.get(key);
2440
2583
  if (row != null) renderRow(this.state, row);
2441
2584
  }
2442
2585
  };
2443
- const dragStyling = toggleStyles(document.body, {
2586
+ //#endregion
2587
+ //#region src/helpers/style.helper.ts
2588
+ const preventSelection = toggleStyles(document.body, {
2444
2589
  userSelect: "none",
2445
2590
  webkitUserSelect: "none"
2446
2591
  });
2592
+ //#endregion
2593
+ //#region src/managers/selection.manager.ts
2447
2594
  var SelectionManager = class {
2448
2595
  handlers = Object.freeze({
2449
2596
  add: (keys) => this.add(keys),
@@ -2507,15 +2654,15 @@ var SelectionManager = class {
2507
2654
  const fromKey = keyed ? from : getKey(from.getAttribute("data-key"));
2508
2655
  const toKey = keyed ? to : getKey(to.getAttribute("data-key"));
2509
2656
  if (fromKey === toKey) return;
2510
- const { keys } = state.managers.data;
2657
+ const { items } = state.managers.data;
2511
2658
  const fromIndex = state.managers.data.getIndex(fromKey);
2512
2659
  const toIndex = state.managers.data.getIndex(toKey);
2513
2660
  if (fromIndex === -1 || toIndex === -1) return;
2514
2661
  const [start, end] = fromIndex < toIndex ? [fromIndex, toIndex] : [toIndex, fromIndex];
2515
2662
  const selected = [];
2516
2663
  for (let index = start; index <= end; index += 1) {
2517
- const key = keys[index];
2518
- if (!(key instanceof GroupComponent)) selected.push(key);
2664
+ const item = items[index];
2665
+ if (!(item instanceof GroupComponent)) selected.push(item);
2519
2666
  }
2520
2667
  if (keyed) this.add(selected);
2521
2668
  else this.set(selected);
@@ -2541,11 +2688,12 @@ var SelectionManager = class {
2541
2688
  }
2542
2689
  toggle() {
2543
2690
  const { items, state } = this;
2544
- const { keys } = state.managers.data;
2545
- if (items.size === keys.length - state.managers.group.items.length) this.clear();
2546
- else this.set(keys.filter((key) => !(key instanceof GroupComponent)));
2691
+ const data = state.managers.data.items;
2692
+ if (items.size === data.length - state.managers.group.items.length) this.clear();
2693
+ else this.set(data.filter((key) => !(key instanceof GroupComponent)));
2547
2694
  }
2548
2695
  update(removed) {
2696
+ const { state } = this;
2549
2697
  const items = [...removed.map((key) => ({
2550
2698
  key,
2551
2699
  removed: true
@@ -2553,28 +2701,28 @@ var SelectionManager = class {
2553
2701
  key,
2554
2702
  removed: false
2555
2703
  }))];
2556
- const { length } = items;
2704
+ let { length } = items;
2557
2705
  for (let index = 0; index < length; index += 1) {
2558
2706
  const { key, removed } = items[index];
2559
- const row = this.state.managers.row.get(key);
2560
- if (row == null || row.element == null) continue;
2561
- setAttribute(row.element, "aria-selected", String(!removed));
2562
- if (removed) row.element.classList.remove("tabela__row--selected");
2563
- else row.element.classList.add("tabela__row--selected");
2707
+ const element = state.managers.row.get(key, false)?.element;
2708
+ if (element == null) continue;
2709
+ setAttribute(element, "aria-selected", String(!removed));
2710
+ if (removed) element.classList.remove(CSS_TABELA_ROW_SELECTED);
2711
+ else element.classList.add(CSS_TABELA_ROW_SELECTED);
2564
2712
  }
2565
2713
  }
2566
2714
  };
2567
2715
  function getPlaceholder() {
2568
- placeholder ??= createElement("div", { className: "tabela__selection--placeholder" }, {}, {});
2716
+ placeholder ??= createElement("div", { className: CSS_TABELA_SELECTION }, {}, {});
2569
2717
  return placeholder;
2570
2718
  }
2571
2719
  function onMouseDown(event) {
2572
2720
  if (shifted) {
2573
- const row = findAncestor(event.target, ".tabela__row--body");
2721
+ const row = findAncestor(event.target, `.${CSS_TABELA_ROW_BODY}`);
2574
2722
  if (!(row instanceof HTMLElement)) return;
2575
2723
  startElement = row;
2576
2724
  startPosition = getPosition(event);
2577
- dragStyling.set();
2725
+ preventSelection.set();
2578
2726
  }
2579
2727
  }
2580
2728
  function onMouseMove(event) {
@@ -2595,14 +2743,14 @@ function onMouseUp(event) {
2595
2743
  if (startElement == null) return;
2596
2744
  if (!event.shiftKey) {
2597
2745
  shifted = false;
2598
- dragStyling.remove();
2746
+ preventSelection.remove();
2599
2747
  }
2600
2748
  getPlaceholder().remove();
2601
2749
  const row = findAncestor(event.target, ".tabela__row--body");
2602
2750
  if (row instanceof HTMLElement) {
2603
2751
  endElement = row;
2604
- const endTable = findAncestor(endElement, ".tabela");
2605
- const startTable = findAncestor(startElement, ".tabela");
2752
+ const endTable = findAncestor(endElement, ".tabela__table");
2753
+ const startTable = findAncestor(startElement, ".tabela__table");
2606
2754
  if (startTable != null && startTable === endTable) mapped.get(startTable)?.range(startElement, endElement);
2607
2755
  }
2608
2756
  endElement = void 0;
@@ -2629,14 +2777,161 @@ on(document, "keyup", onShiftUp);
2629
2777
  on(document, "mousedown", onMouseDown);
2630
2778
  on(document, "mousemove", onMouseMove);
2631
2779
  on(document, "mouseup", onMouseUp);
2780
+ //#endregion
2781
+ //#region src/managers/style.manager.ts
2782
+ var StyleManager = class {
2783
+ constructor(state) {
2784
+ this.state = state;
2785
+ if (appended) return;
2786
+ appended = true;
2787
+ const style = document.createElement("style");
2788
+ style.textContent = styling;
2789
+ document.head.appendChild(style);
2790
+ }
2791
+ };
2792
+ const styling = `/** Table */
2793
+
2794
+ :where(.tabela) {
2795
+ flex: 1;
2796
+ position: relative;
2797
+ background-color: var(--oui-absolute);
2798
+ border: 1px solid grey;
2799
+ }
2800
+
2801
+ :where(.tabela__table) {
2802
+ min-height: 24em;
2803
+ display: flex;
2804
+ flex-flow: column nowrap;
2805
+ flex: 1;
2806
+ overflow: auto;
2807
+ position: absolute;
2808
+ inset: 0;
2809
+ }
2810
+
2811
+ /** Row group */
2812
+
2813
+ :where(.tabela__rowgroup--header),
2814
+ :where(.tabela__rowgroup--footer) {
2815
+ background-color: white;
2816
+ position: sticky;
2817
+ left: 0;
2818
+ z-index: 10;
2819
+ }
2820
+
2821
+ :where(.tabela__rowgroup--header) {
2822
+ top: 0;
2823
+ }
2824
+
2825
+ :where(.tabela__rowgroup--footer) {
2826
+ bottom: 0;
2827
+ }
2828
+
2829
+ :where(.tabela__rowgroup--body) {
2830
+ display: flex;
2831
+ flex-flow: column nowrap;
2832
+ flex: 1;
2833
+ }
2834
+
2835
+ :where(.tabela__rowgroup--body:focus) {
2836
+ outline: none;
2837
+ }
2838
+
2839
+ :where(.tabela:has(.tabela__rowgroup--body:focus-visible)) {
2840
+ outline: 2px solid var(--oui-blue-6);
2841
+ outline-offset: 2px;
2842
+ }
2843
+
2844
+ /** Row */
2845
+
2846
+ :where(.tabela__row) {
2847
+ width: 100%;
2848
+ display: flex;
2849
+ flex-flow: row nowrap;
2850
+ }
2851
+
2852
+ :where(.tabela__row:last-child .tabela__cell) {
2853
+ border-bottom-width: 0;
2854
+ }
2855
+
2856
+ :where(.tabela__row--body),
2857
+ :where(.tabela__row--group) {
2858
+ flex: 1;
2859
+ position: absolute;
2860
+ }
2861
+
2862
+ :where(.tabela__row--selected) {
2863
+ background-color: var(--oui-blue-1);
2864
+ color: var(--oui-blue-9);
2865
+ }
2866
+
2867
+ :where(.tabela:has(.tabela__rowgroup--body:focus-visible) .tabela__row[data-active="true"]) {
2868
+ outline: 2px solid var(--oui-blue-6);
2869
+ outline-offset: 2px;
2870
+ }
2871
+
2872
+ /** Cells */
2873
+
2874
+ :where(.tabela__cell),
2875
+ :where(.tabela__heading) {
2876
+ padding: 0.5em;
2877
+ border-color: gray;
2878
+ border-style: solid;
2879
+ border-width: 0 1px 1px 0;
2880
+ line-height: 1;
2881
+ }
2882
+
2883
+ :where(.tabela__row .tabela__cell:last-child),
2884
+ :where(.tabela__row .tabela__heading:last-child) {
2885
+ flex: 1;
2886
+ border-right-width: 0;
2887
+ }
2888
+
2889
+ :where(.tabela__cell) {
2890
+ overflow: hidden;
2891
+ text-overflow: ellipsis;
2892
+ white-space: nowrap;
2893
+ }
2894
+
2895
+ :where(.tabela__cell--footer) {
2896
+ border-top-width: 1px;
2897
+ border-bottom-width: 0;
2898
+ }
2899
+
2900
+ :where(.tabela__cell--group) {
2901
+ padding: 0;
2902
+ display: flex;
2903
+ flex-flow: row nowrap;
2904
+ align-items: center;
2905
+ gap: 0.5em;
2906
+ }
2907
+
2908
+ :where(.tabela__cell--group .tabela__button) {
2909
+ margin: 0 0 0 .25rem;
2910
+ }
2911
+
2912
+ /** Misc. */
2913
+
2914
+ :where(.tabela__button) {
2915
+ font-size: .75rem;
2916
+ font-weight: bold;
2917
+ }
2918
+
2919
+ :where(.tabela__selection) {
2920
+ background-color: color-mix(in oklch, var(--oui-blue-6), transparent);
2921
+ border: 1px solid var(--oui-blue-6);
2922
+ border-radius: .25rem;
2923
+ position: fixed;
2924
+ z-index: 1000;
2925
+ }
2926
+ `.replace(/^\s+|\s+|\s+$/g, " ");
2927
+ let appended = false;
2928
+ //#endregion
2929
+ //#region src/tabela.ts
2632
2930
  var Tabela = class {
2633
- #components = {
2634
- header: void 0,
2635
- body: void 0,
2636
- footer: void 0
2637
- };
2931
+ #components;
2638
2932
  #element;
2639
2933
  #id = getId();
2934
+ #table;
2640
2935
  #key;
2641
2936
  #managers = {
2642
2937
  column: void 0,
@@ -2648,10 +2943,13 @@ var Tabela = class {
2648
2943
  render: void 0,
2649
2944
  row: void 0,
2650
2945
  selection: void 0,
2651
- sort: void 0
2946
+ sort: void 0,
2947
+ style: void 0
2652
2948
  };
2949
+ #state;
2653
2950
  data;
2654
2951
  filter;
2952
+ group;
2655
2953
  selection;
2656
2954
  sort;
2657
2955
  get key() {
@@ -2660,35 +2958,42 @@ var Tabela = class {
2660
2958
  constructor(element, options) {
2661
2959
  this.#element = element;
2662
2960
  element.innerHTML = "";
2663
- element.role = "table";
2664
- element.classList.add("tabela");
2665
- element.setAttribute("aria-label", options.label);
2961
+ element.classList.add(CSS_TABELA);
2962
+ this.#table = createElement("div", {
2963
+ className: CSS_TABELA_TABLE,
2964
+ role: "table"
2965
+ }, { "aria-label": options.label });
2666
2966
  this.#key = options.key;
2667
- this.#components.header = new HeaderComponent();
2668
- this.#components.body = new BodyComponent();
2669
- this.#components.footer = new FooterComponent();
2670
- const state = {
2671
- element,
2967
+ this.#components = {
2968
+ body: new BodyComponent(),
2969
+ footer: new FooterComponent(),
2970
+ header: new HeaderComponent()
2971
+ };
2972
+ this.#state = {
2672
2973
  options,
2673
2974
  components: this.#components,
2975
+ element: this.#table,
2674
2976
  id: this.#id,
2675
2977
  key: this.#key,
2676
2978
  managers: this.#managers
2677
2979
  };
2678
- this.#managers.column = new ColumnManager(state);
2679
- this.#managers.data = new DataManager(state);
2680
- this.#managers.event = new EventManager(state);
2681
- this.#managers.filter = new FilterManager(state);
2682
- this.#managers.group = new GroupManager(state);
2683
- this.#managers.navigation = new NavigationManager(state);
2684
- this.#managers.render = new RenderManager(state);
2685
- this.#managers.row = new RowManager(state);
2686
- this.#managers.selection = new SelectionManager(state);
2687
- this.#managers.sort = new SortManager(state);
2688
- element.append(this.#components.header.elements.group, this.#components.body.elements.group, this.#components.footer.elements.group);
2980
+ this.#managers.column = new ColumnManager(this.#state);
2981
+ this.#managers.data = new DataManager(this.#state);
2982
+ this.#managers.event = new EventManager(this.#state);
2983
+ this.#managers.filter = new FilterManager(this.#state);
2984
+ this.#managers.group = new GroupManager(this.#state);
2985
+ this.#managers.navigation = new NavigationManager(this.#state);
2986
+ this.#managers.render = new RenderManager(this.#state);
2987
+ this.#managers.row = new RowManager(this.#state);
2988
+ this.#managers.selection = new SelectionManager(this.#state);
2989
+ this.#managers.sort = new SortManager(this.#state);
2990
+ this.#managers.style = new StyleManager(this.#state);
2991
+ this.#table.append(this.#components.header.elements.group, this.#components.body.elements.group, this.#components.footer.elements.group);
2992
+ element.append(this.#table);
2689
2993
  this.#managers.data.set(options.data);
2690
2994
  this.data = this.#managers.data.handlers;
2691
2995
  this.filter = this.#managers.filter.handlers;
2996
+ this.group = this.#managers.group.handlers;
2692
2997
  this.selection = this.#managers.selection.handlers;
2693
2998
  this.sort = this.#managers.sort.handlers;
2694
2999
  }
@@ -2696,6 +3001,7 @@ var Tabela = class {
2696
3001
  const components = this.#components;
2697
3002
  const managers = this.#managers;
2698
3003
  const element = this.#element;
3004
+ const table = this.#table;
2699
3005
  components.body.destroy();
2700
3006
  components.footer.destroy();
2701
3007
  components.header.destroy();
@@ -2703,16 +3009,24 @@ var Tabela = class {
2703
3009
  managers.data.destroy();
2704
3010
  managers.event.destroy();
2705
3011
  managers.filter.destroy();
3012
+ managers.group.destroy();
3013
+ managers.navigation.destroy();
2706
3014
  managers.render.destroy();
2707
3015
  managers.row.destroy();
2708
3016
  managers.selection.destroy();
2709
3017
  managers.sort.destroy();
2710
3018
  element.innerHTML = "";
2711
- element.role = "";
2712
- element.classList.remove("tabela");
2713
- element.removeAttribute("aria-label");
2714
- element.removeAttribute("role");
3019
+ table.innerHTML = "";
3020
+ table.role = "";
3021
+ element.classList.remove(CSS_TABELA);
3022
+ table.removeAttribute("aria-label");
3023
+ table.removeAttribute("role");
3024
+ this.#state.components = void 0;
3025
+ this.#state.managers = void 0;
3026
+ this.#state.element = void 0;
3027
+ this.#state.options = void 0;
2715
3028
  this.#element = void 0;
3029
+ this.#table = void 0;
2716
3030
  }
2717
3031
  };
2718
3032
  function getId() {
@@ -2720,7 +3034,10 @@ function getId() {
2720
3034
  return id;
2721
3035
  }
2722
3036
  let id = 0;
3037
+ //#endregion
3038
+ //#region src/index.ts
2723
3039
  function tabela(element, options) {
2724
3040
  return new Tabela(element, options);
2725
3041
  }
3042
+ //#endregion
2726
3043
  export { tabela };