@design.estate/dees-catalog 3.78.2 → 3.78.3
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_bundle/bundle.js +72 -76
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/elements/00group-dataview/dees-table/dees-table.d.ts +5 -4
- package/dist_ts_web/elements/00group-dataview/dees-table/dees-table.js +84 -90
- package/package.json +1 -1
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/00group-dataview/dees-table/dees-table.ts +97 -99
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@design.estate/dees-catalog",
|
|
3
|
-
"version": "3.78.
|
|
3
|
+
"version": "3.78.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.",
|
|
6
6
|
"main": "dist_ts_web/index.js",
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@design.estate/dees-catalog',
|
|
6
|
-
version: '3.78.
|
|
6
|
+
version: '3.78.3',
|
|
7
7
|
description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.'
|
|
8
8
|
}
|
|
@@ -293,9 +293,9 @@ export class DeesTable<T> extends DeesElement {
|
|
|
293
293
|
private accessor __floatingActive: boolean = false;
|
|
294
294
|
|
|
295
295
|
// ─── Flash-on-update state (only populated when highlightUpdates === 'flash') ──
|
|
296
|
-
/** rowId →
|
|
296
|
+
/** rowId → (colKey → flash token) for cells currently flashing. */
|
|
297
297
|
@state()
|
|
298
|
-
private accessor __flashingCells: Map<string,
|
|
298
|
+
private accessor __flashingCells: Map<string, Map<string, number>> = new Map();
|
|
299
299
|
|
|
300
300
|
/** rowId → (colKey → last-seen resolved cell value). Populated per diff pass. */
|
|
301
301
|
private __prevSnapshot?: Map<string, Map<string, unknown>>;
|
|
@@ -303,7 +303,7 @@ export class DeesTable<T> extends DeesElement {
|
|
|
303
303
|
/** Single shared timer that clears __flashingCells after highlightDuration ms. */
|
|
304
304
|
private __flashClearTimer?: ReturnType<typeof setTimeout>;
|
|
305
305
|
|
|
306
|
-
/** Monotonic counter bumped
|
|
306
|
+
/** Monotonic counter bumped per flash batch so only changed cells restart their animation. */
|
|
307
307
|
private __flashTick: number = 0;
|
|
308
308
|
|
|
309
309
|
/** One-shot console.warn gate for missing rowKey in flash mode. */
|
|
@@ -317,7 +317,7 @@ export class DeesTable<T> extends DeesElement {
|
|
|
317
317
|
columns: any;
|
|
318
318
|
augment: boolean;
|
|
319
319
|
displayFunction: any;
|
|
320
|
-
|
|
320
|
+
displayShapeKey: string;
|
|
321
321
|
out: Column<T>[];
|
|
322
322
|
};
|
|
323
323
|
private __memoViewData?: {
|
|
@@ -329,8 +329,13 @@ export class DeesTable<T> extends DeesElement {
|
|
|
329
329
|
effectiveColumns: Column<T>[];
|
|
330
330
|
out: T[];
|
|
331
331
|
};
|
|
332
|
-
/** Tracks the
|
|
333
|
-
private __columnsSizedFor?: {
|
|
332
|
+
/** Tracks the layout inputs that `determineColumnWidths()` last sized for. */
|
|
333
|
+
private __columnsSizedFor?: {
|
|
334
|
+
effectiveColumns: Column<T>[];
|
|
335
|
+
showSelectionCheckbox: boolean;
|
|
336
|
+
inRowActionCount: number;
|
|
337
|
+
table: HTMLTableElement;
|
|
338
|
+
};
|
|
334
339
|
|
|
335
340
|
// ─── Virtualization state ────────────────────────────────────────────
|
|
336
341
|
/** Estimated row height (px). Measured once from the first rendered row. */
|
|
@@ -409,15 +414,7 @@ export class DeesTable<T> extends DeesElement {
|
|
|
409
414
|
const view: T[] = (this as any)._lastViewData ?? [];
|
|
410
415
|
const item = view.find((r) => this.getRowId(r) === this.__focusedCell!.rowId);
|
|
411
416
|
if (!item) return;
|
|
412
|
-
const allCols
|
|
413
|
-
Array.isArray(this.columns) && this.columns.length > 0
|
|
414
|
-
? computeEffectiveColumnsFn(
|
|
415
|
-
this.columns,
|
|
416
|
-
this.augmentFromDisplayFunction,
|
|
417
|
-
this.displayFunction,
|
|
418
|
-
this.data
|
|
419
|
-
)
|
|
420
|
-
: computeColumnsFromDisplayFunctionFn(this.displayFunction, this.data);
|
|
417
|
+
const allCols = this.__getEffectiveColumns();
|
|
421
418
|
const col = allCols.find((c) => String(c.key) === this.__focusedCell!.colKey);
|
|
422
419
|
if (!col || !this.__isColumnEditable(col)) return;
|
|
423
420
|
eventArg.preventDefault();
|
|
@@ -469,15 +466,24 @@ export class DeesTable<T> extends DeesElement {
|
|
|
469
466
|
* that affect it. Avoids re-running `computeEffectiveColumnsFn` /
|
|
470
467
|
* `computeColumnsFromDisplayFunctionFn` on every Lit update.
|
|
471
468
|
*/
|
|
469
|
+
private __getDisplayFunctionShapeKey(): string {
|
|
470
|
+
if (!this.data || this.data.length === 0) return '';
|
|
471
|
+
const firstTransformedItem = this.displayFunction(this.data[0]) ?? {};
|
|
472
|
+
return Object.keys(firstTransformedItem).join('\u0000');
|
|
473
|
+
}
|
|
474
|
+
|
|
472
475
|
private __getEffectiveColumns(): Column<T>[] {
|
|
473
476
|
const usingColumns = Array.isArray(this.columns) && this.columns.length > 0;
|
|
477
|
+
const displayShapeKey = !usingColumns || this.augmentFromDisplayFunction
|
|
478
|
+
? this.__getDisplayFunctionShapeKey()
|
|
479
|
+
: '';
|
|
474
480
|
const cache = this.__memoEffectiveCols;
|
|
475
481
|
if (
|
|
476
482
|
cache &&
|
|
477
483
|
cache.columns === this.columns &&
|
|
478
484
|
cache.augment === this.augmentFromDisplayFunction &&
|
|
479
485
|
cache.displayFunction === this.displayFunction &&
|
|
480
|
-
cache.
|
|
486
|
+
cache.displayShapeKey === displayShapeKey
|
|
481
487
|
) {
|
|
482
488
|
return cache.out;
|
|
483
489
|
}
|
|
@@ -493,7 +499,7 @@ export class DeesTable<T> extends DeesElement {
|
|
|
493
499
|
columns: this.columns,
|
|
494
500
|
augment: this.augmentFromDisplayFunction,
|
|
495
501
|
displayFunction: this.displayFunction,
|
|
496
|
-
|
|
502
|
+
displayShapeKey,
|
|
497
503
|
out,
|
|
498
504
|
};
|
|
499
505
|
return out;
|
|
@@ -543,6 +549,9 @@ export class DeesTable<T> extends DeesElement {
|
|
|
543
549
|
public render(): TemplateResult {
|
|
544
550
|
const effectiveColumns = this.__getEffectiveColumns();
|
|
545
551
|
const viewData = this.__getViewData(effectiveColumns);
|
|
552
|
+
const headerActions = this.getActionsForType('header');
|
|
553
|
+
const footerActions = this.getActionsForType('footer');
|
|
554
|
+
const inRowActions = this.getActionsForType('inRow');
|
|
546
555
|
(this as any)._lastViewData = viewData;
|
|
547
556
|
|
|
548
557
|
// Virtualization slice — only the rows in `__virtualRange` actually
|
|
@@ -572,29 +581,22 @@ export class DeesTable<T> extends DeesElement {
|
|
|
572
581
|
<div class="heading heading2">${this.heading2}</div>
|
|
573
582
|
</div>
|
|
574
583
|
<div class="headerActions">
|
|
575
|
-
${
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
${action.name}`
|
|
592
|
-
: action.name}
|
|
593
|
-
</div>`
|
|
594
|
-
);
|
|
595
|
-
}
|
|
596
|
-
return resultArray;
|
|
597
|
-
})}
|
|
584
|
+
${headerActions.map(
|
|
585
|
+
(action) => html`<div
|
|
586
|
+
class="headerAction"
|
|
587
|
+
@click=${() => {
|
|
588
|
+
action.actionFunc({
|
|
589
|
+
item: this.selectedDataRow,
|
|
590
|
+
table: this,
|
|
591
|
+
});
|
|
592
|
+
}}
|
|
593
|
+
>
|
|
594
|
+
${action.iconName
|
|
595
|
+
? html`<dees-icon .iconSize=${14} .icon=${action.iconName}></dees-icon>
|
|
596
|
+
${action.name}`
|
|
597
|
+
: action.name}
|
|
598
|
+
</div>`
|
|
599
|
+
)}
|
|
598
600
|
</div>
|
|
599
601
|
</div>
|
|
600
602
|
<div class="headingSeparation"></div>
|
|
@@ -658,11 +660,11 @@ export class DeesTable<T> extends DeesElement {
|
|
|
658
660
|
: html``}
|
|
659
661
|
${directives.repeat(
|
|
660
662
|
renderRows,
|
|
661
|
-
(itemArg
|
|
663
|
+
(itemArg) => this.getRowId(itemArg),
|
|
662
664
|
(itemArg, sliceIdx) => {
|
|
663
665
|
const rowIndex = renderStart + sliceIdx;
|
|
664
666
|
const rowId = this.getRowId(itemArg);
|
|
665
|
-
const
|
|
667
|
+
const flashTokens = this.__flashingCells.get(rowId);
|
|
666
668
|
return html`
|
|
667
669
|
<tr
|
|
668
670
|
data-row-idx=${rowIndex}
|
|
@@ -694,7 +696,8 @@ export class DeesTable<T> extends DeesElement {
|
|
|
694
696
|
const isEditing =
|
|
695
697
|
this.__editingCell?.rowId === rowId &&
|
|
696
698
|
this.__editingCell?.colKey === editKey;
|
|
697
|
-
const
|
|
699
|
+
const flashToken = flashTokens?.get(editKey);
|
|
700
|
+
const isFlashing = flashToken !== undefined;
|
|
698
701
|
const useFlashBorder = isFlashing && !!col.flashBorder;
|
|
699
702
|
const cellClasses = [
|
|
700
703
|
isEditable ? 'editable' : '',
|
|
@@ -720,7 +723,7 @@ export class DeesTable<T> extends DeesElement {
|
|
|
720
723
|
>
|
|
721
724
|
${isFlashing
|
|
722
725
|
? directives.keyed(
|
|
723
|
-
`${rowId}:${editKey}:${
|
|
726
|
+
`${rowId}:${editKey}:${flashToken}`,
|
|
724
727
|
innerHtml
|
|
725
728
|
)
|
|
726
729
|
: innerHtml}
|
|
@@ -728,11 +731,11 @@ export class DeesTable<T> extends DeesElement {
|
|
|
728
731
|
`;
|
|
729
732
|
})}
|
|
730
733
|
${(() => {
|
|
731
|
-
if (
|
|
734
|
+
if (inRowActions.length > 0) {
|
|
732
735
|
return html`
|
|
733
736
|
<td class="actionsCol">
|
|
734
737
|
<div class="actionsContainer">
|
|
735
|
-
${
|
|
738
|
+
${inRowActions.map(
|
|
736
739
|
(actionArg) => html`
|
|
737
740
|
<div
|
|
738
741
|
class="action"
|
|
@@ -780,29 +783,22 @@ export class DeesTable<T> extends DeesElement {
|
|
|
780
783
|
selected
|
|
781
784
|
</div>
|
|
782
785
|
<div class="footerActions">
|
|
783
|
-
${
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
${action.name}`
|
|
800
|
-
: action.name}
|
|
801
|
-
</div>`
|
|
802
|
-
);
|
|
803
|
-
}
|
|
804
|
-
return resultArray;
|
|
805
|
-
})}
|
|
786
|
+
${footerActions.map(
|
|
787
|
+
(action) => html`<div
|
|
788
|
+
class="footerAction"
|
|
789
|
+
@click=${() => {
|
|
790
|
+
action.actionFunc({
|
|
791
|
+
item: this.selectedDataRow,
|
|
792
|
+
table: this,
|
|
793
|
+
});
|
|
794
|
+
}}
|
|
795
|
+
>
|
|
796
|
+
${action.iconName
|
|
797
|
+
? html`<dees-icon .iconSize=${14} .icon=${action.iconName}></dees-icon>
|
|
798
|
+
${action.name}`
|
|
799
|
+
: action.name}
|
|
800
|
+
</div>`
|
|
801
|
+
)}
|
|
806
802
|
</div>
|
|
807
803
|
</div>
|
|
808
804
|
</dees-tile>
|
|
@@ -1160,7 +1156,7 @@ export class DeesTable<T> extends DeesElement {
|
|
|
1160
1156
|
/**
|
|
1161
1157
|
* Measures the height of the first rendered body row and stores it for
|
|
1162
1158
|
* subsequent virtualization math. Idempotent — only measures once per
|
|
1163
|
-
*
|
|
1159
|
+
* rendered table layout (cleared in `updated()` when that layout changes).
|
|
1164
1160
|
*/
|
|
1165
1161
|
private __measureRowHeight() {
|
|
1166
1162
|
if (!this.virtualized || this.__rowHeightMeasured) return;
|
|
@@ -1426,20 +1422,16 @@ export class DeesTable<T> extends DeesElement {
|
|
|
1426
1422
|
if (newlyFlashing.size === 0) return;
|
|
1427
1423
|
|
|
1428
1424
|
// Merge with any in-flight flashes from a rapid second update so a cell
|
|
1429
|
-
// that changes twice before its animation ends gets a
|
|
1430
|
-
//
|
|
1425
|
+
// that changes twice before its animation ends gets a clean restart,
|
|
1426
|
+
// while unrelated cells keep their existing DOM subtree.
|
|
1427
|
+
const flashToken = ++this.__flashTick;
|
|
1428
|
+
const nextFlashingCells = new Map(this.__flashingCells);
|
|
1431
1429
|
for (const [rowId, cols] of newlyFlashing) {
|
|
1432
|
-
const existing =
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
} else {
|
|
1436
|
-
this.__flashingCells.set(rowId, cols);
|
|
1437
|
-
}
|
|
1430
|
+
const existing = new Map(nextFlashingCells.get(rowId) ?? []);
|
|
1431
|
+
for (const colKey of cols) existing.set(colKey, flashToken);
|
|
1432
|
+
nextFlashingCells.set(rowId, existing);
|
|
1438
1433
|
}
|
|
1439
|
-
this.
|
|
1440
|
-
// Reactivity nudge: we've mutated the Map in place, so give Lit a fresh
|
|
1441
|
-
// reference so the @state change fires for render.
|
|
1442
|
-
this.__flashingCells = new Map(this.__flashingCells);
|
|
1434
|
+
this.__flashingCells = nextFlashingCells;
|
|
1443
1435
|
if (this.__flashClearTimer) clearTimeout(this.__flashClearTimer);
|
|
1444
1436
|
this.__flashClearTimer = setTimeout(() => {
|
|
1445
1437
|
this.__flashingCells = new Map();
|
|
@@ -1449,6 +1441,9 @@ export class DeesTable<T> extends DeesElement {
|
|
|
1449
1441
|
|
|
1450
1442
|
public async updated(changedProperties: Map<string | number | symbol, unknown>): Promise<void> {
|
|
1451
1443
|
super.updated(changedProperties);
|
|
1444
|
+
const effectiveColumns = this.__getEffectiveColumns();
|
|
1445
|
+
const currentTable = this.shadowRoot?.querySelector('table') ?? null;
|
|
1446
|
+
const inRowActionCount = this.getActionsForType('inRow').length;
|
|
1452
1447
|
|
|
1453
1448
|
// Feed highlightDuration into the CSS variable so JS and CSS stay in
|
|
1454
1449
|
// sync via a single source of truth.
|
|
@@ -1456,15 +1451,23 @@ export class DeesTable<T> extends DeesElement {
|
|
|
1456
1451
|
this.style.setProperty('--dees-table-flash-duration', `${this.highlightDuration}ms`);
|
|
1457
1452
|
}
|
|
1458
1453
|
|
|
1459
|
-
// Only re-measure column widths when
|
|
1460
|
-
//
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1454
|
+
// Only re-measure column widths when layout-affecting inputs changed or
|
|
1455
|
+
// when a new <table> element was rendered after previously having none.
|
|
1456
|
+
const columnLayoutChanged =
|
|
1457
|
+
!!currentTable && (
|
|
1458
|
+
!this.__columnsSizedFor ||
|
|
1459
|
+
this.__columnsSizedFor.effectiveColumns !== effectiveColumns ||
|
|
1460
|
+
this.__columnsSizedFor.showSelectionCheckbox !== this.showSelectionCheckbox ||
|
|
1461
|
+
this.__columnsSizedFor.inRowActionCount !== inRowActionCount ||
|
|
1462
|
+
this.__columnsSizedFor.table !== currentTable
|
|
1463
|
+
);
|
|
1464
|
+
if (currentTable && columnLayoutChanged) {
|
|
1465
|
+
this.__columnsSizedFor = {
|
|
1466
|
+
effectiveColumns,
|
|
1467
|
+
showSelectionCheckbox: this.showSelectionCheckbox,
|
|
1468
|
+
inRowActionCount,
|
|
1469
|
+
table: currentTable,
|
|
1470
|
+
};
|
|
1468
1471
|
this.determineColumnWidths();
|
|
1469
1472
|
// Force re-measure of row height; structure may have changed.
|
|
1470
1473
|
this.__rowHeightMeasured = false;
|
|
@@ -1502,7 +1505,7 @@ export class DeesTable<T> extends DeesElement {
|
|
|
1502
1505
|
if (
|
|
1503
1506
|
!this.fixedHeight &&
|
|
1504
1507
|
this.data.length > 0 &&
|
|
1505
|
-
(this.__floatingActive ||
|
|
1508
|
+
(this.__floatingActive || columnLayoutChanged)
|
|
1506
1509
|
) {
|
|
1507
1510
|
this.__syncFloatingHeader();
|
|
1508
1511
|
}
|
|
@@ -1804,10 +1807,7 @@ export class DeesTable<T> extends DeesElement {
|
|
|
1804
1807
|
* Used by the modal helper to render human-friendly labels.
|
|
1805
1808
|
*/
|
|
1806
1809
|
private _lookupColumnByKey(key: string): Column<T> | undefined {
|
|
1807
|
-
const
|
|
1808
|
-
const effective = usingColumns
|
|
1809
|
-
? computeEffectiveColumnsFn(this.columns, this.augmentFromDisplayFunction, this.displayFunction, this.data)
|
|
1810
|
-
: computeColumnsFromDisplayFunctionFn(this.displayFunction, this.data);
|
|
1810
|
+
const effective = this.__getEffectiveColumns();
|
|
1811
1811
|
return effective.find((c) => String(c.key) === key);
|
|
1812
1812
|
}
|
|
1813
1813
|
|
|
@@ -2543,9 +2543,7 @@ export class DeesTable<T> extends DeesElement {
|
|
|
2543
2543
|
const view: T[] = (this as any)._lastViewData ?? [];
|
|
2544
2544
|
if (view.length === 0) return;
|
|
2545
2545
|
// Recompute editable columns from the latest effective set.
|
|
2546
|
-
const allCols
|
|
2547
|
-
? computeEffectiveColumnsFn(this.columns, this.augmentFromDisplayFunction, this.displayFunction, this.data)
|
|
2548
|
-
: computeColumnsFromDisplayFunctionFn(this.displayFunction, this.data);
|
|
2546
|
+
const allCols = this.__getEffectiveColumns();
|
|
2549
2547
|
const editableCols = this.__editableColumns(allCols);
|
|
2550
2548
|
if (editableCols.length === 0) return;
|
|
2551
2549
|
|