wunderbaum 0.0.3 → 0.0.6

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.
@@ -63,7 +63,7 @@ declare module "util" {
63
63
  *
64
64
  * If a `<span class="wb-col">` is passed, the first child input is used.
65
65
  * Depending on the target element type, `value` is interpreted accordingly.
66
- * For example for a checkbox, a value of true, false, or null is returned if the
66
+ * For example for a checkbox, a value of true, false, or null is returned if
67
67
  * the element is checked, unchecked, or indeterminate.
68
68
  * For datetime input control a numerical value is assumed, etc.
69
69
  *
@@ -95,6 +95,8 @@ declare module "util" {
95
95
  * @param value a value that matches the target element.
96
96
  */
97
97
  export function setValueToElem(elem: HTMLElement, value: any): void;
98
+ /** Show/hide element by setting the `display`style to 'none'. */
99
+ export function setElemDisplay(elem: string | Element, flag: boolean): void;
98
100
  /** Create and return an unconnected `HTMLElement` from a HTML string. */
99
101
  export function elemFromHtml(html: string): HTMLElement;
100
102
  /** Return a HtmlElement from selector or cast an existing element. */
@@ -165,7 +167,7 @@ declare module "util" {
165
167
  */
166
168
  export function overrideMethod(instance: any, methodName: string, handler: FunctionType, ctx?: any): void;
167
169
  /** Run function after ms milliseconds and return a promise that resolves when done. */
168
- export function setTimeoutPromise(callback: (...args: any[]) => void, ms: number): Promise<unknown>;
170
+ export function setTimeoutPromise(this: unknown, callback: (...args: any[]) => void, ms: number): Promise<unknown>;
169
171
  /**
170
172
  * Wait `ms` microseconds.
171
173
  *
@@ -198,8 +200,71 @@ declare module "util" {
198
200
  export function getOption(opts: any, name: string, defaultValue?: any): any;
199
201
  /** Convert an Array or space-separated string to a Set. */
200
202
  export function toSet(val: any): Set<string>;
201
- /**Return a canonical string representation for an object's type (e.g. 'array', 'number', ...) */
203
+ /** Return a canonical string representation for an object's type (e.g. 'array', 'number', ...). */
202
204
  export function type(obj: any): string;
205
+ /**
206
+ * Return a function that can be called instead of `callback`, but guarantees
207
+ * a limited execution rate.
208
+ * The execution rate is calculated based on the runtime duration of the
209
+ * previous call.
210
+ * Example:
211
+ * ```js
212
+ * throttledFoo = util.adaptiveThrottle(foo.bind(this), {});
213
+ * throttledFoo();
214
+ * throttledFoo();
215
+ * ```
216
+ */
217
+ export function adaptiveThrottle(this: unknown, callback: (...args: any[]) => void, options: any): (...args: any[]) => void;
218
+ }
219
+ declare module "common" {
220
+ /*!
221
+ * Wunderbaum - common
222
+ * Copyright (c) 2021-2022, Martin Wendt. Released under the MIT license.
223
+ * @VERSION, @DATE (https://github.com/mar10/wunderbaum)
224
+ */
225
+ import { MatcherType } from "types";
226
+ export const DEFAULT_DEBUGLEVEL = 4;
227
+ export const ROW_HEIGHT = 22;
228
+ export const ICON_WIDTH = 20;
229
+ export const ROW_EXTRA_PAD = 7;
230
+ export const RENDER_MIN_PREFETCH = 5;
231
+ export const RENDER_MAX_PREFETCH = 5;
232
+ export const TEST_IMG: RegExp;
233
+ export let iconMap: {
234
+ error: string;
235
+ loading: string;
236
+ noData: string;
237
+ expanderExpanded: string;
238
+ expanderCollapsed: string;
239
+ expanderLazy: string;
240
+ checkChecked: string;
241
+ checkUnchecked: string;
242
+ checkUnknown: string;
243
+ radioChecked: string;
244
+ radioUnchecked: string;
245
+ radioUnknown: string;
246
+ folder: string;
247
+ folderOpen: string;
248
+ doc: string;
249
+ };
250
+ export const KEY_NODATA = "__not_found__";
251
+ /** Define which keys are handled by embedded <input> control, and should
252
+ * *not* be passed to tree navigation handler in cell-edit mode. */
253
+ export const INPUT_KEYS: {
254
+ [key: string]: Array<string>;
255
+ };
256
+ /** Dict keys that are evaluated by source loader (others are added to `tree.data` instead). */
257
+ export const RESERVED_TREE_SOURCE_KEYS: Set<string>;
258
+ /** Key codes that trigger grid navigation, even when inside an input element. */
259
+ export const INPUT_BREAKOUT_KEYS: Set<string>;
260
+ /** Map `KeyEvent.key` to navigation action. */
261
+ export const KEY_TO_ACTION_DICT: {
262
+ [key: string]: string;
263
+ };
264
+ /** Return a callback that returns true if the node title contains a substring (case-insensitive). */
265
+ export function makeNodeTitleMatcher(s: string): MatcherType;
266
+ /** Return a callback that returns true if the node title starts with a string (case-insensitive). */
267
+ export function makeNodeTitleStartMatcher(s: string): MatcherType;
203
268
  }
204
269
  declare module "deferred" {
205
270
  /*!
@@ -210,9 +275,19 @@ declare module "deferred" {
210
275
  type PromiseCallbackType = (val: any) => void;
211
276
  type finallyCallbackType = () => void;
212
277
  /**
213
- * Deferred is a ES6 Promise, that exposes the resolve() and reject()` method.
278
+ * Implement a ES6 Promise, that exposes a resolve() and reject() method.
214
279
  *
215
- * Loosely mimics [`jQuery.Deferred`](https://api.jquery.com/category/deferred-object/).
280
+ * Loosely mimics {@link https://api.jquery.com/category/deferred-object/ | jQuery.Deferred}.
281
+ * Example:
282
+ * ```js
283
+ * function foo() {
284
+ * let dfd = new Deferred(),
285
+ * ...
286
+ * dfd.resolve('foo')
287
+ * ...
288
+ * return dfd.promise();
289
+ * }
290
+ * ```
216
291
  */
217
292
  export class Deferred {
218
293
  private _promise;
@@ -233,174 +308,13 @@ declare module "deferred" {
233
308
  finally(cb: finallyCallbackType): Promise<any>;
234
309
  }
235
310
  }
236
- declare module "wb_extension_base" {
237
- import { Wunderbaum } from "wunderbaum";
238
- export type ExtensionsDict = {
239
- [key: string]: WunderbaumExtension;
240
- };
241
- export abstract class WunderbaumExtension {
242
- enabled: boolean;
243
- readonly id: string;
244
- readonly tree: Wunderbaum;
245
- readonly treeOpts: any;
246
- readonly extensionOpts: any;
247
- constructor(tree: Wunderbaum, id: string, defaults: any);
248
- /** Called on tree (re)init after all extensions are added, but before loading.*/
249
- init(): void;
250
- getPluginOption(name: string, defaultValue?: any): any;
251
- setPluginOption(name: string, value: any): void;
252
- setEnabled(flag?: boolean): void;
253
- onKeyEvent(data: any): boolean | undefined;
254
- onRender(data: any): boolean | undefined;
255
- }
256
- }
257
- declare module "wb_ext_dnd" {
258
- import { Wunderbaum } from "wunderbaum";
259
- import { WunderbaumExtension } from "wb_extension_base";
260
- import { WunderbaumNode } from "wb_node";
261
- import { WbNodeEventType } from "common";
262
- export type DropRegionType = "over" | "before" | "after";
263
- type DropRegionTypeSet = Set<DropRegionType>;
264
- export type DndOptionsType = {
265
- /**
266
- * Expand nodes after n milliseconds of hovering
267
- * Default: 1500
268
- */
269
- autoExpandMS: 1500;
270
- /**
271
- * true: Drag multiple (i.e. selected) nodes. Also a callback() is allowed
272
- * Default: false
273
- */
274
- multiSource: false;
275
- /**
276
- * Restrict the possible cursor shapes and modifier operations (can also be set in the dragStart event)
277
- * Default: "all"
278
- */
279
- effectAllowed: "all";
280
- /**
281
- * Default dropEffect ('copy', 'link', or 'move') when no modifier is pressed (overide in dragDrag, dragOver).
282
- * Default: "move"
283
- */
284
- dropEffectDefault: string;
285
- /**
286
- * Prevent dropping nodes from different Wunderbaum trees
287
- * Default: false
288
- */
289
- preventForeignNodes: boolean;
290
- /**
291
- * Prevent dropping items on unloaded lazy Wunderbaum tree nodes
292
- * Default: true
293
- */
294
- preventLazyParents: boolean;
295
- /**
296
- * Prevent dropping items other than Wunderbaum tree nodes
297
- * Default: false
298
- */
299
- preventNonNodes: boolean;
300
- /**
301
- * Prevent dropping nodes on own descendants
302
- * Default: true
303
- */
304
- preventRecursion: boolean;
305
- /**
306
- * Prevent dropping nodes under same direct parent
307
- * Default: false
308
- */
309
- preventSameParent: false;
310
- /**
311
- * Prevent dropping nodes 'before self', etc. (move only)
312
- * Default: true
313
- */
314
- preventVoidMoves: boolean;
315
- /**
316
- * Enable auto-scrolling while dragging
317
- * Default: true
318
- */
319
- scroll: boolean;
320
- /**
321
- * Active top/bottom margin in pixel
322
- * Default: 20
323
- */
324
- scrollSensitivity: 20;
325
- /**
326
- * Pixel per event
327
- * Default: 5
328
- */
329
- scrollSpeed: 5;
330
- /**
331
- * Optional callback passed to `toDict` on dragStart @since 2.38
332
- * Default: null
333
- */
334
- sourceCopyHook: null;
335
- /**
336
- * Callback(sourceNode, data), return true, to enable dnd drag
337
- * Default: null
338
- */
339
- dragStart?: WbNodeEventType;
340
- /**
341
- * Callback(sourceNode, data)
342
- * Default: null
343
- */
344
- dragDrag: null;
345
- /**
346
- * Callback(sourceNode, data)
347
- * Default: null
348
- */
349
- dragEnd: null;
350
- /**
351
- * Callback(targetNode, data), return true, to enable dnd drop
352
- * Default: null
353
- */
354
- dragEnter: null;
355
- /**
356
- * Callback(targetNode, data)
357
- * Default: null
358
- */
359
- dragOver: null;
360
- /**
361
- * Callback(targetNode, data), return false to prevent autoExpand
362
- * Default: null
363
- */
364
- dragExpand: null;
365
- /**
366
- * Callback(targetNode, data)
367
- * Default: null
368
- */
369
- dragDrop: null;
370
- /**
371
- * Callback(targetNode, data)
372
- * Default: null
373
- */
374
- dragLeave: null;
375
- };
376
- export class DndExtension extends WunderbaumExtension {
377
- protected srcNode: WunderbaumNode | null;
378
- protected lastTargetNode: WunderbaumNode | null;
379
- protected lastEnterStamp: number;
380
- protected lastAllowedDropRegions: DropRegionTypeSet | null;
381
- protected lastDropEffect: string | null;
382
- protected lastDropRegion: DropRegionType | false;
383
- constructor(tree: Wunderbaum);
384
- init(): void;
385
- /** Cleanup classes after target node is no longer hovered. */
386
- protected _leaveNode(): void;
387
- /** */
388
- protected unifyDragover(res: any): DropRegionTypeSet | false;
389
- /** */
390
- protected _calcDropRegion(e: DragEvent, allowed: DropRegionTypeSet | null): DropRegionType | false;
391
- protected autoScroll(event: DragEvent): number;
392
- protected onDragEvent(e: DragEvent): boolean;
393
- protected onDropEvent(e: DragEvent): boolean;
394
- }
395
- }
396
311
  declare module "wb_options" {
397
312
  /*!
398
313
  * Wunderbaum - utils
399
314
  * Copyright (c) 2021-2022, Martin Wendt. Released under the MIT license.
400
315
  * @VERSION, @DATE (https://github.com/mar10/wunderbaum)
401
316
  */
402
- import { BoolOptionResolver, NavigationModeOption, WbNodeEventType, WbTreeEventType } from "common";
403
- import { DndOptionsType } from "wb_ext_dnd";
317
+ import { BoolOptionResolver, ColumnDefinitionList, DndOptionsType, NavigationOptions, NodeTypeDefinitions, WbNodeEventType, WbRenderEventType, WbTreeEventType } from "types";
404
318
  export interface WbNodeData {
405
319
  title: string;
406
320
  key?: string;
@@ -423,6 +337,21 @@ declare module "wb_options" {
423
337
  * ...
424
338
  * });
425
339
  * ```
340
+ *
341
+ * Event handlers are also passed as callbacks
342
+ *
343
+ * ```js
344
+ * const tree = new mar10.Wunderbaum({
345
+ * ...
346
+ * init: (e) => {
347
+ * console.log(`Tree ${e.tree} was initialized and loaded.`)
348
+ * },
349
+ * activate: (e) => {
350
+ * console.log(`Node ${e.node} was activated.`)
351
+ * },
352
+ * ...
353
+ * });
354
+ * ```
426
355
  */
427
356
  export interface WunderbaumOptions {
428
357
  /**
@@ -451,7 +380,7 @@ declare module "wb_options" {
451
380
  *
452
381
  * Default: `{}`.
453
382
  */
454
- types?: any;
383
+ types?: NodeTypeDefinitions;
455
384
  /**
456
385
  * A list of maps that define column headers. If this option is set,
457
386
  * Wunderbaum becomes a treegrid control instead of a plain tree.
@@ -459,7 +388,7 @@ declare module "wb_options" {
459
388
  * response.
460
389
  * Default: `[]` meaning this is a plain tree.
461
390
  */
462
- columns?: Array<any>;
391
+ columns?: ColumnDefinitionList;
463
392
  /**
464
393
  * If true, add a `wb-skeleton` class to all nodes, that will result in a
465
394
  * 'glow' effect. Typically used with initial dummy nodes, while loading the
@@ -478,14 +407,10 @@ declare module "wb_options" {
478
407
  debugLevel: number;
479
408
  /**
480
409
  * Number of levels that are forced to be expanded, and have no expander icon.
481
- * Default: 0
410
+ * E.g. 1 would keep all toplevel nodes expanded.
411
+ * Default: 0
482
412
  */
483
413
  minExpandLevel?: number;
484
- /**
485
- * Height of the header row div.
486
- * Default: 22
487
- */
488
- headerHeightPx: number;
489
414
  /**
490
415
  * Height of a node row div.
491
416
  * Default: 22
@@ -497,11 +422,20 @@ declare module "wb_options" {
497
422
  */
498
423
  autoCollapse?: boolean;
499
424
  /**
500
- * Default: NavigationModeOption.startRow
425
+ * HTMLElement that receives the top nodes breadcrumb.
426
+ * Default: undefined
427
+ */
428
+ connectTopBreadcrumb?: HTMLElement;
429
+ /**
430
+ * Default: NavigationOptions.startRow
501
431
  */
502
- navigationMode?: NavigationModeOption;
432
+ navigationModeOption?: NavigationOptions;
503
433
  /**
504
- * Show/hide header (pass bool or string)
434
+ * Show/hide header (default: null)
435
+ * null: assume false for plain tree and true for grids.
436
+ * string: use text as header (only for plain trees)
437
+ * true: display a header (use tree's id as text for plain trees)
438
+ * false: do not display a header
505
439
  */
506
440
  header?: boolean | string | null;
507
441
  /**
@@ -509,51 +443,61 @@ declare module "wb_options" {
509
443
  */
510
444
  showSpinner?: boolean;
511
445
  /**
512
- * Default: true
446
+ * If true, render a checkbox before the node tile to allow selection with the
447
+ * mouse.
448
+ * Default: false.
513
449
  */
514
450
  checkbox?: boolean | "radio" | BoolOptionResolver;
515
451
  /**
516
452
  * Default: 200
517
453
  */
518
454
  updateThrottleWait?: number;
455
+ /**
456
+ * Default: true
457
+ */
458
+ enabled?: boolean;
459
+ /**
460
+ * Default: false
461
+ */
462
+ fixedCol?: boolean;
519
463
  /**
520
464
  * Default: true
521
465
  */
522
466
  quicksearch?: boolean;
523
467
  dnd?: DndOptionsType;
468
+ edit: any;
524
469
  filter: any;
525
470
  grid: any;
526
- /**
527
- * Called after initial data was loaded and tree markup was rendered.
528
- * Check `e.error` for status.
529
- * @category Callback
530
- */
531
- init?: (e: WbTreeEventType) => void;
532
471
  /**
533
472
  *
534
473
  * @category Callback
535
474
  */
536
- update?: (e: WbTreeEventType) => void;
475
+ activate?: (e: WbNodeEventType) => void;
537
476
  /**
538
477
  *
539
478
  * @category Callback
540
479
  */
541
- activate?: (e: WbNodeEventType) => void;
480
+ change?: (e: WbNodeEventType) => void;
542
481
  /**
543
482
  *
483
+ * Return `false` to prevent default handling, e.g. activating the node.
544
484
  * @category Callback
545
485
  */
546
- deactivate?: (e: WbNodeEventType) => void;
486
+ click?: (e: WbTreeEventType) => void;
547
487
  /**
548
488
  *
489
+ * Return `false` to prevent default handling, e.g. activating the node.
549
490
  * @category Callback
550
491
  */
551
- change?: (e: WbNodeEventType) => void;
492
+ beforeActivate?: (e: WbNodeEventType) => void;
493
+ /**
552
494
  /**
553
495
  *
496
+ * Return `false` to prevent default handling, e.g. deactivating the node
497
+ * and activating the next.
554
498
  * @category Callback
555
499
  */
556
- click?: (e: WbTreeEventType) => void;
500
+ deactivate?: (e: WbNodeEventType) => void;
557
501
  /**
558
502
  *
559
503
  * @category Callback
@@ -563,25 +507,42 @@ declare module "wb_options" {
563
507
  *
564
508
  * @category Callback
565
509
  */
566
- error?: (e: WbTreeEventType) => void;
510
+ enhanceTitle?: (e: WbNodeEventType) => void;
567
511
  /**
568
512
  *
569
513
  * @category Callback
570
514
  */
571
- enhanceTitle?: (e: WbNodeEventType) => void;
515
+ error?: (e: WbTreeEventType) => void;
572
516
  /**
573
517
  *
574
518
  * Check `e.flag` for status.
575
519
  * @category Callback
576
520
  */
577
521
  focus?: (e: WbTreeEventType) => void;
522
+ /**
523
+ * Fires when the tree markup was created and the initial source data was loaded.
524
+ * Typical use cases would be activating a node, setting focus, enabling other
525
+ * controls on the page, etc.<br>
526
+ * Check `e.error` for status.
527
+ * @category Callback
528
+ */
529
+ init?: (e: WbTreeEventType) => void;
578
530
  /**
579
531
  *
580
532
  * @category Callback
581
533
  */
582
534
  keydown?: (e: WbNodeEventType) => void;
583
535
  /**
584
- * Called after data was loaded from local storage.
536
+ * Fires when a node that was marked 'lazy', is expanded for the first time.
537
+ * Typically we return an endpoint URL or the Promise of a fetch request that
538
+ * provides a (potentially nested) list of child nodes.
539
+ * @category Callback
540
+ */
541
+ lazyLoad?: (e: WbNodeEventType) => void;
542
+ /**
543
+ * Fires when data was loaded (initial request, reload, or lazy loading),
544
+ * after the data is applied and rendered.
545
+ * @category Callback
585
546
  */
586
547
  load?: (e: WbNodeEventType) => void;
587
548
  /**
@@ -589,15 +550,22 @@ declare module "wb_options" {
589
550
  */
590
551
  modifyChild?: (e: WbNodeEventType) => void;
591
552
  /**
592
- *
553
+ * Fires when data was fetched (initial request, reload, or lazy loading),
554
+ * but before the data is applied and rendered.
555
+ * Here we can modify and adjust the received data, for example to convert an
556
+ * external response to native Wunderbaum syntax.
593
557
  * @category Callback
594
558
  */
595
559
  receive?: (e: WbNodeEventType) => void;
596
560
  /**
597
- *
561
+ * Fires when a node is about to be displayed.
562
+ * The default HTML markup is already created, but not yet added to the DOM.
563
+ * Now we can tweak the markup, create HTML elements in this node's column
564
+ * cells, etc.
565
+ * See also `Custom Rendering` for details.
598
566
  * @category Callback
599
567
  */
600
- render?: (e: WbNodeEventType) => void;
568
+ render?: (e: WbRenderEventType) => void;
601
569
  /**
602
570
  *
603
571
  * @category Callback
@@ -609,6 +577,11 @@ declare module "wb_options" {
609
577
  * @category Callback
610
578
  */
611
579
  select?: (e: WbNodeEventType) => void;
580
+ /**
581
+ * Fires when the viewport content was updated, after scroling, expanding etc.
582
+ * @category Callback
583
+ */
584
+ update?: (e: WbTreeEventType) => void;
612
585
  }
613
586
  }
614
587
  declare module "wb_node" {
@@ -619,7 +592,7 @@ declare module "wb_node" {
619
592
  */
620
593
  import "./wunderbaum.scss";
621
594
  import { Wunderbaum } from "wunderbaum";
622
- import { ChangeType, MatcherType, NodeAnyCallback, NodeStatusType, NodeVisitCallback, NodeVisitResponse, ApplyCommandType, AddNodeType, SetActiveOptions, SetExpandedOptions, SetSelectedOptions } from "common";
595
+ import { AddNodeType, ApplyCommandType, ChangeType, MakeVisibleOptions, MatcherType, NodeAnyCallback, NodeStatusType, NodeVisitCallback, NodeVisitResponse, ScrollIntoViewOptions, SetActiveOptions, SetExpandedOptions, SetSelectedOptions, SetStatusOptions } from "types";
623
596
  import { WbNodeData } from "wb_options";
624
597
  /**
625
598
  * A single tree node.
@@ -647,6 +620,7 @@ declare module "wb_node" {
647
620
  readonly refKey: string | undefined;
648
621
  children: WunderbaumNode[] | null;
649
622
  checkbox?: boolean;
623
+ /** If true, (in grid mode) no cells are rendered, except for the node title.*/
650
624
  colspan?: boolean;
651
625
  icon?: boolean | string;
652
626
  lazy: boolean;
@@ -659,8 +633,8 @@ declare module "wb_node" {
659
633
  type?: string;
660
634
  tooltip?: string;
661
635
  /** Additional classes added to `div.wb-row`.
662
- * @see {@link addClass}, {@link removeClass}, {@link toggleClass}. */
663
- extraClasses: Set<string>;
636
+ * @see {@link hasClass}, {@link setClass}. */
637
+ classes: Set<string> | null;
664
638
  /** Custom data that was passed to the constructor */
665
639
  data: any;
666
640
  statusNodeType?: string;
@@ -689,7 +663,7 @@ declare module "wb_node" {
689
663
  * node._callEvent("edit.beforeEdit", {foo: 42})
690
664
  * ```
691
665
  */
692
- _callEvent(name: string, extra?: any): any;
666
+ _callEvent(type: string, extra?: any): any;
693
667
  /**
694
668
  * Append (or insert) a list of child nodes.
695
669
  *
@@ -716,10 +690,16 @@ declare module "wb_node" {
716
690
  * @see {@link Wunderbaum.applyCommand}
717
691
  */
718
692
  applyCommand(cmd: ApplyCommandType, opts: any): any;
719
- addClass(className: string | string[] | Set<string>): void;
720
- removeClass(className: string | string[] | Set<string>): void;
721
- toggleClass(className: string | string[] | Set<string>, flag: boolean): void;
722
- /** */
693
+ /**
694
+ * Add/remove one or more classes to `<div class='wb-row'>`.
695
+ *
696
+ * This also maintains `node.classes`, so the class will survive a re-render.
697
+ *
698
+ * @param className one or more class names. Multiple classes can be passed
699
+ * as space-separated string, array of strings, or set of strings.
700
+ */
701
+ setClass(className: string | string[] | Set<string>, flag?: boolean): void;
702
+ /** Call `setExpanded()` on al child nodes*/
723
703
  expandAll(flag?: boolean): Promise<void>;
724
704
  /**Find all nodes that match condition (excluding self).
725
705
  *
@@ -775,12 +755,18 @@ declare module "wb_node" {
775
755
  * Return undefined if not sure, i.e. the node is lazy and not yet loaded.
776
756
  */
777
757
  hasChildren(): boolean;
758
+ /** Return true if node has className set. */
759
+ hasClass(className: string): boolean;
778
760
  /** Return true if this node is the currently active tree node. */
779
761
  isActive(): boolean;
780
762
  /** Return true if this node is a *direct* child of `other`.
781
763
  * (See also [[isDescendantOf]].)
782
764
  */
783
765
  isChildOf(other: WunderbaumNode): boolean;
766
+ /** Return true if this node's title spans all columns, i.e. the node has no
767
+ * grid cells.
768
+ */
769
+ isColspan(): boolean;
784
770
  /** Return true if this node is a direct or indirect sub node of `other`.
785
771
  * (See also [[isChildOf]].)
786
772
  */
@@ -848,7 +834,7 @@ declare module "wb_node" {
848
834
  * @param {object} [opts] passed to `setExpanded()`.
849
835
  * Defaults to {noAnimation: false, noEvents: false, scrollIntoView: true}
850
836
  */
851
- makeVisible(opts: any): Promise<any>;
837
+ makeVisible(opts?: MakeVisibleOptions): Promise<any>;
852
838
  /** Move this node to targetNode. */
853
839
  moveTo(targetNode: WunderbaumNode, mode?: AddNodeType, map?: NodeAnyCallback): void;
854
840
  /** Set focus relative to this node and optionally activate.
@@ -870,12 +856,36 @@ declare module "wb_node" {
870
856
  removeChildren(): void;
871
857
  /** Remove all HTML markup from the DOM. */
872
858
  removeMarkup(): void;
873
- protected _getRenderInfo(): {
874
- [key: string]: any;
875
- };
859
+ protected _getRenderInfo(): any;
876
860
  protected _createIcon(parentElem: HTMLElement, replaceChild?: HTMLElement): HTMLElement | null;
877
- /** Create HTML markup for this node, i.e. the whole row. */
878
- render(opts?: any): void;
861
+ /**
862
+ * Create a whole new `<div class="wb-row">` element.
863
+ * @see {@link WunderbaumNode.render}
864
+ */
865
+ protected _render_markup(opts: any): void;
866
+ /**
867
+ * Render `node.title`, `.icon` into an existing row.
868
+ *
869
+ * @see {@link WunderbaumNode.render}
870
+ */
871
+ protected _render_data(opts: any): void;
872
+ /**
873
+ * Update row classes to reflect active, focuses, etc.
874
+ * @see {@link WunderbaumNode.render}
875
+ */
876
+ protected _render_status(opts: any): void;
877
+ /**
878
+ * Create or update node's markup.
879
+ *
880
+ * `options.change` defaults to ChangeType.data, which updates the title,
881
+ * icon, and status. It also triggers the `render` event, that lets the user
882
+ * create or update the content of embeded cell elements.<br>
883
+ *
884
+ * If only the status or other class-only modifications have changed,
885
+ * `options.change` should be set to ChangeType.status instead for best
886
+ * efficiency.
887
+ */
888
+ render(options?: any): void;
879
889
  /**
880
890
  * Remove all children, collapse, and set the lazy-flag, so that the lazyLoad
881
891
  * event is triggered on next expand.
@@ -912,11 +922,11 @@ declare module "wb_node" {
912
922
  /** Make sure that this node is visible in the viewport.
913
923
  * @see {@link Wunderbaum.scrollTo|Wunderbaum.scrollTo()}
914
924
  */
915
- scrollIntoView(options?: any): Promise<void>;
925
+ scrollIntoView(options?: ScrollIntoViewOptions): Promise<void>;
916
926
  /**
917
927
  * Activate this node, deactivate previous, send events, activate column and scroll int viewport.
918
928
  */
919
- setActive(flag?: boolean, options?: SetActiveOptions): Promise<void>;
929
+ setActive(flag?: boolean, options?: SetActiveOptions): Promise<any>;
920
930
  /**
921
931
  * Expand or collapse this node.
922
932
  */
@@ -925,17 +935,23 @@ declare module "wb_node" {
925
935
  * Set keyboard focus here.
926
936
  * @see {@link setActive}
927
937
  */
928
- setFocus(flag?: boolean, options?: any): void;
938
+ setFocus(flag?: boolean): void;
929
939
  /** Set a new icon path or class. */
930
940
  setIcon(): void;
931
941
  /** Change node's {@link key} and/or {@link refKey}. */
932
942
  setKey(key: string | null, refKey: string | null): void;
933
- /** Schedule a render, typically called to update after a status or data change. */
943
+ /**
944
+ * Schedule a render, typically called to update after a status or data change.
945
+ *
946
+ * `change` defaults to 'data', which handles modifcations of title, icon,
947
+ * and column content. It can be reduced to 'ChangeType.status' if only
948
+ * active/focus/selected state has changed.
949
+ */
934
950
  setModified(change?: ChangeType): void;
935
951
  /** Modify the check/uncheck state. */
936
952
  setSelected(flag?: boolean, options?: SetSelectedOptions): void;
937
953
  /** Display node status (ok, loading, error, noData) using styles and a dummy child node. */
938
- setStatus(status: NodeStatusType, message?: string, details?: string): WunderbaumNode | null;
954
+ setStatus(status: NodeStatusType, options?: SetStatusOptions): WunderbaumNode | null;
939
955
  /** Rename this node. */
940
956
  setTitle(title: string): void;
941
957
  /**
@@ -983,53 +999,158 @@ declare module "wb_node" {
983
999
  isMatched(): boolean;
984
1000
  }
985
1001
  }
986
- declare module "common" {
1002
+ declare module "types" {
1003
+ /*!
1004
+ * Wunderbaum - types
1005
+ * Copyright (c) 2021-2022, Martin Wendt. Released under the MIT license.
1006
+ * @VERSION, @DATE (https://github.com/mar10/wunderbaum)
1007
+ */
987
1008
  import { WunderbaumNode } from "wb_node";
988
1009
  import { Wunderbaum } from "wunderbaum";
989
1010
  export type MatcherType = (node: WunderbaumNode) => boolean;
990
1011
  export type BoolOptionResolver = (node: WunderbaumNode) => boolean;
991
- export const DEFAULT_DEBUGLEVEL = 4;
992
- export const ROW_HEIGHT = 22;
993
- export const ICON_WIDTH = 20;
994
- export const ROW_EXTRA_PAD = 7;
995
- export const RENDER_MIN_PREFETCH = 5;
996
- export const RENDER_MAX_PREFETCH = 5;
997
- export const TEST_IMG: RegExp;
998
1012
  export type NodeAnyCallback = (node: WunderbaumNode) => any;
999
1013
  export type NodeVisitResponse = "skip" | boolean | void;
1000
1014
  export type NodeVisitCallback = (node: WunderbaumNode) => NodeVisitResponse;
1001
- export type WbTreeEventType = {
1002
- name: string;
1003
- event: Event;
1015
+ export interface WbTreeEventType {
1016
+ /** Name of the event. */
1017
+ type: string;
1018
+ /** The affected tree. */
1004
1019
  tree: Wunderbaum;
1020
+ /** Originating HTML event, e.g. `click` if any. */
1021
+ event?: Event;
1022
+ }
1023
+ export interface WbNodeEventType extends WbTreeEventType {
1024
+ /** The affected target node. */
1025
+ node: WunderbaumNode;
1026
+ /**
1027
+ * Contains the node's type information, i.e. `tree.types[node.type]` if
1028
+ * defined. Set to `{}` otherwise. @see {@link Wunderbaum.types}
1029
+ */
1030
+ typeInfo: NodeTypeDefinition;
1031
+ }
1032
+ export interface WbRenderEventType extends WbNodeEventType {
1033
+ /**
1034
+ * True if the node's markup was not yet created. In this case the render
1035
+ * event should create embeddeb input controls (in addition to update the
1036
+ * values according to to current node data).
1037
+ */
1038
+ isNew: boolean;
1039
+ /** True if the node only displays the title and is stretched over all remaining columns. */
1040
+ isColspan: boolean;
1041
+ /** The node's `<span class='wb-node'>` element. */
1042
+ nodeElem: HTMLSpanElement;
1043
+ /**
1044
+ * Array of node's `<span class='wb-col'>` elements.
1045
+ * The first element is `<span class='wb-node wb-col'>`, which contains the
1046
+ * node title and icon (`idx: 0`, id: '*'`).
1047
+ */
1048
+ allColInfosById: ColumnEventInfos;
1049
+ /**
1050
+ * Array of node's `<span class='wb-node'>` elements, *that should be rendered*.
1051
+ * In contrast to `allColInfosById`, the node title is not part of this array.
1052
+ * If node.isColspan() is true, this array is empty (`[]`).
1053
+ */
1054
+ renderColInfosById: ColumnEventInfos;
1055
+ }
1056
+ /**
1057
+ * Contains the node's type information, i.e. `tree.types[node.type]` if
1058
+ * defined. @see {@link Wunderbaum.types}
1059
+ */
1060
+ export interface NodeTypeDefinition {
1061
+ /** En/disable checkbox for matching nodes.*/
1062
+ checkbox?: boolean | BoolOptionResolver;
1063
+ /** En/disable checkbox for matching nodes.*/
1064
+ colspan?: boolean | BoolOptionResolver;
1065
+ /** Optional class names that are added to all `div.wb-row` elements of matching nodes.*/
1066
+ classes?: string;
1067
+ /**Default icon for matching nodes.*/
1068
+ icon?: boolean | string | BoolOptionResolver;
1069
+ /**
1070
+ * See also {@link WunderbaumNode.getOption|WunderbaumNode.getOption()}
1071
+ * to evaluate `node.NAME` setting and `tree.types[node.type].NAME`.
1072
+ */
1005
1073
  [key: string]: unknown;
1074
+ }
1075
+ export type NodeTypeDefinitions = {
1076
+ [type: string]: NodeTypeDefinition;
1006
1077
  };
1007
- export type WbNodeEventType = WbTreeEventType & {
1008
- node: WunderbaumNode;
1078
+ /**
1079
+ * @see {@link `Wunderbaum.columns`}
1080
+ */
1081
+ export interface ColumnDefinition {
1082
+ /** Column ID as defined in `tree.columns` definition ("*" for title column). */
1083
+ id: string;
1084
+ /** Column header (defaults to id) */
1085
+ title: string;
1086
+ /** Column header tooltip (optional) */
1087
+ tooltip?: string;
1088
+ /** Column width or weight.
1089
+ * Either an absolute pixel value (e.g. `"50px"`) or a relative weight (e.g. `1`)
1090
+ * that is used to calculate the width inside the remaining available space.
1091
+ * Default: `"*"`, which is interpreted as `1`.
1092
+ */
1093
+ width?: string | number;
1094
+ /** Only used for columns with a relative weight.
1095
+ * Default: `4px`.
1096
+ */
1097
+ minWidth?: string | number;
1098
+ /** Optional class names that are added to all `span.wb-col` elements of that column.*/
1099
+ classes?: string;
1100
+ /** Optional HTML content that is rendered into all `span.wb-col` elements of that column.*/
1101
+ html?: string;
1102
+ _weight?: number;
1103
+ _widthPx?: number;
1104
+ _ofsPx?: number;
1105
+ }
1106
+ export type ColumnDefinitionList = Array<ColumnDefinition>;
1107
+ export interface ColumnEventInfo {
1108
+ /** Column ID as defined in `tree.columns` definition ("*" for title column). */
1109
+ id: string;
1110
+ /** Column index (0: leftmost title column). */
1111
+ idx: number;
1112
+ /** The cell's `<span class='wb-col'>` element (null for plain trees). */
1113
+ elem: HTMLSpanElement | null;
1114
+ /** The value of `tree.columns[]` for the current index. */
1115
+ info: ColumnDefinition;
1116
+ }
1117
+ export type ColumnEventInfos = {
1118
+ [colId: string]: ColumnEventInfo;
1009
1119
  };
1010
1120
  export type WbTreeCallbackType = (e: WbTreeEventType) => any;
1011
1121
  export type WbNodeCallbackType = (e: WbNodeEventType) => any;
1122
+ export type WbRenderCallbackType = (e: WbRenderEventType) => void;
1012
1123
  export type FilterModeType = null | "dim" | "hide";
1013
1124
  export type ApplyCommandType = "moveUp" | "moveDown" | "indent" | "outdent" | "remove" | "rename" | "addChild" | "addSibling" | "cut" | "copy" | "paste" | "down" | "first" | "last" | "left" | "pageDown" | "pageUp" | "parent" | "right" | "up";
1014
1125
  export type NodeFilterResponse = "skip" | "branch" | boolean | void;
1015
1126
  export type NodeFilterCallback = (node: WunderbaumNode) => NodeFilterResponse;
1016
1127
  export type AddNodeType = "before" | "after" | "prependChild" | "appendChild";
1017
1128
  export type DndModeType = "before" | "after" | "over";
1129
+ /** Possible values for `setModified()`. */
1018
1130
  export enum ChangeType {
1131
+ /** Re-render the whole viewport, headers, and all rows. */
1019
1132
  any = "any",
1133
+ /** Update current row title, icon, columns, and status. */
1134
+ data = "data",
1135
+ /** Redraw the header and update the width of all row columns. */
1136
+ header = "header",
1137
+ /** Re-render the whole current row. */
1020
1138
  row = "row",
1139
+ /** Alias for 'any'. */
1021
1140
  structure = "structure",
1141
+ /** Update current row's classes, to reflect active, selected, ... */
1022
1142
  status = "status",
1023
- vscroll = "vscroll",
1024
- header = "header"
1143
+ /** Update the 'top' property of all rows. */
1144
+ vscroll = "vscroll"
1025
1145
  }
1146
+ /** Possible values for `setStatus()`. */
1026
1147
  export enum NodeStatusType {
1027
1148
  ok = "ok",
1028
1149
  loading = "loading",
1029
1150
  error = "error",
1030
1151
  noData = "noData"
1031
1152
  }
1032
- /**Define the subregion of a node, where an event occurred. */
1153
+ /** Define the subregion of a node, where an event occurred. */
1033
1154
  export enum TargetType {
1034
1155
  unknown = "",
1035
1156
  checkbox = "checkbox",
@@ -1039,82 +1160,222 @@ declare module "common" {
1039
1160
  prefix = "prefix",
1040
1161
  title = "title"
1041
1162
  }
1042
- export let iconMap: {
1043
- error: string;
1044
- loading: string;
1045
- noData: string;
1046
- expanderExpanded: string;
1047
- expanderCollapsed: string;
1048
- expanderLazy: string;
1049
- checkChecked: string;
1050
- checkUnchecked: string;
1051
- checkUnknown: string;
1052
- radioChecked: string;
1053
- radioUnchecked: string;
1054
- radioUnknown: string;
1055
- folder: string;
1056
- folderOpen: string;
1057
- doc: string;
1058
- };
1059
- export const KEY_NODATA = "__not_found__";
1060
- export enum NavigationModeOption {
1163
+ /** Initial navigation mode and possible transition. */
1164
+ export enum NavigationOptions {
1061
1165
  startRow = "startRow",
1062
1166
  cell = "cell",
1063
1167
  startCell = "startCell",
1064
1168
  row = "row"
1065
1169
  }
1066
- export enum NavigationMode {
1067
- row = "row",
1068
- cellNav = "cellNav",
1069
- cellEdit = "cellEdit"
1170
+ /** Possible values for `node.makeVisible()`. */
1171
+ export interface MakeVisibleOptions {
1172
+ /** Do not animate expand (currently not implemented). @default false */
1173
+ noAnimation?: boolean;
1174
+ /** Scroll node into visible viewport area if required. @default true */
1175
+ scrollIntoView?: boolean;
1176
+ /** Do not send events. @default false */
1177
+ noEvents?: boolean;
1178
+ }
1179
+ /** Possible values for `node.scrollIntoView()`. */
1180
+ export interface ScrollIntoViewOptions {
1181
+ /** Do not animate (currently not implemented). @default false */
1182
+ noAnimation?: boolean;
1183
+ /** Do not send events. @default false */
1184
+ noEvents?: boolean;
1185
+ /** Keep this node visible at the top in any case. */
1186
+ topNode?: WunderbaumNode;
1187
+ /** Add N pixel offset at top. */
1188
+ ofsY?: number;
1189
+ }
1190
+ /** Possible values for `tree.scrollTo()`. */
1191
+ export interface ScrollToOptions extends ScrollIntoViewOptions {
1192
+ /** Which node to scroll into the viewport.*/
1193
+ node: WunderbaumNode;
1070
1194
  }
1071
- export type SetActiveOptions = {
1072
- /** Generate (de)activate event, even if node already has this status. */
1195
+ /** Possible values for `node.setActive()`. */
1196
+ export interface SetActiveOptions {
1197
+ /** Generate (de)activate event, even if node already has this status (default: false). */
1073
1198
  retrigger?: boolean;
1074
- /** Don not generate (de)activate event. */
1199
+ /** Do not generate (de)activate event (default: false). */
1075
1200
  noEvents?: boolean;
1076
- /** Optional original event that will be passed to the (de)activat handler. */
1201
+ /** Set node as focused node (default: true). */
1202
+ focusNode?: boolean;
1203
+ /** Set node as focused node (default: false). */
1204
+ focusTree?: boolean;
1205
+ /** Optional original event that will be passed to the (de)activate handler. */
1077
1206
  event?: Event;
1078
1207
  /** Call {@link setColumn}. */
1079
1208
  colIdx?: number;
1080
- };
1081
- export type SetExpandedOptions = {
1209
+ }
1210
+ /** Possible values for `node.setExpanded()`. */
1211
+ export interface SetExpandedOptions {
1082
1212
  /** Ignore {@link minExpandLevel}. @default false */
1083
1213
  force?: boolean;
1084
- /** Avoid smooth scrolling. @default false */
1214
+ /** Immediately update viewport (async otherwise). @default false */
1215
+ immediate?: boolean;
1216
+ /** Do not animate expand (currently not implemented). @default false */
1085
1217
  noAnimation?: boolean;
1086
1218
  /** Do not send events. @default false */
1087
1219
  noEvents?: boolean;
1088
- /** Scroll to bring expanded nodes into viewport. @default false */
1220
+ /** Scroll up to bring expanded nodes into viewport. @default false */
1089
1221
  scrollIntoView?: boolean;
1090
- };
1091
- export type SetSelectedOptions = {
1222
+ }
1223
+ /** Possible values for `node.setSetModified()`. */
1224
+ export interface SetModifiedOptions {
1225
+ /** Force immediate redraw instead of throttled/async mode. @default false */
1226
+ immediate?: boolean;
1227
+ /** Remove HTML markup of all rendered nodes before redraw. @default false */
1228
+ removeMarkup?: boolean;
1229
+ }
1230
+ /** Possible values for `node.setSelected()`. */
1231
+ export interface SetSelectedOptions {
1092
1232
  /** Ignore restrictions. @default false */
1093
1233
  force?: boolean;
1094
1234
  /** Do not send events. @default false */
1095
1235
  noEvents?: boolean;
1236
+ }
1237
+ /** Possible values for `node.setSetModified()`. */
1238
+ export interface SetStatusOptions {
1239
+ /** Displayed as status node title. */
1240
+ message?: string;
1241
+ /** Used as tooltip. */
1242
+ details?: string;
1243
+ }
1244
+ export type DropRegionType = "over" | "before" | "after";
1245
+ export type DropRegionTypeSet = Set<DropRegionType>;
1246
+ export type DndOptionsType = {
1247
+ /**
1248
+ * Expand nodes after n milliseconds of hovering
1249
+ * Default: 1500
1250
+ */
1251
+ autoExpandMS: 1500;
1252
+ /**
1253
+ * true: Drag multiple (i.e. selected) nodes. Also a callback() is allowed
1254
+ * Default: false
1255
+ */
1256
+ multiSource: false;
1257
+ /**
1258
+ * Restrict the possible cursor shapes and modifier operations (can also be set in the dragStart event)
1259
+ * Default: "all"
1260
+ */
1261
+ effectAllowed: "all";
1262
+ /**
1263
+ * Default dropEffect ('copy', 'link', or 'move') when no modifier is pressed (overide in dragDrag, dragOver).
1264
+ * Default: "move"
1265
+ */
1266
+ dropEffectDefault: string;
1267
+ /**
1268
+ * Prevent dropping nodes from different Wunderbaum trees
1269
+ * Default: false
1270
+ */
1271
+ preventForeignNodes: boolean;
1272
+ /**
1273
+ * Prevent dropping items on unloaded lazy Wunderbaum tree nodes
1274
+ * Default: true
1275
+ */
1276
+ preventLazyParents: boolean;
1277
+ /**
1278
+ * Prevent dropping items other than Wunderbaum tree nodes
1279
+ * Default: false
1280
+ */
1281
+ preventNonNodes: boolean;
1282
+ /**
1283
+ * Prevent dropping nodes on own descendants
1284
+ * Default: true
1285
+ */
1286
+ preventRecursion: boolean;
1287
+ /**
1288
+ * Prevent dropping nodes under same direct parent
1289
+ * Default: false
1290
+ */
1291
+ preventSameParent: false;
1292
+ /**
1293
+ * Prevent dropping nodes 'before self', etc. (move only)
1294
+ * Default: true
1295
+ */
1296
+ preventVoidMoves: boolean;
1297
+ /**
1298
+ * Enable auto-scrolling while dragging
1299
+ * Default: true
1300
+ */
1301
+ scroll: boolean;
1302
+ /**
1303
+ * Active top/bottom margin in pixel
1304
+ * Default: 20
1305
+ */
1306
+ scrollSensitivity: 20;
1307
+ /**
1308
+ * Pixel per event
1309
+ * Default: 5
1310
+ */
1311
+ scrollSpeed: 5;
1312
+ /**
1313
+ * Optional callback passed to `toDict` on dragStart @since 2.38
1314
+ * Default: null
1315
+ */
1316
+ sourceCopyHook: null;
1317
+ /**
1318
+ * Callback(sourceNode, data), return true, to enable dnd drag
1319
+ * Default: null
1320
+ */
1321
+ dragStart?: WbNodeEventType;
1322
+ /**
1323
+ * Callback(sourceNode, data)
1324
+ * Default: null
1325
+ */
1326
+ dragDrag: null;
1327
+ /**
1328
+ * Callback(sourceNode, data)
1329
+ * Default: null
1330
+ */
1331
+ dragEnd: null;
1332
+ /**
1333
+ * Callback(targetNode, data), return true, to enable dnd drop
1334
+ * Default: null
1335
+ */
1336
+ dragEnter: null;
1337
+ /**
1338
+ * Callback(targetNode, data)
1339
+ * Default: null
1340
+ */
1341
+ dragOver: null;
1342
+ /**
1343
+ * Callback(targetNode, data), return false to prevent autoExpand
1344
+ * Default: null
1345
+ */
1346
+ dragExpand: null;
1347
+ /**
1348
+ * Callback(targetNode, data)
1349
+ * Default: null
1350
+ */
1351
+ dragDrop: null;
1352
+ /**
1353
+ * Callback(targetNode, data)
1354
+ * Default: null
1355
+ */
1356
+ dragLeave: null;
1096
1357
  };
1097
- /** Define which keys are handled by embedded <input> control, and should
1098
- * *not* be passed to tree navigation handler in cell-edit mode: */
1099
- export const INPUT_KEYS: {
1100
- text: string[];
1101
- number: string[];
1102
- checkbox: any[];
1103
- link: any[];
1104
- radiobutton: string[];
1105
- "select-one": string[];
1106
- "select-multiple": string[];
1107
- };
1108
- /** Key codes that trigger grid navigation, even when inside an input element. */
1109
- export const NAVIGATE_IN_INPUT_KEYS: Set<string>;
1110
- /** Map `KeyEvent.key` to navigation action. */
1111
- export const KEY_TO_ACTION_DICT: {
1112
- [key: string]: string;
1358
+ }
1359
+ declare module "wb_extension_base" {
1360
+ import { Wunderbaum } from "wunderbaum";
1361
+ export type ExtensionsDict = {
1362
+ [key: string]: WunderbaumExtension;
1113
1363
  };
1114
- /** */
1115
- export function makeNodeTitleMatcher(s: string): MatcherType;
1116
- /** */
1117
- export function makeNodeTitleStartMatcher(s: string): MatcherType;
1364
+ export abstract class WunderbaumExtension {
1365
+ enabled: boolean;
1366
+ readonly id: string;
1367
+ readonly tree: Wunderbaum;
1368
+ readonly treeOpts: any;
1369
+ readonly extensionOpts: any;
1370
+ constructor(tree: Wunderbaum, id: string, defaults: any);
1371
+ /** Called on tree (re)init after all extensions are added, but before loading.*/
1372
+ init(): void;
1373
+ getPluginOption(name: string, defaultValue?: any): any;
1374
+ setPluginOption(name: string, value: any): void;
1375
+ setEnabled(flag?: boolean): void;
1376
+ onKeyEvent(data: any): boolean | undefined;
1377
+ onRender(data: any): boolean | undefined;
1378
+ }
1118
1379
  }
1119
1380
  declare module "debounce" {
1120
1381
  /*!
@@ -1251,7 +1512,7 @@ declare module "debounce" {
1251
1512
  export function throttle<F extends Procedure>(func: F, wait?: number, options?: ThrottleOptions): DebouncedFunction<F>;
1252
1513
  }
1253
1514
  declare module "wb_ext_filter" {
1254
- import { NodeFilterCallback } from "common";
1515
+ import { NodeFilterCallback } from "types";
1255
1516
  import { Wunderbaum } from "wunderbaum";
1256
1517
  import { WunderbaumExtension } from "wb_extension_base";
1257
1518
  export class FilterExtension extends WunderbaumExtension {
@@ -1259,6 +1520,7 @@ declare module "wb_ext_filter" {
1259
1520
  lastFilterArgs: IArguments | null;
1260
1521
  constructor(tree: Wunderbaum);
1261
1522
  init(): void;
1523
+ setPluginOption(name: string, value: any): void;
1262
1524
  _applyFilterNoUpdate(filter: string | NodeFilterCallback, branchMode: boolean, _opts: any): void;
1263
1525
  _applyFilterImpl(filter: string | NodeFilterCallback, branchMode: boolean, _opts: any): number;
1264
1526
  /**
@@ -1288,6 +1550,8 @@ declare module "wb_ext_keynav" {
1288
1550
  import { WunderbaumExtension } from "wb_extension_base";
1289
1551
  export class KeynavExtension extends WunderbaumExtension {
1290
1552
  constructor(tree: Wunderbaum);
1553
+ protected _getEmbeddedInputElem(elem: any): HTMLInputElement | null;
1554
+ protected _isCurInputFocused(): boolean;
1291
1555
  onKeyEvent(data: any): boolean | undefined;
1292
1556
  }
1293
1557
  }
@@ -1302,6 +1566,31 @@ declare module "wb_ext_logger" {
1302
1566
  onKeyEvent(data: any): boolean | undefined;
1303
1567
  }
1304
1568
  }
1569
+ declare module "wb_ext_dnd" {
1570
+ import { Wunderbaum } from "wunderbaum";
1571
+ import { WunderbaumExtension } from "wb_extension_base";
1572
+ import { WunderbaumNode } from "wb_node";
1573
+ import { DropRegionType, DropRegionTypeSet } from "types";
1574
+ export class DndExtension extends WunderbaumExtension {
1575
+ protected srcNode: WunderbaumNode | null;
1576
+ protected lastTargetNode: WunderbaumNode | null;
1577
+ protected lastEnterStamp: number;
1578
+ protected lastAllowedDropRegions: DropRegionTypeSet | null;
1579
+ protected lastDropEffect: string | null;
1580
+ protected lastDropRegion: DropRegionType | false;
1581
+ constructor(tree: Wunderbaum);
1582
+ init(): void;
1583
+ /** Cleanup classes after target node is no longer hovered. */
1584
+ protected _leaveNode(): void;
1585
+ /** */
1586
+ protected unifyDragover(res: any): DropRegionTypeSet | false;
1587
+ /** */
1588
+ protected _calcDropRegion(e: DragEvent, allowed: DropRegionTypeSet | null): DropRegionType | false;
1589
+ protected autoScroll(event: DragEvent): number;
1590
+ protected onDragEvent(e: DragEvent): boolean;
1591
+ protected onDropEvent(e: DragEvent): boolean;
1592
+ }
1593
+ }
1305
1594
  declare module "drag_observer" {
1306
1595
  export type DragCallbackArgType = {
1307
1596
  /** "dragstart", "drag", or "dragstop". */
@@ -1382,7 +1671,7 @@ declare module "wb_ext_edit" {
1382
1671
  import { Wunderbaum } from "wunderbaum";
1383
1672
  import { WunderbaumExtension } from "wb_extension_base";
1384
1673
  import { WunderbaumNode } from "wb_node";
1385
- import { AddNodeType } from "common";
1674
+ import { AddNodeType } from "types";
1386
1675
  import { WbNodeData } from "wb_options";
1387
1676
  export class EditExtension extends WunderbaumExtension {
1388
1677
  protected debouncedOnChange: (e: Event) => void;
@@ -1414,20 +1703,20 @@ declare module "wunderbaum" {
1414
1703
  /*!
1415
1704
  * wunderbaum.ts
1416
1705
  *
1417
- * A tree control.
1706
+ * A treegrid control.
1418
1707
  *
1419
1708
  * Copyright (c) 2021-2022, Martin Wendt (https://wwWendt.de).
1420
- * Released under the MIT license.
1709
+ * https://github.com/mar10/wunderbaum
1421
1710
  *
1711
+ * Released under the MIT license.
1422
1712
  * @version @VERSION
1423
1713
  * @date @DATE
1424
1714
  */
1425
1715
  import "./wunderbaum.scss";
1426
1716
  import * as util from "util";
1427
1717
  import { ExtensionsDict, WunderbaumExtension } from "wb_extension_base";
1428
- import { NavigationMode, ChangeType, FilterModeType, MatcherType, NodeStatusType, TargetType as NodeRegion, ApplyCommandType } from "common";
1718
+ import { ApplyCommandType, ChangeType, ColumnDefinitionList, FilterModeType, MatcherType, NavigationOptions, NodeStatusType, NodeTypeDefinitions, ScrollToOptions, SetActiveOptions, SetStatusOptions, TargetType as NodeRegion } from "types";
1429
1719
  import { WunderbaumNode } from "wb_node";
1430
- import { DebouncedFunction } from "debounce";
1431
1720
  import { WunderbaumOptions } from "wb_options";
1432
1721
  /**
1433
1722
  * A persistent plain object or array.
@@ -1436,6 +1725,7 @@ declare module "wunderbaum" {
1436
1725
  */
1437
1726
  export class Wunderbaum {
1438
1727
  protected static sequence: number;
1728
+ protected enabled: boolean;
1439
1729
  /** Wunderbaum release version number "MAJOR.MINOR.PATCH". */
1440
1730
  static version: string;
1441
1731
  /** The invisible root node, that holds all visible top level nodes. */
@@ -1445,12 +1735,16 @@ declare module "wunderbaum" {
1445
1735
  /** The `div` container element that was passed to the constructor. */
1446
1736
  readonly element: HTMLDivElement;
1447
1737
  /** The `div.wb-header` element if any. */
1448
- readonly headerElement: HTMLDivElement | null;
1738
+ readonly headerElement: HTMLDivElement;
1449
1739
  /** The `div.wb-scroll-container` element that contains the `nodeListElement`. */
1450
- readonly scrollContainer: HTMLDivElement;
1740
+ readonly scrollContainerElement: HTMLDivElement;
1451
1741
  /** The `div.wb-node-list` element that contains all visible div.wb-row child elements. */
1452
1742
  readonly nodeListElement: HTMLDivElement;
1453
- protected readonly _updateViewportThrottled: DebouncedFunction<(...args: any) => void>;
1743
+ /** Contains additional data that was sent as response to an Ajax source load request. */
1744
+ readonly data: {
1745
+ [key: string]: any;
1746
+ };
1747
+ protected readonly _updateViewportThrottled: (...args: any) => void;
1454
1748
  protected extensionList: WunderbaumExtension[];
1455
1749
  protected extensions: ExtensionsDict;
1456
1750
  /** Merged options from constructor args and tree- and extension defaults. */
@@ -1464,16 +1758,15 @@ declare module "wunderbaum" {
1464
1758
  /** Current node hat has keyboard focus if any. */
1465
1759
  focusNode: WunderbaumNode | null;
1466
1760
  /** Shared properties, referenced by `node.type`. */
1467
- types: {
1468
- [key: string]: any;
1469
- };
1761
+ types: NodeTypeDefinitions;
1470
1762
  /** List of column definitions. */
1471
- columns: any[];
1763
+ columns: ColumnDefinitionList;
1472
1764
  protected _columnsById: {
1473
1765
  [key: string]: any;
1474
1766
  };
1475
1767
  protected resizeObserver: ResizeObserver;
1476
1768
  protected changeRedrawRequestPending: boolean;
1769
+ protected changeScrollRequestPending: boolean;
1477
1770
  /** A Promise that is resolved when the tree was initialized (similar to `init(e)` event). */
1478
1771
  readonly ready: Promise<any>;
1479
1772
  /** Expose some useful methods of the util.ts module as `Wunderbaum.util`. */
@@ -1484,7 +1777,7 @@ declare module "wunderbaum" {
1484
1777
  /** @internal Use `setColumn()`/`getActiveColElem()`*/
1485
1778
  activeColIdx: number;
1486
1779
  /** @internal */
1487
- navMode: NavigationMode;
1780
+ _cellNavMode: boolean;
1488
1781
  /** @internal */
1489
1782
  lastQuicksearchTime: number;
1490
1783
  /** @internal */
@@ -1534,13 +1827,13 @@ declare module "wunderbaum" {
1534
1827
  * tree._callEvent("edit.beforeEdit", {foo: 42})
1535
1828
  * ```
1536
1829
  */
1537
- _callEvent(name: string, extra?: any): any;
1830
+ _callEvent(type: string, extra?: any): any;
1538
1831
  /** Return the node for given row index. */
1539
1832
  protected _getNodeByRowIdx(idx: number): WunderbaumNode | null;
1540
1833
  /** Return the topmost visible node in the viewport. */
1541
- protected _firstNodeInView(complete?: boolean): WunderbaumNode;
1834
+ getTopmostVpNode(complete?: boolean): WunderbaumNode;
1542
1835
  /** Return the lowest visible node in the viewport. */
1543
- protected _lastNodeInView(complete?: boolean): WunderbaumNode;
1836
+ getLowestVpNode(complete?: boolean): WunderbaumNode;
1544
1837
  /** Return preceeding visible node in the viewport. */
1545
1838
  protected _getPrevNodeInView(node?: WunderbaumNode, ofs?: number): WunderbaumNode;
1546
1839
  /** Return following visible node in the viewport. */
@@ -1574,24 +1867,31 @@ declare module "wunderbaum" {
1574
1867
  * Return `tree.option.NAME` (also resolving if this is a callback).
1575
1868
  *
1576
1869
  * See also {@link WunderbaumNode.getOption|WunderbaumNode.getOption()}
1577
- * to consider `node.NAME` setting and `tree.types[node.type].NAME`.
1870
+ * to evaluate `node.NAME` setting and `tree.types[node.type].NAME`.
1578
1871
  *
1579
1872
  * @param name option name (use dot notation to access extension option, e.g.
1580
1873
  * `filter.mode`)
1581
1874
  */
1582
1875
  getOption(name: string, defaultValue?: any): any;
1583
1876
  /**
1584
- *
1585
- * @param name
1586
- * @param value
1877
+ * Set tree option.
1878
+ * Use dot notation to set plugin option, e.g. "filter.mode".
1587
1879
  */
1588
1880
  setOption(name: string, value: any): void;
1589
- /**Return true if the tree (or one of its nodes) has the input focus. */
1881
+ /** Return true if the tree (or one of its nodes) has the input focus. */
1590
1882
  hasFocus(): boolean;
1591
- /** Run code, but defer `updateViewport()` until done. */
1883
+ /**
1884
+ * Return true if the tree displays a header. Grids have a header unless the
1885
+ * `header` option is set to `false`. Plain trees have a header if the `header`
1886
+ * option is a string or `true`.
1887
+ */
1888
+ hasHeader(): boolean;
1889
+ /** Run code, but defer rendering of viewport until done. */
1592
1890
  runWithoutUpdate(func: () => any, hint?: any): void;
1593
1891
  /** Recursively expand all expandable nodes (triggers lazy load id needed). */
1594
1892
  expandAll(flag?: boolean): Promise<void>;
1893
+ /** Recursively select all nodes. */
1894
+ selectAll(flag?: boolean): void;
1595
1895
  /** Return the number of nodes in the data model.*/
1596
1896
  count(visible?: boolean): number;
1597
1897
  /** @internal sanity check. */
@@ -1614,6 +1914,15 @@ declare module "wunderbaum" {
1614
1914
  *
1615
1915
  */
1616
1916
  findFirst(match: string | MatcherType): WunderbaumNode;
1917
+ /**
1918
+ * Find first node that matches condition.
1919
+ *
1920
+ * @param match title string to search for, or a
1921
+ * callback function that returns `true` if a node is matched.
1922
+ * @see {@link WunderbaumNode.findFirst}
1923
+ *
1924
+ */
1925
+ findKey(key: string): WunderbaumNode | undefined;
1617
1926
  /**
1618
1927
  * Find the next visible node that starts with `match`, starting at `startNode`
1619
1928
  * and wrap-around at the end.
@@ -1688,52 +1997,74 @@ declare module "wunderbaum" {
1688
1997
  /** Log to console if opts.debugLevel >= 2 */
1689
1998
  logWarn(...args: any[]): void;
1690
1999
  /**
1691
- * Make sure that this node is scrolled into the viewport.
1692
- *
1693
- * @param {boolean | PlainObject} [effects=false] animation options.
1694
- * @param {object} [options=null] {topNode: null, effects: ..., parent: ...}
1695
- * this node will remain visible in
1696
- * any case, even if `this` is outside the scroll pane.
2000
+ * Make sure that this node is vertically scrolled into the viewport.
2001
+ */
2002
+ scrollTo(nodeOrOpts: ScrollToOptions | WunderbaumNode): void;
2003
+ /**
2004
+ * Make sure that this node is horizontally scrolled into the viewport.
2005
+ * Called by {@link setColumn}.
1697
2006
  */
1698
- scrollTo(opts: any): void;
2007
+ protected scrollToHorz(): void;
1699
2008
  /**
1700
2009
  * Set column #colIdx to 'active'.
1701
2010
  *
1702
2011
  * This higlights the column header and -cells by adding the `wb-active` class.
1703
- * Available in cell-nav and cell-edit mode, not in row-mode.
2012
+ * Available in cell-nav mode only.
1704
2013
  */
1705
2014
  setColumn(colIdx: number): void;
1706
2015
  /** Set or remove keybaord focus to the tree container. */
2016
+ setActiveNode(key: string, flag?: boolean, options?: SetActiveOptions): void;
2017
+ /** Set or remove keybaord focus to the tree container. */
1707
2018
  setFocus(flag?: boolean): void;
1708
2019
  /** Schedule an update request to reflect a tree change. */
1709
2020
  setModified(change: ChangeType, options?: any): void;
1710
2021
  /** Schedule an update request to reflect a single node modification. */
1711
2022
  setModified(change: ChangeType, node: WunderbaumNode, options?: any): void;
2023
+ /** Disable mouse and keyboard interaction (return prev. state). */
2024
+ setEnabled(flag?: boolean): boolean;
2025
+ /** Return false if tree is disabled. */
2026
+ isEnabled(): boolean;
2027
+ /** Return true if tree has more than one column, i.e. has additional data columns. */
2028
+ isGrid(): boolean;
2029
+ /** Return true if cell-navigation mode is acive. */
2030
+ isCellNav(): boolean;
2031
+ /** Return true if row-navigation mode is acive. */
2032
+ isRowNav(): boolean;
1712
2033
  /** Set the tree's navigation mode. */
1713
- setNavigationMode(mode: NavigationMode): void;
2034
+ setCellNav(flag?: boolean): void;
2035
+ /** Set the tree's navigation mode option. */
2036
+ setNavigationOption(mode: NavigationOptions, reset?: boolean): void;
1714
2037
  /** Display tree status (ok, loading, error, noData) using styles and a dummy root node. */
1715
- setStatus(status: NodeStatusType, message?: string, details?: string): WunderbaumNode | null;
2038
+ setStatus(status: NodeStatusType, options?: SetStatusOptions): WunderbaumNode | null;
2039
+ /** Add or redefine node type definitions. */
2040
+ setTypes(types: any, replace?: boolean): void;
1716
2041
  /** Update column headers and width. */
1717
2042
  updateColumns(opts?: any): void;
1718
2043
  /** Create/update header markup from `this.columns` definition.
1719
2044
  * @internal
1720
2045
  */
1721
2046
  protected _renderHeaderMarkup(): void;
1722
- /** Render header and all rows that are visible in the viewport (async, throttled). */
1723
- updateViewport(immediate?: boolean): void;
1724
2047
  /**
1725
- * This is the actual update method, which is wrapped inside a throttle method.
1726
- * This protected method should not be called directly but via
1727
- * `tree.updateViewport()` or `tree.setModified()`.
1728
- * It calls `updateColumns()` and `_updateRows()`.
1729
- * @internal
2048
+ * Render pending changes that were scheduled using {@link WunderbaumNode.setModified} if any.
2049
+ *
2050
+ * This is hardly ever neccessary, since we normally either
2051
+ * - call `setModified(ChangeType.TYPE)` (async, throttled), or
2052
+ * - call `setModified(ChangeType.TYPE, {immediate: true})` (synchronous)
2053
+ *
2054
+ * `updatePendingModifications()` will only force immediate execution of
2055
+ * pending async changes if any.
1730
2056
  */
1731
- protected _updateViewport(): void;
2057
+ updatePendingModifications(): void;
1732
2058
  /**
1733
- * Assert that TR order matches the natural node order
2059
+ * This is the actual update method, which is wrapped inside a throttle method.
2060
+ * It calls `updateColumns()` and `_updateRows()`.
2061
+ *
2062
+ * This protected method should not be called directly but via
2063
+ * {@link WunderbaumNode.setModified}`, {@link Wunderbaum.setModified},
2064
+ * or {@link Wunderbaum.updatePendingModifications}.
1734
2065
  * @internal
1735
2066
  */
1736
- protected _validateRows(): boolean;
2067
+ protected _updateViewportImmediately(): void;
1737
2068
  protected _updateRows(opts?: any): boolean;
1738
2069
  /**
1739
2070
  * Call callback(node) for all nodes in hierarchical order (depth-first).
@@ -1743,7 +2074,7 @@ declare module "wunderbaum" {
1743
2074
  * children only.
1744
2075
  * @returns {boolean} false, if the iterator was stopped.
1745
2076
  */
1746
- visit(callback: (node: WunderbaumNode) => any): import("common").NodeVisitResponse;
2077
+ visit(callback: (node: WunderbaumNode) => any): import("types").NodeVisitResponse;
1747
2078
  /**
1748
2079
  * Call fn(node) for all nodes in vertical order, top down (or bottom up).
1749
2080
  *
@@ -1769,10 +2100,10 @@ declare module "wunderbaum" {
1769
2100
  /**
1770
2101
  * Reload the tree with a new source.
1771
2102
  *
1772
- * Previous data is cleared.
1773
- * Pass `options.columns` to define a header (may also be part of `source.columns`).
2103
+ * Previous data is cleared. Note that also column- and type defintions may
2104
+ * be passed with the `source` object.
1774
2105
  */
1775
- load(source: any, options?: any): Promise<void>;
2106
+ load(source: any): Promise<void>;
1776
2107
  /**
1777
2108
  * Disable render requests during operations that would trigger many updates.
1778
2109
  *
@@ -1781,7 +2112,7 @@ declare module "wunderbaum" {
1781
2112
  * tree.enableUpdate(false);
1782
2113
  * // ... (long running operation that would trigger many updates)
1783
2114
  * foo();
1784
- * // ... NOTE: make sure that async operations have finished
2115
+ * // ... NOTE: make sure that async operations have finished, e.g.
1785
2116
  * await foo();
1786
2117
  * } finally {
1787
2118
  * tree.enableUpdate(true);