wunderbaum 0.12.1 → 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.
@@ -143,6 +143,7 @@ declare module "util" {
143
143
  export const MAX_INT = 9007199254740991;
144
144
  /**True if the client is using a macOS platform. */
145
145
  export const isMac: boolean;
146
+ export type NotPromise<T> = T extends Promise<any> ? never : T;
146
147
  export type FunctionType = (...args: any[]) => any;
147
148
  export type EventCallbackType = (e: Event) => boolean | void;
148
149
  /** A generic error that can be thrown to indicate a validation error when
@@ -189,7 +190,7 @@ declare module "util" {
189
190
  * Return `false` to stop the iteration.
190
191
  */
191
192
  export function each(obj: any, callback: (index: number | string, item: any) => void | boolean): any;
192
- /** Shortcut for `throw new Error(msg)`.*/
193
+ /** Shortcut for `throw new Error(msg)`. */
193
194
  export function error(msg: string): void;
194
195
  /** Convert `<`, `>`, `&`, `"`, `'`, and `/` to the equivalent entities. */
195
196
  export function escapeHtml(s: string): string;
@@ -388,6 +389,8 @@ declare module "util" {
388
389
  * ```
389
390
  */
390
391
  export function toPixel(...defaults: (string | number | undefined | null)[]): number;
392
+ /** Cast any value to <T>. */
393
+ export function unsafeCast<T>(value: any): T;
391
394
  /** Return the the boolean value of the first non-null element.
392
395
  * Example:
393
396
  * ```js
@@ -418,6 +421,14 @@ declare module "util" {
418
421
  * ```
419
422
  */
420
423
  export function adaptiveThrottle(this: unknown, callback: (...args: any[]) => void, options: object): DebouncedFunction<(...args: any[]) => void>;
424
+ /**
425
+ * MurmurHash3 implementation for strings.
426
+ * @param key The input string to hash.
427
+ * @param asString Optional convert result to zero-padded string of 8 characters.
428
+ * @param seed Optional seed value.
429
+ * @returns A 32-bit hash as a number or string.
430
+ */
431
+ export function murmurHash3(key: string, asString?: boolean, seed?: number): number | string;
421
432
  }
422
433
  declare module "common" {
423
434
  /*!
@@ -425,7 +436,7 @@ declare module "common" {
425
436
  * Copyright (c) 2021-2025, Martin Wendt. Released under the MIT license.
426
437
  * @VERSION, @DATE (https://github.com/mar10/wunderbaum)
427
438
  */
428
- import { MatcherCallback, SourceObjectType } from "types";
439
+ import { ApplyCommandType, NavigationType, SourceObjectType, IconMapType, MatcherCallback } from "types";
429
440
  import { WunderbaumNode } from "wb_node";
430
441
  export const DEFAULT_DEBUGLEVEL = 4;
431
442
  /**
@@ -447,10 +458,20 @@ declare module "common" {
447
458
  export const RENDER_MIN_PREFETCH = 5;
448
459
  /** Minimum column width if not set otherwise. */
449
460
  export const DEFAULT_MIN_COL_WIDTH = 4;
461
+ /**
462
+ * A value for `node.type` that by convention may be used to mark a node as directory.
463
+ * It may be used to sort 'directories' to the top.
464
+ */
465
+ export const NODE_TYPE_FOLDER = "folder";
450
466
  /** Regular expression to detect if a string describes an image URL (in contrast
451
467
  * to a class name). Strings are considered image urls if they contain '.' or '/'.
468
+ * `<` is ignored, because it is probably an html tag.
452
469
  */
453
- export const TEST_IMG: RegExp;
470
+ export const TEST_FILE_PATH: RegExp;
471
+ /** Regular expression to detect if a string describes an HTML element. */
472
+ export const TEST_HTML: RegExp;
473
+ /** Currently supported default icon maps. */
474
+ type IconLibrary = "bootstrap" | "fontawesome6";
454
475
  /**
455
476
  * Default node icons for icon libraries
456
477
  *
@@ -458,10 +479,8 @@ declare module "common" {
458
479
  * - 'fontawesome6' {@link https://fontawesome.com/icons}
459
480
  *
460
481
  */
461
- export const iconMaps: {
462
- [key: string]: {
463
- [key: string]: string;
464
- };
482
+ export const defaultIconMaps: {
483
+ [key in IconLibrary]: IconMapType;
465
484
  };
466
485
  export const KEY_NODATA = "__not_found__";
467
486
  /** Define which keys are handled by embedded <input> control, and should
@@ -473,8 +492,12 @@ declare module "common" {
473
492
  /** Dict keys that are evaluated by source loader (others are added to `tree.data` instead). */
474
493
  export const RESERVED_TREE_SOURCE_KEYS: Set<string>;
475
494
  /** Map `KeyEvent.key` to navigation action. */
476
- export const KEY_TO_ACTION_DICT: {
477
- [key: string]: string;
495
+ export const KEY_TO_NAVIGATION_MAP: {
496
+ [key: string]: NavigationType;
497
+ };
498
+ /** Map `KeyEvent.key` to navigation action. */
499
+ export const KEY_TO_COMMAND_MAP: {
500
+ [key: string]: ApplyCommandType;
478
501
  };
479
502
  /** Return a callback that returns true if the node title matches the string
480
503
  * or regular expression.
@@ -483,7 +506,9 @@ declare module "common" {
483
506
  export function makeNodeTitleMatcher(match: string | RegExp): MatcherCallback;
484
507
  /** Return a callback that returns true if the node title starts with a string (case-insensitive). */
485
508
  export function makeNodeTitleStartMatcher(s: string): MatcherCallback;
486
- /** Compare two nodes by title (case-insensitive). */
509
+ /** Compare two nodes by title (case-insensitive).
510
+ * @deprecated Use `key` option instead of `cmp` in sort methods.
511
+ */
487
512
  export function nodeTitleSorter(a: WunderbaumNode, b: WunderbaumNode): number;
488
513
  /**
489
514
  * Decompresses the source data by
@@ -540,7 +565,7 @@ declare module "deferred" {
540
565
  }
541
566
  declare module "wb_node" {
542
567
  import { Wunderbaum } from "wunderbaum";
543
- import { AddChildrenOptions, ApplyCommandOptions, ApplyCommandType, ChangeType, CheckboxOption, ExpandAllOptions, IconOption, InsertNodeType, MakeVisibleOptions, MatcherCallback, NavigateOptions, NodeAnyCallback, NodeStatusType, NodeStringCallback, NodeToDictCallback, NodeVisitCallback, NodeVisitResponse, RenderOptions, ResetOrderOptions, ScrollIntoViewOptions, SetActiveOptions, SetExpandedOptions, SetSelectedOptions, SetStatusOptions, SortByPropertyOptions, SortCallback, SourceType, TooltipOption, TristateType, WbNodeData } from "types";
568
+ import { AddChildrenOptions, ApplyCommandOptions, ApplyCommandType, ChangeType, CheckboxOption, ExpandAllOptions, IconOption, InsertNodeType, MakeVisibleOptions, MatcherCallback, NavigateOptions, NavigationType, NodeAnyCallback, NodeStatusType, NodeStringCallback, NodeToDictCallback, NodeVisitCallback, NodeVisitResponse, RenderOptions, ResetOrderOptions, ScrollIntoViewOptions, SetActiveOptions, SetExpandedOptions, SetSelectedOptions, SetStatusOptions, SortByPropertyOptions, SortCallback, SortOptions, SourceType, TooltipOption, TristateType, WbNodeData } from "types";
544
569
  /**
545
570
  * A single tree node.
546
571
  *
@@ -612,14 +637,18 @@ declare module "wb_node" {
612
637
  _errorInfo: any | null;
613
638
  _partsel: boolean;
614
639
  _partload: boolean;
615
- match?: boolean;
640
+ /**
641
+ * > 0 if matched (-1 to keep system nodes visible);
642
+ * Added and removed by filter code.
643
+ */
644
+ match?: number;
616
645
  subMatchCount?: number;
617
646
  /** @internal */
618
647
  titleWithHighlight?: string;
619
648
  _filterAutoExpanded?: boolean;
620
649
  _rowIdx: number | undefined;
621
650
  _rowElem: HTMLDivElement | undefined;
622
- constructor(tree: Wunderbaum, parent: WunderbaumNode, data: any);
651
+ constructor(tree: Wunderbaum, parent: WunderbaumNode, data: WbNodeData);
623
652
  /**
624
653
  * Return readable string representation for this instance.
625
654
  * @internal
@@ -730,7 +759,7 @@ declare module "wb_node" {
730
759
  *
731
760
  * @see {@link Wunderbaum.findRelatedNode|tree.findRelatedNode()}
732
761
  */
733
- findRelatedNode(where: string, includeHidden?: boolean): any;
762
+ findRelatedNode(where: NavigationType, includeHidden?: boolean): any;
734
763
  /**
735
764
  * Iterator version of {@link WunderbaumNode.format}.
736
765
  */
@@ -782,13 +811,13 @@ declare module "wb_node" {
782
811
  * @param includeSelf Include the node itself.
783
812
  */
784
813
  getParentList(includeRoot?: boolean, includeSelf?: boolean): any[];
785
- /** Return a string representing the hierachical node path, e.g. "a/b/c".
814
+ /** Return a string representing the hierarchical node path, e.g. "a/b/c".
786
815
  * @param includeSelf
787
816
  * @param part property name or callback
788
817
  * @param separator
789
818
  */
790
819
  getPath(includeSelf?: boolean, part?: keyof WunderbaumNode | NodeAnyCallback, separator?: string): string;
791
- /** Return the preceeding node (under the same parent) or null. */
820
+ /** Return the preceding node (under the same parent) or null. */
792
821
  getPrevSibling(): WunderbaumNode | null;
793
822
  /** Return true if node has children.
794
823
  * Return undefined if not sure, i.e. the node is lazy and not yet loaded.
@@ -796,7 +825,7 @@ declare module "wb_node" {
796
825
  hasChildren(): boolean;
797
826
  /** Return true if node has className set. */
798
827
  hasClass(className: string): boolean;
799
- /** Return true if node ist the currently focused node. @since 0.9.0 */
828
+ /** Return true if node is the currently focused node. @since 0.9.0 */
800
829
  hasFocus(): boolean;
801
830
  /** Return true if this node is the currently active tree node. */
802
831
  isActive(): boolean;
@@ -847,13 +876,13 @@ declare module "wb_node" {
847
876
  * @see {@link WunderbaumNode.isAncestorOf}
848
877
  */
849
878
  isParentOf(other: WunderbaumNode): boolean;
850
- /** (experimental) Return true if this node is partially loaded. */
879
+ /** Return true if this node is partially loaded. @experimental */
851
880
  isPartload(): boolean;
852
881
  /** Return true if this node is partially selected (tri-state). */
853
882
  isPartsel(): boolean;
854
- /** Return true if this node has DOM representaion, i.e. is displayed in the viewport. */
883
+ /** Return true if this node has DOM representation, i.e. is displayed in the viewport. */
855
884
  isRadio(): boolean;
856
- /** Return true if this node has DOM representaion, i.e. is displayed in the viewport. */
885
+ /** Return true if this node has DOM representation, i.e. is displayed in the viewport. */
857
886
  isRendered(): boolean;
858
887
  /** Return true if this node is the (invisible) system root node.
859
888
  * @see {@link WunderbaumNode.isTopLevel}
@@ -922,7 +951,7 @@ declare module "wb_node" {
922
951
  * e.g. `ArrowLeft` = 'left'.
923
952
  * @param options
924
953
  */
925
- navigate(where: string, options?: NavigateOptions): Promise<any>;
954
+ navigate(where: NavigationType | string, options?: NavigateOptions): Promise<any>;
926
955
  /** Delete this node and all descendants. */
927
956
  remove(): void;
928
957
  /** Remove all descendants of this node. */
@@ -930,7 +959,7 @@ declare module "wb_node" {
930
959
  /** Remove all HTML markup from the DOM. */
931
960
  removeMarkup(): void;
932
961
  protected _getRenderInfo(): any;
933
- protected _createIcon(iconMap: any, parentElem: HTMLElement, replaceChild: HTMLElement | null, showLoading: boolean): HTMLElement | null;
962
+ protected _createIcon(parentElem: HTMLElement, replaceChild: HTMLElement | null, showLoading: boolean): HTMLElement | null;
934
963
  /**
935
964
  * Create a whole new `<div class="wb-row">` element.
936
965
  * @see {@link WunderbaumNode._render}
@@ -1020,6 +1049,15 @@ declare module "wb_node" {
1020
1049
  * @param stopOnParents only return the topmost selected node (useful with selectMode 'hier')
1021
1050
  */
1022
1051
  getSelectedNodes(stopOnParents?: boolean): WunderbaumNode[];
1052
+ /**
1053
+ * Return an array of refKey values.
1054
+ *
1055
+ * RefKeys are unique identifiers for a node data, and are used to identify
1056
+ * clones.
1057
+ * If more than one node has the same refKey, it is only returned once.
1058
+ * @param selected if true, only return refKeys of selected nodes.
1059
+ */
1060
+ getRefKeys(selected?: boolean): string[];
1023
1061
  /** Toggle the check/uncheck state. */
1024
1062
  toggleSelected(options?: SetSelectedOptions): TristateType;
1025
1063
  /** Return true if at least on selectable descendant end-node is unselected. @internal */
@@ -1045,12 +1083,12 @@ declare module "wb_node" {
1045
1083
  setTitle(title: string): void;
1046
1084
  /** Set the node tooltip. */
1047
1085
  setTooltip(tooltip: TooltipOption): void;
1048
- _sortChildren(cmp: SortCallback, deep: boolean): void;
1049
1086
  /**
1050
1087
  * Sort child list by title or custom criteria.
1051
1088
  * @param {function} cmp custom compare function(a, b) that returns -1, 0, or 1
1052
1089
  * (defaults to sorting by title).
1053
1090
  * @param {boolean} deep pass true to sort all descendant nodes recursively
1091
+ * @deprecated use {@link sort}
1054
1092
  */
1055
1093
  sortChildren(cmp?: SortCallback | null, deep?: boolean): void;
1056
1094
  /**
@@ -1063,8 +1101,26 @@ declare module "wb_node" {
1063
1101
  /**
1064
1102
  * Convenience method to implement column sorting.
1065
1103
  * @since 0.11.0
1104
+ * @deprecated use {@link sort}
1066
1105
  */
1067
1106
  sortByProperty(options: SortByPropertyOptions): void;
1107
+ /**
1108
+ * Implement column sorting.
1109
+ * @since 0.14.0
1110
+ */
1111
+ sort(options: SortOptions): void;
1112
+ /**
1113
+ * Re-apply current sorting if any (use after lazy load).
1114
+ * Example:
1115
+ * ```js
1116
+ * load: function (e) {
1117
+ * // Whe loading a lazy branch, apply current sort order if any
1118
+ * e.node.resort();
1119
+ * },
1120
+ * ```
1121
+ * @since 0.14.0
1122
+ */
1123
+ resort(options?: SortOptions): void;
1068
1124
  /**
1069
1125
  * Trigger `modifyChild` event on a parent to signal that a child was modified.
1070
1126
  * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ...
@@ -1086,7 +1142,8 @@ declare module "wb_node" {
1086
1142
  * @param {function} callback the callback function.
1087
1143
  * Return false to stop iteration, return "skip" to skip this node and
1088
1144
  * its children only.
1089
- * @see {@link IterableIterator<WunderbaumNode>}, {@link Wunderbaum.visit}.
1145
+ * @see `wb_node.WunderbaumNode.IterableIterator<WunderbaumNode>`
1146
+ * @see {@link Wunderbaum.visit}.
1090
1147
  */
1091
1148
  visit(callback: NodeVisitCallback, includeSelf?: boolean): NodeVisitResponse;
1092
1149
  /** Call fn(node) for all parent nodes, bottom-up, including invisible system root.<br>
@@ -1114,131 +1171,73 @@ declare module "wb_node" {
1114
1171
  }
1115
1172
  declare module "wb_options" {
1116
1173
  /*!
1117
- * Wunderbaum - utils
1174
+ * Wunderbaum - options
1118
1175
  * Copyright (c) 2021-2025, Martin Wendt. Released under the MIT license.
1119
1176
  * @VERSION, @DATE (https://github.com/mar10/wunderbaum)
1120
1177
  */
1121
- import { ColumnDefinitionList, DndOptionsType, DynamicBoolOption, DynamicBoolOrStringOption, DynamicCheckboxOption, DynamicIconOption, EditOptionsType, FilterOptionsType, NavModeEnum, NodeTypeDefinitionMap, SelectModeType, WbActivateEventType, WbButtonClickEventType, WbCancelableEventResultType, WbChangeEventType, WbClickEventType, WbDeactivateEventType, WbErrorEventType, WbExpandEventType, WbIconBadgeCallback, WbIconBadgeEventResultType, WbInitEventType, WbKeydownEventType, WbNodeData, WbNodeEventType, WbReceiveEventType, WbRenderEventType, WbSelectEventType, WbTreeEventType } from "types";
1178
+ import { ColumnDefinitionList, DndOptionsType, DynamicBoolOption, DynamicBoolOrStringOption, DynamicCheckboxOption, DynamicIconOption, EditOptionsType, FilterOptionsType, IconMapType, NavModeEnum, NodeTypeDefinitionMap, SelectModeType, SourceType, TranslationsType, WbActivateEventType, WbButtonClickEventType, WbCancelableEventResultType, WbChangeEventType, WbClickEventType, WbDeactivateEventType, WbErrorEventType, WbExpandEventType, WbIconBadgeCallback, WbIconBadgeEventResultType, WbInitEventType, WbKeydownEventType, WbNodeEventType, WbReceiveEventType, WbRenderEventType, WbSelectEventType, WbTreeEventType } from "types";
1122
1179
  /**
1123
- * Available options for {@link wunderbaum.Wunderbaum}.
1124
- *
1125
- * Options are passed to the constructor as plain object:
1180
+ * Properties of {@link wunderbaum.Wunderbaum.options}.
1126
1181
  *
1127
- * ```js
1128
- * const tree = new mar10.Wunderbaum({
1129
- * id: "demo",
1130
- * element: document.getElementById("demo-tree"),
1131
- * source: "url/of/data/request",
1132
- * ...
1133
- * });
1134
- * ```
1135
- *
1136
- * Event handlers are also passed as callbacks
1137
- *
1138
- * ```js
1139
- * const tree = new mar10.Wunderbaum({
1140
- * ...
1141
- * init: (e) => {
1142
- * console.log(`Tree ${e.tree} was initialized and loaded.`)
1143
- * },
1144
- * activate: (e) => {
1145
- * console.log(`Node ${e.node} was activated.`)
1146
- * },
1147
- * ...
1148
- * });
1149
- * ```
1182
+ * This is similar, but not identical, to the options that can be passed to the
1183
+ * constructor(@see {@link InitWunderbaumOptions}).
1150
1184
  */
1151
1185
  export interface WunderbaumOptions {
1152
- /**
1153
- * The target `div` element (or selector) that shall become a Wunderbaum.
1154
- */
1155
- element: string | HTMLDivElement;
1156
- /**
1157
- * The identifier of this tree. Used to reference the instance, especially
1158
- * when multiple trees are present (e.g. `tree = mar10.Wunderbaum.getTree("demo")`).
1159
- *
1160
- * Default: `"wb_" + COUNTER`.
1161
- */
1162
- id?: string;
1163
- /**
1164
- * Define the initial tree data. Typically a URL of an endpoint that serves
1165
- * a JSON formatted structure, but also a callback, Promise, or static data
1166
- * is allowed.
1167
- *
1168
- * Default: `{}`.
1169
- */
1170
- source?: string | Array<WbNodeData>;
1171
- /**
1172
- * Define shared attributes for multiple nodes of the same type.
1173
- * This allows for more compact data models. Type definitions can be passed
1174
- * as tree option, or be part of a `source` response.
1175
- *
1176
- * Default: `{}`.
1177
- */
1178
- types?: NodeTypeDefinitionMap;
1179
- /**
1180
- * A list of maps that define column headers. If this option is set,
1181
- * Wunderbaum becomes a treegrid control instead of a plain tree.
1182
- * Column definitions can be passed as tree option, or be part of a `source`
1183
- * response.
1184
- * Default: `[]` meaning this is a plain tree.
1185
- */
1186
- columns?: ColumnDefinitionList;
1187
1186
  /**
1188
1187
  * If true, add a `wb-skeleton` class to all nodes, that will result in a
1189
1188
  * 'glow' effect. Typically used with initial dummy nodes, while loading the
1190
1189
  * real data.
1191
- * Default: false.
1190
+ * @default false.
1192
1191
  */
1193
- skeleton?: boolean;
1192
+ skeleton: boolean;
1194
1193
  /**
1195
1194
  * Translation map for some system messages.
1196
- * Default:
1197
- * ```js
1198
- * strings: {
1199
- * loading: "Loading...",
1200
- * loadError: "Error",
1201
- * noData: "No data",
1202
- * }
1203
- * ```
1204
1195
  */
1205
- strings?: any;
1196
+ strings: TranslationsType;
1206
1197
  /**
1207
1198
  * 0:quiet, 1:errors, 2:warnings, 3:info, 4:verbose
1208
- * Default: 3 (4 in local debug environment)
1199
+ * @default 3 (4 in local debug environment)
1209
1200
  */
1210
- debugLevel?: number;
1201
+ debugLevel: number;
1211
1202
  /**
1212
1203
  * Number of levels that are forced to be expanded, and have no expander icon.
1213
1204
  * E.g. 1 would keep all toplevel nodes expanded.
1214
- * Default: 0
1205
+ * @default 0
1215
1206
  */
1216
- minExpandLevel?: number;
1207
+ minExpandLevel: number;
1217
1208
  /**
1218
1209
  * If true, allow to expand parent nodes, even if `node.children` conatains
1219
1210
  * an empty array (`[]`). This is the the behavior of macOS Finder, for example.
1220
- * Default: false
1211
+ * @default false
1221
1212
  */
1222
- emptyChildListExpandable?: boolean;
1213
+ emptyChildListExpandable: boolean;
1223
1214
  /**
1224
1215
  * Height of a node row div.
1225
- * Default: 22
1216
+ * @default 22
1226
1217
  */
1227
- rowHeightPx?: number;
1218
+ rowHeightPx: number;
1228
1219
  /**
1229
1220
  * Icon font definition. May be a string (e.g. "fontawesome6" or "bootstrap")
1230
1221
  * or a map of `iconName: iconClass` pairs.
1231
1222
  * Note: the icon font must be loaded separately.
1232
- * Default: "bootstrap"
1223
+ * In order to only override some defauöt icons, use this pattern:
1224
+ * ```js
1225
+ * const tree = new mar10.Wunderbaum({
1226
+ * ...
1227
+ * iconMap: Object.assign(Wunderbaum.iconMaps.bootstrap, {
1228
+ * folder: "bi bi-archive",
1229
+ * }),
1230
+ * });
1231
+ * ```
1232
+
1233
+ * @default "bootstrap"
1233
1234
  */
1234
- iconMap?: string | {
1235
- [key: string]: string;
1236
- };
1235
+ iconMap: string | IconMapType;
1237
1236
  /**
1238
1237
  * Collapse siblings when a node is expanded.
1239
- * Default: false
1238
+ * @default false
1240
1239
  */
1241
- autoCollapse?: boolean;
1240
+ autoCollapse: boolean;
1242
1241
  /**
1243
1242
  * If true, the tree will automatically adjust its height to fit the parent
1244
1243
  * container. This is useful when the tree is embedded in a container with
@@ -1252,16 +1251,16 @@ declare module "wb_options" {
1252
1251
  *
1253
1252
  * @default: true
1254
1253
  */
1255
- adjustHeight?: boolean;
1254
+ adjustHeight: boolean;
1256
1255
  /**
1257
- * HTMLElement that receives the top nodes breadcrumb.
1258
- * Default: undefined
1256
+ * HTMLElement or selector that receives the top nodes breadcrumb.
1257
+ * @default undefined
1259
1258
  */
1260
- connectTopBreadcrumb?: HTMLElement;
1259
+ connectTopBreadcrumb: HTMLElement | string | null;
1261
1260
  /**
1262
- * Default: NavModeEnum.startRow
1261
+ * @default NavModeEnum.startRow
1263
1262
  */
1264
- navigationModeOption?: NavModeEnum;
1263
+ navigationModeOption: NavModeEnum;
1265
1264
  /**
1266
1265
  * Show/hide header (default: null)
1267
1266
  * null: assume false for plain tree and true for grids.
@@ -1269,17 +1268,27 @@ declare module "wb_options" {
1269
1268
  * true: display a header (use tree's id as text for plain trees)
1270
1269
  * false: do not display a header
1271
1270
  */
1272
- header?: boolean | string | null;
1271
+ header: boolean | string | null;
1273
1272
  /**
1274
- *
1273
+ * Show a `<progress>` element while loading data.
1274
+ * @default false.
1275
+ */
1276
+ showSpinner: boolean;
1277
+ /**
1278
+ * Generate missing keys by hashing a combination of refKey (or title) and
1279
+ * the parent key. This is useful when the source data does not contain unique
1280
+ * keys but we want stable keys for persisting the active node, selection or
1281
+ * expansion state. Note that this still assumes that the same refKey must not
1282
+ * appear twice in the same parent node.
1283
+ * @default false.
1275
1284
  */
1276
- showSpinner?: boolean;
1285
+ autoKeys: boolean;
1277
1286
  /**
1278
1287
  * If true, render a checkbox before the node tile to allow selection with the
1279
1288
  * mouse. Pass `"radio"` to render a radio button instead.
1280
- * Default: false.
1289
+ * @default false.
1281
1290
  */
1282
- checkbox?: DynamicCheckboxOption;
1291
+ checkbox: DynamicCheckboxOption;
1283
1292
  /** Optional callback to render icons per node. */
1284
1293
  icon?: DynamicIconOption;
1285
1294
  /** Optional callback to render a tooltip for the icon. */
@@ -1291,53 +1300,67 @@ declare module "wb_options" {
1291
1300
  /** Optional callback to make a node unselectable. */
1292
1301
  unselectable?: DynamicBoolOption;
1293
1302
  /**
1294
- * Default: true
1303
+ * @default true
1295
1304
  */
1296
- enabled?: boolean;
1305
+ enabled: boolean;
1297
1306
  /**
1298
- * Default: false
1307
+ *
1308
+ * @default false
1299
1309
  */
1300
- fixedCol?: boolean;
1310
+ fixedCol: boolean;
1301
1311
  /**
1302
1312
  * Default value for ColumnDefinition.filterable option.
1303
- * Default: false
1313
+ * @default false
1304
1314
  * @since 0.11.0
1305
1315
  */
1306
- columnsFilterable?: boolean;
1316
+ columnsFilterable: boolean;
1307
1317
  /**
1308
1318
  * Default value for ColumnDefinition.menu option.
1309
- * Default: false
1319
+ * @default false
1310
1320
  * @since 0.11.0
1311
1321
  */
1312
- columnsMenu?: boolean;
1322
+ columnsMenu: boolean;
1313
1323
  /**
1314
1324
  * Default value for ColumnDefinition.resizable option.
1315
- * Default: false
1325
+ * @default false
1316
1326
  * @since 0.10.0
1317
1327
  */
1318
1328
  columnsResizable?: boolean;
1319
1329
  /**
1320
1330
  * Default value for ColumnDefinition.sortable option.
1321
- * Default: false
1331
+ * @default false
1322
1332
  * @since 0.11.0
1323
1333
  */
1324
1334
  columnsSortable?: boolean;
1325
1335
  /**
1326
- * Default: "multi"
1336
+ * Group nodes with children or of `type: 'folder'` at the top when sorting.
1337
+ * If a function is passed, it is called with the node as argument to determine
1338
+ * whether the node is a folder or not. The function should return `true` for
1339
+ * folders.
1340
+ * and should return `true` for folders.
1341
+ * @default false
1342
+ * @since 0.14.0
1327
1343
  */
1328
- selectMode?: SelectModeType;
1344
+ sortFoldersFirst?: DynamicBoolOption;
1329
1345
  /**
1330
- * Default: true
1346
+ * @default "multi"
1331
1347
  */
1332
- quicksearch?: boolean;
1348
+ selectMode: SelectModeType;
1349
+ /**
1350
+ * @default true
1351
+ */
1352
+ quicksearch: boolean;
1333
1353
  /**
1334
1354
  * Scroll Node into view on Expand Click
1335
1355
  * @default true
1336
1356
  */
1337
- scrollIntoViewOnExpandClick?: boolean;
1338
- dnd?: DndOptionsType;
1339
- edit?: EditOptionsType;
1340
- filter?: FilterOptionsType;
1357
+ scrollIntoViewOnExpandClick: boolean;
1358
+ /** Configuration options for the drag-and-drop extension. */
1359
+ dnd: DndOptionsType;
1360
+ /** Configuration options for the edit-title extension. */
1361
+ edit: EditOptionsType;
1362
+ /** Configuration options for the node-filter extension. */
1363
+ filter: FilterOptionsType;
1341
1364
  /**
1342
1365
  * `e.node` was activated.
1343
1366
  * @category Callback
@@ -1482,6 +1505,90 @@ declare module "wb_options" {
1482
1505
  */
1483
1506
  update?: (e: WbTreeEventType) => void;
1484
1507
  }
1508
+ /**
1509
+ * Available options for {@link wunderbaum.Wunderbaum}.
1510
+ *
1511
+ * Options are passed to the constructor as plain object:
1512
+ *
1513
+ * ```js
1514
+ * const tree = new mar10.Wunderbaum({
1515
+ * id: "demo",
1516
+ * element: document.getElementById("demo-tree"),
1517
+ * source: "url/of/data/request",
1518
+ * ...
1519
+ * });
1520
+ * ```
1521
+ *
1522
+ * Event handlers are also passed as callbacks
1523
+ *
1524
+ * ```js
1525
+ * const tree = new mar10.Wunderbaum({
1526
+ * ...
1527
+ * init: (e) => {
1528
+ * console.log(`Tree ${e.tree} was initialized and loaded.`)
1529
+ * },
1530
+ * activate: (e) => {
1531
+ * console.log(`Node ${e.node} was activated.`)
1532
+ * },
1533
+ * ...
1534
+ * });
1535
+ * ```
1536
+ *
1537
+ * Most of the properties are optional and have resonable default.
1538
+ * They are then available as {@link Wunderbaum.options} property and can be
1539
+ * changed at runtime. <br>
1540
+ * Only the `element` option is mandatory.
1541
+ *
1542
+ * Note that some options passed here, are *not* available as {@link Wunderbaum.options}.
1543
+ * They are moved to the `tree` instance instead:
1544
+ * - `tree.element`
1545
+ * - `tree.id`
1546
+ * - `tree.columns`
1547
+ * - `tree.types`
1548
+ * - ...
1549
+ *
1550
+ * Some options are only used during initialization and are not stored in the
1551
+ * tree instance:
1552
+ * - `source`
1553
+ *
1554
+ */
1555
+ export interface InitWunderbaumOptions extends Partial<WunderbaumOptions> {
1556
+ /**
1557
+ * The target `div` element (or selector) that shall become a Wunderbaum.
1558
+ */
1559
+ element: string | HTMLDivElement;
1560
+ /**
1561
+ * The identifier of this tree. Used to reference the instance, especially
1562
+ * when multiple trees are present (e.g. `tree = mar10.Wunderbaum.getTree("demo")`).
1563
+ *
1564
+ * @default `"wb_" + COUNTER`.
1565
+ */
1566
+ id?: string;
1567
+ /**
1568
+ * A list of maps that define column headers. If this option is set,
1569
+ * Wunderbaum becomes a treegrid control instead of a plain tree.
1570
+ * Column definitions can be passed as tree option, or be part of a `source`
1571
+ * response.
1572
+ * @default `[]` meaning this is a plain tree.
1573
+ */
1574
+ columns?: ColumnDefinitionList;
1575
+ /**
1576
+ * Define shared attributes for multiple nodes of the same type.
1577
+ * This allows for more compact data models. Type definitions can be passed
1578
+ * as tree option, or be part of a `source` response.
1579
+ *
1580
+ * @default `{}`.
1581
+ */
1582
+ types?: NodeTypeDefinitionMap;
1583
+ /**
1584
+ * Define the initial tree data. Typically a URL of an endpoint that serves
1585
+ * a JSON formatted structure, but also a callback, Promise, or static data
1586
+ * is allowed.
1587
+ *
1588
+ * @default `[]`.
1589
+ */
1590
+ source?: SourceType;
1591
+ }
1485
1592
  }
1486
1593
  declare module "types" {
1487
1594
  /*!
@@ -1534,8 +1641,13 @@ declare module "types" {
1534
1641
  export type MatcherCallback = (node: WunderbaumNode) => boolean;
1535
1642
  /** Used for `tree.iconBadge` event. */
1536
1643
  export type WbIconBadgeCallback = (e: WbIconBadgeEventType) => WbIconBadgeEventResultType;
1537
- /** Passed to `sortChildren()` methods. Should return -1, 0, or 1. */
1644
+ /**
1645
+ * Passed to `sort()` methods. Should return -1, 0, or 1.
1646
+ * @deprecated Use SortKeyCallback instead
1647
+ */
1538
1648
  export type SortCallback = (a: WunderbaumNode, b: WunderbaumNode) => number;
1649
+ /** Passed to `sort()` methods. Should return a representation that can be compared using `<`. */
1650
+ export type SortKeyCallback = (node: WunderbaumNode) => string | number | any[];
1539
1651
  /** When set as option, called when the value is needed (e.g. `colspan` type definition). */
1540
1652
  export type BoolOptionResolver = (node: WunderbaumNode) => boolean;
1541
1653
  /** When set as option, called when the value is needed (e.g. `icon` type definition). */
@@ -1564,6 +1676,11 @@ declare module "types" {
1564
1676
  * (de)selection.
1565
1677
  */
1566
1678
  export type NodeSelectCallback = (node: WunderbaumNode) => boolean | void;
1679
+ /** @internal */
1680
+ export type DeprecationOptions = {
1681
+ since?: string;
1682
+ hint?: string;
1683
+ };
1567
1684
  /**
1568
1685
  * See also {@link WunderbaumNode.getOption|WunderbaumNode.getOption()}
1569
1686
  * to evaluate `node.NAME` setting and `tree.types[node.type].NAME`.
@@ -1623,7 +1740,7 @@ declare module "types" {
1623
1740
  title: string;
1624
1741
  /** Pass true to set node tooltip to the node's title. Defaults to {@link WunderbaumOptions.tooltip}. */
1625
1742
  tooltip?: TooltipOption;
1626
- /** Inherit shared settings from the matching entry in {@link WunderbaumOptions.types}. */
1743
+ /** Inherit shared settings from the matching entry in `InitWunderbaumOptions.types`. */
1627
1744
  type?: string;
1628
1745
  /** Set to `true` to prevent selection. Defaults to {@link WunderbaumOptions.unselectable}. */
1629
1746
  unselectable?: boolean;
@@ -1632,7 +1749,33 @@ declare module "types" {
1632
1749
  /** Other data is passed to `node.data` and can be accessed via `node.data.NAME` */
1633
1750
  [key: string]: unknown;
1634
1751
  }
1635
- /** A callback that receives a node instance and returns a string value. */
1752
+ /** A plain object (dictionary) that defines node icons. */
1753
+ export interface IconMapType {
1754
+ error: string;
1755
+ loading: string;
1756
+ noData: string;
1757
+ expanderExpanded: string;
1758
+ expanderCollapsed: string;
1759
+ expanderLazy: string;
1760
+ checkChecked: string;
1761
+ checkUnchecked: string;
1762
+ checkUnknown: string;
1763
+ radioChecked: string;
1764
+ radioUnchecked: string;
1765
+ radioUnknown: string;
1766
+ folder: string;
1767
+ folderOpen: string;
1768
+ folderLazy: string;
1769
+ doc: string;
1770
+ colSortable: string;
1771
+ colSortAsc: string;
1772
+ colSortDesc: string;
1773
+ colFilter: string;
1774
+ colFilterActive: string;
1775
+ colMenu: string;
1776
+ [key: string]: string;
1777
+ }
1778
+ /** Retuen value of an event handler that can return `false` to prevent the default action. */
1636
1779
  export type WbCancelableEventResultType = false | void;
1637
1780
  export interface WbTreeEventType {
1638
1781
  /** Name of the event. */
@@ -1931,9 +2074,10 @@ declare module "types" {
1931
2074
  /** The affected column's span tag if any. */
1932
2075
  colElem?: HTMLSpanElement;
1933
2076
  }
1934
- export type FilterModeType = null | "dim" | "hide";
2077
+ export type FilterModeType = null | "mark" | "dim" | "hide";
1935
2078
  export type SelectModeType = "single" | "multi" | "hier";
1936
- export type ApplyCommandType = "addChild" | "addSibling" | "copy" | "cut" | "down" | "first" | "indent" | "last" | "left" | "moveDown" | "moveUp" | "outdent" | "pageDown" | "pageUp" | "parent" | "paste" | "remove" | "rename" | "right" | "up";
2079
+ export type NavigationType = "down" | "first" | "firstCol" | "last" | "lastCol" | "left" | "nextMatch" | "pageDown" | "pageUp" | "parent" | "prevMatch" | "right" | "up";
2080
+ export type ApplyCommandType = NavigationType | "addChild" | "addSibling" | "collapse" | "collapseAll" | "copy" | "cut" | "edit" | "expand" | "expandAll" | "indent" | "moveDown" | "moveUp" | "outdent" | "paste" | "remove" | "rename" | "toggleSelect";
1937
2081
  export type NodeFilterResponse = "skip" | "branch" | boolean | void;
1938
2082
  export type NodeFilterCallback = (node: WunderbaumNode) => NodeFilterResponse;
1939
2083
  /**
@@ -1993,6 +2137,23 @@ declare module "types" {
1993
2137
  /** Row mode only */
1994
2138
  row = "row"
1995
2139
  }
2140
+ /** Translatable strings. */
2141
+ export type TranslationsType = {
2142
+ /** @default "Loading..." */
2143
+ loading: string;
2144
+ /** @default "Error" */
2145
+ loadError: string;
2146
+ /** @default "No data" */
2147
+ noData: string;
2148
+ /** @default " » " */
2149
+ breadcrumbDelimiter: string;
2150
+ /** @default "Found ${matches} of ${count}" */
2151
+ queryResult: string;
2152
+ /** @default "No result" */
2153
+ noMatch: string;
2154
+ /** @default "${match} of ${matches}" */
2155
+ matchIndex: string;
2156
+ };
1996
2157
  /** Possible values for {@link WunderbaumNode.addChildren}. */
1997
2158
  export interface AddChildrenOptions {
1998
2159
  /** Insert children before this node (or index)
@@ -2060,8 +2221,7 @@ declare module "types" {
2060
2221
  /**Hide expanders if all child nodes are hidden by filter @default false */
2061
2222
  hideExpanders?: boolean;
2062
2223
  /** Highlight matches by wrapping inside `<mark>` tags.
2063
- * Does not work for filter callbacks.
2064
- * @default true
2224
+ * Does not work for filter callbacks. @default true
2065
2225
  */
2066
2226
  highlight?: boolean;
2067
2227
  /** Match end nodes only @default false */
@@ -2071,6 +2231,40 @@ declare module "types" {
2071
2231
  /** Display a 'no data' status node if result is empty @default true */
2072
2232
  noData?: boolean | string;
2073
2233
  }
2234
+ /** Possible values for {@link Wunderbaum.getState}. */
2235
+ export interface GetStateOptions {
2236
+ /** Include the active node's key (and expand its parents). @default true */
2237
+ activeKey?: boolean;
2238
+ /** Include the expanded keys. @default false */
2239
+ expandedKeys?: boolean;
2240
+ /** Include the selected keys. @default false */
2241
+ selectedKeys?: boolean;
2242
+ }
2243
+ /** Possible values for {@link Wunderbaum.setState}. */
2244
+ export interface SetStateOptions {
2245
+ /** Recursively load lazy nodes as needed. @default false */
2246
+ expandLazy?: boolean;
2247
+ }
2248
+ /** Used by {@link Wunderbaum.getState} and {@link Wunderbaum.setState}. */
2249
+ export interface TreeStateDefinition {
2250
+ /** List of expanded node's keys. */
2251
+ expandedKeys: Array<string> | undefined;
2252
+ /** The active node's key if any. */
2253
+ activeKey: string | null;
2254
+ /** The active column index if any. */
2255
+ activeColIdx: number | null;
2256
+ /** List of selected node's keys. */
2257
+ selectedKeys: Array<string> | undefined;
2258
+ }
2259
+ /** Possible values for {@link Wunderbaum.loadLazyNodes} `options` argument. */
2260
+ export interface LoadLazyNodesOptions {
2261
+ /** Expand node (otherwise load, but keep collapsed). @default true */
2262
+ expand?: boolean;
2263
+ /** Force reloading even if already loaded. @default false */
2264
+ force?: boolean;
2265
+ /** Do not send events. @default false */
2266
+ noEvents?: boolean;
2267
+ }
2074
2268
  /** Possible values for {@link WunderbaumNode.makeVisible}. */
2075
2269
  export interface MakeVisibleOptions {
2076
2270
  /** Do not animate expand (currently not implemented). @default false */
@@ -2189,7 +2383,16 @@ declare module "types" {
2189
2383
  details?: string;
2190
2384
  }
2191
2385
  /**
2192
- * Possible values for {@link WunderbaumNode.sortByProperty} `options` argument.
2386
+ * Possible values for {@link Wunderbaum.reload} `options` argument.
2387
+ */
2388
+ export interface ReloadOptions {
2389
+ /** Load this source instead. @default initial source (if loaded via ajax) */
2390
+ source?: SourceType;
2391
+ /** Reactivate currently active node if any. @default true */
2392
+ reactivate?: boolean;
2393
+ }
2394
+ /**
2395
+ * Possible values for {@link WunderbaumNode.resetNativeChildOrder} `options` argument.
2193
2396
  */
2194
2397
  export interface ResetOrderOptions {
2195
2398
  /** Sort descendants recursively. @default true */
@@ -2200,27 +2403,37 @@ declare module "types" {
2200
2403
  propName?: string;
2201
2404
  }
2202
2405
  /**
2203
- * Possible values for {@link WunderbaumNode.sortByProperty} `options` argument.
2406
+ * Possible values for {@link Wunderbaum.sort} and {@link WunderbaumNode.sort}
2407
+ * `options` argument.
2204
2408
  */
2205
- export interface SortByPropertyOptions {
2206
- /** Column ID as defined in `tree.columns` definition. Required if updateColInfo is true.*/
2207
- colId?: string;
2409
+ export interface SortOptions {
2208
2410
  /** The name of the node property that will be used for sorting.
2209
- * @default use the `colId` as property name.
2411
+ * Mandatory, unless {@link key} or {@link colId} are given.
2210
2412
  */
2211
2413
  propName?: string;
2212
- /** Sort order. @default Use value from column definition (rotated).*/
2414
+ /** Callback that determines a node representation for comparison.
2415
+ * @default {@link common.nodeTitleKeyGetter} */
2416
+ key?: SortKeyCallback;
2417
+ /** Callback that determines the order. @default {@link common.nodeTitleSorter}
2418
+ * @deprecated use {@link key} instead
2419
+ */
2420
+ cmp?: SortCallback;
2421
+ /** Sort order 'asc' or 'desc'.
2422
+ * @default 'asc' (or if `updateColInfo` is true, the rotated status of the
2423
+ * column definition.
2424
+ * See also {@link WunderbaumOptions.sortFoldersFirst}.
2425
+ */
2213
2426
  order?: SortOrderType;
2427
+ /** Sort descendants recursively. @default true */
2428
+ deep?: boolean;
2429
+ /** Sort string values case insensitive. @default false */
2430
+ caseInsensitive?: boolean;
2214
2431
  /**
2215
2432
  * Sort by this property if order is `undefined`.
2216
2433
  * See also {@link WunderbaumNode.resetNativeChildOrder}.
2217
2434
  * @default `_nativeIndex`.
2218
2435
  */
2219
2436
  nativeOrderPropName?: string;
2220
- /** Sort string values case insensitive. @default false */
2221
- caseInsensitive?: boolean;
2222
- /** Sort descendants recursively. @default true */
2223
- deep?: boolean;
2224
2437
  /**
2225
2438
  * Rotate sort order (asc -> desc -> none) before sorting.
2226
2439
  * Update the sort icons in the column header
@@ -2231,7 +2444,14 @@ declare module "types" {
2231
2444
  * @default false
2232
2445
  */
2233
2446
  updateColInfo?: boolean;
2447
+ /** Column ID as defined in `tree.columns` definition. Required if updateColInfo is true.*/
2448
+ colId?: string;
2234
2449
  }
2450
+ /**
2451
+ * Possible values for {@link WunderbaumNode.sortByProperty} `options` argument.
2452
+ * @deprecated
2453
+ */
2454
+ export type SortByPropertyOptions = SortOptions;
2235
2455
  /** Options passed to {@link Wunderbaum.visitRows}. */
2236
2456
  export interface VisitRowsOptions {
2237
2457
  /** Skip filtered nodes and children of collapsed nodes. @default false */
@@ -2246,6 +2466,17 @@ declare module "types" {
2246
2466
  * until the start node is reached again @default false */
2247
2467
  wrap?: boolean;
2248
2468
  }
2469
+ /**
2470
+ * Passed as tree option.filer.connect to configure automatic integration of
2471
+ * filter UI controls. @experimental
2472
+ */
2473
+ export interface FilterConnectType {
2474
+ inputElem: string | HTMLInputElement | null;
2475
+ modeButton?: string | HTMLButtonElement | null;
2476
+ nextButton?: string | HTMLButtonElement | HTMLAnchorElement | null;
2477
+ prevButton?: string | HTMLButtonElement | HTMLAnchorElement | null;
2478
+ matchInfoElem?: string | HTMLElement | null;
2479
+ }
2249
2480
  /**
2250
2481
  * Passed as tree options to configure default filtering behavior.
2251
2482
  *
@@ -2254,10 +2485,12 @@ declare module "types" {
2254
2485
  */
2255
2486
  export type FilterOptionsType = {
2256
2487
  /**
2257
- * Element or selector of an input control for filter query strings
2488
+ * Element or selector of input controls and buttons for filter query strings.
2489
+ * @experimental
2490
+ * @since 0.13
2258
2491
  * @default null
2259
2492
  */
2260
- connectInput?: null | string | Element;
2493
+ connect?: null | FilterConnectType;
2261
2494
  /**
2262
2495
  * Re-apply last filter if lazy data is loaded
2263
2496
  * @default true
@@ -2341,6 +2574,7 @@ declare module "types" {
2341
2574
  export type DropEffectAllowedType = "none" | "copy" | "copyLink" | "copyMove" | "link" | "linkMove" | "move" | "all";
2342
2575
  export type DropRegionType = "over" | "before" | "after";
2343
2576
  export type DropRegionTypeSet = Set<DropRegionType>;
2577
+ export type DropRegionTypeList = Array<DropRegionType>;
2344
2578
  export interface DragEventType extends WbNodeEventType {
2345
2579
  /** The original event. */
2346
2580
  event: DragEvent;
@@ -2354,6 +2588,8 @@ declare module "types" {
2354
2588
  node: WunderbaumNode;
2355
2589
  /** The source node if any. */
2356
2590
  sourceNode: WunderbaumNode;
2591
+ /** The DataTransfer object. */
2592
+ dataTransfer: DataTransfer;
2357
2593
  }
2358
2594
  export type DndOptionsType = {
2359
2595
  /**
@@ -2466,7 +2702,7 @@ declare module "types" {
2466
2702
  * @default null
2467
2703
  * @category Callback
2468
2704
  */
2469
- dragEnter?: null | ((e: DropEventType) => DropRegionType | DropRegionTypeSet | boolean);
2705
+ dragEnter?: null | ((e: DropEventType) => DropRegionType | DropRegionTypeSet | DropRegionTypeList | boolean);
2470
2706
  /**
2471
2707
  * Callback(targetNode, data)
2472
2708
  * @default null
@@ -2503,95 +2739,6 @@ declare module "types" {
2503
2739
  export type KeynavOptionsType = object;
2504
2740
  export type LoggerOptionsType = object;
2505
2741
  }
2506
- declare module "wb_extension_base" {
2507
- import { Wunderbaum } from "wunderbaum";
2508
- export type ExtensionsDict = {
2509
- [key: string]: WunderbaumExtension<any>;
2510
- };
2511
- export abstract class WunderbaumExtension<TOptions> {
2512
- enabled: boolean;
2513
- readonly id: string;
2514
- readonly tree: Wunderbaum;
2515
- readonly treeOpts: any;
2516
- readonly extensionOpts: any;
2517
- constructor(tree: Wunderbaum, id: string, defaults: TOptions);
2518
- /** Called on tree (re)init after all extensions are added, but before loading.*/
2519
- init(): void;
2520
- getPluginOption(name: string, defaultValue?: any): any;
2521
- setPluginOption(name: string, value: any): void;
2522
- setEnabled(flag?: boolean): void;
2523
- onKeyEvent(data: any): boolean | undefined;
2524
- onRender(data: any): boolean | undefined;
2525
- }
2526
- }
2527
- declare module "wb_ext_filter" {
2528
- import { FilterNodesOptions, FilterOptionsType, NodeFilterCallback } from "types";
2529
- import { Wunderbaum } from "wunderbaum";
2530
- import { WunderbaumExtension } from "wb_extension_base";
2531
- export class FilterExtension extends WunderbaumExtension<FilterOptionsType> {
2532
- queryInput?: HTMLInputElement;
2533
- lastFilterArgs: IArguments | null;
2534
- constructor(tree: Wunderbaum);
2535
- init(): void;
2536
- setPluginOption(name: string, value: any): void;
2537
- _applyFilterNoUpdate(filter: string | RegExp | NodeFilterCallback, _opts: FilterNodesOptions): number;
2538
- _applyFilterImpl(filter: string | RegExp | NodeFilterCallback, _opts: FilterNodesOptions): number;
2539
- /**
2540
- * [ext-filter] Dim or hide nodes.
2541
- */
2542
- filterNodes(filter: string | RegExp | NodeFilterCallback, options: FilterNodesOptions): number;
2543
- /**
2544
- * [ext-filter] Dim or hide whole branches.
2545
- * @deprecated Use {@link filterNodes} instead and set `options.matchBranch: true`.
2546
- */
2547
- filterBranches(filter: string | NodeFilterCallback, options: FilterNodesOptions): number;
2548
- /**
2549
- * [ext-filter] Return the number of matched nodes.
2550
- */
2551
- countMatches(): number;
2552
- /**
2553
- * [ext-filter] Re-apply current filter.
2554
- */
2555
- updateFilter(): void;
2556
- /**
2557
- * [ext-filter] Reset the filter.
2558
- */
2559
- clearFilter(): void;
2560
- }
2561
- }
2562
- declare module "wb_ext_keynav" {
2563
- /*!
2564
- * Wunderbaum - ext-keynav
2565
- * Copyright (c) 2021-2025, Martin Wendt. Released under the MIT license.
2566
- * @VERSION, @DATE (https://github.com/mar10/wunderbaum)
2567
- */
2568
- import { KeynavOptionsType } from "types";
2569
- import { Wunderbaum } from "wunderbaum";
2570
- import { WunderbaumExtension } from "wb_extension_base";
2571
- export class KeynavExtension extends WunderbaumExtension<KeynavOptionsType> {
2572
- constructor(tree: Wunderbaum);
2573
- protected _getEmbeddedInputElem(elem: any): HTMLInputElement | null;
2574
- protected _isCurInputFocused(): boolean;
2575
- onKeyEvent(data: any): boolean | undefined;
2576
- }
2577
- }
2578
- declare module "wb_ext_logger" {
2579
- /*!
2580
- * Wunderbaum - ext-logger
2581
- * Copyright (c) 2021-2025, Martin Wendt. Released under the MIT license.
2582
- * @VERSION, @DATE (https://github.com/mar10/wunderbaum)
2583
- */
2584
- import { LoggerOptionsType } from "types";
2585
- import { WunderbaumExtension } from "wb_extension_base";
2586
- import { Wunderbaum } from "wunderbaum";
2587
- export class LoggerExtension extends WunderbaumExtension<LoggerOptionsType> {
2588
- readonly prefix: string;
2589
- protected ignoreEvents: Set<string>;
2590
- constructor(tree: Wunderbaum);
2591
- init(): void;
2592
- onKeyEvent(data: any): boolean | undefined;
2593
- }
2594
- }
2595
2742
  declare module "wb_ext_dnd" {
2596
2743
  import { Wunderbaum } from "wunderbaum";
2597
2744
  import { WunderbaumExtension } from "wb_extension_base";
@@ -2639,6 +2786,42 @@ declare module "wb_ext_dnd" {
2639
2786
  protected onDropEvent(e: DragEvent): boolean;
2640
2787
  }
2641
2788
  }
2789
+ declare module "wb_ext_edit" {
2790
+ /*!
2791
+ * Wunderbaum - ext-edit
2792
+ * Copyright (c) 2021-2025, Martin Wendt. Released under the MIT license.
2793
+ * @VERSION, @DATE (https://github.com/mar10/wunderbaum)
2794
+ */
2795
+ import { Wunderbaum } from "wunderbaum";
2796
+ import { WunderbaumExtension } from "wb_extension_base";
2797
+ import { WunderbaumNode } from "wb_node";
2798
+ import { EditOptionsType, InsertNodeType, WbNodeData } from "types";
2799
+ export class EditExtension extends WunderbaumExtension<EditOptionsType> {
2800
+ protected debouncedOnChange: (e: Event) => void;
2801
+ protected curEditNode: WunderbaumNode | null;
2802
+ protected relatedNode: WunderbaumNode | null;
2803
+ constructor(tree: Wunderbaum);
2804
+ protected _applyChange(eventName: string, node: WunderbaumNode, colElem: HTMLElement, inputElem: HTMLInputElement, extra: any): Promise<any>;
2805
+ protected _onChange(e: Event): void;
2806
+ init(): void;
2807
+ _preprocessKeyEvent(data: any): boolean | undefined;
2808
+ /** Return true if a title is currently being edited. */
2809
+ isEditingTitle(node?: WunderbaumNode): boolean;
2810
+ /** Start renaming, i.e. replace the title with an embedded `<input>`. */
2811
+ startEditTitle(node?: WunderbaumNode | null): void;
2812
+ /**
2813
+ *
2814
+ * @param apply
2815
+ * @returns
2816
+ */
2817
+ stopEditTitle(apply: boolean): void;
2818
+ _stopEditTitle(apply: boolean, options: any): void;
2819
+ /**
2820
+ * Create a new child or sibling node and start edit mode.
2821
+ */
2822
+ createNode(mode?: InsertNodeType, node?: WunderbaumNode | null, init?: string | WbNodeData): void;
2823
+ }
2824
+ }
2642
2825
  declare module "drag_observer" {
2643
2826
  /*!
2644
2827
  * Wunderbaum - drag_observer
@@ -2723,45 +2906,117 @@ declare module "wb_ext_grid" {
2723
2906
  constructor(tree: Wunderbaum);
2724
2907
  init(): void;
2725
2908
  /**
2726
- * Hanldes drag and sragstop events for column resizing.
2909
+ * Handles drag and sragstop events for column resizing.
2727
2910
  */
2728
2911
  protected handleDrag(e: DragCallbackArgType): void;
2729
2912
  }
2730
2913
  }
2731
- declare module "wb_ext_edit" {
2914
+ declare module "wb_ext_keynav" {
2732
2915
  /*!
2733
- * Wunderbaum - ext-edit
2916
+ * Wunderbaum - ext-keynav
2734
2917
  * Copyright (c) 2021-2025, Martin Wendt. Released under the MIT license.
2735
2918
  * @VERSION, @DATE (https://github.com/mar10/wunderbaum)
2736
2919
  */
2920
+ import { KeynavOptionsType } from "types";
2737
2921
  import { Wunderbaum } from "wunderbaum";
2738
2922
  import { WunderbaumExtension } from "wb_extension_base";
2739
- import { WunderbaumNode } from "wb_node";
2740
- import { EditOptionsType, InsertNodeType, WbNodeData } from "types";
2741
- export class EditExtension extends WunderbaumExtension<EditOptionsType> {
2742
- protected debouncedOnChange: (e: Event) => void;
2743
- protected curEditNode: WunderbaumNode | null;
2744
- protected relatedNode: WunderbaumNode | null;
2923
+ export class KeynavExtension extends WunderbaumExtension<KeynavOptionsType> {
2924
+ constructor(tree: Wunderbaum);
2925
+ protected _getEmbeddedInputElem(elem: any): HTMLInputElement | null;
2926
+ protected _isCurInputFocused(): boolean;
2927
+ onKeyEvent(data: any): boolean | undefined;
2928
+ }
2929
+ }
2930
+ declare module "wb_ext_logger" {
2931
+ /*!
2932
+ * Wunderbaum - ext-logger
2933
+ * Copyright (c) 2021-2025, Martin Wendt. Released under the MIT license.
2934
+ * @VERSION, @DATE (https://github.com/mar10/wunderbaum)
2935
+ */
2936
+ import { LoggerOptionsType } from "types";
2937
+ import { WunderbaumExtension } from "wb_extension_base";
2938
+ import { Wunderbaum } from "wunderbaum";
2939
+ export class LoggerExtension extends WunderbaumExtension<LoggerOptionsType> {
2940
+ readonly prefix: string;
2941
+ protected ignoreEvents: Set<string>;
2745
2942
  constructor(tree: Wunderbaum);
2746
- protected _applyChange(eventName: string, node: WunderbaumNode, colElem: HTMLElement, inputElem: HTMLInputElement, extra: any): Promise<any>;
2747
- protected _onChange(e: Event): void;
2748
2943
  init(): void;
2749
- _preprocessKeyEvent(data: any): boolean | undefined;
2750
- /** Return true if a title is currently being edited. */
2751
- isEditingTitle(node?: WunderbaumNode): boolean;
2752
- /** Start renaming, i.e. replace the title with an embedded `<input>`. */
2753
- startEditTitle(node?: WunderbaumNode | null): void;
2944
+ onKeyEvent(data: any): boolean | undefined;
2945
+ }
2946
+ }
2947
+ declare module "wb_extension_base" {
2948
+ import { DndExtension } from "wb_ext_dnd";
2949
+ import { EditExtension } from "wb_ext_edit";
2950
+ import { FilterExtension } from "wb_ext_filter";
2951
+ import { GridExtension } from "wb_ext_grid";
2952
+ import { KeynavExtension } from "wb_ext_keynav";
2953
+ import { LoggerExtension } from "wb_ext_logger";
2954
+ import { WunderbaumOptions } from "wb_options";
2955
+ import { Wunderbaum } from "wunderbaum";
2956
+ export type ExtensionsDict = {
2957
+ dnd: DndExtension;
2958
+ edit: EditExtension;
2959
+ filter: FilterExtension;
2960
+ grid: GridExtension;
2961
+ keynav: KeynavExtension;
2962
+ logger: LoggerExtension;
2963
+ [key: string]: WunderbaumExtension<any>;
2964
+ };
2965
+ export abstract class WunderbaumExtension<TOptions> {
2966
+ enabled: boolean;
2967
+ readonly id: string;
2968
+ readonly tree: Wunderbaum;
2969
+ readonly treeOpts: WunderbaumOptions;
2970
+ readonly extensionOpts: any;
2971
+ constructor(tree: Wunderbaum, id: string, defaults: TOptions);
2972
+ /** Called on tree (re)init after all extensions are added, but before loading.*/
2973
+ init(): void;
2974
+ getPluginOption(name: string, defaultValue?: any): any;
2975
+ setPluginOption(name: string, value: any): void;
2976
+ setEnabled(flag?: boolean): void;
2977
+ onKeyEvent(data: any): boolean | undefined;
2978
+ onRender(data: any): boolean | undefined;
2979
+ }
2980
+ }
2981
+ declare module "wb_ext_filter" {
2982
+ import { FilterNodesOptions, FilterOptionsType, NodeFilterCallback } from "types";
2983
+ import { Wunderbaum } from "wunderbaum";
2984
+ import { WunderbaumExtension } from "wb_extension_base";
2985
+ export class FilterExtension extends WunderbaumExtension<FilterOptionsType> {
2986
+ queryInput: HTMLInputElement | null;
2987
+ prevButton: HTMLElement | HTMLAnchorElement | null;
2988
+ nextButton: HTMLElement | HTMLAnchorElement | null;
2989
+ modeButton: HTMLButtonElement | null;
2990
+ matchInfoElem: HTMLElement | null;
2991
+ lastFilterArgs: IArguments | null;
2992
+ constructor(tree: Wunderbaum);
2993
+ init(): void;
2994
+ setPluginOption(name: string, value: any): void;
2995
+ _updatedConnectedControls(): void;
2996
+ _connectControls(): void;
2997
+ _applyFilterNoUpdate(filter: string | RegExp | NodeFilterCallback, _opts: FilterNodesOptions): number;
2998
+ _applyFilterImpl(filter: string | RegExp | NodeFilterCallback, _opts: FilterNodesOptions): number;
2754
2999
  /**
2755
- *
2756
- * @param apply
2757
- * @returns
3000
+ * [ext-filter] Dim or hide nodes.
2758
3001
  */
2759
- stopEditTitle(apply: boolean): void;
2760
- _stopEditTitle(apply: boolean, options: any): void;
3002
+ filterNodes(filter: string | RegExp | NodeFilterCallback, options: FilterNodesOptions): number;
2761
3003
  /**
2762
- * Create a new child or sibling node and start edit mode.
3004
+ * [ext-filter] Dim or hide whole branches.
3005
+ * @deprecated Use {@link filterNodes} instead and set `options.matchBranch: true`.
2763
3006
  */
2764
- createNode(mode?: InsertNodeType, node?: WunderbaumNode | null, init?: string | WbNodeData): void;
3007
+ filterBranches(filter: string | NodeFilterCallback, options: FilterNodesOptions): number;
3008
+ /**
3009
+ * [ext-filter] Return the number of matched nodes.
3010
+ */
3011
+ countMatches(): number;
3012
+ /**
3013
+ * [ext-filter] Re-apply current filter.
3014
+ */
3015
+ updateFilter(): void;
3016
+ /**
3017
+ * [ext-filter] Reset the filter.
3018
+ */
3019
+ clearFilter(): void;
2765
3020
  }
2766
3021
  }
2767
3022
  declare module "wunderbaum" {
@@ -2779,9 +3034,9 @@ declare module "wunderbaum" {
2779
3034
  */
2780
3035
  import * as util from "util";
2781
3036
  import { ExtensionsDict, WunderbaumExtension } from "wb_extension_base";
2782
- import { AddChildrenOptions, ApplyCommandOptions, ApplyCommandType, ChangeType, ColumnDefinitionList, DynamicBoolOption, DynamicCheckboxOption, DynamicIconOption, DynamicStringOption, DynamicTooltipOption, ExpandAllOptions, FilterModeType, FilterNodesOptions, MatcherCallback, NavModeEnum, NodeFilterCallback, NodeStatusType, NodeStringCallback, NodeToDictCallback, NodeTypeDefinitionMap, NodeVisitCallback, RenderFlag, ScrollToOptions, SetActiveOptions, SetColumnOptions, SetStatusOptions, SortByPropertyOptions, SortCallback, SourceType, UpdateOptions, VisitRowsOptions, WbEventInfo, WbNodeData } from "types";
3037
+ import { AddChildrenOptions, ApplyCommandOptions, ApplyCommandType, ChangeType, ColumnDefinitionList, ExpandAllOptions, FilterModeType, FilterNodesOptions, IconMapType, GetStateOptions, MatcherCallback, NavigationType, NavModeEnum, NodeFilterCallback, NodeStatusType, NodeStringCallback, NodeToDictCallback, NodeTypeDefinitionMap, NodeVisitCallback, RenderFlag, ScrollToOptions, SetActiveOptions, SetColumnOptions, SetStateOptions, SetStatusOptions, SortCallback, SourceType, TreeStateDefinition, UpdateOptions, VisitRowsOptions, WbEventInfo, WbNodeData, SortOptions, DeprecationOptions, SortByPropertyOptions, ReloadOptions, LoadLazyNodesOptions } from "types";
2783
3038
  import { WunderbaumNode } from "wb_node";
2784
- import { WunderbaumOptions } from "wb_options";
3039
+ import { InitWunderbaumOptions, WunderbaumOptions } from "wb_options";
2785
3040
  import { DebouncedFunction } from "debounce";
2786
3041
  /**
2787
3042
  * A persistent plain object or array.
@@ -2821,6 +3076,7 @@ declare module "wunderbaum" {
2821
3076
  protected _disableUpdateIgnoreCount: number;
2822
3077
  protected _activeNode: WunderbaumNode | null;
2823
3078
  protected _focusNode: WunderbaumNode | null;
3079
+ protected _initialSource: SourceType | null;
2824
3080
  /** Currently active node if any.
2825
3081
  * Use {@link WunderbaumNode.setActive|setActive} to modify.
2826
3082
  */
@@ -2833,16 +3089,6 @@ declare module "wunderbaum" {
2833
3089
  types: NodeTypeDefinitionMap;
2834
3090
  /** List of column definitions. */
2835
3091
  columns: ColumnDefinitionList;
2836
- /** Show/hide a checkbox or radiobutton. */
2837
- checkbox?: DynamicCheckboxOption;
2838
- /** Show/hide a node icon. */
2839
- icon?: DynamicIconOption;
2840
- /** Show/hide a tooltip for the node icon. */
2841
- iconTooltip?: DynamicStringOption;
2842
- /** Show/hide a tooltip. */
2843
- tooltip?: DynamicTooltipOption;
2844
- /** Define a node checkbox as readonly. */
2845
- unselectable?: DynamicBoolOption;
2846
3092
  protected _columnsById: {
2847
3093
  [key: string]: any;
2848
3094
  };
@@ -2852,9 +3098,26 @@ declare module "wunderbaum" {
2852
3098
  readonly ready: Promise<any>;
2853
3099
  /** Expose some useful methods of the util.ts module as `Wunderbaum.util`. */
2854
3100
  static util: typeof util;
3101
+ /** A map of default iconMaps.
3102
+ * May be used as default, when passing partial icon definition maps:
3103
+ * ```js
3104
+ * const tree = new mar10.Wunderbaum({
3105
+ * ...
3106
+ * iconMap: Object.assign(Wunderbaum.iconMaps.bootstrap, {
3107
+ * folder: "bi bi-archive",
3108
+ * }),
3109
+ * });
3110
+ * ```
3111
+ */
3112
+ static iconMaps: {
3113
+ bootstrap: IconMapType;
3114
+ fontawesome6: IconMapType;
3115
+ };
2855
3116
  /** Expose some useful methods of the util.ts module as `tree._util`. */
2856
3117
  _util: typeof util;
2857
3118
  /** Filter options (used as defaults for calls to {@link Wunderbaum.filterNodes} ) */
3119
+ breadcrumb: HTMLElement | null;
3120
+ /** Filter options (used as defaults for calls to {@link Wunderbaum.filterNodes} ) */
2858
3121
  filterMode: FilterModeType;
2859
3122
  /** @internal Use `setColumn()`/`getActiveColElem()` to access. */
2860
3123
  activeColIdx: number;
@@ -2865,7 +3128,8 @@ declare module "wunderbaum" {
2865
3128
  /** @internal */
2866
3129
  lastQuicksearchTerm: string;
2867
3130
  protected lastClickTime: number;
2868
- constructor(options: WunderbaumOptions);
3131
+ constructor(options: InitWunderbaumOptions);
3132
+ private _registerEventHandlers;
2869
3133
  /**
2870
3134
  * Return a Wunderbaum instance, from element, id, index, or event.
2871
3135
  *
@@ -2880,10 +3144,9 @@ declare module "wunderbaum" {
2880
3144
  static getTree(el?: Element | Event | number | string | WunderbaumNode): Wunderbaum | null;
2881
3145
  /**
2882
3146
  * Return the icon-function -> icon-definition mapping.
3147
+ * @deprecated Use {@link Wunderbaum.iconMaps}
2883
3148
  */
2884
- get iconMap(): {
2885
- [key: string]: string;
2886
- };
3149
+ get iconMap(): IconMapType;
2887
3150
  /**
2888
3151
  * Return a WunderbaumNode instance from element or event.
2889
3152
  */
@@ -2904,9 +3167,16 @@ declare module "wunderbaum" {
2904
3167
  protected _registerExtension(extension: WunderbaumExtension<any>): void;
2905
3168
  /** Called on tree (re)init after markup is created, before loading. */
2906
3169
  protected _initExtensions(): void;
2907
- /** Add node to tree's bookkeeping data structures. */
3170
+ /**
3171
+ * Calculate a *stable*, unique key for a node from its refKey (or title).
3172
+ * We also add information from the parent, because a refKey may occur multiple
3173
+ * times in a tree (but not as child of the same parent).
3174
+ * @internal
3175
+ */
3176
+ _calculateKey(data: WbNodeData, parent?: WunderbaumNode): string;
3177
+ /** Add node to tree's bookkeeping data structures. @internal */
2908
3178
  _registerNode(node: WunderbaumNode): void;
2909
- /** Remove node from tree's bookkeeping data structures. */
3179
+ /** Remove node from tree's bookkeeping data structures. @internal */
2910
3180
  _unregisterNode(node: WunderbaumNode): void;
2911
3181
  /** Call all hook methods of all registered extensions.*/
2912
3182
  protected _callHook(hook: keyof WunderbaumExtension<any>, data?: any): any;
@@ -2930,14 +3200,21 @@ declare module "wunderbaum" {
2930
3200
  _callEvent(type: string, extra?: any): any;
2931
3201
  /** Return the node for given row index. */
2932
3202
  protected _getNodeByRowIdx(idx: number): WunderbaumNode | null;
2933
- /** Return the topmost visible node in the viewport. */
3203
+ /** Return the topmost visible node in the viewport.
3204
+ * @param complete If `false`, the node is considered visible if at least one
3205
+ * pixel is visible.
3206
+ */
2934
3207
  getTopmostVpNode(complete?: boolean): WunderbaumNode;
2935
3208
  /** Return the lowest visible node in the viewport. */
2936
3209
  getLowestVpNode(complete?: boolean): WunderbaumNode;
2937
- /** Return preceeding visible node in the viewport. */
3210
+ /** Return preceding visible node in the viewport. */
2938
3211
  protected _getPrevNodeInView(node?: WunderbaumNode, ofs?: number): WunderbaumNode;
2939
3212
  /** Return following visible node in the viewport. */
2940
- protected _getNextNodeInView(node?: WunderbaumNode, ofs?: number): WunderbaumNode;
3213
+ protected _getNextNodeInView(node?: WunderbaumNode, options?: {
3214
+ ofs?: number;
3215
+ reverse?: boolean;
3216
+ cb?: (n: WunderbaumNode) => boolean;
3217
+ }): WunderbaumNode;
2941
3218
  /**
2942
3219
  * Append (or insert) a list of toplevel nodes.
2943
3220
  *
@@ -2989,12 +3266,21 @@ declare module "wunderbaum" {
2989
3266
  /** Run code, but defer rendering of viewport until done.
2990
3267
  *
2991
3268
  * ```js
2992
- * tree.runWithDeferredUpdate(() => {
2993
- * return someFuncThatWouldUpdateManyNodes();
3269
+ * const res = tree.runWithDeferredUpdate(() => {
3270
+ * return someFunctionThatWouldUpdateManyNodes();
2994
3271
  * });
2995
3272
  * ```
2996
3273
  */
2997
- runWithDeferredUpdate(func: () => any, hint?: any): any;
3274
+ runWithDeferredUpdate<T>(func: () => util.NotPromise<T>): T;
3275
+ /** Run code, but defer rendering of viewport until done.
3276
+ *
3277
+ * ```js
3278
+ * const res = await tree.runWithDeferredUpdate(async () => {
3279
+ * return someAsyncFunctionThatWouldUpdateManyNodes();
3280
+ * });
3281
+ * ```
3282
+ */
3283
+ runWithDeferredUpdateAsync<T>(func: () => Promise<T>): Promise<T>;
2998
3284
  /** Recursively expand all expandable nodes (triggers lazy load if needed). */
2999
3285
  expandAll(flag?: boolean, options?: ExpandAllOptions): Promise<void>;
3000
3286
  /** Recursively select all nodes. */
@@ -3006,11 +3292,23 @@ declare module "wunderbaum" {
3006
3292
  * @param stopOnParents only return the topmost selected node (useful with selectMode 'hier')
3007
3293
  */
3008
3294
  getSelectedNodes(stopOnParents?: boolean): WunderbaumNode[];
3295
+ /**
3296
+ * Return an array of refKey values.
3297
+ *
3298
+ * RefKeys are unique identifiers for a node data, and are used to identify
3299
+ * clones.
3300
+ * If more than one node has the same refKey, it is only returned once.
3301
+ * @param selected if true, only return refKeys of selected nodes.
3302
+ */
3303
+ getRefKeys(selected?: boolean): string[];
3009
3304
  protected _selectRange(eventInfo: WbEventInfo): false | void;
3010
3305
  /** Return the number of nodes in the data model.
3011
3306
  * @param visible if true, nodes that are hidden due to collapsed parents are ignored.
3012
3307
  */
3013
3308
  count(visible?: boolean): number;
3309
+ /** Return the number of *unique* nodes in the data model, i.e. unique `node.refKey`.
3310
+ */
3311
+ countUnique(): number;
3014
3312
  /** @internal sanity check. */
3015
3313
  _check(): void;
3016
3314
  /**
@@ -3051,7 +3349,7 @@ declare module "wunderbaum" {
3051
3349
  * and wrap-around at the end.
3052
3350
  * Used by quicksearch and keyboard navigation.
3053
3351
  */
3054
- findNextNode(match: string | MatcherCallback, startNode?: WunderbaumNode | null): WunderbaumNode | null;
3352
+ findNextNode(match: string | MatcherCallback, startNode?: WunderbaumNode | null, reverse?: boolean): WunderbaumNode | null;
3055
3353
  /**
3056
3354
  * Find a node relative to another node.
3057
3355
  *
@@ -3061,7 +3359,7 @@ declare module "wunderbaum" {
3061
3359
  * e.g. `$.ui.keyCode.LEFT` = 'left'.
3062
3360
  * @param includeHidden Not yet implemented
3063
3361
  */
3064
- findRelatedNode(node: WunderbaumNode, where: string, includeHidden?: boolean): any;
3362
+ findRelatedNode(node: WunderbaumNode, where: NavigationType, includeHidden?: boolean): any;
3065
3363
  /**
3066
3364
  * Iterator version of {@link Wunderbaum.format}.
3067
3365
  */
@@ -3087,6 +3385,14 @@ declare module "wunderbaum" {
3087
3385
  * @see {@link Wunderbaum.format_iter} and {@link WunderbaumNode.format}.
3088
3386
  */
3089
3387
  format(name_cb?: NodeStringCallback, connectors?: string[]): string;
3388
+ /**
3389
+ * Always returns null (so a tree instance behaves as `tree.root`).
3390
+ */
3391
+ get parent(): null;
3392
+ /**
3393
+ * Return a list of top-level nodes.
3394
+ */
3395
+ get children(): WunderbaumNode[];
3090
3396
  /**
3091
3397
  * Return the active cell (`span.wb-col`) of the currently active node or null.
3092
3398
  */
@@ -3105,6 +3411,10 @@ declare module "wunderbaum" {
3105
3411
  * Return the first top level node if any (not the invisible root node).
3106
3412
  */
3107
3413
  getFirstChild(): WunderbaumNode;
3414
+ /**
3415
+ * Return the last top level node if any (not the invisible root node).
3416
+ */
3417
+ getLastChild(): WunderbaumNode;
3108
3418
  /**
3109
3419
  * Return the node that currently has keyboard focus or null.
3110
3420
  * Alias for {@link Wunderbaum.focusNode}.
@@ -3128,12 +3438,12 @@ declare module "wunderbaum" {
3128
3438
  toString(): string;
3129
3439
  /** Return true if any node title or grid cell is currently beeing edited.
3130
3440
  *
3131
- * See also {@link Wunderbaum.isEditingTitle}.
3441
+ * See also {@link isEditingTitle}.
3132
3442
  */
3133
3443
  isEditing(): boolean;
3134
3444
  /** Return true if any node is currently in edit-title mode.
3135
3445
  *
3136
- * See also {@link WunderbaumNode.isEditingTitle} and {@link Wunderbaum.isEditing}.
3446
+ * See also {@link WunderbaumNode.isEditingTitle} and {@link isEditing}.
3137
3447
  */
3138
3448
  isEditingTitle(): boolean;
3139
3449
  /**
@@ -3141,12 +3451,12 @@ declare module "wunderbaum" {
3141
3451
  */
3142
3452
  isLoading(): boolean;
3143
3453
  /** Write to `console.log` with tree name as prefix if opts.debugLevel >= 4.
3144
- * @see {@link Wunderbaum.logDebug}
3454
+ * @see {@link logDebug}
3145
3455
  */
3146
3456
  log(...args: any[]): void;
3147
3457
  /** Write to `console.debug` with tree name as prefix if opts.debugLevel >= 4.
3148
3458
  * and browser console level includes debug/verbose messages.
3149
- * @see {@link Wunderbaum.log}
3459
+ * @see {@link log}
3150
3460
  */
3151
3461
  logDebug(...args: any[]): void;
3152
3462
  /** Write to `console.error` with tree name as prefix. */
@@ -3159,6 +3469,8 @@ declare module "wunderbaum" {
3159
3469
  logTimeEnd(label: string): void;
3160
3470
  /** Write to `console.warn` with tree name as prefix with if opts.debugLevel >= 2. */
3161
3471
  logWarn(...args: any[]): void;
3472
+ /** Emit a warning for deprecated methods. @internal */
3473
+ logDeprecate(method: string, options?: DeprecationOptions): void;
3162
3474
  /** Reset column widths to default. @since 0.10.0 */
3163
3475
  resetColumns(): void;
3164
3476
  /**
@@ -3190,6 +3502,10 @@ declare module "wunderbaum" {
3190
3502
  /** Set or remove keyboard focus to the tree container. */
3191
3503
  setFocus(flag?: boolean): void;
3192
3504
  _setFocusNode(node: WunderbaumNode | null): void;
3505
+ /** Return the current selection/expansion/activation status. @experimental */
3506
+ getState(options?: GetStateOptions): TreeStateDefinition;
3507
+ /** Apply selection/expansion/activation status. @experimental */
3508
+ setState(state: TreeStateDefinition, options?: SetStateOptions): Promise<void>;
3193
3509
  /**
3194
3510
  * Schedule an update request to reflect a tree change.
3195
3511
  * The render operation is async and debounced unless the `immediate` option
@@ -3228,14 +3544,21 @@ declare module "wunderbaum" {
3228
3544
  * @param {function} cmp custom compare function(a, b) that returns -1, 0, or 1
3229
3545
  * (defaults to sorting by title).
3230
3546
  * @param {boolean} deep pass true to sort all descendant nodes recursively
3547
+ * @deprecated use {@link sort}
3231
3548
  */
3232
3549
  sortChildren(cmp?: SortCallback | null, deep?: boolean): void;
3233
3550
  /**
3234
3551
  * Convenience method to implement column sorting.
3235
3552
  * @see {@link WunderbaumNode.sortByProperty}.
3236
3553
  * @since 0.11.0
3554
+ * @deprecated use {@link sort}
3237
3555
  */
3238
3556
  sortByProperty(options: SortByPropertyOptions): void;
3557
+ /**
3558
+ * Sort nodes list by title or custom criteria.
3559
+ * @since 0.14.0
3560
+ */
3561
+ sort(options: SortOptions): void;
3239
3562
  /** Convert tree to an array of plain objects.
3240
3563
  *
3241
3564
  * @param callback is called for every node, in order to allow
@@ -3250,7 +3573,6 @@ declare module "wunderbaum" {
3250
3573
  * Return true if at least one column width changed.
3251
3574
  */
3252
3575
  _updateColumnWidths(): boolean;
3253
- protected _insertIcon(icon: string, elem: HTMLElement): void;
3254
3576
  /** Create/update header markup from `this.columns` definition.
3255
3577
  * @internal
3256
3578
  */
@@ -3266,6 +3588,9 @@ declare module "wunderbaum" {
3266
3588
  * pending async changes if any.
3267
3589
  */
3268
3590
  updatePendingModifications(): void;
3591
+ /** @internal */
3592
+ _createNodeIcon(node: WunderbaumNode, showLoading: boolean, showBadge: boolean): HTMLElement | null;
3593
+ private _updateTopBreadcrumb;
3269
3594
  /**
3270
3595
  * This is the actual update method, which is wrapped inside a throttle method.
3271
3596
  * It calls `updateColumns()` and `_updateRows()`.
@@ -3279,7 +3604,8 @@ declare module "wunderbaum" {
3279
3604
  protected _updateRows(options?: any): boolean;
3280
3605
  /**
3281
3606
  * Call `callback(node)` for all nodes in hierarchical order (depth-first, pre-order).
3282
- * @see {@link IterableIterator<WunderbaumNode>}, {@link WunderbaumNode.visit}.
3607
+ * @see `wb_node.WunderbaumNode.IterableIterator<WunderbaumNode>`
3608
+ * @see {@link WunderbaumNode.visit}.
3283
3609
  *
3284
3610
  * @param {function} callback the callback function.
3285
3611
  * Return false to stop iteration, return "skip" to skip this node and
@@ -3309,8 +3635,24 @@ declare module "wunderbaum" {
3309
3635
  *
3310
3636
  * Previous data is cleared. Note that also column- and type defintions may
3311
3637
  * be passed with the `source` object.
3638
+ * @see {@link Wunderbaum.reload} for a shortcut to reload the last ajax request
3639
+ * and restore the previous state.
3312
3640
  */
3313
3641
  load(source: SourceType): Promise<void>;
3642
+ /** Reload the tree and optionally restore state.
3643
+ * Source defaults to last ajax url if any.
3644
+ * Restoring the active node requires stable keys
3645
+ * @see {@link WunderbaumOptions.autoKeys}
3646
+ * @see {@link Wunderbaum.load}
3647
+ * @experimental
3648
+ */
3649
+ reload(options?: ReloadOptions): Promise<void>;
3650
+ /**
3651
+ * Make sure that all nodes in the given keyList are accessible.
3652
+ * This may include loading lazy parent nodes.
3653
+ * Recursively load (and optionally expand) all requested node paths.
3654
+ */
3655
+ protected _loadLazyNodes(keyList: string[], options?: LoadLazyNodesOptions): Promise<void>;
3314
3656
  /**
3315
3657
  * Disable render requests during operations that would trigger many updates.
3316
3658
  *