wunderbaum 0.13.0 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
  /*!
@@ -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,8 +479,8 @@ declare module "common" {
458
479
  * - 'fontawesome6' {@link https://fontawesome.com/icons}
459
480
  *
460
481
  */
461
- export const iconMaps: {
462
- [key: string]: IconMapType;
482
+ export const defaultIconMaps: {
483
+ [key in IconLibrary]: IconMapType;
463
484
  };
464
485
  export const KEY_NODATA = "__not_found__";
465
486
  /** Define which keys are handled by embedded <input> control, and should
@@ -485,7 +506,9 @@ declare module "common" {
485
506
  export function makeNodeTitleMatcher(match: string | RegExp): MatcherCallback;
486
507
  /** Return a callback that returns true if the node title starts with a string (case-insensitive). */
487
508
  export function makeNodeTitleStartMatcher(s: string): MatcherCallback;
488
- /** 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
+ */
489
512
  export function nodeTitleSorter(a: WunderbaumNode, b: WunderbaumNode): number;
490
513
  /**
491
514
  * Decompresses the source data by
@@ -542,7 +565,7 @@ declare module "deferred" {
542
565
  }
543
566
  declare module "wb_node" {
544
567
  import { Wunderbaum } from "wunderbaum";
545
- 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, 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";
546
569
  /**
547
570
  * A single tree node.
548
571
  *
@@ -625,7 +648,7 @@ declare module "wb_node" {
625
648
  _filterAutoExpanded?: boolean;
626
649
  _rowIdx: number | undefined;
627
650
  _rowElem: HTMLDivElement | undefined;
628
- constructor(tree: Wunderbaum, parent: WunderbaumNode, data: any);
651
+ constructor(tree: Wunderbaum, parent: WunderbaumNode, data: WbNodeData);
629
652
  /**
630
653
  * Return readable string representation for this instance.
631
654
  * @internal
@@ -788,13 +811,13 @@ declare module "wb_node" {
788
811
  * @param includeSelf Include the node itself.
789
812
  */
790
813
  getParentList(includeRoot?: boolean, includeSelf?: boolean): any[];
791
- /** 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".
792
815
  * @param includeSelf
793
816
  * @param part property name or callback
794
817
  * @param separator
795
818
  */
796
819
  getPath(includeSelf?: boolean, part?: keyof WunderbaumNode | NodeAnyCallback, separator?: string): string;
797
- /** Return the preceeding node (under the same parent) or null. */
820
+ /** Return the preceding node (under the same parent) or null. */
798
821
  getPrevSibling(): WunderbaumNode | null;
799
822
  /** Return true if node has children.
800
823
  * Return undefined if not sure, i.e. the node is lazy and not yet loaded.
@@ -802,7 +825,7 @@ declare module "wb_node" {
802
825
  hasChildren(): boolean;
803
826
  /** Return true if node has className set. */
804
827
  hasClass(className: string): boolean;
805
- /** 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 */
806
829
  hasFocus(): boolean;
807
830
  /** Return true if this node is the currently active tree node. */
808
831
  isActive(): boolean;
@@ -857,9 +880,9 @@ declare module "wb_node" {
857
880
  isPartload(): boolean;
858
881
  /** Return true if this node is partially selected (tri-state). */
859
882
  isPartsel(): boolean;
860
- /** 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. */
861
884
  isRadio(): boolean;
862
- /** 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. */
863
886
  isRendered(): boolean;
864
887
  /** Return true if this node is the (invisible) system root node.
865
888
  * @see {@link WunderbaumNode.isTopLevel}
@@ -1026,6 +1049,15 @@ declare module "wb_node" {
1026
1049
  * @param stopOnParents only return the topmost selected node (useful with selectMode 'hier')
1027
1050
  */
1028
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[];
1029
1061
  /** Toggle the check/uncheck state. */
1030
1062
  toggleSelected(options?: SetSelectedOptions): TristateType;
1031
1063
  /** Return true if at least on selectable descendant end-node is unselected. @internal */
@@ -1051,12 +1083,12 @@ declare module "wb_node" {
1051
1083
  setTitle(title: string): void;
1052
1084
  /** Set the node tooltip. */
1053
1085
  setTooltip(tooltip: TooltipOption): void;
1054
- _sortChildren(cmp: SortCallback, deep: boolean): void;
1055
1086
  /**
1056
1087
  * Sort child list by title or custom criteria.
1057
1088
  * @param {function} cmp custom compare function(a, b) that returns -1, 0, or 1
1058
1089
  * (defaults to sorting by title).
1059
1090
  * @param {boolean} deep pass true to sort all descendant nodes recursively
1091
+ * @deprecated use {@link sort}
1060
1092
  */
1061
1093
  sortChildren(cmp?: SortCallback | null, deep?: boolean): void;
1062
1094
  /**
@@ -1069,8 +1101,26 @@ declare module "wb_node" {
1069
1101
  /**
1070
1102
  * Convenience method to implement column sorting.
1071
1103
  * @since 0.11.0
1104
+ * @deprecated use {@link sort}
1072
1105
  */
1073
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;
1074
1124
  /**
1075
1125
  * Trigger `modifyChild` event on a parent to signal that a child was modified.
1076
1126
  * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ...
@@ -1092,7 +1142,8 @@ declare module "wb_node" {
1092
1142
  * @param {function} callback the callback function.
1093
1143
  * Return false to stop iteration, return "skip" to skip this node and
1094
1144
  * its children only.
1095
- * @see {@link IterableIterator<WunderbaumNode>}, {@link Wunderbaum.visit}.
1145
+ * @see `wb_node.WunderbaumNode.IterableIterator<WunderbaumNode>`
1146
+ * @see {@link Wunderbaum.visit}.
1096
1147
  */
1097
1148
  visit(callback: NodeVisitCallback, includeSelf?: boolean): NodeVisitResponse;
1098
1149
  /** Call fn(node) for all parent nodes, bottom-up, including invisible system root.<br>
@@ -1120,121 +1171,73 @@ declare module "wb_node" {
1120
1171
  }
1121
1172
  declare module "wb_options" {
1122
1173
  /*!
1123
- * Wunderbaum - utils
1174
+ * Wunderbaum - options
1124
1175
  * Copyright (c) 2021-2025, Martin Wendt. Released under the MIT license.
1125
1176
  * @VERSION, @DATE (https://github.com/mar10/wunderbaum)
1126
1177
  */
1127
- import { ColumnDefinitionList, DndOptionsType, DynamicBoolOption, DynamicBoolOrStringOption, DynamicCheckboxOption, DynamicIconOption, EditOptionsType, FilterOptionsType, IconMapType, NavModeEnum, NodeTypeDefinitionMap, SelectModeType, TranslationsType, 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";
1128
1179
  /**
1129
- * Available options for {@link wunderbaum.Wunderbaum}.
1130
- *
1131
- * Options are passed to the constructor as plain object:
1132
- *
1133
- * ```js
1134
- * const tree = new mar10.Wunderbaum({
1135
- * id: "demo",
1136
- * element: document.getElementById("demo-tree"),
1137
- * source: "url/of/data/request",
1138
- * ...
1139
- * });
1140
- * ```
1141
- *
1142
- * Event handlers are also passed as callbacks
1180
+ * Properties of {@link wunderbaum.Wunderbaum.options}.
1143
1181
  *
1144
- * ```js
1145
- * const tree = new mar10.Wunderbaum({
1146
- * ...
1147
- * init: (e) => {
1148
- * console.log(`Tree ${e.tree} was initialized and loaded.`)
1149
- * },
1150
- * activate: (e) => {
1151
- * console.log(`Node ${e.node} was activated.`)
1152
- * },
1153
- * ...
1154
- * });
1155
- * ```
1182
+ * This is similar, but not identical, to the options that can be passed to the
1183
+ * constructor(@see {@link InitWunderbaumOptions}).
1156
1184
  */
1157
1185
  export interface WunderbaumOptions {
1158
- /**
1159
- * The target `div` element (or selector) that shall become a Wunderbaum.
1160
- */
1161
- element: string | HTMLDivElement;
1162
- /**
1163
- * The identifier of this tree. Used to reference the instance, especially
1164
- * when multiple trees are present (e.g. `tree = mar10.Wunderbaum.getTree("demo")`).
1165
- *
1166
- * Default: `"wb_" + COUNTER`.
1167
- */
1168
- id?: string;
1169
- /**
1170
- * Define the initial tree data. Typically a URL of an endpoint that serves
1171
- * a JSON formatted structure, but also a callback, Promise, or static data
1172
- * is allowed.
1173
- *
1174
- * Default: `{}`.
1175
- */
1176
- source?: string | Array<WbNodeData>;
1177
- /**
1178
- * Define shared attributes for multiple nodes of the same type.
1179
- * This allows for more compact data models. Type definitions can be passed
1180
- * as tree option, or be part of a `source` response.
1181
- *
1182
- * Default: `{}`.
1183
- */
1184
- types?: NodeTypeDefinitionMap;
1185
- /**
1186
- * A list of maps that define column headers. If this option is set,
1187
- * Wunderbaum becomes a treegrid control instead of a plain tree.
1188
- * Column definitions can be passed as tree option, or be part of a `source`
1189
- * response.
1190
- * Default: `[]` meaning this is a plain tree.
1191
- */
1192
- columns?: ColumnDefinitionList;
1193
1186
  /**
1194
1187
  * If true, add a `wb-skeleton` class to all nodes, that will result in a
1195
1188
  * 'glow' effect. Typically used with initial dummy nodes, while loading the
1196
1189
  * real data.
1197
- * Default: false.
1190
+ * @default false.
1198
1191
  */
1199
- skeleton?: boolean;
1192
+ skeleton: boolean;
1200
1193
  /**
1201
1194
  * Translation map for some system messages.
1202
1195
  */
1203
- strings?: TranslationsType;
1196
+ strings: TranslationsType;
1204
1197
  /**
1205
1198
  * 0:quiet, 1:errors, 2:warnings, 3:info, 4:verbose
1206
- * Default: 3 (4 in local debug environment)
1199
+ * @default 3 (4 in local debug environment)
1207
1200
  */
1208
- debugLevel?: number;
1201
+ debugLevel: number;
1209
1202
  /**
1210
1203
  * Number of levels that are forced to be expanded, and have no expander icon.
1211
1204
  * E.g. 1 would keep all toplevel nodes expanded.
1212
- * Default: 0
1205
+ * @default 0
1213
1206
  */
1214
- minExpandLevel?: number;
1207
+ minExpandLevel: number;
1215
1208
  /**
1216
1209
  * If true, allow to expand parent nodes, even if `node.children` conatains
1217
1210
  * an empty array (`[]`). This is the the behavior of macOS Finder, for example.
1218
- * Default: false
1211
+ * @default false
1219
1212
  */
1220
- emptyChildListExpandable?: boolean;
1213
+ emptyChildListExpandable: boolean;
1221
1214
  /**
1222
1215
  * Height of a node row div.
1223
- * Default: 22
1216
+ * @default 22
1224
1217
  */
1225
- rowHeightPx?: number;
1218
+ rowHeightPx: number;
1226
1219
  /**
1227
1220
  * Icon font definition. May be a string (e.g. "fontawesome6" or "bootstrap")
1228
1221
  * or a map of `iconName: iconClass` pairs.
1229
1222
  * Note: the icon font must be loaded separately.
1230
- * 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"
1231
1234
  */
1232
- iconMap?: string | IconMapType;
1235
+ iconMap: string | IconMapType;
1233
1236
  /**
1234
1237
  * Collapse siblings when a node is expanded.
1235
- * Default: false
1238
+ * @default false
1236
1239
  */
1237
- autoCollapse?: boolean;
1240
+ autoCollapse: boolean;
1238
1241
  /**
1239
1242
  * If true, the tree will automatically adjust its height to fit the parent
1240
1243
  * container. This is useful when the tree is embedded in a container with
@@ -1248,16 +1251,16 @@ declare module "wb_options" {
1248
1251
  *
1249
1252
  * @default: true
1250
1253
  */
1251
- adjustHeight?: boolean;
1254
+ adjustHeight: boolean;
1252
1255
  /**
1253
1256
  * HTMLElement or selector that receives the top nodes breadcrumb.
1254
- * Default: undefined
1257
+ * @default undefined
1255
1258
  */
1256
- connectTopBreadcrumb?: HTMLElement | string;
1259
+ connectTopBreadcrumb: HTMLElement | string | null;
1257
1260
  /**
1258
- * Default: NavModeEnum.startRow
1261
+ * @default NavModeEnum.startRow
1259
1262
  */
1260
- navigationModeOption?: NavModeEnum;
1263
+ navigationModeOption: NavModeEnum;
1261
1264
  /**
1262
1265
  * Show/hide header (default: null)
1263
1266
  * null: assume false for plain tree and true for grids.
@@ -1265,17 +1268,27 @@ declare module "wb_options" {
1265
1268
  * true: display a header (use tree's id as text for plain trees)
1266
1269
  * false: do not display a header
1267
1270
  */
1268
- header?: boolean | string | null;
1271
+ header: boolean | string | null;
1269
1272
  /**
1270
- *
1273
+ * Show a `<progress>` element while loading data.
1274
+ * @default false.
1271
1275
  */
1272
- showSpinner?: boolean;
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.
1284
+ */
1285
+ autoKeys: boolean;
1273
1286
  /**
1274
1287
  * If true, render a checkbox before the node tile to allow selection with the
1275
1288
  * mouse. Pass `"radio"` to render a radio button instead.
1276
- * Default: false.
1289
+ * @default false.
1277
1290
  */
1278
- checkbox?: DynamicCheckboxOption;
1291
+ checkbox: DynamicCheckboxOption;
1279
1292
  /** Optional callback to render icons per node. */
1280
1293
  icon?: DynamicIconOption;
1281
1294
  /** Optional callback to render a tooltip for the icon. */
@@ -1287,53 +1300,67 @@ declare module "wb_options" {
1287
1300
  /** Optional callback to make a node unselectable. */
1288
1301
  unselectable?: DynamicBoolOption;
1289
1302
  /**
1290
- * Default: true
1303
+ * @default true
1291
1304
  */
1292
- enabled?: boolean;
1305
+ enabled: boolean;
1293
1306
  /**
1294
- * Default: false
1307
+ *
1308
+ * @default false
1295
1309
  */
1296
- fixedCol?: boolean;
1310
+ fixedCol: boolean;
1297
1311
  /**
1298
1312
  * Default value for ColumnDefinition.filterable option.
1299
- * Default: false
1313
+ * @default false
1300
1314
  * @since 0.11.0
1301
1315
  */
1302
- columnsFilterable?: boolean;
1316
+ columnsFilterable: boolean;
1303
1317
  /**
1304
1318
  * Default value for ColumnDefinition.menu option.
1305
- * Default: false
1319
+ * @default false
1306
1320
  * @since 0.11.0
1307
1321
  */
1308
- columnsMenu?: boolean;
1322
+ columnsMenu: boolean;
1309
1323
  /**
1310
1324
  * Default value for ColumnDefinition.resizable option.
1311
- * Default: false
1325
+ * @default false
1312
1326
  * @since 0.10.0
1313
1327
  */
1314
1328
  columnsResizable?: boolean;
1315
1329
  /**
1316
1330
  * Default value for ColumnDefinition.sortable option.
1317
- * Default: false
1331
+ * @default false
1318
1332
  * @since 0.11.0
1319
1333
  */
1320
1334
  columnsSortable?: boolean;
1321
1335
  /**
1322
- * 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
1343
+ */
1344
+ sortFoldersFirst?: DynamicBoolOption;
1345
+ /**
1346
+ * @default "multi"
1323
1347
  */
1324
- selectMode?: SelectModeType;
1348
+ selectMode: SelectModeType;
1325
1349
  /**
1326
- * Default: true
1350
+ * @default true
1327
1351
  */
1328
- quicksearch?: boolean;
1352
+ quicksearch: boolean;
1329
1353
  /**
1330
1354
  * Scroll Node into view on Expand Click
1331
1355
  * @default true
1332
1356
  */
1333
- scrollIntoViewOnExpandClick?: boolean;
1334
- dnd?: DndOptionsType;
1335
- edit?: EditOptionsType;
1336
- 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;
1337
1364
  /**
1338
1365
  * `e.node` was activated.
1339
1366
  * @category Callback
@@ -1478,6 +1505,90 @@ declare module "wb_options" {
1478
1505
  */
1479
1506
  update?: (e: WbTreeEventType) => void;
1480
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
+ }
1481
1592
  }
1482
1593
  declare module "types" {
1483
1594
  /*!
@@ -1530,8 +1641,13 @@ declare module "types" {
1530
1641
  export type MatcherCallback = (node: WunderbaumNode) => boolean;
1531
1642
  /** Used for `tree.iconBadge` event. */
1532
1643
  export type WbIconBadgeCallback = (e: WbIconBadgeEventType) => WbIconBadgeEventResultType;
1533
- /** 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
+ */
1534
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[];
1535
1651
  /** When set as option, called when the value is needed (e.g. `colspan` type definition). */
1536
1652
  export type BoolOptionResolver = (node: WunderbaumNode) => boolean;
1537
1653
  /** When set as option, called when the value is needed (e.g. `icon` type definition). */
@@ -1560,6 +1676,11 @@ declare module "types" {
1560
1676
  * (de)selection.
1561
1677
  */
1562
1678
  export type NodeSelectCallback = (node: WunderbaumNode) => boolean | void;
1679
+ /** @internal */
1680
+ export type DeprecationOptions = {
1681
+ since?: string;
1682
+ hint?: string;
1683
+ };
1563
1684
  /**
1564
1685
  * See also {@link WunderbaumNode.getOption|WunderbaumNode.getOption()}
1565
1686
  * to evaluate `node.NAME` setting and `tree.types[node.type].NAME`.
@@ -1619,7 +1740,7 @@ declare module "types" {
1619
1740
  title: string;
1620
1741
  /** Pass true to set node tooltip to the node's title. Defaults to {@link WunderbaumOptions.tooltip}. */
1621
1742
  tooltip?: TooltipOption;
1622
- /** Inherit shared settings from the matching entry in {@link WunderbaumOptions.types}. */
1743
+ /** Inherit shared settings from the matching entry in `InitWunderbaumOptions.types`. */
1623
1744
  type?: string;
1624
1745
  /** Set to `true` to prevent selection. Defaults to {@link WunderbaumOptions.unselectable}. */
1625
1746
  unselectable?: boolean;
@@ -1654,7 +1775,7 @@ declare module "types" {
1654
1775
  colMenu: string;
1655
1776
  [key: string]: string;
1656
1777
  }
1657
- /** A callback that receives a node instance and returns a string value. */
1778
+ /** Retuen value of an event handler that can return `false` to prevent the default action. */
1658
1779
  export type WbCancelableEventResultType = false | void;
1659
1780
  export interface WbTreeEventType {
1660
1781
  /** Name of the event. */
@@ -1911,19 +2032,6 @@ declare module "types" {
1911
2032
  [key: string]: unknown;
1912
2033
  }
1913
2034
  export type ColumnDefinitionList = Array<ColumnDefinition>;
1914
- /**
1915
- * Used by {@link Wunderbaum.getState} and {@link Wunderbaum.setState}.
1916
- */
1917
- export interface TreeStateDefinition {
1918
- /** The active node's key if any. */
1919
- activeKey: string | null;
1920
- /** The active column index if any. */
1921
- activeColIdx: number | null;
1922
- /** List of selected node's keys. */
1923
- selectedKeys: Array<string> | undefined;
1924
- /** List of expanded node's keys. */
1925
- expandedKeys: Array<string> | undefined;
1926
- }
1927
2035
  /**
1928
2036
  * Column information (passed to the `render` event).
1929
2037
  */
@@ -2113,8 +2221,7 @@ declare module "types" {
2113
2221
  /**Hide expanders if all child nodes are hidden by filter @default false */
2114
2222
  hideExpanders?: boolean;
2115
2223
  /** Highlight matches by wrapping inside `<mark>` tags.
2116
- * Does not work for filter callbacks.
2117
- * @default true
2224
+ * Does not work for filter callbacks. @default true
2118
2225
  */
2119
2226
  highlight?: boolean;
2120
2227
  /** Match end nodes only @default false */
@@ -2126,9 +2233,11 @@ declare module "types" {
2126
2233
  }
2127
2234
  /** Possible values for {@link Wunderbaum.getState}. */
2128
2235
  export interface GetStateOptions {
2129
- /** Include the expanded keys. @default true */
2236
+ /** Include the active node's key (and expand its parents). @default true */
2237
+ activeKey?: boolean;
2238
+ /** Include the expanded keys. @default false */
2130
2239
  expandedKeys?: boolean;
2131
- /** Include the selected keys. @default true */
2240
+ /** Include the selected keys. @default false */
2132
2241
  selectedKeys?: boolean;
2133
2242
  }
2134
2243
  /** Possible values for {@link Wunderbaum.setState}. */
@@ -2136,6 +2245,26 @@ declare module "types" {
2136
2245
  /** Recursively load lazy nodes as needed. @default false */
2137
2246
  expandLazy?: boolean;
2138
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
+ }
2139
2268
  /** Possible values for {@link WunderbaumNode.makeVisible}. */
2140
2269
  export interface MakeVisibleOptions {
2141
2270
  /** Do not animate expand (currently not implemented). @default false */
@@ -2254,7 +2383,16 @@ declare module "types" {
2254
2383
  details?: string;
2255
2384
  }
2256
2385
  /**
2257
- * 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.
2258
2396
  */
2259
2397
  export interface ResetOrderOptions {
2260
2398
  /** Sort descendants recursively. @default true */
@@ -2265,27 +2403,37 @@ declare module "types" {
2265
2403
  propName?: string;
2266
2404
  }
2267
2405
  /**
2268
- * Possible values for {@link WunderbaumNode.sortByProperty} `options` argument.
2406
+ * Possible values for {@link Wunderbaum.sort} and {@link WunderbaumNode.sort}
2407
+ * `options` argument.
2269
2408
  */
2270
- export interface SortByPropertyOptions {
2271
- /** Column ID as defined in `tree.columns` definition. Required if updateColInfo is true.*/
2272
- colId?: string;
2409
+ export interface SortOptions {
2273
2410
  /** The name of the node property that will be used for sorting.
2274
- * @default use the `colId` as property name.
2411
+ * Mandatory, unless {@link key} or {@link colId} are given.
2275
2412
  */
2276
2413
  propName?: string;
2277
- /** 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
+ */
2278
2426
  order?: SortOrderType;
2427
+ /** Sort descendants recursively. @default true */
2428
+ deep?: boolean;
2429
+ /** Sort string values case insensitive. @default false */
2430
+ caseInsensitive?: boolean;
2279
2431
  /**
2280
2432
  * Sort by this property if order is `undefined`.
2281
2433
  * See also {@link WunderbaumNode.resetNativeChildOrder}.
2282
2434
  * @default `_nativeIndex`.
2283
2435
  */
2284
2436
  nativeOrderPropName?: string;
2285
- /** Sort string values case insensitive. @default false */
2286
- caseInsensitive?: boolean;
2287
- /** Sort descendants recursively. @default true */
2288
- deep?: boolean;
2289
2437
  /**
2290
2438
  * Rotate sort order (asc -> desc -> none) before sorting.
2291
2439
  * Update the sort icons in the column header
@@ -2296,7 +2444,14 @@ declare module "types" {
2296
2444
  * @default false
2297
2445
  */
2298
2446
  updateColInfo?: boolean;
2447
+ /** Column ID as defined in `tree.columns` definition. Required if updateColInfo is true.*/
2448
+ colId?: string;
2299
2449
  }
2450
+ /**
2451
+ * Possible values for {@link WunderbaumNode.sortByProperty} `options` argument.
2452
+ * @deprecated
2453
+ */
2454
+ export type SortByPropertyOptions = SortOptions;
2300
2455
  /** Options passed to {@link Wunderbaum.visitRows}. */
2301
2456
  export interface VisitRowsOptions {
2302
2457
  /** Skip filtered nodes and children of collapsed nodes. @default false */
@@ -2419,6 +2574,7 @@ declare module "types" {
2419
2574
  export type DropEffectAllowedType = "none" | "copy" | "copyLink" | "copyMove" | "link" | "linkMove" | "move" | "all";
2420
2575
  export type DropRegionType = "over" | "before" | "after";
2421
2576
  export type DropRegionTypeSet = Set<DropRegionType>;
2577
+ export type DropRegionTypeList = Array<DropRegionType>;
2422
2578
  export interface DragEventType extends WbNodeEventType {
2423
2579
  /** The original event. */
2424
2580
  event: DragEvent;
@@ -2432,6 +2588,8 @@ declare module "types" {
2432
2588
  node: WunderbaumNode;
2433
2589
  /** The source node if any. */
2434
2590
  sourceNode: WunderbaumNode;
2591
+ /** The DataTransfer object. */
2592
+ dataTransfer: DataTransfer;
2435
2593
  }
2436
2594
  export type DndOptionsType = {
2437
2595
  /**
@@ -2544,7 +2702,7 @@ declare module "types" {
2544
2702
  * @default null
2545
2703
  * @category Callback
2546
2704
  */
2547
- dragEnter?: null | ((e: DropEventType) => DropRegionType | DropRegionTypeSet | boolean);
2705
+ dragEnter?: null | ((e: DropEventType) => DropRegionType | DropRegionTypeSet | DropRegionTypeList | boolean);
2548
2706
  /**
2549
2707
  * Callback(targetNode, data)
2550
2708
  * @default null
@@ -2581,102 +2739,6 @@ declare module "types" {
2581
2739
  export type KeynavOptionsType = object;
2582
2740
  export type LoggerOptionsType = object;
2583
2741
  }
2584
- declare module "wb_extension_base" {
2585
- import { WunderbaumOptions } from "wb_options";
2586
- import { Wunderbaum } from "wunderbaum";
2587
- export type ExtensionsDict = {
2588
- [key: string]: WunderbaumExtension<any>;
2589
- };
2590
- export abstract class WunderbaumExtension<TOptions> {
2591
- enabled: boolean;
2592
- readonly id: string;
2593
- readonly tree: Wunderbaum;
2594
- readonly treeOpts: WunderbaumOptions;
2595
- readonly extensionOpts: any;
2596
- constructor(tree: Wunderbaum, id: string, defaults: TOptions);
2597
- /** Called on tree (re)init after all extensions are added, but before loading.*/
2598
- init(): void;
2599
- getPluginOption(name: string, defaultValue?: any): any;
2600
- setPluginOption(name: string, value: any): void;
2601
- setEnabled(flag?: boolean): void;
2602
- onKeyEvent(data: any): boolean | undefined;
2603
- onRender(data: any): boolean | undefined;
2604
- }
2605
- }
2606
- declare module "wb_ext_filter" {
2607
- import { FilterNodesOptions, FilterOptionsType, NodeFilterCallback } from "types";
2608
- import { Wunderbaum } from "wunderbaum";
2609
- import { WunderbaumExtension } from "wb_extension_base";
2610
- export class FilterExtension extends WunderbaumExtension<FilterOptionsType> {
2611
- queryInput: HTMLInputElement | null;
2612
- prevButton: HTMLElement | HTMLAnchorElement | null;
2613
- nextButton: HTMLElement | HTMLAnchorElement | null;
2614
- modeButton: HTMLButtonElement | null;
2615
- matchInfoElem: HTMLElement | null;
2616
- lastFilterArgs: IArguments | null;
2617
- constructor(tree: Wunderbaum);
2618
- init(): void;
2619
- setPluginOption(name: string, value: any): void;
2620
- _updatedConnectedControls(): void;
2621
- _connectControls(): void;
2622
- _applyFilterNoUpdate(filter: string | RegExp | NodeFilterCallback, _opts: FilterNodesOptions): number;
2623
- _applyFilterImpl(filter: string | RegExp | NodeFilterCallback, _opts: FilterNodesOptions): number;
2624
- /**
2625
- * [ext-filter] Dim or hide nodes.
2626
- */
2627
- filterNodes(filter: string | RegExp | NodeFilterCallback, options: FilterNodesOptions): number;
2628
- /**
2629
- * [ext-filter] Dim or hide whole branches.
2630
- * @deprecated Use {@link filterNodes} instead and set `options.matchBranch: true`.
2631
- */
2632
- filterBranches(filter: string | NodeFilterCallback, options: FilterNodesOptions): number;
2633
- /**
2634
- * [ext-filter] Return the number of matched nodes.
2635
- */
2636
- countMatches(): number;
2637
- /**
2638
- * [ext-filter] Re-apply current filter.
2639
- */
2640
- updateFilter(): void;
2641
- /**
2642
- * [ext-filter] Reset the filter.
2643
- */
2644
- clearFilter(): void;
2645
- }
2646
- }
2647
- declare module "wb_ext_keynav" {
2648
- /*!
2649
- * Wunderbaum - ext-keynav
2650
- * Copyright (c) 2021-2025, Martin Wendt. Released under the MIT license.
2651
- * @VERSION, @DATE (https://github.com/mar10/wunderbaum)
2652
- */
2653
- import { KeynavOptionsType } from "types";
2654
- import { Wunderbaum } from "wunderbaum";
2655
- import { WunderbaumExtension } from "wb_extension_base";
2656
- export class KeynavExtension extends WunderbaumExtension<KeynavOptionsType> {
2657
- constructor(tree: Wunderbaum);
2658
- protected _getEmbeddedInputElem(elem: any): HTMLInputElement | null;
2659
- protected _isCurInputFocused(): boolean;
2660
- onKeyEvent(data: any): boolean | undefined;
2661
- }
2662
- }
2663
- declare module "wb_ext_logger" {
2664
- /*!
2665
- * Wunderbaum - ext-logger
2666
- * Copyright (c) 2021-2025, Martin Wendt. Released under the MIT license.
2667
- * @VERSION, @DATE (https://github.com/mar10/wunderbaum)
2668
- */
2669
- import { LoggerOptionsType } from "types";
2670
- import { WunderbaumExtension } from "wb_extension_base";
2671
- import { Wunderbaum } from "wunderbaum";
2672
- export class LoggerExtension extends WunderbaumExtension<LoggerOptionsType> {
2673
- readonly prefix: string;
2674
- protected ignoreEvents: Set<string>;
2675
- constructor(tree: Wunderbaum);
2676
- init(): void;
2677
- onKeyEvent(data: any): boolean | undefined;
2678
- }
2679
- }
2680
2742
  declare module "wb_ext_dnd" {
2681
2743
  import { Wunderbaum } from "wunderbaum";
2682
2744
  import { WunderbaumExtension } from "wb_extension_base";
@@ -2724,6 +2786,42 @@ declare module "wb_ext_dnd" {
2724
2786
  protected onDropEvent(e: DragEvent): boolean;
2725
2787
  }
2726
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
+ }
2727
2825
  declare module "drag_observer" {
2728
2826
  /*!
2729
2827
  * Wunderbaum - drag_observer
@@ -2808,45 +2906,117 @@ declare module "wb_ext_grid" {
2808
2906
  constructor(tree: Wunderbaum);
2809
2907
  init(): void;
2810
2908
  /**
2811
- * Hanldes drag and sragstop events for column resizing.
2909
+ * Handles drag and sragstop events for column resizing.
2812
2910
  */
2813
2911
  protected handleDrag(e: DragCallbackArgType): void;
2814
2912
  }
2815
2913
  }
2816
- declare module "wb_ext_edit" {
2914
+ declare module "wb_ext_keynav" {
2817
2915
  /*!
2818
- * Wunderbaum - ext-edit
2916
+ * Wunderbaum - ext-keynav
2819
2917
  * Copyright (c) 2021-2025, Martin Wendt. Released under the MIT license.
2820
2918
  * @VERSION, @DATE (https://github.com/mar10/wunderbaum)
2821
2919
  */
2920
+ import { KeynavOptionsType } from "types";
2822
2921
  import { Wunderbaum } from "wunderbaum";
2823
2922
  import { WunderbaumExtension } from "wb_extension_base";
2824
- import { WunderbaumNode } from "wb_node";
2825
- import { EditOptionsType, InsertNodeType, WbNodeData } from "types";
2826
- export class EditExtension extends WunderbaumExtension<EditOptionsType> {
2827
- protected debouncedOnChange: (e: Event) => void;
2828
- protected curEditNode: WunderbaumNode | null;
2829
- 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>;
2830
2942
  constructor(tree: Wunderbaum);
2831
- protected _applyChange(eventName: string, node: WunderbaumNode, colElem: HTMLElement, inputElem: HTMLInputElement, extra: any): Promise<any>;
2832
- protected _onChange(e: Event): void;
2833
2943
  init(): void;
2834
- _preprocessKeyEvent(data: any): boolean | undefined;
2835
- /** Return true if a title is currently being edited. */
2836
- isEditingTitle(node?: WunderbaumNode): boolean;
2837
- /** Start renaming, i.e. replace the title with an embedded `<input>`. */
2838
- 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;
2839
2999
  /**
2840
- *
2841
- * @param apply
2842
- * @returns
3000
+ * [ext-filter] Dim or hide nodes.
2843
3001
  */
2844
- stopEditTitle(apply: boolean): void;
2845
- _stopEditTitle(apply: boolean, options: any): void;
3002
+ filterNodes(filter: string | RegExp | NodeFilterCallback, options: FilterNodesOptions): number;
2846
3003
  /**
2847
- * 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`.
2848
3006
  */
2849
- 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;
2850
3020
  }
2851
3021
  }
2852
3022
  declare module "wunderbaum" {
@@ -2864,9 +3034,9 @@ declare module "wunderbaum" {
2864
3034
  */
2865
3035
  import * as util from "util";
2866
3036
  import { ExtensionsDict, WunderbaumExtension } from "wb_extension_base";
2867
- import { AddChildrenOptions, ApplyCommandOptions, ApplyCommandType, ChangeType, ColumnDefinitionList, DynamicBoolOption, DynamicCheckboxOption, DynamicIconOption, DynamicStringOption, DynamicTooltipOption, ExpandAllOptions, FilterModeType, FilterNodesOptions, IconMapType, GetStateOptions, MatcherCallback, NavigationType, NavModeEnum, NodeFilterCallback, NodeStatusType, NodeStringCallback, NodeToDictCallback, NodeTypeDefinitionMap, NodeVisitCallback, RenderFlag, ScrollToOptions, SetActiveOptions, SetColumnOptions, SetStateOptions, SetStatusOptions, SortByPropertyOptions, SortCallback, SourceType, TreeStateDefinition, 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";
2868
3038
  import { WunderbaumNode } from "wb_node";
2869
- import { WunderbaumOptions } from "wb_options";
3039
+ import { InitWunderbaumOptions, WunderbaumOptions } from "wb_options";
2870
3040
  import { DebouncedFunction } from "debounce";
2871
3041
  /**
2872
3042
  * A persistent plain object or array.
@@ -2906,6 +3076,7 @@ declare module "wunderbaum" {
2906
3076
  protected _disableUpdateIgnoreCount: number;
2907
3077
  protected _activeNode: WunderbaumNode | null;
2908
3078
  protected _focusNode: WunderbaumNode | null;
3079
+ protected _initialSource: SourceType | null;
2909
3080
  /** Currently active node if any.
2910
3081
  * Use {@link WunderbaumNode.setActive|setActive} to modify.
2911
3082
  */
@@ -2918,16 +3089,6 @@ declare module "wunderbaum" {
2918
3089
  types: NodeTypeDefinitionMap;
2919
3090
  /** List of column definitions. */
2920
3091
  columns: ColumnDefinitionList;
2921
- /** Show/hide a checkbox or radiobutton. */
2922
- checkbox?: DynamicCheckboxOption;
2923
- /** Show/hide a node icon. */
2924
- icon?: DynamicIconOption;
2925
- /** Show/hide a tooltip for the node icon. */
2926
- iconTooltip?: DynamicStringOption;
2927
- /** Show/hide a tooltip. */
2928
- tooltip?: DynamicTooltipOption;
2929
- /** Define a node checkbox as readonly. */
2930
- unselectable?: DynamicBoolOption;
2931
3092
  protected _columnsById: {
2932
3093
  [key: string]: any;
2933
3094
  };
@@ -2937,6 +3098,21 @@ declare module "wunderbaum" {
2937
3098
  readonly ready: Promise<any>;
2938
3099
  /** Expose some useful methods of the util.ts module as `Wunderbaum.util`. */
2939
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
+ };
2940
3116
  /** Expose some useful methods of the util.ts module as `tree._util`. */
2941
3117
  _util: typeof util;
2942
3118
  /** Filter options (used as defaults for calls to {@link Wunderbaum.filterNodes} ) */
@@ -2952,7 +3128,8 @@ declare module "wunderbaum" {
2952
3128
  /** @internal */
2953
3129
  lastQuicksearchTerm: string;
2954
3130
  protected lastClickTime: number;
2955
- constructor(options: WunderbaumOptions);
3131
+ constructor(options: InitWunderbaumOptions);
3132
+ private _registerEventHandlers;
2956
3133
  /**
2957
3134
  * Return a Wunderbaum instance, from element, id, index, or event.
2958
3135
  *
@@ -2967,6 +3144,7 @@ declare module "wunderbaum" {
2967
3144
  static getTree(el?: Element | Event | number | string | WunderbaumNode): Wunderbaum | null;
2968
3145
  /**
2969
3146
  * Return the icon-function -> icon-definition mapping.
3147
+ * @deprecated Use {@link Wunderbaum.iconMaps}
2970
3148
  */
2971
3149
  get iconMap(): IconMapType;
2972
3150
  /**
@@ -2989,9 +3167,16 @@ declare module "wunderbaum" {
2989
3167
  protected _registerExtension(extension: WunderbaumExtension<any>): void;
2990
3168
  /** Called on tree (re)init after markup is created, before loading. */
2991
3169
  protected _initExtensions(): void;
2992
- /** 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 */
2993
3178
  _registerNode(node: WunderbaumNode): void;
2994
- /** Remove node from tree's bookkeeping data structures. */
3179
+ /** Remove node from tree's bookkeeping data structures. @internal */
2995
3180
  _unregisterNode(node: WunderbaumNode): void;
2996
3181
  /** Call all hook methods of all registered extensions.*/
2997
3182
  protected _callHook(hook: keyof WunderbaumExtension<any>, data?: any): any;
@@ -3022,6 +3207,8 @@ declare module "wunderbaum" {
3022
3207
  getTopmostVpNode(complete?: boolean): WunderbaumNode;
3023
3208
  /** Return the lowest visible node in the viewport. */
3024
3209
  getLowestVpNode(complete?: boolean): WunderbaumNode;
3210
+ /** Return preceding visible node in the viewport. */
3211
+ protected _getPrevNodeInView(node?: WunderbaumNode, ofs?: number): WunderbaumNode;
3025
3212
  /** Return following visible node in the viewport. */
3026
3213
  protected _getNextNodeInView(node?: WunderbaumNode, options?: {
3027
3214
  ofs?: number;
@@ -3079,12 +3266,21 @@ declare module "wunderbaum" {
3079
3266
  /** Run code, but defer rendering of viewport until done.
3080
3267
  *
3081
3268
  * ```js
3082
- * tree.runWithDeferredUpdate(() => {
3083
- * return someFuncThatWouldUpdateManyNodes();
3269
+ * const res = tree.runWithDeferredUpdate(() => {
3270
+ * return someFunctionThatWouldUpdateManyNodes();
3084
3271
  * });
3085
3272
  * ```
3086
3273
  */
3087
- 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>;
3088
3284
  /** Recursively expand all expandable nodes (triggers lazy load if needed). */
3089
3285
  expandAll(flag?: boolean, options?: ExpandAllOptions): Promise<void>;
3090
3286
  /** Recursively select all nodes. */
@@ -3096,6 +3292,15 @@ declare module "wunderbaum" {
3096
3292
  * @param stopOnParents only return the topmost selected node (useful with selectMode 'hier')
3097
3293
  */
3098
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[];
3099
3304
  protected _selectRange(eventInfo: WbEventInfo): false | void;
3100
3305
  /** Return the number of nodes in the data model.
3101
3306
  * @param visible if true, nodes that are hidden due to collapsed parents are ignored.
@@ -3180,6 +3385,14 @@ declare module "wunderbaum" {
3180
3385
  * @see {@link Wunderbaum.format_iter} and {@link WunderbaumNode.format}.
3181
3386
  */
3182
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[];
3183
3396
  /**
3184
3397
  * Return the active cell (`span.wb-col`) of the currently active node or null.
3185
3398
  */
@@ -3225,12 +3438,12 @@ declare module "wunderbaum" {
3225
3438
  toString(): string;
3226
3439
  /** Return true if any node title or grid cell is currently beeing edited.
3227
3440
  *
3228
- * See also {@link Wunderbaum.isEditingTitle}.
3441
+ * See also {@link isEditingTitle}.
3229
3442
  */
3230
3443
  isEditing(): boolean;
3231
3444
  /** Return true if any node is currently in edit-title mode.
3232
3445
  *
3233
- * See also {@link WunderbaumNode.isEditingTitle} and {@link Wunderbaum.isEditing}.
3446
+ * See also {@link WunderbaumNode.isEditingTitle} and {@link isEditing}.
3234
3447
  */
3235
3448
  isEditingTitle(): boolean;
3236
3449
  /**
@@ -3238,12 +3451,12 @@ declare module "wunderbaum" {
3238
3451
  */
3239
3452
  isLoading(): boolean;
3240
3453
  /** Write to `console.log` with tree name as prefix if opts.debugLevel >= 4.
3241
- * @see {@link Wunderbaum.logDebug}
3454
+ * @see {@link logDebug}
3242
3455
  */
3243
3456
  log(...args: any[]): void;
3244
3457
  /** Write to `console.debug` with tree name as prefix if opts.debugLevel >= 4.
3245
3458
  * and browser console level includes debug/verbose messages.
3246
- * @see {@link Wunderbaum.log}
3459
+ * @see {@link log}
3247
3460
  */
3248
3461
  logDebug(...args: any[]): void;
3249
3462
  /** Write to `console.error` with tree name as prefix. */
@@ -3256,6 +3469,8 @@ declare module "wunderbaum" {
3256
3469
  logTimeEnd(label: string): void;
3257
3470
  /** Write to `console.warn` with tree name as prefix with if opts.debugLevel >= 2. */
3258
3471
  logWarn(...args: any[]): void;
3472
+ /** Emit a warning for deprecated methods. @internal */
3473
+ logDeprecate(method: string, options?: DeprecationOptions): void;
3259
3474
  /** Reset column widths to default. @since 0.10.0 */
3260
3475
  resetColumns(): void;
3261
3476
  /**
@@ -3288,9 +3503,9 @@ declare module "wunderbaum" {
3288
3503
  setFocus(flag?: boolean): void;
3289
3504
  _setFocusNode(node: WunderbaumNode | null): void;
3290
3505
  /** Return the current selection/expansion/activation status. @experimental */
3291
- getState(options: GetStateOptions): TreeStateDefinition;
3506
+ getState(options?: GetStateOptions): TreeStateDefinition;
3292
3507
  /** Apply selection/expansion/activation status. @experimental */
3293
- setState(state: TreeStateDefinition, options: SetStateOptions): void;
3508
+ setState(state: TreeStateDefinition, options?: SetStateOptions): Promise<void>;
3294
3509
  /**
3295
3510
  * Schedule an update request to reflect a tree change.
3296
3511
  * The render operation is async and debounced unless the `immediate` option
@@ -3329,14 +3544,21 @@ declare module "wunderbaum" {
3329
3544
  * @param {function} cmp custom compare function(a, b) that returns -1, 0, or 1
3330
3545
  * (defaults to sorting by title).
3331
3546
  * @param {boolean} deep pass true to sort all descendant nodes recursively
3547
+ * @deprecated use {@link sort}
3332
3548
  */
3333
3549
  sortChildren(cmp?: SortCallback | null, deep?: boolean): void;
3334
3550
  /**
3335
3551
  * Convenience method to implement column sorting.
3336
3552
  * @see {@link WunderbaumNode.sortByProperty}.
3337
3553
  * @since 0.11.0
3554
+ * @deprecated use {@link sort}
3338
3555
  */
3339
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;
3340
3562
  /** Convert tree to an array of plain objects.
3341
3563
  *
3342
3564
  * @param callback is called for every node, in order to allow
@@ -3382,7 +3604,8 @@ declare module "wunderbaum" {
3382
3604
  protected _updateRows(options?: any): boolean;
3383
3605
  /**
3384
3606
  * Call `callback(node)` for all nodes in hierarchical order (depth-first, pre-order).
3385
- * @see {@link IterableIterator<WunderbaumNode>}, {@link WunderbaumNode.visit}.
3607
+ * @see `wb_node.WunderbaumNode.IterableIterator<WunderbaumNode>`
3608
+ * @see {@link WunderbaumNode.visit}.
3386
3609
  *
3387
3610
  * @param {function} callback the callback function.
3388
3611
  * Return false to stop iteration, return "skip" to skip this node and
@@ -3412,8 +3635,24 @@ declare module "wunderbaum" {
3412
3635
  *
3413
3636
  * Previous data is cleared. Note that also column- and type defintions may
3414
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.
3415
3640
  */
3416
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>;
3417
3656
  /**
3418
3657
  * Disable render requests during operations that would trigger many updates.
3419
3658
  *