wunderbaum 0.10.1 → 0.11.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.
@@ -288,7 +288,7 @@ function throttle(func, wait = 0, options = {}) {
288
288
  /*!
289
289
  * Wunderbaum - util
290
290
  * Copyright (c) 2021-2024, Martin Wendt. Released under the MIT license.
291
- * v0.10.1, Sat, 20 Jul 2024 13:53:46 GMT (https://github.com/mar10/wunderbaum)
291
+ * v0.11.0, Sun, 04 Aug 2024 15:35:53 GMT (https://github.com/mar10/wunderbaum)
292
292
  */
293
293
  /** @module util */
294
294
  /** Readable names for `MouseEvent.button` */
@@ -920,6 +920,11 @@ function getOption(opts, name, defaultValue = undefined) {
920
920
  // Use value from value options dict, fallback do default
921
921
  return value !== null && value !== void 0 ? value : defaultValue;
922
922
  }
923
+ /** Return the next value from a list of values (rotating). @since 0.11 */
924
+ function rotate(value, values) {
925
+ const idx = values.indexOf(value);
926
+ return values[(idx + 1) % values.length];
927
+ }
923
928
  /** Convert an Array or space-separated string to a Set. */
924
929
  function toSet(val) {
925
930
  if (val instanceof Set) {
@@ -948,12 +953,7 @@ function toSet(val) {
948
953
  * const width = util.toPixel(x, y, 100); // returns 123
949
954
  * ```
950
955
  */
951
- function toPixel(
952
- // val: string | number | undefined | null,
953
- ...defaults) {
954
- // if (typeof val === "number") {
955
- // return val;
956
- // }
956
+ function toPixel(...defaults) {
957
957
  for (const d of defaults) {
958
958
  if (typeof d === "number") {
959
959
  return d;
@@ -972,12 +972,7 @@ function toPixel(
972
972
  * const value = util.toBool(opts.foo, opts.flag, false); // returns true
973
973
  * ```
974
974
  */
975
- function toBool(
976
- // val: boolean | undefined | null,
977
- ...boolDefaults) {
978
- // if (val != null) {
979
- // return !!val;
980
- // }
975
+ function toBool(...boolDefaults) {
981
976
  for (const d of boolDefaults) {
982
977
  if (d != null) {
983
978
  return !!d;
@@ -1121,6 +1116,7 @@ var util = /*#__PURE__*/Object.freeze({
1121
1116
  noop: noop,
1122
1117
  onEvent: onEvent,
1123
1118
  overrideMethod: overrideMethod,
1119
+ rotate: rotate,
1124
1120
  setElemDisplay: setElemDisplay,
1125
1121
  setTimeoutPromise: setTimeoutPromise,
1126
1122
  setValueToElem: setValueToElem,
@@ -1136,10 +1132,10 @@ var util = /*#__PURE__*/Object.freeze({
1136
1132
  /*!
1137
1133
  * Wunderbaum - types
1138
1134
  * Copyright (c) 2021-2024, Martin Wendt. Released under the MIT license.
1139
- * v0.10.1, Sat, 20 Jul 2024 13:53:46 GMT (https://github.com/mar10/wunderbaum)
1135
+ * v0.11.0, Sun, 04 Aug 2024 15:35:53 GMT (https://github.com/mar10/wunderbaum)
1140
1136
  */
1141
1137
  /**
1142
- * Possible values for {@link WunderbaumNode.update()} and {@link Wunderbaum.update()}.
1138
+ * Possible values for {@link WunderbaumNode.update} and {@link Wunderbaum.update}.
1143
1139
  */
1144
1140
  var ChangeType;
1145
1141
  (function (ChangeType) {
@@ -1168,7 +1164,7 @@ var RenderFlag;
1168
1164
  RenderFlag["redraw"] = "redraw";
1169
1165
  RenderFlag["scroll"] = "scroll";
1170
1166
  })(RenderFlag || (RenderFlag = {}));
1171
- /** Possible values for {@link WunderbaumNode.setStatus()}. */
1167
+ /** Possible values for {@link WunderbaumNode.setStatus}. */
1172
1168
  var NodeStatusType;
1173
1169
  (function (NodeStatusType) {
1174
1170
  NodeStatusType["ok"] = "ok";
@@ -1200,7 +1196,7 @@ var NavModeEnum;
1200
1196
  /*!
1201
1197
  * Wunderbaum - wb_extension_base
1202
1198
  * Copyright (c) 2021-2024, Martin Wendt. Released under the MIT license.
1203
- * v0.10.1, Sat, 20 Jul 2024 13:53:46 GMT (https://github.com/mar10/wunderbaum)
1199
+ * v0.11.0, Sun, 04 Aug 2024 15:35:53 GMT (https://github.com/mar10/wunderbaum)
1204
1200
  */
1205
1201
  class WunderbaumExtension {
1206
1202
  constructor(tree, id, defaults) {
@@ -1259,7 +1255,7 @@ class WunderbaumExtension {
1259
1255
  /*!
1260
1256
  * Wunderbaum - ext-filter
1261
1257
  * Copyright (c) 2021-2024, Martin Wendt. Released under the MIT license.
1262
- * v0.10.1, Sat, 20 Jul 2024 13:53:46 GMT (https://github.com/mar10/wunderbaum)
1258
+ * v0.11.0, Sun, 04 Aug 2024 15:35:53 GMT (https://github.com/mar10/wunderbaum)
1263
1259
  */
1264
1260
  const START_MARKER = "\uFFF7";
1265
1261
  const END_MARKER = "\uFFF8";
@@ -1584,7 +1580,7 @@ function _markFuzzyMatchedChars(text, matches, escapeTitles = true) {
1584
1580
  /*!
1585
1581
  * Wunderbaum - ext-keynav
1586
1582
  * Copyright (c) 2021-2024, Martin Wendt. Released under the MIT license.
1587
- * v0.10.1, Sat, 20 Jul 2024 13:53:46 GMT (https://github.com/mar10/wunderbaum)
1583
+ * v0.11.0, Sun, 04 Aug 2024 15:35:53 GMT (https://github.com/mar10/wunderbaum)
1588
1584
  */
1589
1585
  const QUICKSEARCH_DELAY = 500;
1590
1586
  class KeynavExtension extends WunderbaumExtension {
@@ -1948,7 +1944,7 @@ class KeynavExtension extends WunderbaumExtension {
1948
1944
  /*!
1949
1945
  * Wunderbaum - ext-logger
1950
1946
  * Copyright (c) 2021-2024, Martin Wendt. Released under the MIT license.
1951
- * v0.10.1, Sat, 20 Jul 2024 13:53:46 GMT (https://github.com/mar10/wunderbaum)
1947
+ * v0.11.0, Sun, 04 Aug 2024 15:35:53 GMT (https://github.com/mar10/wunderbaum)
1952
1948
  */
1953
1949
  class LoggerExtension extends WunderbaumExtension {
1954
1950
  constructor(tree) {
@@ -1990,7 +1986,7 @@ class LoggerExtension extends WunderbaumExtension {
1990
1986
  /*!
1991
1987
  * Wunderbaum - common
1992
1988
  * Copyright (c) 2021-2024, Martin Wendt. Released under the MIT license.
1993
- * v0.10.1, Sat, 20 Jul 2024 13:53:46 GMT (https://github.com/mar10/wunderbaum)
1989
+ * v0.11.0, Sun, 04 Aug 2024 15:35:53 GMT (https://github.com/mar10/wunderbaum)
1994
1990
  */
1995
1991
  const DEFAULT_DEBUGLEVEL = 3; // Replaced by rollup script
1996
1992
  /**
@@ -2045,6 +2041,15 @@ const iconMaps = {
2045
2041
  folderOpen: "bi bi-folder2-open",
2046
2042
  folderLazy: "bi bi-folder-symlink",
2047
2043
  doc: "bi bi-file-earmark",
2044
+ colSortable: "bi bi-chevron-expand",
2045
+ // colSortable: "bi bi-arrow-down-up",
2046
+ // colSortAsc: "bi bi-chevron-down",
2047
+ // colSortDesc: "bi bi-chevron-up",
2048
+ colSortAsc: "bi bi-arrow-down",
2049
+ colSortDesc: "bi bi-arrow-up",
2050
+ colFilter: "bi bi-filter-circle",
2051
+ colFilterActive: "bi bi-filter-circle-fill wb-helper-invalid",
2052
+ colMenu: "bi bi-three-dots-vertical",
2048
2053
  },
2049
2054
  fontawesome6: {
2050
2055
  error: "fa-solid fa-triangle-exclamation",
@@ -2063,6 +2068,12 @@ const iconMaps = {
2063
2068
  folderOpen: "fa-regular fa-folder-open",
2064
2069
  folderLazy: "fa-solid fa-folder-plus",
2065
2070
  doc: "fa-regular fa-file",
2071
+ colSortable: "fa-solid fa-fw fa-sort",
2072
+ colSortAsc: "fa-solid fa-fw fa-sort-up",
2073
+ colSortDesc: "fa-solid fa-fw fa-sort-down",
2074
+ colFilter: "fa-solid fa-fw fa-filter",
2075
+ colFilterActive: "fa-solid fa-fw fa-filter wb-helper-invalid",
2076
+ colMenu: "fa-solid fa-fw fa-ellipsis-v",
2066
2077
  },
2067
2078
  };
2068
2079
  /** Dict keys that are evaluated by source loader (others are added to `tree.data` instead). */
@@ -2111,7 +2122,7 @@ const KEY_TO_ACTION_DICT = {
2111
2122
  };
2112
2123
  /** Return a callback that returns true if the node title matches the string
2113
2124
  * or regular expression.
2114
- * @see {@link WunderbaumNode.findAll()}
2125
+ * @see {@link WunderbaumNode.findAll}
2115
2126
  */
2116
2127
  function makeNodeTitleMatcher(match) {
2117
2128
  if (match instanceof RegExp) {
@@ -2315,7 +2326,7 @@ function decompressSourceData(source) {
2315
2326
  /*!
2316
2327
  * Wunderbaum - ext-dnd
2317
2328
  * Copyright (c) 2021-2024, Martin Wendt. Released under the MIT license.
2318
- * v0.10.1, Sat, 20 Jul 2024 13:53:46 GMT (https://github.com/mar10/wunderbaum)
2329
+ * v0.11.0, Sun, 04 Aug 2024 15:35:53 GMT (https://github.com/mar10/wunderbaum)
2319
2330
  */
2320
2331
  const nodeMimeType = "application/x-wunderbaum-node";
2321
2332
  class DndExtension extends WunderbaumExtension {
@@ -2760,7 +2771,7 @@ class DndExtension extends WunderbaumExtension {
2760
2771
  /*!
2761
2772
  * Wunderbaum - drag_observer
2762
2773
  * Copyright (c) 2021-2024, Martin Wendt. Released under the MIT license.
2763
- * v0.10.1, Sat, 20 Jul 2024 13:53:46 GMT (https://github.com/mar10/wunderbaum)
2774
+ * v0.11.0, Sun, 04 Aug 2024 15:35:53 GMT (https://github.com/mar10/wunderbaum)
2764
2775
  */
2765
2776
  /**
2766
2777
  * Convert mouse- and touch events to 'dragstart', 'drag', and 'dragstop'.
@@ -2909,7 +2920,7 @@ class DragObserver {
2909
2920
  /*!
2910
2921
  * Wunderbaum - ext-grid
2911
2922
  * Copyright (c) 2021-2024, Martin Wendt. Released under the MIT license.
2912
- * v0.10.1, Sat, 20 Jul 2024 13:53:46 GMT (https://github.com/mar10/wunderbaum)
2923
+ * v0.11.0, Sun, 04 Aug 2024 15:35:53 GMT (https://github.com/mar10/wunderbaum)
2913
2924
  */
2914
2925
  class GridExtension extends WunderbaumExtension {
2915
2926
  constructor(tree) {
@@ -2926,7 +2937,7 @@ class GridExtension extends WunderbaumExtension {
2926
2937
  const colDef = info.colDef;
2927
2938
  const allow = colDef &&
2928
2939
  this.tree.element.contains(e.dragElem) &&
2929
- toBool(colDef.resizable, tree.options.resizableColumns, false);
2940
+ toBool(colDef.resizable, tree.options.columnsResizable, false);
2930
2941
  // this.tree.log("dragstart", colDef, e, info);
2931
2942
  this.tree.element.classList.toggle("wb-col-resizing", !!allow);
2932
2943
  info.colElem.classList.toggle("wb-col-resizing", !!allow);
@@ -3000,7 +3011,7 @@ class GridExtension extends WunderbaumExtension {
3000
3011
  /*!
3001
3012
  * Wunderbaum - deferred
3002
3013
  * Copyright (c) 2021-2024, Martin Wendt. Released under the MIT license.
3003
- * v0.10.1, Sat, 20 Jul 2024 13:53:46 GMT (https://github.com/mar10/wunderbaum)
3014
+ * v0.11.0, Sun, 04 Aug 2024 15:35:53 GMT (https://github.com/mar10/wunderbaum)
3004
3015
  */
3005
3016
  /**
3006
3017
  * Implement a ES6 Promise, that exposes a resolve() and reject() method.
@@ -3053,7 +3064,7 @@ class Deferred {
3053
3064
  /*!
3054
3065
  * Wunderbaum - wunderbaum_node
3055
3066
  * Copyright (c) 2021-2024, Martin Wendt. Released under the MIT license.
3056
- * v0.10.1, Sat, 20 Jul 2024 13:53:46 GMT (https://github.com/mar10/wunderbaum)
3067
+ * v0.11.0, Sun, 04 Aug 2024 15:35:53 GMT (https://github.com/mar10/wunderbaum)
3057
3068
  */
3058
3069
  /** WunderbaumNode properties that can be passed with source data.
3059
3070
  * (Any other source properties will be stored as `node.data.PROP`.)
@@ -3096,6 +3107,12 @@ class WunderbaumNode {
3096
3107
  * @see Use {@link setKey} to modify.
3097
3108
  */
3098
3109
  this.refKey = undefined;
3110
+ /**
3111
+ * Array of child nodes (null for leaf nodes).
3112
+ * For lazy nodes, this is `null` or ùndefined` until the children are loaded
3113
+ * and leaf nodes may be `[]` (empty array).
3114
+ * @see {@link hasChildren}, {@link addChildren}, {@link lazy}.
3115
+ */
3099
3116
  this.children = null;
3100
3117
  /** Additional classes added to `div.wb-row`.
3101
3118
  * @see {@link hasClass}, {@link setClass}. */
@@ -3683,7 +3700,7 @@ class WunderbaumNode {
3683
3700
  hasClass(className) {
3684
3701
  return this.classes ? this.classes.has(className) : false;
3685
3702
  }
3686
- /** Return true if node ist the currently focused node. */
3703
+ /** Return true if node ist the currently focused node. @since 0.9.0 */
3687
3704
  hasFocus() {
3688
3705
  return this.tree.focusNode === this;
3689
3706
  }
@@ -3905,6 +3922,8 @@ class WunderbaumNode {
3905
3922
  if (tree.options.selectMode === "hier") {
3906
3923
  this.fixSelection3FromEndNodes();
3907
3924
  }
3925
+ // Allow to un-sort nodes after sorting
3926
+ this.resetNativeChildOrder();
3908
3927
  this._callEvent("load");
3909
3928
  }
3910
3929
  async _fetchWithOptions(source) {
@@ -4848,7 +4867,7 @@ class WunderbaumNode {
4848
4867
  *
4849
4868
  * @param name name of the option property (on node and tree)
4850
4869
  * @param defaultValue return this if nothing else matched
4851
- * {@link Wunderbaum.getOption|Wunderbaum.getOption()}
4870
+ * {@link Wunderbaum.getOption|Wunderbaum.getOption}
4852
4871
  */
4853
4872
  getOption(name, defaultValue) {
4854
4873
  const tree = this.tree;
@@ -4884,7 +4903,7 @@ class WunderbaumNode {
4884
4903
  return value !== null && value !== void 0 ? value : defaultValue;
4885
4904
  }
4886
4905
  /** Make sure that this node is visible in the viewport.
4887
- * @see {@link Wunderbaum.scrollTo|Wunderbaum.scrollTo()}
4906
+ * @see {@link Wunderbaum.scrollTo|Wunderbaum.scrollTo}
4888
4907
  */
4889
4908
  async scrollIntoView(options) {
4890
4909
  const opts = Object.assign({ node: this }, options);
@@ -5023,9 +5042,9 @@ class WunderbaumNode {
5023
5042
  * and column content. It can be reduced to 'ChangeType.status' if only
5024
5043
  * active/focus/selected state has changed.
5025
5044
  *
5026
- * This method will eventually call {@link WunderbaumNode._render()} with
5045
+ * This method will eventually call {@link WunderbaumNode._render} with
5027
5046
  * default options, but may be more consistent with the tree's
5028
- * {@link Wunderbaum.update()} API.
5047
+ * {@link Wunderbaum.update} API.
5029
5048
  */
5030
5049
  update(change = ChangeType.data) {
5031
5050
  assert(change === ChangeType.status || change === ChangeType.data, `Invalid change type ${change}`);
@@ -5354,6 +5373,80 @@ class WunderbaumNode {
5354
5373
  this.tree.update(ChangeType.structure);
5355
5374
  // this.triggerModify("sort"); // TODO
5356
5375
  }
5376
+ /**
5377
+ * Renumber nodes `_nativeIndex`. This is useful to allow to restore the
5378
+ * order after sorting a column.
5379
+ * This method is automatically called after loading new child nodes.
5380
+ * @since 0.11.0
5381
+ */
5382
+ resetNativeChildOrder(options) {
5383
+ const { recursive = true, propName = "_nativeIndex" } = options !== null && options !== void 0 ? options : {};
5384
+ if (this.children) {
5385
+ this.children.forEach((child, i) => {
5386
+ child.data[propName] = i;
5387
+ if (recursive && child.children) {
5388
+ child.resetNativeChildOrder(options);
5389
+ }
5390
+ });
5391
+ }
5392
+ }
5393
+ /**
5394
+ * Convenience method to implement column sorting.
5395
+ * @since 0.11.0
5396
+ */
5397
+ sortByProperty(options) {
5398
+ var _a, _b, _c;
5399
+ const { caseInsensitive = true, deep = true, nativeOrderPropName = "_nativeIndex", updateColInfo = false, } = options;
5400
+ let order;
5401
+ let colDef;
5402
+ if (updateColInfo) {
5403
+ colDef = this.tree["_columnsById"][options.colId];
5404
+ assert(colDef, `Invalid colId specified: ${options.colId}`);
5405
+ order =
5406
+ (_a = options.order) !== null && _a !== void 0 ? _a : rotate(colDef.sortOrder, ["asc", "desc", undefined]);
5407
+ for (const col of this.tree.columns) {
5408
+ col.sortOrder = col === colDef ? order : undefined;
5409
+ }
5410
+ this.tree.update(ChangeType.colStructure);
5411
+ }
5412
+ else {
5413
+ order = (_b = options.order) !== null && _b !== void 0 ? _b : "asc";
5414
+ }
5415
+ let propName = (_c = options.propName) !== null && _c !== void 0 ? _c : (options.colId || "");
5416
+ if (propName === "*") {
5417
+ propName = "title";
5418
+ }
5419
+ if (order == null) {
5420
+ propName = nativeOrderPropName;
5421
+ order = "asc";
5422
+ }
5423
+ this.logDebug(`sortByProperty(), propName=${propName}, ${order}`, options);
5424
+ assert(propName, "No property name specified");
5425
+ const cmp = (a, b) => {
5426
+ let av, bv;
5427
+ if (NODE_DICT_PROPS.has(propName)) {
5428
+ av = a[propName];
5429
+ bv = b[propName];
5430
+ }
5431
+ else {
5432
+ av = a.data[propName];
5433
+ bv = b.data[propName];
5434
+ }
5435
+ if (caseInsensitive) {
5436
+ if (typeof av === "string") {
5437
+ av = av.toLowerCase();
5438
+ }
5439
+ if (typeof bv === "string") {
5440
+ bv = bv.toLowerCase();
5441
+ }
5442
+ }
5443
+ if (order === "desc") {
5444
+ return av === bv ? 0 : av > bv ? -1 : 1;
5445
+ }
5446
+ return av === bv ? 0 : av > bv ? 1 : -1;
5447
+ };
5448
+ return this.sortChildren(cmp, deep);
5449
+ }
5357
5450
  /**
5358
5451
  * Trigger `modifyChild` event on a parent to signal that a child was modified.
5359
5452
  * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ...
@@ -5462,7 +5555,7 @@ WunderbaumNode.sequence = 0;
5462
5555
  /*!
5463
5556
  * Wunderbaum - ext-edit
5464
5557
  * Copyright (c) 2021-2024, Martin Wendt. Released under the MIT license.
5465
- * v0.10.1, Sat, 20 Jul 2024 13:53:46 GMT (https://github.com/mar10/wunderbaum)
5558
+ * v0.11.0, Sun, 04 Aug 2024 15:35:53 GMT (https://github.com/mar10/wunderbaum)
5466
5559
  */
5467
5560
  // const START_MARKER = "\uFFF7";
5468
5561
  class EditExtension extends WunderbaumExtension {
@@ -5793,8 +5886,8 @@ class EditExtension extends WunderbaumExtension {
5793
5886
  * https://github.com/mar10/wunderbaum
5794
5887
  *
5795
5888
  * Released under the MIT license.
5796
- * @version v0.10.1
5797
- * @date Sat, 20 Jul 2024 13:53:46 GMT
5889
+ * @version v0.11.0
5890
+ * @date Sun, 04 Aug 2024 15:35:53 GMT
5798
5891
  */
5799
5892
  // import "./wunderbaum.scss";
5800
5893
  class WbSystemRoot extends WunderbaumNode {
@@ -5964,7 +6057,8 @@ class Wunderbaum {
5964
6057
  // Attach tree instance to <div>
5965
6058
  this.element._wb_tree = this;
5966
6059
  // Create header markup, or take it from the existing html
5967
- this.headerElement = this.element.querySelector("div.wb-header");
6060
+ this.headerElement =
6061
+ this.element.querySelector("div.wb-header");
5968
6062
  const wantHeader = opts.header == null ? this.columns.length > 1 : !!opts.header;
5969
6063
  if (this.headerElement) {
5970
6064
  // User existing header markup to define `this.columns`
@@ -6001,8 +6095,10 @@ class Wunderbaum {
6001
6095
  <div class="wb-node-list"></div>
6002
6096
  </div>`;
6003
6097
  this.listContainerElement = this.element.querySelector("div.wb-list-container");
6004
- this.nodeListElement = this.listContainerElement.querySelector("div.wb-node-list");
6005
- this.headerElement = this.element.querySelector("div.wb-header");
6098
+ this.nodeListElement =
6099
+ this.listContainerElement.querySelector("div.wb-node-list");
6100
+ this.headerElement =
6101
+ this.element.querySelector("div.wb-header");
6006
6102
  this.element.classList.toggle("wb-grid", this.columns.length > 1);
6007
6103
  this._initExtensions();
6008
6104
  // --- apply initial options
@@ -6059,6 +6155,16 @@ class Wunderbaum {
6059
6155
  this.update(ChangeType.resize);
6060
6156
  });
6061
6157
  this.resizeObserver.observe(this.element);
6158
+ onEvent(this.element, "click", ".wb-button,.wb-col-icon", (e) => {
6159
+ var _a, _b;
6160
+ const info = Wunderbaum.getEventInfo(e);
6161
+ const command = (_b = (_a = e.target) === null || _a === void 0 ? void 0 : _a.dataset) === null || _b === void 0 ? void 0 : _b.command;
6162
+ this._callEvent("buttonClick", {
6163
+ event: e,
6164
+ info: info,
6165
+ command: command,
6166
+ });
6167
+ });
6062
6168
  onEvent(this.nodeListElement, "click", "div.wb-row", (e) => {
6063
6169
  const info = Wunderbaum.getEventInfo(e);
6064
6170
  const node = info.node;
@@ -6639,7 +6745,7 @@ class Wunderbaum {
6639
6745
  }
6640
6746
  /** Run code, but defer rendering of viewport until done.
6641
6747
  *
6642
- * ```
6748
+ * ```js
6643
6749
  * tree.runWithDeferredUpdate(() => {
6644
6750
  * return someFuncThatWouldUpdateManyNodes();
6645
6751
  * });
@@ -7117,13 +7223,17 @@ class Wunderbaum {
7117
7223
  console.warn(this.toString(), ...args); // eslint-disable-line no-console
7118
7224
  }
7119
7225
  }
7120
- /** Reset column widths to default. */
7226
+ /** Reset column widths to default. @since 0.10.0 */
7121
7227
  resetColumns() {
7122
7228
  this.columns.forEach((col) => {
7123
7229
  delete col.customWidthPx;
7124
7230
  });
7125
7231
  this.update(ChangeType.colStructure);
7126
7232
  }
7233
+ // /** Renumber nodes `_nativeIndex`. @see {@link WunderbaumNode.resetNativeChildOrder} */
7234
+ // resetNativeChildOrder(options?: ResetOrderOptions) {
7235
+ // this.root.resetNativeChildOrder(options);
7236
+ // }
7127
7237
  /**
7128
7238
  * Make sure that this node is vertically scrolled into the viewport.
7129
7239
  *
@@ -7438,6 +7548,14 @@ class Wunderbaum {
7438
7548
  sortChildren(cmp = nodeTitleSorter, deep = false) {
7439
7549
  this.root.sortChildren(cmp, deep);
7440
7550
  }
7551
+ /**
7552
+ * Convenience method to implement column sorting.
7553
+ * @see {@link WunderbaumNode.sortByProperty}.
7554
+ * @since 0.11.0
7555
+ */
7556
+ sortByProperty(options) {
7557
+ this.root.sortByProperty(options);
7558
+ }
7441
7559
  /** Convert tree to an array of plain objects.
7442
7560
  *
7443
7561
  * @param callback is called for every node, in order to allow
@@ -7551,6 +7669,11 @@ class Wunderbaum {
7551
7669
  // }
7552
7670
  return modified;
7553
7671
  }
7672
+ _insertIcon(icon, elem) {
7673
+ const iconElem = document.createElement("i");
7674
+ iconElem.className = icon;
7675
+ elem.appendChild(iconElem);
7676
+ }
7554
7677
  /** Create/update header markup from `this.columns` definition.
7555
7678
  * @internal
7556
7679
  */
@@ -7561,6 +7684,7 @@ class Wunderbaum {
7561
7684
  if (!wantHeader) {
7562
7685
  return;
7563
7686
  }
7687
+ const iconMap = this.iconMap;
7564
7688
  const colCount = this.columns.length;
7565
7689
  const headerRow = this.headerElement.querySelector(".wb-row");
7566
7690
  assert(headerRow, "Expected a row in header element");
@@ -7579,23 +7703,54 @@ class Wunderbaum {
7579
7703
  else {
7580
7704
  col.classes ? colElem.classList.add(...col.classes.split(" ")) : 0;
7581
7705
  }
7582
- const title = escapeHtml(col.title || col.id);
7706
+ // Add tooltip to column title
7583
7707
  let tooltip = "";
7584
7708
  if (col.tooltip) {
7585
7709
  tooltip = escapeTooltip(col.tooltip);
7586
7710
  tooltip = ` title="${tooltip}"`;
7587
7711
  }
7588
- let resizer = "";
7712
+ // Add column header icons
7713
+ let addMarkup = "";
7714
+ // NOTE: we use CSS float: right to align icons, so they must be added in
7715
+ // reverse order
7716
+ if (toBool(col.menu, this.options.columnsMenu, false)) {
7717
+ const iconClass = "wb-col-icon-menu " + iconMap.colMenu;
7718
+ const icon = `<i data-command=menu class="wb-col-icon ${iconClass}"></i>`;
7719
+ addMarkup += icon;
7720
+ }
7721
+ if (toBool(col.sortable, this.options.columnsSortable, false)) {
7722
+ let iconClass = "wb-col-icon-sort " + iconMap.colSortable;
7723
+ if (col.sortOrder) {
7724
+ iconClass += `wb-col-sort-${col.sortOrder}`;
7725
+ iconClass +=
7726
+ col.sortOrder === "asc" ? iconMap.colSortAsc : iconMap.colSortDesc;
7727
+ }
7728
+ const icon = `<i data-command=sort class="wb-col-icon ${iconClass}"></i>`;
7729
+ addMarkup += icon;
7730
+ }
7731
+ if (toBool(col.filterable, this.options.columnsFilterable, false)) {
7732
+ colElem.classList.toggle("wb-col-filter", !!col.filterActive);
7733
+ let iconClass = "wb-col-icon-filter " + iconMap.colFilter;
7734
+ if (col.filterActive) {
7735
+ iconClass += iconMap.colFilterActive;
7736
+ }
7737
+ const icon = `<i data-command=filter class="wb-col-icon ${iconClass}"></i>`;
7738
+ addMarkup += icon;
7739
+ }
7740
+ // Add resizer to all but the last column
7589
7741
  if (i < colCount - 1) {
7590
- if (toBool(col.resizable, this.options.resizableColumns, false)) {
7591
- resizer =
7742
+ if (toBool(col.resizable, this.options.columnsResizable, false)) {
7743
+ addMarkup +=
7592
7744
  '<span class="wb-col-resizer wb-col-resizer-active"></span>';
7593
7745
  }
7594
7746
  else {
7595
- resizer = '<span class="wb-col-resizer"></span>';
7747
+ addMarkup += '<span class="wb-col-resizer"></span>';
7596
7748
  }
7597
7749
  }
7598
- colElem.innerHTML = `<span class="wb-col-title"${tooltip}>${title}</span>${resizer}`;
7750
+ // Create column header
7751
+ const title = escapeHtml(col.title || col.id);
7752
+ colElem.innerHTML = `<span class="wb-col-title"${tooltip}>${title}</span>${addMarkup}`;
7753
+ // Highlight active column
7599
7754
  if (this.isCellNav()) {
7600
7755
  colElem.classList.toggle("wb-active", i === this.activeColIdx);
7601
7756
  }
@@ -8012,6 +8167,7 @@ class Wunderbaum {
8012
8167
  /**
8013
8168
  * Return the number of nodes that match the current filter.
8014
8169
  * @see {@link Wunderbaum.filterNodes}
8170
+ * @since 0.9.0
8015
8171
  */
8016
8172
  countMatches() {
8017
8173
  return this.extensions.filter.countMatches();
@@ -8044,7 +8200,7 @@ class Wunderbaum {
8044
8200
  }
8045
8201
  Wunderbaum.sequence = 0;
8046
8202
  /** Wunderbaum release version number "MAJOR.MINOR.PATCH". */
8047
- Wunderbaum.version = "v0.10.1"; // Set to semver by 'grunt release'
8203
+ Wunderbaum.version = "v0.11.0"; // Set to semver by 'grunt release'
8048
8204
  /** Expose some useful methods of the util.ts module as `Wunderbaum.util`. */
8049
8205
  Wunderbaum.util = util;
8050
8206