@oscarpalmer/tabela 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/body.component.js +1 -2
- package/dist/components/column.component.js +2 -3
- package/dist/components/footer.component.js +1 -2
- package/dist/components/header.component.js +1 -2
- package/dist/components/row.component.js +7 -7
- package/dist/managers/column.manager.js +16 -15
- package/dist/managers/data.manager.js +96 -15
- package/dist/managers/row.manager.js +13 -3
- package/dist/managers/virtualization.manager.js +38 -31
- package/dist/models/tabela.model.js +0 -0
- package/dist/tabela.full.js +220 -101
- package/dist/tabela.js +36 -22
- package/package.json +3 -3
- package/src/components/body.component.ts +1 -2
- package/src/components/column.component.ts +2 -6
- package/src/components/footer.component.ts +1 -2
- package/src/components/header.component.ts +1 -2
- package/src/components/row.component.ts +10 -8
- package/src/managers/column.manager.ts +17 -20
- package/src/managers/data.manager.ts +161 -20
- package/src/managers/row.manager.ts +19 -3
- package/src/managers/virtualization.manager.ts +55 -34
- package/src/models/tabela.model.ts +31 -0
- package/src/tabela.ts +47 -40
- package/types/components/body.component.d.ts +1 -3
- package/types/components/column.component.d.ts +1 -3
- package/types/components/footer.component.d.ts +1 -3
- package/types/components/header.component.d.ts +1 -3
- package/types/components/row.component.d.ts +3 -3
- package/types/managers/column.manager.d.ts +5 -4
- package/types/managers/data.manager.d.ts +15 -6
- package/types/managers/row.manager.d.ts +6 -3
- package/types/managers/virtualization.manager.d.ts +5 -3
- package/types/models/tabela.model.d.ts +28 -0
- package/types/tabela.d.ts +4 -23
package/dist/tabela.full.js
CHANGED
|
@@ -164,8 +164,7 @@ var BodyComponent = class {
|
|
|
164
164
|
faker: createFaker(),
|
|
165
165
|
group: void 0
|
|
166
166
|
};
|
|
167
|
-
constructor(
|
|
168
|
-
this.tabela = tabela;
|
|
167
|
+
constructor() {
|
|
169
168
|
const group = createRowGroup(false);
|
|
170
169
|
this.elements.group = group;
|
|
171
170
|
group.className += " tabela__rowgroup-body";
|
|
@@ -184,8 +183,7 @@ var BodyComponent = class {
|
|
|
184
183
|
};
|
|
185
184
|
var FooterComponent = class {
|
|
186
185
|
elements;
|
|
187
|
-
constructor(
|
|
188
|
-
this.tabela = tabela;
|
|
186
|
+
constructor() {
|
|
189
187
|
const { group, row } = createRowGroup();
|
|
190
188
|
this.elements = {
|
|
191
189
|
group,
|
|
@@ -216,8 +214,7 @@ var FooterComponent = class {
|
|
|
216
214
|
};
|
|
217
215
|
var HeaderComponent = class {
|
|
218
216
|
elements;
|
|
219
|
-
constructor(
|
|
220
|
-
this.tabela = tabela;
|
|
217
|
+
constructor() {
|
|
221
218
|
const { group, row } = createRowGroup();
|
|
222
219
|
this.elements = {
|
|
223
220
|
group,
|
|
@@ -245,9 +242,8 @@ function createHeading(title, width) {
|
|
|
245
242
|
var ColumnComponent = class {
|
|
246
243
|
element;
|
|
247
244
|
options;
|
|
248
|
-
constructor(
|
|
249
|
-
|
|
250
|
-
const width = Number.parseInt(getComputedStyle(tabela.element).fontSize, 10) * (options.width ?? options.title.length * 1.5);
|
|
245
|
+
constructor(options) {
|
|
246
|
+
const width = Number.parseInt(getComputedStyle(document.body).fontSize, 10) * (options.width ?? options.title.length * 1.5);
|
|
251
247
|
this.options = {
|
|
252
248
|
...options,
|
|
253
249
|
width
|
|
@@ -256,33 +252,34 @@ var ColumnComponent = class {
|
|
|
256
252
|
}
|
|
257
253
|
};
|
|
258
254
|
var ColumnManager = class {
|
|
259
|
-
|
|
260
|
-
constructor(
|
|
261
|
-
this.
|
|
255
|
+
items = [];
|
|
256
|
+
constructor(managers, components, columns) {
|
|
257
|
+
this.managers = managers;
|
|
258
|
+
this.components = components;
|
|
262
259
|
this.set(columns);
|
|
263
260
|
}
|
|
264
261
|
destroy() {
|
|
265
|
-
this.
|
|
262
|
+
this.items.length = 0;
|
|
266
263
|
}
|
|
267
264
|
remove(value) {
|
|
268
|
-
const { components,
|
|
265
|
+
const { components, items, managers } = this;
|
|
269
266
|
const fields = (Array.isArray(value) ? value : [value]).filter((item) => typeof item === "string");
|
|
270
267
|
const { length } = fields;
|
|
271
268
|
if (length === 0) return;
|
|
272
269
|
for (let fieldIndex = 0; fieldIndex < length; fieldIndex += 1) {
|
|
273
|
-
const
|
|
274
|
-
if (
|
|
270
|
+
const itemIndex = items.findIndex((component) => component.options.field === fields[fieldIndex]);
|
|
271
|
+
if (itemIndex > -1) items.splice(itemIndex, 1);
|
|
275
272
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
273
|
+
components.header.update(items);
|
|
274
|
+
components.footer.update(items);
|
|
275
|
+
managers.virtualization.removeCells(fields);
|
|
279
276
|
}
|
|
280
277
|
set(columns) {
|
|
281
|
-
const { components,
|
|
282
|
-
const { footer, header } =
|
|
283
|
-
|
|
284
|
-
header.update(
|
|
285
|
-
footer.update(
|
|
278
|
+
const { components, items } = this;
|
|
279
|
+
const { footer, header } = components;
|
|
280
|
+
items.splice(0, items.length, ...columns.map((column) => new ColumnComponent(column)));
|
|
281
|
+
header.update(items);
|
|
282
|
+
footer.update(items);
|
|
286
283
|
}
|
|
287
284
|
};
|
|
288
285
|
function getArrayCallback(value) {
|
|
@@ -324,21 +321,50 @@ toMap.arrays = toMapArrays;
|
|
|
324
321
|
function toMapArrays(array, first, second) {
|
|
325
322
|
return getMapValues(array, first, second, true);
|
|
326
323
|
}
|
|
324
|
+
/**
|
|
325
|
+
* Is the value a plain object?
|
|
326
|
+
* @param value Value to check
|
|
327
|
+
* @returns `true` if the value is a plain object, otherwise `false`
|
|
328
|
+
*/
|
|
329
|
+
function isPlainObject(value) {
|
|
330
|
+
if (value === null || typeof value !== "object") return false;
|
|
331
|
+
if (Symbol.toStringTag in value || Symbol.iterator in value) return false;
|
|
332
|
+
const prototype = Object.getPrototypeOf(value);
|
|
333
|
+
return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
|
|
334
|
+
}
|
|
327
335
|
var DataManager = class {
|
|
328
|
-
|
|
329
|
-
|
|
336
|
+
handlers = Object.freeze({
|
|
337
|
+
add: (data) => void this.add(data, true),
|
|
338
|
+
clear: () => void this.clear(),
|
|
339
|
+
get: (active) => this.get(active),
|
|
340
|
+
remove: (items) => void this.remove(items, true),
|
|
341
|
+
synchronize: (data, remove) => void this.synchronize(data, remove),
|
|
342
|
+
update: (data) => void this.update(data)
|
|
343
|
+
});
|
|
344
|
+
values = {
|
|
345
|
+
keys: { original: [] },
|
|
346
|
+
objects: {
|
|
347
|
+
mapped: /* @__PURE__ */ new Map(),
|
|
348
|
+
array: []
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
get size() {
|
|
330
352
|
return this.values.keys.active?.length ?? this.values.keys.original.length;
|
|
331
353
|
}
|
|
332
|
-
constructor(
|
|
333
|
-
this.
|
|
334
|
-
|
|
335
|
-
this.
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
354
|
+
constructor(managers, components, field) {
|
|
355
|
+
this.managers = managers;
|
|
356
|
+
this.components = components;
|
|
357
|
+
this.field = field;
|
|
358
|
+
}
|
|
359
|
+
async add(data, render) {
|
|
360
|
+
const { field, values } = this;
|
|
361
|
+
values.objects.array.push(...data);
|
|
362
|
+
values.objects.mapped = toMap(values.objects.array, field);
|
|
363
|
+
values.keys.original = [...values.objects.mapped.keys()];
|
|
364
|
+
if (render) this.managers.virtualization.update(true);
|
|
365
|
+
}
|
|
366
|
+
clear() {
|
|
367
|
+
if (this.values.objects.array.length > 0) this.set([]);
|
|
342
368
|
}
|
|
343
369
|
destroy() {
|
|
344
370
|
const { values } = this;
|
|
@@ -347,12 +373,74 @@ var DataManager = class {
|
|
|
347
373
|
values.keys.original.length = 0;
|
|
348
374
|
values.objects.array.length = 0;
|
|
349
375
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
376
|
+
get(active) {
|
|
377
|
+
const { values } = this;
|
|
378
|
+
return active ?? false ? values.keys.active?.map((key) => values.objects.mapped.get(key)) ?? [] : values.objects.array;
|
|
379
|
+
}
|
|
380
|
+
async remove(items, render) {
|
|
381
|
+
const { field, managers, values } = this;
|
|
382
|
+
const keys = items.map((value) => isPlainObject(value) ? value[field] : value).filter((key) => values.objects.mapped.has(key));
|
|
383
|
+
const { length } = keys;
|
|
384
|
+
if (length === 0) return;
|
|
385
|
+
for (let keyIndex = 0; keyIndex < length; keyIndex += 1) {
|
|
386
|
+
const key = keys[keyIndex];
|
|
387
|
+
values.objects.mapped.delete(key);
|
|
388
|
+
const arrayIndex = values.objects.array.findIndex((object) => object[field] === key);
|
|
389
|
+
if (arrayIndex > -1) values.objects.array.splice(arrayIndex, 1);
|
|
390
|
+
values.keys.original.splice(values.keys.original.indexOf(key), 1);
|
|
391
|
+
managers.row.remove(key);
|
|
392
|
+
}
|
|
393
|
+
if (render) this.managers.virtualization.update(true);
|
|
394
|
+
}
|
|
395
|
+
set(data) {
|
|
396
|
+
const { field, values } = this;
|
|
397
|
+
const mapped = toMap(data, field);
|
|
398
|
+
values.keys.active = void 0;
|
|
399
|
+
values.keys.original = [...mapped.keys()];
|
|
400
|
+
values.objects.mapped = mapped;
|
|
401
|
+
values.objects.array = data;
|
|
402
|
+
this.managers.virtualization.update(true);
|
|
403
|
+
}
|
|
404
|
+
async synchronize(data, remove) {
|
|
405
|
+
const { field, values } = this;
|
|
406
|
+
const add = [];
|
|
407
|
+
const updated = [];
|
|
408
|
+
const keys = /* @__PURE__ */ new Set([]);
|
|
409
|
+
const { length } = data;
|
|
410
|
+
for (let index = 0; index < length; index += 1) {
|
|
411
|
+
const object = data[index];
|
|
412
|
+
const key = object[field];
|
|
413
|
+
if (values.objects.mapped.has(key)) updated.push(object);
|
|
414
|
+
else add.push(object);
|
|
415
|
+
keys.add(key);
|
|
416
|
+
}
|
|
417
|
+
if (keys.size === 0) return;
|
|
418
|
+
if (remove ?? false) {
|
|
419
|
+
const toRemove = values.keys.original.filter((key) => !keys.has(key));
|
|
420
|
+
if (toRemove.length > 0) await this.remove(toRemove, false);
|
|
421
|
+
}
|
|
422
|
+
await this.update(updated);
|
|
423
|
+
if (add.length > 0) await this.add(add, false);
|
|
424
|
+
if (add.length > 0 || (remove ?? false)) this.managers.virtualization.update(true);
|
|
425
|
+
}
|
|
426
|
+
async update(data) {
|
|
427
|
+
const { field, managers, values } = this;
|
|
428
|
+
const { length } = data;
|
|
429
|
+
for (let index = 0; index < length; index += 1) {
|
|
430
|
+
const object = data[index];
|
|
431
|
+
const key = object[field];
|
|
432
|
+
const value = values.objects.mapped.get(key);
|
|
433
|
+
if (value != null) {
|
|
434
|
+
values.objects.mapped.set(key, {
|
|
435
|
+
...value,
|
|
436
|
+
...object
|
|
437
|
+
});
|
|
438
|
+
managers.row.update(key);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
353
441
|
}
|
|
354
442
|
};
|
|
355
|
-
function removeRow(
|
|
443
|
+
function removeRow(pool, row) {
|
|
356
444
|
if (row.element != null) {
|
|
357
445
|
row.element.innerHTML = "";
|
|
358
446
|
pool.rows.push(row.element);
|
|
@@ -361,19 +449,19 @@ function removeRow(row, pool) {
|
|
|
361
449
|
}
|
|
362
450
|
row.cells = {};
|
|
363
451
|
}
|
|
364
|
-
function renderRow(
|
|
365
|
-
const element = row.element ?? pool.rows.shift() ?? createRow();
|
|
452
|
+
function renderRow(managers, row) {
|
|
453
|
+
const element = row.element ?? managers.virtualization.pool.rows.shift() ?? createRow();
|
|
366
454
|
row.element = element;
|
|
367
455
|
element.dataset.key = String(row.key);
|
|
368
456
|
element.innerHTML = "";
|
|
369
|
-
const columns =
|
|
457
|
+
const columns = managers.column.items;
|
|
370
458
|
const { length } = columns;
|
|
371
|
-
const data =
|
|
459
|
+
const data = managers.data.values.objects.mapped.get(row.key);
|
|
372
460
|
if (data == null) return;
|
|
373
461
|
for (let index = 0; index < length; index += 1) {
|
|
374
462
|
const { options } = columns[index];
|
|
375
|
-
pool.cells[options.field] ??= [];
|
|
376
|
-
const cell = pool.cells[columns[index].options.field].shift() ?? createCell(options.width);
|
|
463
|
+
managers.virtualization.pool.cells[options.field] ??= [];
|
|
464
|
+
const cell = managers.virtualization.pool.cells[columns[index].options.field].shift() ?? createCell(options.width);
|
|
377
465
|
cell.textContent = String(data[options.field]);
|
|
378
466
|
row.cells[options.field] = cell;
|
|
379
467
|
element.append(cell);
|
|
@@ -389,8 +477,8 @@ var RowComponent = class {
|
|
|
389
477
|
var RowManager = class {
|
|
390
478
|
components = /* @__PURE__ */ new Map();
|
|
391
479
|
height;
|
|
392
|
-
constructor(
|
|
393
|
-
this.
|
|
480
|
+
constructor(managers, rowHeight) {
|
|
481
|
+
this.managers = managers;
|
|
394
482
|
this.height = rowHeight;
|
|
395
483
|
}
|
|
396
484
|
destroy() {
|
|
@@ -404,6 +492,16 @@ var RowManager = class {
|
|
|
404
492
|
}
|
|
405
493
|
return row;
|
|
406
494
|
}
|
|
495
|
+
has(key) {
|
|
496
|
+
return this.components.has(key);
|
|
497
|
+
}
|
|
498
|
+
remove(key) {
|
|
499
|
+
this.components.delete(key);
|
|
500
|
+
}
|
|
501
|
+
update(key) {
|
|
502
|
+
const row = this.components.get(key);
|
|
503
|
+
if (row != null) renderRow(this.managers, row);
|
|
504
|
+
}
|
|
407
505
|
};
|
|
408
506
|
function addDelegatedHandler(doc, type, name, passive) {
|
|
409
507
|
if (DELEGATED.has(name)) return;
|
|
@@ -509,25 +607,23 @@ function on(target, type, listener, options) {
|
|
|
509
607
|
target.removeEventListener(type, listener, extended);
|
|
510
608
|
};
|
|
511
609
|
}
|
|
512
|
-
function getRange(
|
|
513
|
-
const { components, managers } =
|
|
514
|
-
const {
|
|
515
|
-
const
|
|
516
|
-
const
|
|
517
|
-
const
|
|
518
|
-
const
|
|
519
|
-
const before = Math.ceil(clientHeight / rows.height) * (down ? 1 : 2);
|
|
520
|
-
const after = Math.ceil(clientHeight / rows.height) * (down ? 2 : 1);
|
|
610
|
+
function getRange(down) {
|
|
611
|
+
const { components, managers } = this;
|
|
612
|
+
const { clientHeight, scrollTop } = components.body.elements.group;
|
|
613
|
+
const first = Math.floor(scrollTop / managers.row.height);
|
|
614
|
+
const last = Math.min(managers.data.values.keys.active?.length ?? managers.data.values.keys.original.length - 1, Math.ceil((scrollTop + clientHeight) / managers.row.height) - 1);
|
|
615
|
+
const before = Math.ceil(clientHeight / managers.row.height) * (down ? 1 : 2);
|
|
616
|
+
const after = Math.ceil(clientHeight / managers.row.height) * (down ? 2 : 1);
|
|
521
617
|
const start = Math.max(0, first - before);
|
|
522
618
|
return {
|
|
523
|
-
end: Math.min(data.length - 1, last + after),
|
|
619
|
+
end: Math.min(managers.data.values.keys.active?.length ?? managers.data.values.keys.original.length - 1, last + after),
|
|
524
620
|
start
|
|
525
621
|
};
|
|
526
622
|
}
|
|
527
623
|
function onScroll() {
|
|
528
624
|
if (!this.state.active) {
|
|
529
625
|
requestAnimationFrame(() => {
|
|
530
|
-
const top = this.
|
|
626
|
+
const top = this.components.body.elements.group.scrollTop;
|
|
531
627
|
this.update(top > this.state.top);
|
|
532
628
|
this.state.active = false;
|
|
533
629
|
this.state.top = top;
|
|
@@ -547,14 +643,15 @@ var VirtualizationManager = class {
|
|
|
547
643
|
top: 0
|
|
548
644
|
};
|
|
549
645
|
visible = /* @__PURE__ */ new Map();
|
|
550
|
-
constructor(
|
|
551
|
-
this.
|
|
552
|
-
this.
|
|
646
|
+
constructor(managers, components) {
|
|
647
|
+
this.managers = managers;
|
|
648
|
+
this.components = components;
|
|
649
|
+
this.listener = on(components.body.elements.group, "scroll", onScroll.bind(this));
|
|
553
650
|
}
|
|
554
651
|
destroy() {
|
|
555
652
|
this.listener();
|
|
556
653
|
for (const [index, row] of this.visible) {
|
|
557
|
-
removeRow(
|
|
654
|
+
removeRow(this.pool, row);
|
|
558
655
|
this.visible.delete(index);
|
|
559
656
|
}
|
|
560
657
|
this.pool.cells = {};
|
|
@@ -569,74 +666,96 @@ var VirtualizationManager = class {
|
|
|
569
666
|
delete row.cells[fields[index]];
|
|
570
667
|
}
|
|
571
668
|
}
|
|
669
|
+
getFragment() {
|
|
670
|
+
this.fragment ??= document.createDocumentFragment();
|
|
671
|
+
this.fragment.replaceChildren();
|
|
672
|
+
return this.fragment;
|
|
673
|
+
}
|
|
572
674
|
update(down) {
|
|
573
|
-
const {
|
|
574
|
-
|
|
675
|
+
const { components, managers, pool, visible } = this;
|
|
676
|
+
components.body.elements.faker.style.height = `${managers.data.size * managers.row.height}px`;
|
|
575
677
|
const indices = /* @__PURE__ */ new Set();
|
|
576
|
-
const range = getRange(
|
|
678
|
+
const range = getRange.call(this, down);
|
|
577
679
|
for (let index = range.start; index <= range.end; index += 1) indices.add(index);
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
680
|
+
let remove = false;
|
|
681
|
+
for (const [index, row] of visible) {
|
|
682
|
+
if (!managers.row.has(row.key) || !indices.has(index)) remove = true;
|
|
683
|
+
if (remove) {
|
|
684
|
+
visible.delete(index);
|
|
685
|
+
removeRow(pool, row);
|
|
686
|
+
}
|
|
581
687
|
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
const keys = tabela.managers.data.values.keys.active ?? tabela.managers.data.values.keys.original;
|
|
688
|
+
const fragment = this.getFragment();
|
|
689
|
+
const keys = managers.data.values.keys.active ?? managers.data.values.keys.original;
|
|
585
690
|
let count = 0;
|
|
586
691
|
for (let index = range.start; index <= range.end; index += 1) {
|
|
587
|
-
if (
|
|
588
|
-
const row =
|
|
692
|
+
if (visible.has(index)) continue;
|
|
693
|
+
const row = managers.row.get(keys[index]);
|
|
589
694
|
if (row == null) continue;
|
|
590
695
|
count += 1;
|
|
591
|
-
renderRow(
|
|
592
|
-
|
|
696
|
+
renderRow(managers, row);
|
|
697
|
+
visible.set(index, row);
|
|
593
698
|
if (row.element != null) {
|
|
594
|
-
row.element.style.transform = `translateY(${index *
|
|
595
|
-
|
|
699
|
+
row.element.style.transform = `translateY(${index * managers.row.height}px)`;
|
|
700
|
+
fragment.append(row.element);
|
|
596
701
|
}
|
|
597
702
|
}
|
|
598
|
-
if (count > 0)
|
|
703
|
+
if (count > 0) components.body.elements.group[down ? "append" : "prepend"](fragment);
|
|
599
704
|
}
|
|
600
705
|
};
|
|
601
706
|
var Tabela = class {
|
|
602
|
-
components
|
|
603
|
-
|
|
604
|
-
|
|
707
|
+
#components = {
|
|
708
|
+
header: void 0,
|
|
709
|
+
body: void 0,
|
|
710
|
+
footer: void 0
|
|
711
|
+
};
|
|
712
|
+
#element;
|
|
713
|
+
#key;
|
|
714
|
+
#managers = {
|
|
715
|
+
column: void 0,
|
|
716
|
+
data: void 0,
|
|
717
|
+
row: void 0,
|
|
718
|
+
virtualization: void 0
|
|
719
|
+
};
|
|
720
|
+
data;
|
|
721
|
+
get key() {
|
|
722
|
+
return this.#key;
|
|
723
|
+
}
|
|
605
724
|
constructor(element, options) {
|
|
606
|
-
this
|
|
725
|
+
this.#element = element;
|
|
607
726
|
element.innerHTML = "";
|
|
608
727
|
element.role = "table";
|
|
609
728
|
element.classList.add("tabela");
|
|
610
729
|
element.setAttribute("aria-label", options.label);
|
|
611
|
-
this
|
|
612
|
-
this.
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
this.
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
};
|
|
623
|
-
element.append(this.components.header.elements.group, this.components.body.elements.group, this.components.footer.elements.group);
|
|
624
|
-
this.managers.data.update();
|
|
730
|
+
this.#key = options.key;
|
|
731
|
+
this.#components.header = new HeaderComponent();
|
|
732
|
+
this.#components.body = new BodyComponent();
|
|
733
|
+
this.#components.footer = new FooterComponent();
|
|
734
|
+
this.#managers.column = new ColumnManager(this.#managers, this.#components, options.columns);
|
|
735
|
+
this.#managers.data = new DataManager(this.#managers, this.#components, options.key);
|
|
736
|
+
this.#managers.row = new RowManager(this.#managers, options.rowHeight);
|
|
737
|
+
this.#managers.virtualization = new VirtualizationManager(this.#managers, this.#components);
|
|
738
|
+
element.append(this.#components.header.elements.group, this.#components.body.elements.group, this.#components.footer.elements.group);
|
|
739
|
+
this.#managers.data.set(options.data);
|
|
740
|
+
this.data = this.#managers.data.handlers;
|
|
625
741
|
}
|
|
626
742
|
destroy() {
|
|
627
|
-
const
|
|
743
|
+
const components = this.#components;
|
|
744
|
+
const managers = this.#managers;
|
|
745
|
+
const element = this.#element;
|
|
628
746
|
components.body.destroy();
|
|
629
747
|
components.footer.destroy();
|
|
630
748
|
components.header.destroy();
|
|
631
|
-
managers.
|
|
749
|
+
managers.column.destroy();
|
|
632
750
|
managers.data.destroy();
|
|
633
|
-
managers.
|
|
751
|
+
managers.row.destroy();
|
|
752
|
+
managers.virtualization.destroy();
|
|
634
753
|
element.innerHTML = "";
|
|
635
754
|
element.role = "";
|
|
636
755
|
element.classList.remove("tabela");
|
|
637
756
|
element.removeAttribute("aria-label");
|
|
638
757
|
element.removeAttribute("role");
|
|
639
|
-
this
|
|
758
|
+
this.#element = void 0;
|
|
640
759
|
}
|
|
641
760
|
};
|
|
642
761
|
function tabela(element, options) {
|
package/dist/tabela.js
CHANGED
|
@@ -6,44 +6,58 @@ import { DataManager } from "./managers/data.manager.js";
|
|
|
6
6
|
import { RowManager } from "./managers/row.manager.js";
|
|
7
7
|
import { VirtualizationManager } from "./managers/virtualization.manager.js";
|
|
8
8
|
var Tabela = class {
|
|
9
|
-
components
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
#components = {
|
|
10
|
+
header: void 0,
|
|
11
|
+
body: void 0,
|
|
12
|
+
footer: void 0
|
|
13
|
+
};
|
|
14
|
+
#element;
|
|
15
|
+
#key;
|
|
16
|
+
#managers = {
|
|
17
|
+
column: void 0,
|
|
18
|
+
data: void 0,
|
|
19
|
+
row: void 0,
|
|
20
|
+
virtualization: void 0
|
|
21
|
+
};
|
|
22
|
+
data;
|
|
23
|
+
get key() {
|
|
24
|
+
return this.#key;
|
|
25
|
+
}
|
|
12
26
|
constructor(element, options) {
|
|
13
|
-
this
|
|
27
|
+
this.#element = element;
|
|
14
28
|
element.innerHTML = "";
|
|
15
29
|
element.role = "table";
|
|
16
30
|
element.classList.add("tabela");
|
|
17
31
|
element.setAttribute("aria-label", options.label);
|
|
18
|
-
this
|
|
19
|
-
this.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
this.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
};
|
|
30
|
-
element.append(this.components.header.elements.group, this.components.body.elements.group, this.components.footer.elements.group);
|
|
31
|
-
this.managers.data.update();
|
|
32
|
+
this.#key = options.key;
|
|
33
|
+
this.#components.header = new HeaderComponent();
|
|
34
|
+
this.#components.body = new BodyComponent();
|
|
35
|
+
this.#components.footer = new FooterComponent();
|
|
36
|
+
this.#managers.column = new ColumnManager(this.#managers, this.#components, options.columns);
|
|
37
|
+
this.#managers.data = new DataManager(this.#managers, this.#components, options.key);
|
|
38
|
+
this.#managers.row = new RowManager(this.#managers, options.rowHeight);
|
|
39
|
+
this.#managers.virtualization = new VirtualizationManager(this.#managers, this.#components);
|
|
40
|
+
element.append(this.#components.header.elements.group, this.#components.body.elements.group, this.#components.footer.elements.group);
|
|
41
|
+
this.#managers.data.set(options.data);
|
|
42
|
+
this.data = this.#managers.data.handlers;
|
|
32
43
|
}
|
|
33
44
|
destroy() {
|
|
34
|
-
const
|
|
45
|
+
const components = this.#components;
|
|
46
|
+
const managers = this.#managers;
|
|
47
|
+
const element = this.#element;
|
|
35
48
|
components.body.destroy();
|
|
36
49
|
components.footer.destroy();
|
|
37
50
|
components.header.destroy();
|
|
38
|
-
managers.
|
|
51
|
+
managers.column.destroy();
|
|
39
52
|
managers.data.destroy();
|
|
40
|
-
managers.
|
|
53
|
+
managers.row.destroy();
|
|
54
|
+
managers.virtualization.destroy();
|
|
41
55
|
element.innerHTML = "";
|
|
42
56
|
element.role = "";
|
|
43
57
|
element.classList.remove("tabela");
|
|
44
58
|
element.removeAttribute("aria-label");
|
|
45
59
|
element.removeAttribute("role");
|
|
46
|
-
this
|
|
60
|
+
this.#element = void 0;
|
|
47
61
|
}
|
|
48
62
|
};
|
|
49
63
|
export { Tabela };
|
package/package.json
CHANGED
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
"url": "https://oscarpalmer.se"
|
|
5
5
|
},
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@oscarpalmer/atoms": "^0.
|
|
7
|
+
"@oscarpalmer/atoms": "^0.159",
|
|
8
8
|
"@oscarpalmer/toretto": "^0.38"
|
|
9
9
|
},
|
|
10
10
|
"description": "A modern table.",
|
|
11
11
|
"devDependencies": {
|
|
12
12
|
"@oscarpalmer/oui": "^0.19",
|
|
13
|
-
"@types/node": "^25.
|
|
13
|
+
"@types/node": "^25.3",
|
|
14
14
|
"@vitest/coverage-istanbul": "^4",
|
|
15
15
|
"jsdom": "^28.1",
|
|
16
16
|
"oxfmt": "^0.36",
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
},
|
|
47
47
|
"type": "module",
|
|
48
48
|
"types": "./types/index.d.ts",
|
|
49
|
-
"version": "0.
|
|
49
|
+
"version": "0.7.0"
|
|
50
50
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {setStyles} from '@oscarpalmer/toretto/style';
|
|
2
2
|
import {createElement, createRowGroup} from '../helpers/dom.helpers';
|
|
3
3
|
import type {BodyElements} from '../models/body.model';
|
|
4
|
-
import type {Tabela} from '../tabela';
|
|
5
4
|
|
|
6
5
|
function createFaker(): HTMLDivElement {
|
|
7
6
|
return createElement(
|
|
@@ -24,7 +23,7 @@ export class BodyComponent {
|
|
|
24
23
|
group: undefined as never,
|
|
25
24
|
};
|
|
26
25
|
|
|
27
|
-
constructor(
|
|
26
|
+
constructor() {
|
|
28
27
|
const group = createRowGroup(false);
|
|
29
28
|
|
|
30
29
|
this.elements.group = group;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {createElement} from '../helpers/dom.helpers';
|
|
2
2
|
import type {TabelaColumn, TabelaColumnOptions} from '../models/column.model';
|
|
3
|
-
import type {Tabela} from '../tabela';
|
|
4
3
|
|
|
5
4
|
function createHeading(title: string, width: number): HTMLDivElement {
|
|
6
5
|
const cell = createElement(
|
|
@@ -22,12 +21,9 @@ export class ColumnComponent {
|
|
|
22
21
|
readonly element: HTMLDivElement;
|
|
23
22
|
readonly options: TabelaColumn;
|
|
24
23
|
|
|
25
|
-
constructor(
|
|
26
|
-
readonly tabela: Tabela,
|
|
27
|
-
options: TabelaColumnOptions,
|
|
28
|
-
) {
|
|
24
|
+
constructor(options: TabelaColumnOptions) {
|
|
29
25
|
const width =
|
|
30
|
-
Number.parseInt(getComputedStyle(
|
|
26
|
+
Number.parseInt(getComputedStyle(document.body).fontSize, 10) *
|
|
31
27
|
(options.width ?? options.title.length * 1.5);
|
|
32
28
|
|
|
33
29
|
this.options = {
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import {createCell, createRowGroup} from '../helpers/dom.helpers';
|
|
2
2
|
import type {FooterElements} from '../models/footer.model';
|
|
3
|
-
import type {Tabela} from '../tabela';
|
|
4
3
|
import type {ColumnComponent} from './column.component';
|
|
5
4
|
|
|
6
5
|
export class FooterComponent {
|
|
7
6
|
readonly elements: FooterElements;
|
|
8
7
|
|
|
9
|
-
constructor(
|
|
8
|
+
constructor() {
|
|
10
9
|
const {group, row} = createRowGroup();
|
|
11
10
|
|
|
12
11
|
this.elements = {
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import {createRowGroup} from '../helpers/dom.helpers';
|
|
2
2
|
import type {HeaderElements} from '../models/header.model';
|
|
3
|
-
import type {Tabela} from '../tabela';
|
|
4
3
|
import type {ColumnComponent} from './column.component';
|
|
5
4
|
|
|
6
5
|
export class HeaderComponent {
|
|
7
6
|
readonly elements: HeaderElements;
|
|
8
7
|
|
|
9
|
-
constructor(
|
|
8
|
+
constructor() {
|
|
10
9
|
const {group, row} = createRowGroup();
|
|
11
10
|
|
|
12
11
|
this.elements = {group, row};
|