wunderbaum 0.10.1 → 0.11.1
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/README.md +6 -7
- package/dist/wunderbaum.css +18 -10
- package/dist/wunderbaum.css.map +1 -1
- package/dist/wunderbaum.d.ts +204 -49
- package/dist/wunderbaum.esm.js +826 -606
- package/dist/wunderbaum.esm.min.js +26 -26
- package/dist/wunderbaum.esm.min.js.map +1 -1
- package/dist/wunderbaum.umd.js +826 -606
- package/dist/wunderbaum.umd.min.js +32 -32
- package/dist/wunderbaum.umd.min.js.map +1 -1
- package/package.json +11 -10
- package/src/common.ts +17 -2
- package/src/types.ts +126 -30
- package/src/util.ts +18 -8
- package/src/wb_ext_dnd.ts +9 -4
- package/src/wb_ext_edit.ts +4 -0
- package/src/wb_ext_grid.ts +1 -1
- package/src/wb_node.ts +164 -17
- package/src/wb_options.ts +26 -2
- package/src/wunderbaum.scss +10 -0
- package/src/wunderbaum.ts +124 -47
package/src/wunderbaum.ts
CHANGED
|
@@ -47,6 +47,7 @@ import {
|
|
|
47
47
|
SetActiveOptions,
|
|
48
48
|
SetColumnOptions,
|
|
49
49
|
SetStatusOptions,
|
|
50
|
+
SortByPropertyOptions,
|
|
50
51
|
SortCallback,
|
|
51
52
|
SourceType,
|
|
52
53
|
UpdateOptions,
|
|
@@ -60,7 +61,7 @@ import {
|
|
|
60
61
|
makeNodeTitleStartMatcher,
|
|
61
62
|
nodeTitleSorter,
|
|
62
63
|
RENDER_MAX_PREFETCH,
|
|
63
|
-
|
|
64
|
+
DEFAULT_ROW_HEIGHT,
|
|
64
65
|
} from "./common";
|
|
65
66
|
import { WunderbaumNode } from "./wb_node";
|
|
66
67
|
import { Deferred } from "./deferred";
|
|
@@ -196,7 +197,7 @@ export class Wunderbaum {
|
|
|
196
197
|
debugLevel: DEFAULT_DEBUGLEVEL, // 0:quiet, 1:errors, 2:warnings, 3:info, 4:verbose
|
|
197
198
|
header: null, // Show/hide header (pass bool or string)
|
|
198
199
|
// headerHeightPx: ROW_HEIGHT,
|
|
199
|
-
rowHeightPx:
|
|
200
|
+
rowHeightPx: DEFAULT_ROW_HEIGHT,
|
|
200
201
|
iconMap: "bootstrap",
|
|
201
202
|
columns: null,
|
|
202
203
|
types: null,
|
|
@@ -285,7 +286,7 @@ export class Wunderbaum {
|
|
|
285
286
|
delete opts.types;
|
|
286
287
|
|
|
287
288
|
// --- Create Markup
|
|
288
|
-
this.element = util.elemFromSelector(opts.element)
|
|
289
|
+
this.element = util.elemFromSelector<HTMLDivElement>(opts.element)!;
|
|
289
290
|
util.assert(!!this.element, `Invalid 'element' option: ${opts.element}`);
|
|
290
291
|
|
|
291
292
|
this.element.classList.add("wunderbaum");
|
|
@@ -293,14 +294,23 @@ export class Wunderbaum {
|
|
|
293
294
|
this.element.tabIndex = 0;
|
|
294
295
|
}
|
|
295
296
|
|
|
297
|
+
if (opts.rowHeightPx !== DEFAULT_ROW_HEIGHT) {
|
|
298
|
+
this.element.style.setProperty(
|
|
299
|
+
"--wb-row-outer-height",
|
|
300
|
+
opts.rowHeightPx + "px"
|
|
301
|
+
);
|
|
302
|
+
this.element.style.setProperty(
|
|
303
|
+
"--wb-row-inner-height",
|
|
304
|
+
opts.rowHeightPx - 2 + "px"
|
|
305
|
+
);
|
|
306
|
+
}
|
|
296
307
|
// Attach tree instance to <div>
|
|
297
308
|
(<any>this.element)._wb_tree = this;
|
|
298
309
|
|
|
299
310
|
// Create header markup, or take it from the existing html
|
|
300
311
|
|
|
301
|
-
this.headerElement =
|
|
302
|
-
"div.wb-header"
|
|
303
|
-
) as HTMLDivElement;
|
|
312
|
+
this.headerElement =
|
|
313
|
+
this.element.querySelector<HTMLDivElement>("div.wb-header")!;
|
|
304
314
|
|
|
305
315
|
const wantHeader =
|
|
306
316
|
opts.header == null ? this.columns.length > 1 : !!opts.header;
|
|
@@ -312,9 +322,8 @@ export class Wunderbaum {
|
|
|
312
322
|
"`opts.columns` must not be set if markup already contains a header"
|
|
313
323
|
);
|
|
314
324
|
this.columns = [];
|
|
315
|
-
const rowElement =
|
|
316
|
-
"div.wb-row"
|
|
317
|
-
) as HTMLDivElement;
|
|
325
|
+
const rowElement =
|
|
326
|
+
this.headerElement.querySelector<HTMLDivElement>("div.wb-row")!;
|
|
318
327
|
for (const colDiv of rowElement.querySelectorAll("div")) {
|
|
319
328
|
this.columns.push({
|
|
320
329
|
id: colDiv.dataset.id || `col_${this.columns.length}`,
|
|
@@ -337,9 +346,7 @@ export class Wunderbaum {
|
|
|
337
346
|
</div>`;
|
|
338
347
|
|
|
339
348
|
if (!wantHeader) {
|
|
340
|
-
const he = this.element.querySelector(
|
|
341
|
-
"div.wb-header"
|
|
342
|
-
) as HTMLDivElement;
|
|
349
|
+
const he = this.element.querySelector<HTMLDivElement>("div.wb-header")!;
|
|
343
350
|
he.style.display = "none";
|
|
344
351
|
}
|
|
345
352
|
}
|
|
@@ -349,15 +356,15 @@ export class Wunderbaum {
|
|
|
349
356
|
<div class="wb-list-container">
|
|
350
357
|
<div class="wb-node-list"></div>
|
|
351
358
|
</div>`;
|
|
352
|
-
this.listContainerElement = this.element.querySelector(
|
|
359
|
+
this.listContainerElement = this.element.querySelector<HTMLDivElement>(
|
|
353
360
|
"div.wb-list-container"
|
|
354
|
-
)
|
|
355
|
-
this.nodeListElement =
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
+
)!;
|
|
362
|
+
this.nodeListElement =
|
|
363
|
+
this.listContainerElement.querySelector<HTMLDivElement>(
|
|
364
|
+
"div.wb-node-list"
|
|
365
|
+
)!;
|
|
366
|
+
this.headerElement =
|
|
367
|
+
this.element.querySelector<HTMLDivElement>("div.wb-header")!;
|
|
361
368
|
|
|
362
369
|
this.element.classList.toggle("wb-grid", this.columns.length > 1);
|
|
363
370
|
|
|
@@ -418,6 +425,17 @@ export class Wunderbaum {
|
|
|
418
425
|
});
|
|
419
426
|
this.resizeObserver.observe(this.element);
|
|
420
427
|
|
|
428
|
+
util.onEvent(this.element, "click", ".wb-button,.wb-col-icon", (e) => {
|
|
429
|
+
const info = Wunderbaum.getEventInfo(e);
|
|
430
|
+
const command = (<HTMLElement>e.target)?.dataset?.command;
|
|
431
|
+
|
|
432
|
+
this._callEvent("buttonClick", {
|
|
433
|
+
event: e,
|
|
434
|
+
info: info,
|
|
435
|
+
command: command,
|
|
436
|
+
});
|
|
437
|
+
});
|
|
438
|
+
|
|
421
439
|
util.onEvent(this.nodeListElement, "click", "div.wb-row", (e) => {
|
|
422
440
|
const info = Wunderbaum.getEventInfo(e);
|
|
423
441
|
const node = info.node;
|
|
@@ -751,6 +769,7 @@ export class Wunderbaum {
|
|
|
751
769
|
|
|
752
770
|
/** Return the topmost visible node in the viewport. */
|
|
753
771
|
getTopmostVpNode(complete = true) {
|
|
772
|
+
const rowHeight = this.options.rowHeightPx!;
|
|
754
773
|
const gracePx = 1; // ignore subpixel scrolling
|
|
755
774
|
const scrollParent = this.element;
|
|
756
775
|
// const headerHeight = this.headerElement.clientHeight; // May be 0
|
|
@@ -758,15 +777,16 @@ export class Wunderbaum {
|
|
|
758
777
|
let topIdx: number;
|
|
759
778
|
|
|
760
779
|
if (complete) {
|
|
761
|
-
topIdx = Math.ceil((scrollTop - gracePx) /
|
|
780
|
+
topIdx = Math.ceil((scrollTop - gracePx) / rowHeight);
|
|
762
781
|
} else {
|
|
763
|
-
topIdx = Math.floor(scrollTop /
|
|
782
|
+
topIdx = Math.floor(scrollTop / rowHeight);
|
|
764
783
|
}
|
|
765
784
|
return this._getNodeByRowIdx(topIdx)!;
|
|
766
785
|
}
|
|
767
786
|
|
|
768
787
|
/** Return the lowest visible node in the viewport. */
|
|
769
788
|
getLowestVpNode(complete = true) {
|
|
789
|
+
const rowHeight = this.options.rowHeightPx!;
|
|
770
790
|
const scrollParent = this.element;
|
|
771
791
|
const headerHeight = this.headerElement.clientHeight; // May be 0
|
|
772
792
|
const scrollTop = scrollParent.scrollTop;
|
|
@@ -774,9 +794,9 @@ export class Wunderbaum {
|
|
|
774
794
|
let bottomIdx: number;
|
|
775
795
|
|
|
776
796
|
if (complete) {
|
|
777
|
-
bottomIdx = Math.floor((scrollTop + clientHeight) /
|
|
797
|
+
bottomIdx = Math.floor((scrollTop + clientHeight) / rowHeight) - 1;
|
|
778
798
|
} else {
|
|
779
|
-
bottomIdx = Math.ceil((scrollTop + clientHeight) /
|
|
799
|
+
bottomIdx = Math.ceil((scrollTop + clientHeight) / rowHeight) - 1;
|
|
780
800
|
}
|
|
781
801
|
bottomIdx = Math.min(bottomIdx, this.count(true) - 1);
|
|
782
802
|
return this._getNodeByRowIdx(bottomIdx)!;
|
|
@@ -1078,7 +1098,7 @@ export class Wunderbaum {
|
|
|
1078
1098
|
|
|
1079
1099
|
/** Run code, but defer rendering of viewport until done.
|
|
1080
1100
|
*
|
|
1081
|
-
* ```
|
|
1101
|
+
* ```js
|
|
1082
1102
|
* tree.runWithDeferredUpdate(() => {
|
|
1083
1103
|
* return someFuncThatWouldUpdateManyNodes();
|
|
1084
1104
|
* });
|
|
@@ -1274,9 +1294,10 @@ export class Wunderbaum {
|
|
|
1274
1294
|
* @param includeHidden Not yet implemented
|
|
1275
1295
|
*/
|
|
1276
1296
|
findRelatedNode(node: WunderbaumNode, where: string, includeHidden = false) {
|
|
1297
|
+
const rowHeight = this.options.rowHeightPx!;
|
|
1277
1298
|
let res = null;
|
|
1278
1299
|
const pageSize = Math.floor(
|
|
1279
|
-
this.listContainerElement.clientHeight /
|
|
1300
|
+
this.listContainerElement.clientHeight / rowHeight
|
|
1280
1301
|
);
|
|
1281
1302
|
|
|
1282
1303
|
switch (where) {
|
|
@@ -1602,7 +1623,7 @@ export class Wunderbaum {
|
|
|
1602
1623
|
}
|
|
1603
1624
|
}
|
|
1604
1625
|
|
|
1605
|
-
/** Reset column widths to default. */
|
|
1626
|
+
/** Reset column widths to default. @since 0.10.0 */
|
|
1606
1627
|
resetColumns() {
|
|
1607
1628
|
this.columns.forEach((col) => {
|
|
1608
1629
|
delete col.customWidthPx;
|
|
@@ -1610,6 +1631,11 @@ export class Wunderbaum {
|
|
|
1610
1631
|
this.update(ChangeType.colStructure);
|
|
1611
1632
|
}
|
|
1612
1633
|
|
|
1634
|
+
// /** Renumber nodes `_nativeIndex`. @see {@link WunderbaumNode.resetNativeChildOrder} */
|
|
1635
|
+
// resetNativeChildOrder(options?: ResetOrderOptions) {
|
|
1636
|
+
// this.root.resetNativeChildOrder(options);
|
|
1637
|
+
// }
|
|
1638
|
+
|
|
1613
1639
|
/**
|
|
1614
1640
|
* Make sure that this node is vertically scrolled into the viewport.
|
|
1615
1641
|
*
|
|
@@ -1620,7 +1646,7 @@ export class Wunderbaum {
|
|
|
1620
1646
|
const PADDING = 2; // leave some pixels between viewport bounds
|
|
1621
1647
|
|
|
1622
1648
|
let node;
|
|
1623
|
-
WunderbaumNode;
|
|
1649
|
+
// WunderbaumNode;
|
|
1624
1650
|
let options: ScrollToOptions | undefined;
|
|
1625
1651
|
|
|
1626
1652
|
if (nodeOrOpts instanceof WunderbaumNode) {
|
|
@@ -1631,14 +1657,15 @@ export class Wunderbaum {
|
|
|
1631
1657
|
}
|
|
1632
1658
|
util.assert(node && node._rowIdx != null, `Invalid node: ${node}`);
|
|
1633
1659
|
|
|
1660
|
+
const rowHeight = this.options.rowHeightPx!;
|
|
1634
1661
|
const scrollParent = this.element;
|
|
1635
1662
|
const headerHeight = this.headerElement.clientHeight; // May be 0
|
|
1636
1663
|
const scrollTop = scrollParent.scrollTop;
|
|
1637
1664
|
const vpHeight = scrollParent.clientHeight;
|
|
1638
|
-
const rowTop = node._rowIdx! *
|
|
1665
|
+
const rowTop = node._rowIdx! * rowHeight + headerHeight;
|
|
1639
1666
|
const vpTop = headerHeight;
|
|
1640
1667
|
const vpRowTop = rowTop - scrollTop;
|
|
1641
|
-
const vpRowBottom = vpRowTop +
|
|
1668
|
+
const vpRowBottom = vpRowTop + rowHeight;
|
|
1642
1669
|
const topNode = options?.topNode;
|
|
1643
1670
|
|
|
1644
1671
|
// this.log( `scrollTo(${node.title}), vpTop:${vpTop}px, scrollTop:${scrollTop}, vpHeight:${vpHeight}, rowTop:${rowTop}, vpRowTop:${vpRowTop}`, nodeOrOpts , options);
|
|
@@ -1651,7 +1678,7 @@ export class Wunderbaum {
|
|
|
1651
1678
|
} else {
|
|
1652
1679
|
// Node is below viewport
|
|
1653
1680
|
// this.log("Below viewport");
|
|
1654
|
-
newScrollTop = rowTop +
|
|
1681
|
+
newScrollTop = rowTop + rowHeight - vpHeight + PADDING; // leave some pixels between viewport bounds
|
|
1655
1682
|
}
|
|
1656
1683
|
} else {
|
|
1657
1684
|
// Node is above viewport
|
|
@@ -1790,15 +1817,15 @@ export class Wunderbaum {
|
|
|
1790
1817
|
* The render operation is async and debounced unless the `immediate` option
|
|
1791
1818
|
* is set.
|
|
1792
1819
|
*
|
|
1793
|
-
* Use {@link WunderbaumNode.update
|
|
1794
|
-
* or {@link WunderbaumNode._render
|
|
1820
|
+
* Use {@link WunderbaumNode.update} if only a single node has changed,
|
|
1821
|
+
* or {@link WunderbaumNode._render}) to pass special options.
|
|
1795
1822
|
*/
|
|
1796
1823
|
update(change: ChangeType, options?: UpdateOptions): void;
|
|
1797
1824
|
|
|
1798
1825
|
/**
|
|
1799
1826
|
* Update a row to reflect a single node's modification.
|
|
1800
1827
|
*
|
|
1801
|
-
* @see {@link WunderbaumNode.update
|
|
1828
|
+
* @see {@link WunderbaumNode.update}, {@link WunderbaumNode._render}
|
|
1802
1829
|
*/
|
|
1803
1830
|
update(
|
|
1804
1831
|
change: ChangeType,
|
|
@@ -1988,6 +2015,15 @@ export class Wunderbaum {
|
|
|
1988
2015
|
this.root.sortChildren(cmp, deep);
|
|
1989
2016
|
}
|
|
1990
2017
|
|
|
2018
|
+
/**
|
|
2019
|
+
* Convenience method to implement column sorting.
|
|
2020
|
+
* @see {@link WunderbaumNode.sortByProperty}.
|
|
2021
|
+
* @since 0.11.0
|
|
2022
|
+
*/
|
|
2023
|
+
sortByProperty(options: SortByPropertyOptions) {
|
|
2024
|
+
this.root.sortByProperty(options);
|
|
2025
|
+
}
|
|
2026
|
+
|
|
1991
2027
|
/** Convert tree to an array of plain objects.
|
|
1992
2028
|
*
|
|
1993
2029
|
* @param callback is called for every node, in order to allow
|
|
@@ -2109,6 +2145,12 @@ export class Wunderbaum {
|
|
|
2109
2145
|
return modified;
|
|
2110
2146
|
}
|
|
2111
2147
|
|
|
2148
|
+
protected _insertIcon(icon: string, elem: HTMLElement) {
|
|
2149
|
+
const iconElem = document.createElement("i");
|
|
2150
|
+
iconElem.className = icon;
|
|
2151
|
+
elem.appendChild(iconElem);
|
|
2152
|
+
}
|
|
2153
|
+
|
|
2112
2154
|
/** Create/update header markup from `this.columns` definition.
|
|
2113
2155
|
* @internal
|
|
2114
2156
|
*/
|
|
@@ -2119,6 +2161,7 @@ export class Wunderbaum {
|
|
|
2119
2161
|
if (!wantHeader) {
|
|
2120
2162
|
return;
|
|
2121
2163
|
}
|
|
2164
|
+
const iconMap = this.iconMap;
|
|
2122
2165
|
const colCount = this.columns.length;
|
|
2123
2166
|
const headerRow = this.headerElement.querySelector(".wb-row")!;
|
|
2124
2167
|
util.assert(headerRow, "Expected a row in header element");
|
|
@@ -2139,22 +2182,55 @@ export class Wunderbaum {
|
|
|
2139
2182
|
col.classes ? colElem.classList.add(...col.classes.split(" ")) : 0;
|
|
2140
2183
|
}
|
|
2141
2184
|
|
|
2142
|
-
|
|
2185
|
+
// Add tooltip to column title
|
|
2143
2186
|
let tooltip = "";
|
|
2144
2187
|
if (col.tooltip) {
|
|
2145
2188
|
tooltip = util.escapeTooltip(col.tooltip);
|
|
2146
2189
|
tooltip = ` title="${tooltip}"`;
|
|
2147
2190
|
}
|
|
2148
|
-
|
|
2191
|
+
// Add column header icons
|
|
2192
|
+
let addMarkup = "";
|
|
2193
|
+
// NOTE: we use CSS float: right to align icons, so they must be added in
|
|
2194
|
+
// reverse order
|
|
2195
|
+
if (util.toBool(col.menu, this.options.columnsMenu, false)) {
|
|
2196
|
+
const iconClass = "wb-col-icon-menu " + iconMap.colMenu;
|
|
2197
|
+
const icon = `<i data-command=menu class="wb-col-icon ${iconClass}"></i>`;
|
|
2198
|
+
addMarkup += icon;
|
|
2199
|
+
}
|
|
2200
|
+
if (util.toBool(col.sortable, this.options.columnsSortable, false)) {
|
|
2201
|
+
let iconClass = "wb-col-icon-sort " + iconMap.colSortable;
|
|
2202
|
+
if (col.sortOrder) {
|
|
2203
|
+
iconClass += `wb-col-sort-${col.sortOrder}`;
|
|
2204
|
+
iconClass +=
|
|
2205
|
+
col.sortOrder === "asc" ? iconMap.colSortAsc : iconMap.colSortDesc;
|
|
2206
|
+
}
|
|
2207
|
+
const icon = `<i data-command=sort class="wb-col-icon ${iconClass}"></i>`;
|
|
2208
|
+
addMarkup += icon;
|
|
2209
|
+
}
|
|
2210
|
+
if (util.toBool(col.filterable, this.options.columnsFilterable, false)) {
|
|
2211
|
+
colElem.classList.toggle("wb-col-filter", !!col.filterActive);
|
|
2212
|
+
let iconClass = "wb-col-icon-filter " + iconMap.colFilter;
|
|
2213
|
+
if (col.filterActive) {
|
|
2214
|
+
iconClass += iconMap.colFilterActive;
|
|
2215
|
+
}
|
|
2216
|
+
const icon = `<i data-command=filter class="wb-col-icon ${iconClass}"></i>`;
|
|
2217
|
+
addMarkup += icon;
|
|
2218
|
+
}
|
|
2219
|
+
// Add resizer to all but the last column
|
|
2149
2220
|
if (i < colCount - 1) {
|
|
2150
|
-
if (util.toBool(col.resizable, this.options.
|
|
2151
|
-
|
|
2221
|
+
if (util.toBool(col.resizable, this.options.columnsResizable, false)) {
|
|
2222
|
+
addMarkup +=
|
|
2152
2223
|
'<span class="wb-col-resizer wb-col-resizer-active"></span>';
|
|
2153
2224
|
} else {
|
|
2154
|
-
|
|
2225
|
+
addMarkup += '<span class="wb-col-resizer"></span>';
|
|
2155
2226
|
}
|
|
2156
2227
|
}
|
|
2157
|
-
|
|
2228
|
+
|
|
2229
|
+
// Create column header
|
|
2230
|
+
const title = util.escapeHtml(col.title || col.id);
|
|
2231
|
+
colElem.innerHTML = `<span class="wb-col-title"${tooltip}>${title}</span>${addMarkup}`;
|
|
2232
|
+
|
|
2233
|
+
// Highlight active column
|
|
2158
2234
|
if (this.isCellNav()) {
|
|
2159
2235
|
colElem.classList.toggle("wb-active", i === this.activeColIdx);
|
|
2160
2236
|
}
|
|
@@ -2300,20 +2376,20 @@ export class Wunderbaum {
|
|
|
2300
2376
|
options = Object.assign({ newNodesOnly: false }, options);
|
|
2301
2377
|
const newNodesOnly = !!options.newNodesOnly;
|
|
2302
2378
|
|
|
2303
|
-
const
|
|
2304
|
-
const
|
|
2379
|
+
const rowHeight = this.options.rowHeightPx!;
|
|
2380
|
+
const vpHeight = this.element.clientHeight;
|
|
2305
2381
|
const prefetch = RENDER_MAX_PREFETCH;
|
|
2306
2382
|
// const grace_prefetch = RENDER_MAX_PREFETCH - RENDER_MIN_PREFETCH;
|
|
2307
2383
|
const ofs = this.element.scrollTop;
|
|
2308
2384
|
|
|
2309
|
-
let startIdx = Math.max(0, ofs /
|
|
2385
|
+
let startIdx = Math.max(0, ofs / rowHeight - prefetch);
|
|
2310
2386
|
startIdx = Math.floor(startIdx);
|
|
2311
2387
|
// Make sure start is always even, so the alternating row colors don't
|
|
2312
2388
|
// change when scrolling:
|
|
2313
2389
|
if (startIdx % 2) {
|
|
2314
2390
|
startIdx--;
|
|
2315
2391
|
}
|
|
2316
|
-
let endIdx = Math.max(0, (ofs +
|
|
2392
|
+
let endIdx = Math.max(0, (ofs + vpHeight) / rowHeight + prefetch);
|
|
2317
2393
|
endIdx = Math.ceil(endIdx);
|
|
2318
2394
|
|
|
2319
2395
|
// this.debug("render", opts);
|
|
@@ -2346,20 +2422,20 @@ export class Wunderbaum {
|
|
|
2346
2422
|
} else if (rowDiv && newNodesOnly) {
|
|
2347
2423
|
obsoleteNodes.delete(node);
|
|
2348
2424
|
// no need to update existing node markup
|
|
2349
|
-
rowDiv.style.top = idx *
|
|
2425
|
+
rowDiv.style.top = idx * rowHeight + "px";
|
|
2350
2426
|
prevElem = rowDiv;
|
|
2351
2427
|
} else {
|
|
2352
2428
|
obsoleteNodes.delete(node);
|
|
2353
2429
|
// Create new markup
|
|
2354
2430
|
if (rowDiv) {
|
|
2355
|
-
rowDiv.style.top = idx *
|
|
2431
|
+
rowDiv.style.top = idx * rowHeight + "px";
|
|
2356
2432
|
}
|
|
2357
2433
|
node._render({ top: top, after: prevElem });
|
|
2358
2434
|
// node.log("render", top, prevElem, "=>", node._rowElem);
|
|
2359
2435
|
prevElem = node._rowElem!;
|
|
2360
2436
|
}
|
|
2361
2437
|
idx++;
|
|
2362
|
-
top +=
|
|
2438
|
+
top += rowHeight;
|
|
2363
2439
|
});
|
|
2364
2440
|
this.treeRowCount = idx;
|
|
2365
2441
|
for (const n of obsoleteNodes) {
|
|
@@ -2633,6 +2709,7 @@ export class Wunderbaum {
|
|
|
2633
2709
|
/**
|
|
2634
2710
|
* Return the number of nodes that match the current filter.
|
|
2635
2711
|
* @see {@link Wunderbaum.filterNodes}
|
|
2712
|
+
* @since 0.9.0
|
|
2636
2713
|
*/
|
|
2637
2714
|
countMatches(): number {
|
|
2638
2715
|
return (this.extensions.filter as FilterExtension).countMatches();
|