@oscarpalmer/tabela 0.12.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tabela.full.js +146 -18
- package/package.json +45 -37
- package/src/components/body.component.ts +11 -7
- package/src/components/column.component.ts +23 -24
- package/src/components/footer.component.ts +7 -5
- package/src/components/group.component.ts +73 -9
- package/src/components/header.component.ts +6 -4
- package/src/components/row.component.ts +28 -18
- package/src/helpers/dom.helpers.ts +27 -29
- package/src/helpers/misc.helpers.ts +5 -0
- package/src/helpers/style.helper.ts +1 -1
- package/src/managers/column.manager.ts +4 -0
- package/src/managers/data.manager.ts +197 -124
- package/src/managers/event.manager.ts +27 -17
- package/src/managers/filter.manager.ts +49 -25
- package/src/managers/group.manager.ts +73 -12
- package/src/managers/navigation.manager.ts +48 -50
- package/src/managers/render.manager.ts +56 -29
- package/src/managers/row.manager.ts +22 -10
- package/src/managers/selection.manager.ts +40 -31
- package/src/managers/sort.manager.ts +58 -43
- package/src/managers/style.manager.ts +171 -0
- package/src/models/column.model.ts +2 -6
- package/src/models/data.model.ts +12 -10
- package/src/models/dom.model.ts +33 -0
- package/src/models/event.model.ts +7 -0
- package/src/models/filter.model.ts +20 -0
- package/src/models/group.model.ts +10 -2
- package/src/models/sort.model.ts +4 -0
- package/src/models/style.model.ts +51 -0
- package/src/models/tabela.model.ts +11 -8
- package/src/tabela.ts +67 -37
- package/types/components/body.component.d.ts +0 -6
- package/types/components/column.component.d.ts +0 -13
- package/types/components/footer.component.d.ts +0 -8
- package/types/components/group.component.d.ts +0 -14
- package/types/components/header.component.d.ts +0 -8
- package/types/components/row.component.d.ts +0 -11
- package/types/helpers/dom.helpers.d.ts +0 -10
- package/types/helpers/misc.helpers.d.ts +0 -2
- package/types/helpers/style.helper.d.ts +0 -1
- package/types/index.d.ts +0 -4
- package/types/managers/column.manager.d.ts +0 -12
- package/types/managers/data.manager.d.ts +0 -29
- package/types/managers/event.manager.d.ts +0 -7
- package/types/managers/filter.manager.d.ts +0 -19
- package/types/managers/group.manager.d.ts +0 -17
- package/types/managers/navigation.manager.d.ts +0 -10
- package/types/managers/render.manager.d.ts +0 -17
- package/types/managers/row.manager.d.ts +0 -13
- package/types/managers/selection.manager.d.ts +0 -24
- package/types/managers/sort.manager.d.ts +0 -28
- package/types/models/body.model.d.ts +0 -4
- package/types/models/column.model.d.ts +0 -13
- package/types/models/data.model.d.ts +0 -24
- package/types/models/filter.model.d.ts +0 -13
- package/types/models/footer.model.d.ts +0 -5
- package/types/models/group.model.d.ts +0 -4
- package/types/models/header.model.d.ts +0 -4
- package/types/models/render.model.d.ts +0 -13
- package/types/models/selection.model.d.ts +0 -8
- package/types/models/sort.model.d.ts +0 -12
- package/types/models/tabela.model.d.ts +0 -39
- package/types/models/tabela.options.d.ts +0 -10
- package/types/tabela.d.ts +0 -15
package/dist/tabela.full.js
CHANGED
|
@@ -485,10 +485,11 @@ function createCell(width, body) {
|
|
|
485
485
|
}
|
|
486
486
|
function createElement(tagName, properties, attributes, style) {
|
|
487
487
|
const element = document.createElement(tagName);
|
|
488
|
-
const
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
488
|
+
const props = properties ?? {};
|
|
489
|
+
const keys = Object.keys(props);
|
|
490
|
+
for (const key of keys) element[key] = props[key];
|
|
491
|
+
setAttributes(element, attributes ?? {});
|
|
492
|
+
setStyles(element, style ?? {});
|
|
492
493
|
return element;
|
|
493
494
|
}
|
|
494
495
|
function createRowGroup(withRow) {
|
|
@@ -673,6 +674,26 @@ function getArrayCallbacks(bool, key, value) {
|
|
|
673
674
|
value: getArrayCallback(value)
|
|
674
675
|
};
|
|
675
676
|
}
|
|
677
|
+
function findValue(type, array, parameters) {
|
|
678
|
+
const findIndex = type === FIND_VALUE_INDEX;
|
|
679
|
+
if (!Array.isArray(array) || array.length === 0) return findIndex ? -1 : void 0;
|
|
680
|
+
const { bool, key, value } = getParameters(parameters);
|
|
681
|
+
const callbacks = getArrayCallbacks(bool, key);
|
|
682
|
+
if (callbacks?.bool == null && callbacks?.keyed == null) return findIndex ? array.indexOf(value) : array.find((item) => Object.is(item, value));
|
|
683
|
+
if (callbacks.bool != null) {
|
|
684
|
+
const index = array.findIndex(callbacks.bool);
|
|
685
|
+
return findIndex ? index : array[index];
|
|
686
|
+
}
|
|
687
|
+
return findValueInArray(array, callbacks.keyed, value, findIndex);
|
|
688
|
+
}
|
|
689
|
+
function findValueInArray(array, callback, value, findIndex) {
|
|
690
|
+
const { length } = array;
|
|
691
|
+
for (let index = 0; index < length; index += 1) {
|
|
692
|
+
const item = array[index];
|
|
693
|
+
if (Object.is(callback?.(item, index, array), value)) return findIndex ? index : item;
|
|
694
|
+
}
|
|
695
|
+
return findIndex ? -1 : void 0;
|
|
696
|
+
}
|
|
676
697
|
function findValues(type, array, parameters, mapper) {
|
|
677
698
|
const result = {
|
|
678
699
|
matched: [],
|
|
@@ -715,6 +736,7 @@ function getParameters(original) {
|
|
|
715
736
|
value: length === 1 && typeof original[0] !== "function" ? original[0] : original[1]
|
|
716
737
|
};
|
|
717
738
|
}
|
|
739
|
+
var FIND_VALUE_INDEX = "index";
|
|
718
740
|
var UNIQUE_THRESHOLD = 100;
|
|
719
741
|
function filter(array, ...parameters) {
|
|
720
742
|
return findValues("all", array, parameters).matched;
|
|
@@ -812,6 +834,48 @@ function compact(array, strict) {
|
|
|
812
834
|
}
|
|
813
835
|
return compacted;
|
|
814
836
|
}
|
|
837
|
+
function indexOf(array, ...parameters) {
|
|
838
|
+
return findValue(FIND_VALUE_INDEX, array, parameters);
|
|
839
|
+
}
|
|
840
|
+
function getName(start, haystack, needle) {
|
|
841
|
+
if (start === 0) return haystack === needle ? POSITION_SAME : POSITION_START;
|
|
842
|
+
return start + needle === haystack ? POSITION_END : POSITION_INSIDE;
|
|
843
|
+
}
|
|
844
|
+
function getPosition$1(haystack, needle, key) {
|
|
845
|
+
if (!Array.isArray(haystack) || !Array.isArray(needle)) return invalid;
|
|
846
|
+
const haystackLength = haystack.length;
|
|
847
|
+
const needleLength = needle.length;
|
|
848
|
+
if (haystackLength === 0 || needleLength === 0) return outside;
|
|
849
|
+
if (needleLength > haystackLength) return outside;
|
|
850
|
+
const callback = getArrayCallback(key);
|
|
851
|
+
const limit = haystackLength - needleLength + 1;
|
|
852
|
+
let needleValues = callback == null ? needle : needle.slice();
|
|
853
|
+
if (callback != null) for (let needleIndex = 0; needleIndex < needleLength; needleIndex += 1) needleValues[needleIndex] = callback(needle[needleIndex], needleIndex, needle);
|
|
854
|
+
for (let haystackIndex = 0; haystackIndex < limit; haystackIndex += 1) {
|
|
855
|
+
let haystackItem = haystack[haystackIndex];
|
|
856
|
+
let haystackValue = callback?.(haystackItem, haystackIndex, haystack) ?? haystackItem;
|
|
857
|
+
if (!Object.is(haystackValue, needleValues[0])) continue;
|
|
858
|
+
if (needleLength === 1) return [haystackIndex, getName(haystackIndex, haystackLength, needleLength)];
|
|
859
|
+
for (let needleIndex = 1; needleIndex < needleLength; needleIndex += 1) {
|
|
860
|
+
haystackItem = haystack[haystackIndex + needleIndex];
|
|
861
|
+
haystackValue = callback?.(haystackItem, haystackIndex + needleIndex, haystack) ?? haystackItem;
|
|
862
|
+
if (!Object.is(haystackValue, needleValues[needleIndex])) break;
|
|
863
|
+
if (needleIndex === needleLength - 1) return [haystackIndex, getName(haystackIndex, haystackLength, needleLength)];
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
return outside;
|
|
867
|
+
}
|
|
868
|
+
function indexOfArray(haystack, needle, key) {
|
|
869
|
+
return getPosition$1(haystack, needle, key)[0];
|
|
870
|
+
}
|
|
871
|
+
var POSITION_END = "end";
|
|
872
|
+
var POSITION_INSIDE = "inside";
|
|
873
|
+
var POSITION_INVALID = "invalid";
|
|
874
|
+
var POSITION_OUTSIDE = "outside";
|
|
875
|
+
var POSITION_SAME = "same";
|
|
876
|
+
var POSITION_START = "start";
|
|
877
|
+
var invalid = [-1, POSITION_INVALID];
|
|
878
|
+
var outside = [-1, POSITION_OUTSIDE];
|
|
815
879
|
function select(array, ...parameters) {
|
|
816
880
|
return findValues("all", array, parameters, parameters.pop()).matched;
|
|
817
881
|
}
|
|
@@ -923,6 +987,7 @@ function getHandlers(owner, options) {
|
|
|
923
987
|
function isConstructable(value) {
|
|
924
988
|
return typeof value === "object" && value !== null;
|
|
925
989
|
}
|
|
990
|
+
var COMPARE_NAME = "compare";
|
|
926
991
|
/**
|
|
927
992
|
* Compare two values _(for sorting purposes)_
|
|
928
993
|
* @param first First value
|
|
@@ -955,7 +1020,7 @@ compare.handlers = getCompareHandlers(compare, {
|
|
|
955
1020
|
callback: (first, second, compareStrings) => {
|
|
956
1021
|
if (compareStrings) return getString(first).localeCompare(getString(second));
|
|
957
1022
|
},
|
|
958
|
-
method:
|
|
1023
|
+
method: COMPARE_NAME
|
|
959
1024
|
});
|
|
960
1025
|
compare.register = registerComparator;
|
|
961
1026
|
compare.unregister = unregisterComparator;
|
|
@@ -977,7 +1042,7 @@ function unregisterComparator(constructor) {
|
|
|
977
1042
|
function compareNumbers(first, second) {
|
|
978
1043
|
const firstNumber = Number(first);
|
|
979
1044
|
const secondNumber = Number(second);
|
|
980
|
-
if (firstNumber
|
|
1045
|
+
if (Object.is(firstNumber, secondNumber)) return 0;
|
|
981
1046
|
return firstNumber > secondNumber ? 1 : -1;
|
|
982
1047
|
}
|
|
983
1048
|
function compareSymbols(first, second) {
|
|
@@ -1031,7 +1096,7 @@ function getSorter(value, modifier) {
|
|
|
1031
1096
|
function sort(array, first, second) {
|
|
1032
1097
|
if (!Array.isArray(array)) return [];
|
|
1033
1098
|
if (array.length < 2) return array;
|
|
1034
|
-
const modifier = (first === true || second === true ? "
|
|
1099
|
+
const modifier = (first === true || second === true ? "descending" : "ascending") === "ascending" ? 1 : -1;
|
|
1035
1100
|
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
1101
|
const { length } = sorters;
|
|
1037
1102
|
if (length === 0) return array.sort((firstItem, secondItem) => compare(firstItem, secondItem) * modifier);
|
|
@@ -1056,6 +1121,56 @@ function sort(array, first, second) {
|
|
|
1056
1121
|
return 0;
|
|
1057
1122
|
});
|
|
1058
1123
|
}
|
|
1124
|
+
function swap(array, first, second, third) {
|
|
1125
|
+
if (!Array.isArray(array)) return [];
|
|
1126
|
+
if (array.length === 0) return array;
|
|
1127
|
+
if (Array.isArray(first) && Array.isArray(second)) return swapArrays(array, first, second, third);
|
|
1128
|
+
return swapValues(array, first, second, third);
|
|
1129
|
+
}
|
|
1130
|
+
swap.indices = swapIndices;
|
|
1131
|
+
function swapArrays(array, from, to, key) {
|
|
1132
|
+
if (from.length === 0 || to.length === 0) return array;
|
|
1133
|
+
if (from.length === 1 && to.length === 1) return swapValues(array, from[0], to[0], key);
|
|
1134
|
+
const fromIndex = indexOfArray(array, from, key);
|
|
1135
|
+
const toIndex = indexOfArray(array, to, key);
|
|
1136
|
+
if (fromIndex === -1 || toIndex === -1) return array;
|
|
1137
|
+
const first = fromIndex < toIndex ? from : to;
|
|
1138
|
+
const second = fromIndex < toIndex ? to : from;
|
|
1139
|
+
const firstIndex = first === from ? fromIndex : toIndex;
|
|
1140
|
+
const secondIndex = first === from ? toIndex : fromIndex;
|
|
1141
|
+
const firstEnd = firstIndex + first.length - 1;
|
|
1142
|
+
if (firstIndex <= secondIndex + second.length - 1 && firstEnd >= secondIndex) return array;
|
|
1143
|
+
array.splice(firstIndex, first.length, ...second);
|
|
1144
|
+
array.splice(secondIndex, second.length, ...first);
|
|
1145
|
+
return array;
|
|
1146
|
+
}
|
|
1147
|
+
/**
|
|
1148
|
+
* Swap two indiced items in an array
|
|
1149
|
+
*
|
|
1150
|
+
* If either index is out of bounds, the array will be returned unchanged
|
|
1151
|
+
* @param array Array of items to swap
|
|
1152
|
+
* @param first First index _(can be negative to count from the end)_
|
|
1153
|
+
* @param second Second index _(can be negative to count from the end)_
|
|
1154
|
+
* @returns Original array with items swapped _(or unchanged if unable to swap)_
|
|
1155
|
+
*/
|
|
1156
|
+
function swapIndices(array, first, second) {
|
|
1157
|
+
if (!Array.isArray(array) || array.length === 0) return [];
|
|
1158
|
+
if (typeof first !== "number" || typeof second !== "number") return array;
|
|
1159
|
+
const firstIndex = first < 0 ? array.length + first : first;
|
|
1160
|
+
const secondIndex = second < 0 ? array.length + second : second;
|
|
1161
|
+
if (firstIndex === secondIndex || firstIndex >= array.length || secondIndex >= array.length) return array;
|
|
1162
|
+
const temp = array[firstIndex];
|
|
1163
|
+
array[firstIndex] = array[secondIndex];
|
|
1164
|
+
array[secondIndex] = temp;
|
|
1165
|
+
return array;
|
|
1166
|
+
}
|
|
1167
|
+
function swapValues(array, from, to, key) {
|
|
1168
|
+
const callback = getArrayCallback(key);
|
|
1169
|
+
const first = callback == null ? array.indexOf(from) : indexOf(array, callback, callback(from, void 0, []));
|
|
1170
|
+
const second = callback == null ? array.indexOf(to) : indexOf(array, callback, callback(to, void 0, []));
|
|
1171
|
+
if (first === second || first === -1 || second === -1) return array;
|
|
1172
|
+
return swapIndices(array, first, second);
|
|
1173
|
+
}
|
|
1059
1174
|
function getMapValues(array, first, second, arrays) {
|
|
1060
1175
|
if (!Array.isArray(array)) return /* @__PURE__ */ new Map();
|
|
1061
1176
|
const { length } = array;
|
|
@@ -1737,7 +1852,7 @@ var Memoized = class {
|
|
|
1737
1852
|
constructor(callback, options) {
|
|
1738
1853
|
const cache = new SizedMap(options.cacheSize);
|
|
1739
1854
|
const getter = (...parameters) => {
|
|
1740
|
-
const key = options.cacheKey?.(...parameters) ?? (parameters.length === 1 ? parameters[0] : join(parameters.map(getString),
|
|
1855
|
+
const key = options.cacheKey?.(...parameters) ?? (parameters.length === 1 ? parameters[0] : join(parameters.map(getString), SEPARATOR));
|
|
1741
1856
|
if (cache.has(key)) return cache.get(key);
|
|
1742
1857
|
const value = callback(...parameters);
|
|
1743
1858
|
cache.set(key, value);
|
|
@@ -1813,6 +1928,7 @@ function memoize(callback, options) {
|
|
|
1813
1928
|
return new Memoized(callback, getMemoizationOptions(options));
|
|
1814
1929
|
}
|
|
1815
1930
|
var DEFAULT_CACHE_SIZE = 1024;
|
|
1931
|
+
var SEPARATOR = "_";
|
|
1816
1932
|
/**
|
|
1817
1933
|
* Check if a string ends with a specified substring
|
|
1818
1934
|
* @param haystack String to look in
|
|
@@ -1821,7 +1937,7 @@ var DEFAULT_CACHE_SIZE = 1024;
|
|
|
1821
1937
|
* @returns `true` if the string ends with the given substring, otherwise `false`
|
|
1822
1938
|
*/
|
|
1823
1939
|
function endsWith(haystack, needle, ignoreCase) {
|
|
1824
|
-
return match(
|
|
1940
|
+
return match(MATCH_ENDS_WITH, haystack, needle, ignoreCase === true);
|
|
1825
1941
|
}
|
|
1826
1942
|
/**
|
|
1827
1943
|
* Check if a string includes a specified substring
|
|
@@ -1831,7 +1947,7 @@ function endsWith(haystack, needle, ignoreCase) {
|
|
|
1831
1947
|
* @returns `true` if the string includes the given substring, otherwise `false`
|
|
1832
1948
|
*/
|
|
1833
1949
|
function includes(haystack, needle, ignoreCase) {
|
|
1834
|
-
return match(
|
|
1950
|
+
return match(MATCH_INCLUDES, haystack, needle, ignoreCase === true);
|
|
1835
1951
|
}
|
|
1836
1952
|
function match(type, haystack, needle, ignoreCase) {
|
|
1837
1953
|
if (typeof haystack !== "string" || typeof needle !== "string") return false;
|
|
@@ -1849,8 +1965,11 @@ function matchCallback(haystack, needle, ignoreCase) {
|
|
|
1849
1965
|
* @returns `true` if the string starts with the given substring, otherwise `false`
|
|
1850
1966
|
*/
|
|
1851
1967
|
function startsWith(haystack, needle, ignoreCase) {
|
|
1852
|
-
return match(
|
|
1968
|
+
return match(MATCH_STARTS_WITH, haystack, needle, ignoreCase === true);
|
|
1853
1969
|
}
|
|
1970
|
+
var MATCH_ENDS_WITH = "endsWith";
|
|
1971
|
+
var MATCH_INCLUDES = "includes";
|
|
1972
|
+
var MATCH_STARTS_WITH = "startsWith";
|
|
1854
1973
|
var matchMemoizers = {};
|
|
1855
1974
|
function equal(first, second, options) {
|
|
1856
1975
|
return equalValue(first, second, getEqualOptions(options));
|
|
@@ -1948,9 +2067,9 @@ function equalValue(first, second, options) {
|
|
|
1948
2067
|
case first instanceof ArrayBuffer && second instanceof ArrayBuffer: return equalArrayBuffer(first, second, options);
|
|
1949
2068
|
case first instanceof Date && second instanceof Date: return Object.is(Number(first), Number(second));
|
|
1950
2069
|
case first instanceof DataView && second instanceof DataView: return equalDataView(first, second, options);
|
|
1951
|
-
case first instanceof Error && second instanceof Error: return equalProperties(first, second,
|
|
2070
|
+
case first instanceof Error && second instanceof Error: return equalProperties(first, second, ERROR_PROPERTIES, options);
|
|
1952
2071
|
case first instanceof Map && second instanceof Map: return equalMap(first, second, options);
|
|
1953
|
-
case first instanceof RegExp && second instanceof RegExp: return equalProperties(first, second,
|
|
2072
|
+
case first instanceof RegExp && second instanceof RegExp: return equalProperties(first, second, EXPRESSION_PROPERTIES, options);
|
|
1954
2073
|
case first instanceof Set && second instanceof Set: return equalSet(first, second, options);
|
|
1955
2074
|
case Array.isArray(first) && Array.isArray(second): return equalArray(first, second, options);
|
|
1956
2075
|
case isPlainObject(first) && isPlainObject(second): return equalPlainObject(first, second, options);
|
|
@@ -2019,6 +2138,8 @@ function getEqualOptions(input) {
|
|
|
2019
2138
|
}
|
|
2020
2139
|
var ARRAY_PEEK_PERCENTAGE = 10;
|
|
2021
2140
|
var ARRAY_THRESHOLD = 100;
|
|
2141
|
+
var ERROR_PROPERTIES = ["name", "message"];
|
|
2142
|
+
var EXPRESSION_PROPERTIES = ["source", "flags"];
|
|
2022
2143
|
var FilterManager = class {
|
|
2023
2144
|
handlers = Object.freeze({
|
|
2024
2145
|
add: (item) => this.add(item),
|
|
@@ -2637,6 +2758,7 @@ var Tabela = class {
|
|
|
2637
2758
|
};
|
|
2638
2759
|
#element;
|
|
2639
2760
|
#id = getId();
|
|
2761
|
+
#table;
|
|
2640
2762
|
#key;
|
|
2641
2763
|
#managers = {
|
|
2642
2764
|
column: void 0,
|
|
@@ -2660,17 +2782,20 @@ var Tabela = class {
|
|
|
2660
2782
|
constructor(element, options) {
|
|
2661
2783
|
this.#element = element;
|
|
2662
2784
|
element.innerHTML = "";
|
|
2663
|
-
element.role = "table";
|
|
2664
2785
|
element.classList.add("tabela");
|
|
2786
|
+
this.#table = createElement("div", {
|
|
2787
|
+
className: "tabela__table",
|
|
2788
|
+
role: "table"
|
|
2789
|
+
});
|
|
2665
2790
|
element.setAttribute("aria-label", options.label);
|
|
2666
2791
|
this.#key = options.key;
|
|
2667
2792
|
this.#components.header = new HeaderComponent();
|
|
2668
2793
|
this.#components.body = new BodyComponent();
|
|
2669
2794
|
this.#components.footer = new FooterComponent();
|
|
2670
2795
|
const state = {
|
|
2671
|
-
element,
|
|
2672
2796
|
options,
|
|
2673
2797
|
components: this.#components,
|
|
2798
|
+
element: this.#table,
|
|
2674
2799
|
id: this.#id,
|
|
2675
2800
|
key: this.#key,
|
|
2676
2801
|
managers: this.#managers
|
|
@@ -2685,7 +2810,7 @@ var Tabela = class {
|
|
|
2685
2810
|
this.#managers.row = new RowManager(state);
|
|
2686
2811
|
this.#managers.selection = new SelectionManager(state);
|
|
2687
2812
|
this.#managers.sort = new SortManager(state);
|
|
2688
|
-
|
|
2813
|
+
this.#table.append(this.#components.header.elements.group, this.#components.body.elements.group, this.#components.footer.elements.group);
|
|
2689
2814
|
this.#managers.data.set(options.data);
|
|
2690
2815
|
this.data = this.#managers.data.handlers;
|
|
2691
2816
|
this.filter = this.#managers.filter.handlers;
|
|
@@ -2696,6 +2821,7 @@ var Tabela = class {
|
|
|
2696
2821
|
const components = this.#components;
|
|
2697
2822
|
const managers = this.#managers;
|
|
2698
2823
|
const element = this.#element;
|
|
2824
|
+
const table = this.#table;
|
|
2699
2825
|
components.body.destroy();
|
|
2700
2826
|
components.footer.destroy();
|
|
2701
2827
|
components.header.destroy();
|
|
@@ -2703,6 +2829,7 @@ var Tabela = class {
|
|
|
2703
2829
|
managers.data.destroy();
|
|
2704
2830
|
managers.event.destroy();
|
|
2705
2831
|
managers.filter.destroy();
|
|
2832
|
+
managers.navigation.destroy();
|
|
2706
2833
|
managers.render.destroy();
|
|
2707
2834
|
managers.row.destroy();
|
|
2708
2835
|
managers.selection.destroy();
|
|
@@ -2710,9 +2837,10 @@ var Tabela = class {
|
|
|
2710
2837
|
element.innerHTML = "";
|
|
2711
2838
|
element.role = "";
|
|
2712
2839
|
element.classList.remove("tabela");
|
|
2713
|
-
|
|
2714
|
-
|
|
2840
|
+
table.removeAttribute("aria-label");
|
|
2841
|
+
table.removeAttribute("role");
|
|
2715
2842
|
this.#element = void 0;
|
|
2843
|
+
this.#table = void 0;
|
|
2716
2844
|
}
|
|
2717
2845
|
};
|
|
2718
2846
|
function getId() {
|
package/package.json
CHANGED
|
@@ -1,50 +1,58 @@
|
|
|
1
1
|
{
|
|
2
|
+
"name": "@oscarpalmer/tabela",
|
|
3
|
+
"version": "0.14.0",
|
|
4
|
+
"description": "A modern table.",
|
|
5
|
+
"keywords": [],
|
|
6
|
+
"license": "MIT",
|
|
2
7
|
"author": {
|
|
3
8
|
"name": "Oscar Palmér",
|
|
4
9
|
"url": "https://oscarpalmer.se"
|
|
5
10
|
},
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
},
|
|
10
|
-
"description": "A modern table.",
|
|
11
|
-
"devDependencies": {
|
|
12
|
-
"@oscarpalmer/oui": "^0.19",
|
|
13
|
-
"@types/node": "^25.3",
|
|
14
|
-
"@vitest/coverage-istanbul": "^4",
|
|
15
|
-
"jsdom": "^28.1",
|
|
16
|
-
"oxfmt": "^0.36",
|
|
17
|
-
"oxlint": "^1.51",
|
|
18
|
-
"rolldown": "1.0.0-rc.7",
|
|
19
|
-
"tslib": "^2.8",
|
|
20
|
-
"typescript": "^5.9",
|
|
21
|
-
"vite": "8.0.0-beta.16",
|
|
22
|
-
"vitest": "^4"
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/oscarpalmer/tabela.git"
|
|
23
14
|
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"src"
|
|
18
|
+
],
|
|
19
|
+
"type": "module",
|
|
20
|
+
"module": "./dist/index.mjs",
|
|
21
|
+
"types": "./dist/index.d.mts",
|
|
24
22
|
"exports": {
|
|
25
23
|
".": {
|
|
26
|
-
"types": "./
|
|
27
|
-
"default": "./dist/index.
|
|
24
|
+
"types": "./dist/index.d.mts",
|
|
25
|
+
"default": "./dist/index.mjs"
|
|
28
26
|
}
|
|
29
27
|
},
|
|
30
|
-
"files": ["dist", "src", "types"],
|
|
31
|
-
"keywords": [],
|
|
32
|
-
"license": "MIT",
|
|
33
|
-
"module": "./dist/index.js",
|
|
34
|
-
"name": "@oscarpalmer/tabela",
|
|
35
|
-
"repository": {
|
|
36
|
-
"type": "git",
|
|
37
|
-
"url": "git+https://github.com/oscarpalmer/tabela.git"
|
|
38
|
-
},
|
|
39
28
|
"scripts": {
|
|
40
|
-
"build": "
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"test": "
|
|
45
|
-
"watch": "
|
|
29
|
+
"build": "vpx vp run tsdown:build && vpx vp pack",
|
|
30
|
+
"tsdown:build": "vpx tsdown -c ./tsdown.config.ts",
|
|
31
|
+
"tsdown:watch": "vpx tsdown -c ./tsdown.config.ts --watch",
|
|
32
|
+
"test": "vpx vp test run --coverage",
|
|
33
|
+
"test:leak": "vpx vp test run --detect-async-leaks --coverage",
|
|
34
|
+
"watch": "vpx vite build --watch",
|
|
35
|
+
"www": "concurrently \"vpx vp run www:css\" \"vpx vp run www:js\"",
|
|
36
|
+
"www:css": "sass --watch www/.app/css:./www/css",
|
|
37
|
+
"www:js": "vpx tsdown -c ./www/.app/js/tsdown.config.ts --watch"
|
|
46
38
|
},
|
|
47
|
-
"
|
|
48
|
-
|
|
49
|
-
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@oscarpalmer/atoms": "^0.165",
|
|
41
|
+
"@oscarpalmer/toretto": "^0.41"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@oscarpalmer/abydon": "^0.19",
|
|
45
|
+
"@oscarpalmer/oui": "^0.19",
|
|
46
|
+
"@types/node": "^25.5",
|
|
47
|
+
"@vitest/coverage-istanbul": "^4.1",
|
|
48
|
+
"concurrently": "^9.2",
|
|
49
|
+
"jsdom": "^28.1",
|
|
50
|
+
"sass": "^1.98",
|
|
51
|
+
"tsdown": "^0.21",
|
|
52
|
+
"typescript": "^5.9",
|
|
53
|
+
"vite": "npm:@voidzero-dev/vite-plus-core@latest",
|
|
54
|
+
"vite-plus": "latest",
|
|
55
|
+
"vitest": "npm:@voidzero-dev/vite-plus-test@latest"
|
|
56
|
+
},
|
|
57
|
+
"packageManager": "npm@11.11.1"
|
|
50
58
|
}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import {createElement, createRowGroup} from '../helpers/dom.helpers';
|
|
2
2
|
import type {BodyElements} from '../models/body.model';
|
|
3
|
+
import {ATTRIBUTE_DATA_EVENT, ELEMENT_DIV} from '../models/dom.model';
|
|
4
|
+
import {EVENT_BODY} from '../models/event.model';
|
|
5
|
+
import {CSS_FAKER, CSS_ROWGROUP_BODY} from '../models/style.model';
|
|
6
|
+
import type {State} from '../models/tabela.model';
|
|
3
7
|
|
|
4
8
|
function createFaker(): HTMLDivElement {
|
|
5
|
-
return createElement(
|
|
6
|
-
className:
|
|
7
|
-
}
|
|
9
|
+
return createElement(ELEMENT_DIV, {
|
|
10
|
+
className: CSS_FAKER,
|
|
11
|
+
});
|
|
8
12
|
}
|
|
9
13
|
|
|
10
14
|
export class BodyComponent {
|
|
@@ -13,16 +17,16 @@ export class BodyComponent {
|
|
|
13
17
|
group: undefined as never,
|
|
14
18
|
};
|
|
15
19
|
|
|
16
|
-
constructor() {
|
|
17
|
-
const group = createRowGroup(false);
|
|
20
|
+
constructor(state: State) {
|
|
21
|
+
const group = createRowGroup(state.options.rowHeight, false);
|
|
18
22
|
|
|
19
23
|
this.elements.group = group;
|
|
20
24
|
|
|
21
|
-
group.className +=
|
|
25
|
+
group.className += ` ${CSS_ROWGROUP_BODY}`;
|
|
22
26
|
|
|
23
27
|
group.tabIndex = 0;
|
|
24
28
|
|
|
25
|
-
group.setAttribute(
|
|
29
|
+
group.setAttribute(ATTRIBUTE_DATA_EVENT, EVENT_BODY);
|
|
26
30
|
|
|
27
31
|
group.append(this.elements.faker);
|
|
28
32
|
}
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import {createElement} from '../helpers/dom.helpers';
|
|
2
2
|
import type {Column, TabelaColumn} from '../models/column.model';
|
|
3
|
+
import {
|
|
4
|
+
ATTRIBUTE_DATA_EVENT,
|
|
5
|
+
ATTRIBUTE_DATA_FIELD,
|
|
6
|
+
ATTRIBUTE_ROLE,
|
|
7
|
+
ELEMENT_DIV,
|
|
8
|
+
ROLE_COLUMNHEADER,
|
|
9
|
+
} from '../models/dom.model';
|
|
10
|
+
import {EVENT_HEADING} from '../models/event.model';
|
|
11
|
+
import {CSS_HEADING, CSS_HEADING_CONTENT, CSS_HEADING_SORTER} from '../models/style.model';
|
|
3
12
|
|
|
4
13
|
export class ColumnComponent {
|
|
5
14
|
elements: ColumnElements;
|
|
@@ -8,14 +17,14 @@ export class ColumnComponent {
|
|
|
8
17
|
constructor(column: TabelaColumn) {
|
|
9
18
|
const width =
|
|
10
19
|
Number.parseInt(getComputedStyle(document.body).fontSize, 10) *
|
|
11
|
-
(column.width ?? column.
|
|
20
|
+
(column.width ?? column.label.length * 1.5);
|
|
12
21
|
|
|
13
22
|
this.options = {
|
|
14
23
|
...column,
|
|
15
24
|
width,
|
|
16
25
|
};
|
|
17
26
|
|
|
18
|
-
this.elements = createHeading(this.options.field, this.options.
|
|
27
|
+
this.elements = createHeading(this.options.field, this.options.label, width);
|
|
19
28
|
}
|
|
20
29
|
|
|
21
30
|
destroy(): void {
|
|
@@ -36,38 +45,28 @@ type ColumnElements = {
|
|
|
36
45
|
|
|
37
46
|
function createHeading(field: string, title: string, width: number): ColumnElements {
|
|
38
47
|
const wrapper = createElement(
|
|
39
|
-
|
|
48
|
+
ELEMENT_DIV,
|
|
40
49
|
{
|
|
41
|
-
className:
|
|
42
|
-
|
|
50
|
+
className: CSS_HEADING,
|
|
51
|
+
[ATTRIBUTE_ROLE]: ROLE_COLUMNHEADER,
|
|
43
52
|
},
|
|
44
53
|
{
|
|
45
|
-
|
|
46
|
-
|
|
54
|
+
[ATTRIBUTE_DATA_EVENT]: EVENT_HEADING,
|
|
55
|
+
[ATTRIBUTE_DATA_FIELD]: field,
|
|
47
56
|
},
|
|
48
57
|
{
|
|
49
58
|
width: `${width}px`,
|
|
50
59
|
},
|
|
51
60
|
);
|
|
52
61
|
|
|
53
|
-
const content = createElement(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
textContent: title,
|
|
58
|
-
},
|
|
59
|
-
{},
|
|
60
|
-
{},
|
|
61
|
-
);
|
|
62
|
+
const content = createElement(ELEMENT_DIV, {
|
|
63
|
+
className: CSS_HEADING_CONTENT,
|
|
64
|
+
textContent: title,
|
|
65
|
+
});
|
|
62
66
|
|
|
63
|
-
const sorter = createElement(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
className: 'tabela__heading__sorter',
|
|
67
|
-
},
|
|
68
|
-
{},
|
|
69
|
-
{},
|
|
70
|
-
);
|
|
67
|
+
const sorter = createElement(ELEMENT_DIV, {
|
|
68
|
+
className: CSS_HEADING_SORTER,
|
|
69
|
+
});
|
|
71
70
|
|
|
72
71
|
wrapper.append(content, sorter);
|
|
73
72
|
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import {createCell, createRowGroup} from '../helpers/dom.helpers';
|
|
2
2
|
import type {FooterElements} from '../models/footer.model';
|
|
3
|
+
import {CSS_CELL_FOOTER, CSS_ROW_FOOTER, CSS_ROWGROUP_FOOTER} from '../models/style.model';
|
|
4
|
+
import type {State} from '../models/tabela.model';
|
|
3
5
|
import type {ColumnComponent} from './column.component';
|
|
4
6
|
|
|
5
7
|
export class FooterComponent {
|
|
6
8
|
readonly elements: FooterElements;
|
|
7
9
|
|
|
8
|
-
constructor() {
|
|
9
|
-
const {group, row} = createRowGroup();
|
|
10
|
+
constructor(state: State) {
|
|
11
|
+
const {group, row} = createRowGroup(state.options.rowHeight);
|
|
10
12
|
|
|
11
13
|
this.elements = {
|
|
12
14
|
group,
|
|
@@ -14,8 +16,8 @@ export class FooterComponent {
|
|
|
14
16
|
cells: [],
|
|
15
17
|
};
|
|
16
18
|
|
|
17
|
-
group.className +=
|
|
18
|
-
row.className +=
|
|
19
|
+
group.className += ` ${CSS_ROWGROUP_FOOTER}`;
|
|
20
|
+
row.className += ` ${CSS_ROW_FOOTER}`;
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
destroy(): void {
|
|
@@ -35,7 +37,7 @@ export class FooterComponent {
|
|
|
35
37
|
for (let index = 0; index < length; index += 1) {
|
|
36
38
|
const cell = createCell(columns[index].options.width ?? 4, false);
|
|
37
39
|
|
|
38
|
-
cell.className +=
|
|
40
|
+
cell.className += ` ${CSS_CELL_FOOTER}`;
|
|
39
41
|
cell.innerHTML = ' ';
|
|
40
42
|
|
|
41
43
|
elements.cells.push(cell);
|