wunderbaum 0.3.4 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -369,781 +369,785 @@ declare module "deferred" {
369
369
  finally(cb: finallyCallbackType): Promise<any>;
370
370
  }
371
371
  }
372
- declare module "wb_options" {
373
- /*!
374
- * Wunderbaum - utils
375
- * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license.
376
- * @VERSION, @DATE (https://github.com/mar10/wunderbaum)
377
- */
378
- import { BoolOptionResolver, ColumnDefinitionList, DndOptionsType, NavModeEnum, NodeTypeDefinitionMap, WbActivateEventType, WbChangeEventType, WbClickEventType, WbDeactivateEventType, WbEnhanceTitleEventType, WbErrorEventType, WbInitEventType, WbKeydownEventType, WbNodeEventType, WbReceiveEventType, WbRenderEventType, WbTreeEventType } from "types";
379
- export interface WbNodeData {
380
- title: string;
381
- key?: string;
382
- refKey?: string;
383
- expanded?: boolean;
384
- selected?: boolean;
385
- checkbox?: boolean | string;
386
- colspan?: boolean;
387
- children?: Array<WbNodeData>;
388
- }
372
+ declare module "wb_node" {
373
+ import { Wunderbaum } from "wunderbaum";
374
+ import { AddChildrenOptions, InsertNodeType, ApplyCommandOptions, ApplyCommandType, ChangeType, ExpandAllOptions, MakeVisibleOptions, MatcherCallback, NavigateOptions, NodeAnyCallback, NodeStatusType, NodeStringCallback, NodeVisitCallback, NodeVisitResponse, RenderOptions, ScrollIntoViewOptions, SetActiveOptions, SetExpandedOptions, SetSelectedOptions, SetStatusOptions, SortCallback, NodeToDictCallback, WbNodeData, TristateType } from "types";
389
375
  /**
390
- * Available options for [[Wunderbaum]].
391
- *
392
- * Options are passed to the constructor as plain object:
393
- *
394
- * ```js
395
- * const tree = new mar10.Wunderbaum({
396
- * id: "demo",
397
- * element: document.getElementById("demo-tree"),
398
- * source: "url/of/data/request",
399
- * ...
400
- * });
401
- * ```
402
- *
403
- * Event handlers are also passed as callbacks
376
+ * A single tree node.
404
377
  *
405
- * ```js
406
- * const tree = new mar10.Wunderbaum({
407
- * ...
408
- * init: (e) => {
409
- * console.log(`Tree ${e.tree} was initialized and loaded.`)
410
- * },
411
- * activate: (e) => {
412
- * console.log(`Node ${e.node} was activated.`)
413
- * },
414
- * ...
415
- * });
416
- * ```
378
+ * **NOTE:** <br>
379
+ * Generally you should not modify properties directly, since this may break
380
+ * the internal bookkeeping.
417
381
  */
418
- export interface WunderbaumOptions {
382
+ export class WunderbaumNode {
383
+ static sequence: number;
384
+ /** Reference to owning tree. */
385
+ tree: Wunderbaum;
386
+ /** Parent node (null for the invisible root node `tree.root`). */
387
+ parent: WunderbaumNode;
388
+ /** Name of the node.
389
+ * @see Use {@link setTitle} to modify. */
390
+ title: string;
391
+ /** Unique key. Passed with constructor or defaults to `SEQUENCE`.
392
+ * @see Use {@link setKey} to modify. */
393
+ readonly key: string;
394
+ /** Reference key. Unlike {@link key}, a `refKey` may occur multiple
395
+ * times within a tree (in this case we have 'clone nodes').
396
+ * @see Use {@link setKey} to modify.
397
+ */
398
+ readonly refKey: string | undefined;
399
+ children: WunderbaumNode[] | null;
400
+ checkbox?: boolean;
401
+ radiogroup?: boolean;
402
+ /** If true, (in grid mode) no cells are rendered, except for the node title.*/
403
+ colspan?: boolean;
404
+ icon?: boolean | string;
405
+ lazy: boolean;
406
+ /** Expansion state.
407
+ * @see {@link isExpandable}, {@link isExpanded}, {@link setExpanded}. */
408
+ expanded: boolean;
409
+ /** Selection state.
410
+ * @see {@link isSelected}, {@link setSelected}, {@link toggleSelected}. */
411
+ selected: boolean;
412
+ unselectable?: boolean;
413
+ type?: string;
414
+ tooltip?: string;
415
+ /** Additional classes added to `div.wb-row`.
416
+ * @see {@link hasClass}, {@link setClass}. */
417
+ classes: Set<string> | null;
418
+ /** Custom data that was passed to the constructor */
419
+ data: any;
420
+ statusNodeType?: string;
421
+ _isLoading: boolean;
422
+ _requestId: number;
423
+ _errorInfo: any | null;
424
+ _partsel: boolean;
425
+ _partload: boolean;
426
+ match?: boolean;
427
+ subMatchCount?: number;
428
+ subMatchBadge?: HTMLElement;
429
+ /** @internal */
430
+ titleWithHighlight?: string;
431
+ _filterAutoExpanded?: boolean;
432
+ _rowIdx: number | undefined;
433
+ _rowElem: HTMLDivElement | undefined;
434
+ constructor(tree: Wunderbaum, parent: WunderbaumNode, data: any);
419
435
  /**
420
- * The target `div` element (or selector) that shall become a Wunderbaum.
436
+ * Return readable string representation for this instance.
437
+ * @internal
421
438
  */
422
- element: string | HTMLDivElement;
439
+ toString(): string;
423
440
  /**
424
- * The identifier of this tree. Used to reference the instance, especially
425
- * when multiple trees are present (e.g. `tree = mar10.Wunderbaum.getTree("demo")`).
441
+ * Iterate all descendant nodes depth-first, pre-order using `for ... of ...` syntax.
442
+ * More concise, but slightly slower than {@link WunderbaumNode.visit}.
426
443
  *
427
- * Default: `"wb_" + COUNTER`.
444
+ * Example:
445
+ * ```js
446
+ * for(const n of node) {
447
+ * ...
448
+ * }
449
+ * ```
428
450
  */
429
- id?: string;
451
+ [Symbol.iterator](): IterableIterator<WunderbaumNode>;
452
+ /** Call event handler if defined in tree.options.
453
+ * Example:
454
+ * ```js
455
+ * node._callEvent("edit.beforeEdit", {foo: 42})
456
+ * ```
457
+ */
458
+ _callEvent(type: string, extra?: any): any;
430
459
  /**
431
- * Define the initial tree data. Typically a URL of an endpoint that serves
432
- * a JSON formatted structure, but also a callback, Promise, or static data
433
- * is allowed.
460
+ * Append (or insert) a list of child nodes.
434
461
  *
435
- * Default: `{}`.
462
+ * Tip: pass `{ before: 0 }` to prepend new nodes as first children.
463
+ *
464
+ * @returns first child added
436
465
  */
437
- source?: string | Array<WbNodeData>;
466
+ addChildren(nodeData: WbNodeData | WbNodeData[], options?: AddChildrenOptions): WunderbaumNode;
438
467
  /**
439
- * Define shared attributes for multiple nodes of the same type.
440
- * This allows for more compact data models. Type definitions can be passed
441
- * as tree option, or be part of a `source` response.
468
+ * Append or prepend a node, or append a child node.
442
469
  *
443
- * Default: `{}`.
470
+ * This a convenience function that calls addChildren()
471
+ *
472
+ * @param nodeData node definition
473
+ * @param [mode=child] 'before', 'after', 'firstChild', or 'child' ('over' is a synonym for 'child')
474
+ * @returns new node
444
475
  */
445
- types?: NodeTypeDefinitionMap;
476
+ addNode(nodeData: WbNodeData, mode?: InsertNodeType): WunderbaumNode;
446
477
  /**
447
- * A list of maps that define column headers. If this option is set,
448
- * Wunderbaum becomes a treegrid control instead of a plain tree.
449
- * Column definitions can be passed as tree option, or be part of a `source`
450
- * response.
451
- * Default: `[]` meaning this is a plain tree.
478
+ * Apply a modification (or navigation) operation.
479
+ *
480
+ * @see {@link Wunderbaum.applyCommand}
452
481
  */
453
- columns?: ColumnDefinitionList;
482
+ applyCommand(cmd: ApplyCommandType, options: ApplyCommandOptions): any;
454
483
  /**
455
- * If true, add a `wb-skeleton` class to all nodes, that will result in a
456
- * 'glow' effect. Typically used with initial dummy nodes, while loading the
457
- * real data.
458
- * Default: false.
484
+ * Collapse all expanded sibling nodes if any.
485
+ * (Automatically called when `autoCollapse` is true.)
459
486
  */
460
- skeleton?: boolean;
487
+ collapseSiblings(options?: SetExpandedOptions): any;
461
488
  /**
462
- * Translation map for some system messages.
489
+ * Add/remove one or more classes to `<div class='wb-row'>`.
490
+ *
491
+ * This also maintains `node.classes`, so the class will survive a re-render.
492
+ *
493
+ * @param className one or more class names. Multiple classes can be passed
494
+ * as space-separated string, array of strings, or set of strings.
463
495
  */
464
- strings?: any;
496
+ setClass(className: string | string[] | Set<string>, flag?: boolean): void;
497
+ /** Call `setExpanded()` on all descendant nodes. */
498
+ expandAll(flag?: boolean, options?: ExpandAllOptions): Promise<void>;
465
499
  /**
466
- * 0:quiet, 1:errors, 2:warnings, 3:info, 4:verbose
467
- * Default: 3 (4 in local debug environment)
500
+ * Find all descendant nodes that match condition (excluding self).
501
+ *
502
+ * If `match` is a string, search for exact node title.
503
+ * If `match` is a RegExp expression, apply it to node.title, using
504
+ * [RegExp.test()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test).
505
+ * If `match` is a callback, match all nodes for that the callback(node) returns true.
506
+ *
507
+ * Returns an empty array if no nodes were found.
508
+ *
509
+ * Examples:
510
+ * ```js
511
+ * // Match all node titles that match exactly 'Joe':
512
+ * nodeList = node.findAll("Joe")
513
+ * // Match all node titles that start with 'Joe' case sensitive:
514
+ * nodeList = node.findAll(/^Joe/)
515
+ * // Match all node titles that contain 'oe', case insensitive:
516
+ * nodeList = node.findAll(/oe/i)
517
+ * // Match all nodes with `data.price` >= 99:
518
+ * nodeList = node.findAll((n) => {
519
+ * return n.data.price >= 99;
520
+ * })
521
+ * ```
468
522
  */
469
- debugLevel?: number;
523
+ findAll(match: string | RegExp | MatcherCallback): WunderbaumNode[];
524
+ /** Return the direct child with a given key, index or null. */
525
+ findDirectChild(ptr: number | string | WunderbaumNode): WunderbaumNode | null;
470
526
  /**
471
- * Number of levels that are forced to be expanded, and have no expander icon.
472
- * E.g. 1 would keep all toplevel nodes expanded.
473
- * Default: 0
527
+ * Find first descendant node that matches condition (excluding self) or null.
528
+ *
529
+ * @see {@link WunderbaumNode.findAll} for examples.
474
530
  */
475
- minExpandLevel?: number;
476
- /**
477
- * If true, allow to expand parent nodes, even if `node.children` conatains
478
- * an empty array (`[]`). This is the the behavior of macOS Finder, for example.
479
- * Default: false
531
+ findFirst(match: string | RegExp | MatcherCallback): WunderbaumNode | null;
532
+ /** Find a node relative to self.
533
+ *
534
+ * @see {@link Wunderbaum.findRelatedNode|tree.findRelatedNode()}
480
535
  */
481
- emptyChildListExpandable?: boolean;
536
+ findRelatedNode(where: string, includeHidden?: boolean): any;
482
537
  /**
483
- * Height of a node row div.
484
- * Default: 22
538
+ * Iterator version of {@link WunderbaumNode.format}.
485
539
  */
486
- rowHeightPx?: number;
540
+ format_iter(name_cb?: NodeStringCallback, connectors?: string[]): IterableIterator<string>;
487
541
  /**
488
- * Collapse siblings when a node is expanded.
489
- * Default: false
542
+ * Return a multiline string representation of a node/subnode hierarchy.
543
+ * Mostly useful for debugging.
544
+ *
545
+ * Example:
546
+ * ```js
547
+ * console.info(tree.getActiveNode().format((n)=>n.title));
548
+ * ```
549
+ * logs
550
+ * ```
551
+ * Books
552
+ * ├─ Art of War
553
+ * ╰─ Don Quixote
554
+ * ```
555
+ * @see {@link WunderbaumNode.format_iter}
490
556
  */
491
- autoCollapse?: boolean;
492
- /**
493
- * HTMLElement that receives the top nodes breadcrumb.
494
- * Default: undefined
557
+ format(name_cb?: NodeStringCallback, connectors?: string[]): string;
558
+ /** Return the `<span class='wb-col'>` element with a given index or id.
559
+ * @returns {WunderbaumNode | null}
495
560
  */
496
- connectTopBreadcrumb?: HTMLElement;
497
- /**
498
- * Default: NavModeEnum.startRow
561
+ getColElem(colIdx: number | string): HTMLSpanElement;
562
+ /** Return the first child node or null.
563
+ * @returns {WunderbaumNode | null}
499
564
  */
500
- navigationModeOption?: NavModeEnum;
501
- /**
502
- * Show/hide header (default: null)
503
- * null: assume false for plain tree and true for grids.
504
- * string: use text as header (only for plain trees)
505
- * true: display a header (use tree's id as text for plain trees)
506
- * false: do not display a header
565
+ getFirstChild(): WunderbaumNode;
566
+ /** Return the last child node or null.
567
+ * @returns {WunderbaumNode | null}
507
568
  */
508
- header?: boolean | string | null;
509
- /**
510
- *
569
+ getLastChild(): WunderbaumNode;
570
+ /** Return node depth (starting with 1 for top level nodes). */
571
+ getLevel(): number;
572
+ /** Return the successive node (under the same parent) or null. */
573
+ getNextSibling(): WunderbaumNode | null;
574
+ /** Return the parent node (null for the system root node). */
575
+ getParent(): WunderbaumNode | null;
576
+ /** Return an array of all parent nodes (top-down).
577
+ * @param includeRoot Include the invisible system root node.
578
+ * @param includeSelf Include the node itself.
511
579
  */
512
- showSpinner?: boolean;
513
- /**
514
- * If true, render a checkbox before the node tile to allow selection with the
515
- * mouse.
516
- * Default: false.
580
+ getParentList(includeRoot?: boolean, includeSelf?: boolean): any[];
581
+ /** Return a string representing the hierachical node path, e.g. "a/b/c".
582
+ * @param includeSelf
583
+ * @param node property name or callback
584
+ * @param separator
517
585
  */
518
- checkbox?: boolean | "radio" | BoolOptionResolver;
519
- /**
520
- * Default: 200
586
+ getPath(includeSelf?: boolean, part?: keyof WunderbaumNode | NodeAnyCallback, separator?: string): string;
587
+ /** Return the preceeding node (under the same parent) or null. */
588
+ getPrevSibling(): WunderbaumNode | null;
589
+ /** Return true if node has children.
590
+ * Return undefined if not sure, i.e. the node is lazy and not yet loaded.
521
591
  */
522
- updateThrottleWait?: number;
523
- /**
524
- * Default: true
592
+ hasChildren(): boolean;
593
+ /** Return true if node has className set. */
594
+ hasClass(className: string): boolean;
595
+ /** Return true if this node is the currently active tree node. */
596
+ isActive(): boolean;
597
+ /** Return true if this node is a direct or indirect parent of `other`.
598
+ * (See also [[isParentOf]].)
525
599
  */
526
- enabled?: boolean;
527
- /**
528
- * Default: false
600
+ isAncestorOf(other: WunderbaumNode): boolean;
601
+ /** Return true if this node is a **direct** subnode of `other`.
602
+ * (See also [[isDescendantOf]].)
529
603
  */
530
- fixedCol?: boolean;
531
- /**
532
- * Default: true
604
+ isChildOf(other: WunderbaumNode): boolean;
605
+ /** Return true if this node's title spans all columns, i.e. the node has no
606
+ * grid cells.
533
607
  */
534
- quicksearch?: boolean;
535
- dnd?: DndOptionsType;
536
- edit?: any;
537
- filter?: any;
538
- grid?: any;
539
- /**
540
- *
541
- * @category Callback
608
+ isColspan(): boolean;
609
+ /** Return true if this node is a direct or indirect subnode of `other`.
610
+ * (See also [[isChildOf]].)
542
611
  */
543
- activate?: (e: WbActivateEventType) => void;
544
- /**
612
+ isDescendantOf(other: WunderbaumNode): boolean;
613
+ /** Return true if this node has children, i.e. the node is generally expandable.
614
+ * If `andCollapsed` is set, we also check if this node is collapsed, i.e.
615
+ * an expand operation is currently possible.
616
+ */
617
+ isExpandable(andCollapsed?: boolean): boolean;
618
+ /** Return true if this node is currently in edit-title mode. */
619
+ isEditing(): boolean;
620
+ /** Return true if this node is currently expanded. */
621
+ isExpanded(): boolean;
622
+ /** Return true if this node is the first node of its parent's children. */
623
+ isFirstSibling(): boolean;
624
+ /** Return true if this node is the last node of its parent's children. */
625
+ isLastSibling(): boolean;
626
+ /** Return true if this node is lazy (even if data was already loaded) */
627
+ isLazy(): boolean;
628
+ /** Return true if node is lazy and loaded. For non-lazy nodes always return true. */
629
+ isLoaded(): boolean;
630
+ /** Return true if node is currently loading, i.e. a GET request is pending. */
631
+ isLoading(): boolean;
632
+ /** Return true if this node is a temporarily generated status node of type 'paging'. */
633
+ isPagingNode(): boolean;
634
+ /** Return true if this node is a **direct** parent of `other`.
635
+ * (See also [[isAncestorOf]].)
636
+ */
637
+ isParentOf(other: WunderbaumNode): boolean;
638
+ /** (experimental) Return true if this node is partially loaded. */
639
+ isPartload(): boolean;
640
+ /** Return true if this node is partially selected (tri-state). */
641
+ isPartsel(): boolean;
642
+ /** Return true if this node has DOM representaion, i.e. is displayed in the viewport. */
643
+ isRendered(): boolean;
644
+ /** Return true if this node is the (invisible) system root node.
645
+ * (See also [[isTopLevel()]].)
646
+ */
647
+ isRootNode(): boolean;
648
+ /** Return true if this node is selected, i.e. the checkbox is set.
649
+ * `undefined` if partly selected (tri-state), false otherwise.
650
+ */
651
+ isSelected(): TristateType;
652
+ /** Return true if this node is a temporarily generated system node like
653
+ * 'loading', 'paging', or 'error' (node.statusNodeType contains the type).
654
+ */
655
+ isStatusNode(): boolean;
656
+ /** Return true if this a top level node, i.e. a direct child of the (invisible) system root node. */
657
+ isTopLevel(): boolean;
658
+ /** Return true if node is marked lazy but not yet loaded.
659
+ * For non-lazy nodes always return false.
660
+ */
661
+ isUnloaded(): boolean;
662
+ /** Return true if all parent nodes are expanded. Note: this does not check
663
+ * whether the node is scrolled into the visible part of the screen or viewport.
664
+ */
665
+ isVisible(): boolean;
666
+ protected _loadSourceObject(source: any, level?: number): void;
667
+ _fetchWithOptions(source: any): Promise<any>;
668
+ /** Download data from the cloud, then call `.update()`. */
669
+ load(source: any): Promise<void>;
670
+ /**Load content of a lazy node. */
671
+ loadLazy(forceReload?: boolean): Promise<void>;
672
+ /** Alias for `logDebug` */
673
+ log(...args: any[]): void;
674
+ logDebug(...args: any[]): void;
675
+ logError(...args: any[]): void;
676
+ logInfo(...args: any[]): void;
677
+ logWarn(...args: any[]): void;
678
+ /** Expand all parents and optionally scroll into visible area as neccessary.
679
+ * Promise is resolved, when lazy loading and animations are done.
680
+ * @param {object} [options] passed to `setExpanded()`.
681
+ * Defaults to {noAnimation: false, noEvents: false, scrollIntoView: true}
682
+ */
683
+ makeVisible(options?: MakeVisibleOptions): Promise<any>;
684
+ /** Move this node to targetNode. */
685
+ moveTo(targetNode: WunderbaumNode, mode?: InsertNodeType, map?: NodeAnyCallback): void;
686
+ /** Set focus relative to this node and optionally activate.
545
687
  *
546
- * Return `false` to prevent default handling, e.g. activating the node.
547
- * @category Callback
688
+ * 'left' collapses the node if it is expanded, or move to the parent
689
+ * otherwise.
690
+ * 'right' expands the node if it is collapsed, or move to the first
691
+ * child otherwise.
692
+ *
693
+ * @param where 'down', 'first', 'last', 'left', 'parent', 'right', or 'up'.
694
+ * (Alternatively the `event.key` that would normally trigger this move,
695
+ * e.g. `ArrowLeft` = 'left'.
696
+ * @param options
548
697
  */
549
- beforeActivate?: (e: WbActivateEventType) => void;
698
+ navigate(where: string, options?: NavigateOptions): Promise<any>;
699
+ /** Delete this node and all descendants. */
700
+ remove(): void;
701
+ /** Remove all descendants of this node. */
702
+ removeChildren(): void;
703
+ /** Remove all HTML markup from the DOM. */
704
+ removeMarkup(): void;
705
+ protected _getRenderInfo(): any;
706
+ protected _createIcon(parentElem: HTMLElement, replaceChild: HTMLElement | null, showLoading: boolean): HTMLElement | null;
550
707
  /**
551
- *
552
- * @category Callback
708
+ * Create a whole new `<div class="wb-row">` element.
709
+ * @see {@link WunderbaumNode._render}
553
710
  */
554
- change?: (e: WbChangeEventType) => void;
711
+ protected _render_markup(opts: RenderOptions): void;
555
712
  /**
713
+ * Render `node.title`, `.icon` into an existing row.
556
714
  *
557
- * Return `false` to prevent default handling, e.g. activating the node.
558
- * @category Callback
715
+ * @see {@link WunderbaumNode._render}
559
716
  */
560
- click?: (e: WbClickEventType) => void;
717
+ protected _render_data(opts: RenderOptions): void;
561
718
  /**
562
- *
563
- * @category Callback
719
+ * Update row classes to reflect active, focuses, etc.
720
+ * @see {@link WunderbaumNode._render}
564
721
  */
565
- dblclick?: (e: WbClickEventType) => void;
722
+ protected _render_status(opts: RenderOptions): void;
723
+ _render(options?: RenderOptions): void;
566
724
  /**
725
+ * Remove all children, collapse, and set the lazy-flag, so that the lazyLoad
726
+ * event is triggered on next expand.
727
+ */
728
+ resetLazy(): void;
729
+ /** Convert node (or whole branch) into a plain object.
567
730
  *
568
- * Return `false` to prevent default handling, e.g. deactivating the node
569
- * and activating the next.
570
- * @category Callback
731
+ * The result is compatible with node.addChildren().
732
+ *
733
+ * @param include child nodes
734
+ * @param callback(dict, node) is called for every node, in order to allow
735
+ * modifications.
736
+ * Return `false` to ignore this node or `"skip"` to include this node
737
+ * without its children.
738
+ * @see {@link Wunderbaum.toDictArray}.
571
739
  */
572
- deactivate?: (e: WbDeactivateEventType) => void;
573
- /**
740
+ toDict(recursive?: boolean, callback?: NodeToDictCallback): WbNodeData;
741
+ /** Return an option value that has a default, but may be overridden by a
742
+ * callback or a node instance attribute.
574
743
  *
575
- * @category Callback
744
+ * Evaluation sequence:
745
+ *
746
+ * - If `tree.options.<name>` is a callback that returns something, use that.
747
+ * - Else if `node.<name>` is defined, use that.
748
+ * - Else if `tree.types[<node.type>]` is a value, use that.
749
+ * - Else if `tree.options.<name>` is a value, use that.
750
+ * - Else use `defaultValue`.
751
+ *
752
+ * @param name name of the option property (on node and tree)
753
+ * @param defaultValue return this if nothing else matched
754
+ * {@link Wunderbaum.getOption|Wunderbaum.getOption()}
576
755
  */
577
- discard?: (e: WbNodeEventType) => void;
756
+ getOption(name: string, defaultValue?: any): any;
757
+ /** Make sure that this node is visible in the viewport.
758
+ * @see {@link Wunderbaum.scrollTo|Wunderbaum.scrollTo()}
759
+ */
760
+ scrollIntoView(options?: ScrollIntoViewOptions): Promise<void>;
578
761
  /**
579
- *
580
- * @category Callback
762
+ * Activate this node, deactivate previous, send events, activate column and scroll int viewport.
581
763
  */
582
- enhanceTitle?: (e: WbEnhanceTitleEventType) => void;
764
+ setActive(flag?: boolean, options?: SetActiveOptions): Promise<any>;
583
765
  /**
584
- *
585
- * @category Callback
766
+ * Expand or collapse this node.
586
767
  */
587
- error?: (e: WbErrorEventType) => void;
768
+ setExpanded(flag?: boolean, options?: SetExpandedOptions): Promise<void>;
588
769
  /**
589
- *
590
- * Check `e.flag` for status.
591
- * @category Callback
770
+ * Set keyboard focus here.
771
+ * @see {@link setActive}
592
772
  */
593
- focus?: (e: WbTreeEventType) => void;
773
+ setFocus(flag?: boolean): void;
774
+ /** Set a new icon path or class. */
775
+ setIcon(icon: string): void;
776
+ /** Change node's {@link key} and/or {@link refKey}. */
777
+ setKey(key: string | null, refKey: string | null): void;
594
778
  /**
595
- * Fires when the tree markup was created and the initial source data was loaded.
596
- * Typical use cases would be activating a node, setting focus, enabling other
597
- * controls on the page, etc.<br>
598
- * Check `e.error` for status.
599
- * @category Callback
779
+ * @deprecated since v0.3.6: use `update()` instead.
600
780
  */
601
- init?: (e: WbInitEventType) => void;
781
+ setModified(change?: ChangeType): void;
602
782
  /**
783
+ * Trigger a repaint, typically after a status or data change.
603
784
  *
604
- * @category Callback
785
+ * `change` defaults to 'data', which handles modifcations of title, icon,
786
+ * and column content. It can be reduced to 'ChangeType.status' if only
787
+ * active/focus/selected state has changed.
788
+ *
789
+ * This method will eventually call {@link WunderbaumNode._render()} with
790
+ * default options, but may be more consistent with the tree's
791
+ * {@link Wunderbaum.update()} API.
605
792
  */
606
- keydown?: (e: WbKeydownEventType) => void;
793
+ update(change?: ChangeType): void;
607
794
  /**
608
- * Fires when a node that was marked 'lazy', is expanded for the first time.
609
- * Typically we return an endpoint URL or the Promise of a fetch request that
610
- * provides a (potentially nested) list of child nodes.
611
- * @category Callback
795
+ * Return an array of selected nodes.
796
+ * @param stopOnParents only return the topmost selected node (useful with selectMode 'hier')
612
797
  */
613
- lazyLoad?: (e: WbNodeEventType) => void;
798
+ getSelectedNodes(stopOnParents?: boolean): WunderbaumNode[];
799
+ /** Toggle the check/uncheck state. */
800
+ toggleSelected(options?: SetSelectedOptions): TristateType;
801
+ /** Return true if at least on selectable descendant end-node is unselected. @internal */
802
+ _anySelectable(): boolean;
803
+ protected _changeSelectStatusProps(state: TristateType): boolean;
614
804
  /**
615
- * Fires when data was loaded (initial request, reload, or lazy loading),
616
- * after the data is applied and rendered.
617
- * @category Callback
805
+ * Fix selection status, after this node was (de)selected in `selectMode: 'hier'`.
806
+ * This includes (de)selecting all descendants.
618
807
  */
619
- load?: (e: WbNodeEventType) => void;
808
+ fixSelection3AfterClick(opts?: SetSelectedOptions): void;
620
809
  /**
621
- * @category Callback
810
+ * Fix selection status for multi-hier mode.
811
+ * Only end-nodes are considered to update the descendants branch and parents.
812
+ * Should be called after this node has loaded new children or after
813
+ * children have been modified using the API.
622
814
  */
623
- modifyChild?: (e: WbNodeEventType) => void;
815
+ fixSelection3FromEndNodes(opts?: SetSelectedOptions): void;
816
+ /** Modify the check/uncheck state. */
817
+ setSelected(flag?: boolean, options?: SetSelectedOptions): TristateType;
818
+ /** Display node status (ok, loading, error, noData) using styles and a dummy child node. */
819
+ setStatus(status: NodeStatusType, options?: SetStatusOptions): WunderbaumNode | null;
820
+ /** Rename this node. */
821
+ setTitle(title: string): void;
822
+ _sortChildren(cmp: SortCallback, deep: boolean): void;
624
823
  /**
625
- * Fires when data was fetched (initial request, reload, or lazy loading),
626
- * but before the data is applied and rendered.
627
- * Here we can modify and adjust the received data, for example to convert an
628
- * external response to native Wunderbaum syntax.
629
- * @category Callback
824
+ * Sort child list by title or custom criteria.
825
+ * @param {function} cmp custom compare function(a, b) that returns -1, 0, or 1
826
+ * (defaults to sorting by title).
827
+ * @param {boolean} deep pass true to sort all descendant nodes recursively
630
828
  */
631
- receive?: (e: WbReceiveEventType) => void;
829
+ sortChildren(cmp?: SortCallback | null, deep?: boolean): void;
632
830
  /**
633
- * Fires when a node is about to be displayed.
634
- * The default HTML markup is already created, but not yet added to the DOM.
635
- * Now we can tweak the markup, create HTML elements in this node's column
636
- * cells, etc.
637
- * See also `Custom Rendering` for details.
638
- * @category Callback
831
+ * Trigger `modifyChild` event on a parent to signal that a child was modified.
832
+ * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ...
639
833
  */
640
- render?: (e: WbRenderEventType) => void;
834
+ triggerModifyChild(operation: string, child: WunderbaumNode | null, extra?: any): void;
641
835
  /**
836
+ * Trigger `modifyChild` event on node.parent(!).
837
+ * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ...
838
+ * @param {object} [extra]
839
+ */
840
+ triggerModify(operation: string, extra?: any): void;
841
+ /**
842
+ * Call `callback(node)` for all descendant nodes in hierarchical order (depth-first, pre-order).
642
843
  *
643
- * @category Callback
844
+ * Stop iteration, if fn() returns false. Skip current branch, if fn()
845
+ * returns "skip".<br>
846
+ * Return false if iteration was stopped.
847
+ *
848
+ * @param {function} callback the callback function.
849
+ * Return false to stop iteration, return "skip" to skip this node and
850
+ * its children only.
851
+ * @see {@link IterableIterator<WunderbaumNode>}, {@link Wunderbaum.visit}.
644
852
  */
645
- renderStatusNode?: (e: WbRenderEventType) => void;
853
+ visit(callback: NodeVisitCallback, includeSelf?: boolean): NodeVisitResponse;
854
+ /** Call fn(node) for all parent nodes, bottom-up, including invisible system root.<br>
855
+ * Stop iteration, if callback() returns false.<br>
856
+ * Return false if iteration was stopped.
857
+ *
858
+ * @param callback the callback function. Return false to stop iteration
859
+ */
860
+ visitParents(callback: (node: WunderbaumNode) => boolean | void, includeSelf?: boolean): boolean;
646
861
  /**
862
+ * Call fn(node) for all sibling nodes.<br>
863
+ * Stop iteration, if fn() returns false.<br>
864
+ * Return false if iteration was stopped.
647
865
  *
648
- * Check `e.flag` for status.
649
- * @category Callback
866
+ * @param {function} fn the callback function.
867
+ * Return false to stop iteration.
650
868
  */
651
- select?: (e: WbNodeEventType) => void;
869
+ visitSiblings(callback: (node: WunderbaumNode) => boolean | void, includeSelf?: boolean): boolean;
652
870
  /**
653
- * Fires when the viewport content was updated, after scroling, expanding etc.
654
- * @category Callback
871
+ * [ext-filter] Return true if this node is matched by current filter (or no filter is active).
655
872
  */
656
- update?: (e: WbTreeEventType) => void;
873
+ isMatched(): boolean;
657
874
  }
658
875
  }
659
- declare module "wb_node" {
876
+ declare module "wb_options" {
660
877
  /*!
661
- * Wunderbaum - wunderbaum_node
878
+ * Wunderbaum - utils
662
879
  * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license.
663
880
  * @VERSION, @DATE (https://github.com/mar10/wunderbaum)
664
881
  */
665
- import "./wunderbaum.scss";
666
- import { Wunderbaum } from "wunderbaum";
667
- import { AddChildrenOptions, InsertNodeType, ApplyCommandOptions, ApplyCommandType, ChangeType, ExpandAllOptions, MakeVisibleOptions, MatcherCallback, NavigateOptions, NodeAnyCallback, NodeStatusType, NodeStringCallback, NodeVisitCallback, NodeVisitResponse, RenderOptions, ScrollIntoViewOptions, SetActiveOptions, SetExpandedOptions, SetSelectedOptions, SetStatusOptions, SortCallback } from "types";
668
- import { WbNodeData } from "wb_options";
882
+ import { BoolOptionResolver, ColumnDefinitionList, DndOptionsType, NavModeEnum, NodeTypeDefinitionMap, SelectModeType, WbActivateEventType, WbChangeEventType, WbClickEventType, WbDeactivateEventType, WbEnhanceTitleEventType, WbErrorEventType, WbInitEventType, WbKeydownEventType, WbNodeData, WbNodeEventType, WbReceiveEventType, WbRenderEventType, WbTreeEventType } from "types";
669
883
  /**
670
- * A single tree node.
884
+ * Available options for [[Wunderbaum]].
671
885
  *
672
- * **NOTE:** <br>
673
- * Generally you should not modify properties directly, since this may break
674
- * the internal bookkeeping.
886
+ * Options are passed to the constructor as plain object:
887
+ *
888
+ * ```js
889
+ * const tree = new mar10.Wunderbaum({
890
+ * id: "demo",
891
+ * element: document.getElementById("demo-tree"),
892
+ * source: "url/of/data/request",
893
+ * ...
894
+ * });
895
+ * ```
896
+ *
897
+ * Event handlers are also passed as callbacks
898
+ *
899
+ * ```js
900
+ * const tree = new mar10.Wunderbaum({
901
+ * ...
902
+ * init: (e) => {
903
+ * console.log(`Tree ${e.tree} was initialized and loaded.`)
904
+ * },
905
+ * activate: (e) => {
906
+ * console.log(`Node ${e.node} was activated.`)
907
+ * },
908
+ * ...
909
+ * });
910
+ * ```
675
911
  */
676
- export class WunderbaumNode {
677
- static sequence: number;
678
- /** Reference to owning tree. */
679
- tree: Wunderbaum;
680
- /** Parent node (null for the invisible root node `tree.root`). */
681
- parent: WunderbaumNode;
682
- /** Name of the node.
683
- * @see Use {@link setTitle} to modify. */
684
- title: string;
685
- /** Unique key. Passed with constructor or defaults to `SEQUENCE`.
686
- * @see Use {@link setKey} to modify. */
687
- readonly key: string;
688
- /** Reference key. Unlike {@link key}, a `refKey` may occur multiple
689
- * times within a tree (in this case we have 'clone nodes').
690
- * @see Use {@link setKey} to modify.
691
- */
692
- readonly refKey: string | undefined;
693
- children: WunderbaumNode[] | null;
694
- checkbox?: boolean;
695
- /** If true, (in grid mode) no cells are rendered, except for the node title.*/
696
- colspan?: boolean;
697
- icon?: boolean | string;
698
- lazy: boolean;
699
- /** Expansion state.
700
- * @see {@link isExpandable}, {@link isExpanded}, {@link setExpanded}. */
701
- expanded: boolean;
702
- /** Selection state.
703
- * @see {@link isSelected}, {@link setSelected}. */
704
- selected: boolean;
705
- type?: string;
706
- tooltip?: string;
707
- /** Additional classes added to `div.wb-row`.
708
- * @see {@link hasClass}, {@link setClass}. */
709
- classes: Set<string> | null;
710
- /** Custom data that was passed to the constructor */
711
- data: any;
712
- statusNodeType?: string;
713
- _isLoading: boolean;
714
- _requestId: number;
715
- _errorInfo: any | null;
716
- _partsel: boolean;
717
- _partload: boolean;
718
- match?: boolean;
719
- subMatchCount?: number;
720
- subMatchBadge?: HTMLElement;
721
- /** @internal */
722
- titleWithHighlight?: string;
723
- _filterAutoExpanded?: boolean;
724
- _rowIdx: number | undefined;
725
- _rowElem: HTMLDivElement | undefined;
726
- constructor(tree: Wunderbaum, parent: WunderbaumNode, data: any);
912
+ export interface WunderbaumOptions {
727
913
  /**
728
- * Return readable string representation for this instance.
729
- * @internal
914
+ * The target `div` element (or selector) that shall become a Wunderbaum.
730
915
  */
731
- toString(): string;
916
+ element: string | HTMLDivElement;
732
917
  /**
733
- * Iterate all descendant nodes depth-first, pre-order using `for ... of ...` syntax.
734
- * More concise, but slightly slower than {@link WunderbaumNode.visit}.
918
+ * The identifier of this tree. Used to reference the instance, especially
919
+ * when multiple trees are present (e.g. `tree = mar10.Wunderbaum.getTree("demo")`).
735
920
  *
736
- * Example:
737
- * ```js
738
- * for(const n of node) {
739
- * ...
740
- * }
741
- * ```
742
- */
743
- [Symbol.iterator](): IterableIterator<WunderbaumNode>;
744
- /** Call event handler if defined in tree.options.
745
- * Example:
746
- * ```js
747
- * node._callEvent("edit.beforeEdit", {foo: 42})
748
- * ```
921
+ * Default: `"wb_" + COUNTER`.
749
922
  */
750
- _callEvent(type: string, extra?: any): any;
923
+ id?: string;
751
924
  /**
752
- * Append (or insert) a list of child nodes.
753
- *
754
- * Tip: pass `{ before: 0 }` to prepend new nodes as first children.
925
+ * Define the initial tree data. Typically a URL of an endpoint that serves
926
+ * a JSON formatted structure, but also a callback, Promise, or static data
927
+ * is allowed.
755
928
  *
756
- * @returns first child added
929
+ * Default: `{}`.
757
930
  */
758
- addChildren(nodeData: WbNodeData | WbNodeData[], options?: AddChildrenOptions): WunderbaumNode;
931
+ source?: string | Array<WbNodeData>;
759
932
  /**
760
- * Append or prepend a node, or append a child node.
761
- *
762
- * This a convenience function that calls addChildren()
933
+ * Define shared attributes for multiple nodes of the same type.
934
+ * This allows for more compact data models. Type definitions can be passed
935
+ * as tree option, or be part of a `source` response.
763
936
  *
764
- * @param {NodeData} node node definition
765
- * @param [mode=child] 'before', 'after', 'firstChild', or 'child' ('over' is a synonym for 'child')
766
- * @returns new node
937
+ * Default: `{}`.
767
938
  */
768
- addNode(nodeData: WbNodeData, mode?: InsertNodeType): WunderbaumNode;
939
+ types?: NodeTypeDefinitionMap;
769
940
  /**
770
- * Apply a modification (or navigation) operation.
771
- *
772
- * @see {@link Wunderbaum.applyCommand}
941
+ * A list of maps that define column headers. If this option is set,
942
+ * Wunderbaum becomes a treegrid control instead of a plain tree.
943
+ * Column definitions can be passed as tree option, or be part of a `source`
944
+ * response.
945
+ * Default: `[]` meaning this is a plain tree.
773
946
  */
774
- applyCommand(cmd: ApplyCommandType, options: ApplyCommandOptions): any;
947
+ columns?: ColumnDefinitionList;
775
948
  /**
776
- * Add/remove one or more classes to `<div class='wb-row'>`.
777
- *
778
- * This also maintains `node.classes`, so the class will survive a re-render.
779
- *
780
- * @param className one or more class names. Multiple classes can be passed
781
- * as space-separated string, array of strings, or set of strings.
949
+ * If true, add a `wb-skeleton` class to all nodes, that will result in a
950
+ * 'glow' effect. Typically used with initial dummy nodes, while loading the
951
+ * real data.
952
+ * Default: false.
782
953
  */
783
- setClass(className: string | string[] | Set<string>, flag?: boolean): void;
784
- /** Call `setExpanded()` on all descendant nodes. */
785
- expandAll(flag?: boolean, options?: ExpandAllOptions): Promise<void>;
954
+ skeleton?: boolean;
786
955
  /**
787
- * Find all descendant nodes that match condition (excluding self).
788
- *
789
- * If `match` is a string, search for exact node title.
790
- * If `match` is a RegExp expression, apply it to node.title, using
791
- * [RegExp.test()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test).
792
- * If `match` is a callback, match all nodes for that the callback(node) returns true.
793
- *
794
- * Returns an empty array if no nodes were found.
795
- *
796
- * Examples:
797
- * ```js
798
- * // Match all node titles that match exactly 'Joe':
799
- * nodeList = node.findAll("Joe")
800
- * // Match all node titles that start with 'Joe' case sensitive:
801
- * nodeList = node.findAll(/^Joe/)
802
- * // Match all node titles that contain 'oe', case insensitive:
803
- * nodeList = node.findAll(/oe/i)
804
- * // Match all nodes with `data.price` >= 99:
805
- * nodeList = node.findAll((n) => {
806
- * return n.data.price >= 99;
807
- * })
808
- * ```
956
+ * Translation map for some system messages.
809
957
  */
810
- findAll(match: string | RegExp | MatcherCallback): WunderbaumNode[];
811
- /** Return the direct child with a given key, index or null. */
812
- findDirectChild(ptr: number | string | WunderbaumNode): WunderbaumNode | null;
958
+ strings?: any;
813
959
  /**
814
- * Find first descendant node that matches condition (excluding self) or null.
815
- *
816
- * @see {@link WunderbaumNode.findAll} for examples.
817
- */
818
- findFirst(match: string | RegExp | MatcherCallback): WunderbaumNode | null;
819
- /** Find a node relative to self.
820
- *
821
- * @see {@link Wunderbaum.findRelatedNode|tree.findRelatedNode()}
960
+ * 0:quiet, 1:errors, 2:warnings, 3:info, 4:verbose
961
+ * Default: 3 (4 in local debug environment)
822
962
  */
823
- findRelatedNode(where: string, includeHidden?: boolean): any;
963
+ debugLevel?: number;
824
964
  /**
825
- * Iterator version of {@link WunderbaumNode.format}.
965
+ * Number of levels that are forced to be expanded, and have no expander icon.
966
+ * E.g. 1 would keep all toplevel nodes expanded.
967
+ * Default: 0
826
968
  */
827
- format_iter(name_cb?: NodeStringCallback, connectors?: string[]): IterableIterator<string>;
969
+ minExpandLevel?: number;
828
970
  /**
829
- * Return a multiline string representation of a node/subnode hierarchy.
830
- * Mostly useful for debugging.
831
- *
832
- * Example:
833
- * ```js
834
- * console.info(tree.getActiveNode().format((n)=>n.title));
835
- * ```
836
- * logs
837
- * ```
838
- * Books
839
- * ├─ Art of War
840
- * ╰─ Don Quixote
841
- * ```
842
- * @see {@link WunderbaumNode.format_iter}
843
- */
844
- format(name_cb?: NodeStringCallback, connectors?: string[]): string;
845
- /** Return the `<span class='wb-col'>` element with a given index or id.
846
- * @returns {WunderbaumNode | null}
847
- */
848
- getColElem(colIdx: number | string): HTMLSpanElement;
849
- /** Return the first child node or null.
850
- * @returns {WunderbaumNode | null}
851
- */
852
- getFirstChild(): WunderbaumNode;
853
- /** Return the last child node or null.
854
- * @returns {WunderbaumNode | null}
855
- */
856
- getLastChild(): WunderbaumNode;
857
- /** Return node depth (starting with 1 for top level nodes). */
858
- getLevel(): number;
859
- /** Return the successive node (under the same parent) or null. */
860
- getNextSibling(): WunderbaumNode | null;
861
- /** Return the parent node (null for the system root node). */
862
- getParent(): WunderbaumNode | null;
863
- /** Return an array of all parent nodes (top-down).
864
- * @param includeRoot Include the invisible system root node.
865
- * @param includeSelf Include the node itself.
866
- */
867
- getParentList(includeRoot?: boolean, includeSelf?: boolean): any[];
868
- /** Return a string representing the hierachical node path, e.g. "a/b/c".
869
- * @param includeSelf
870
- * @param node property name or callback
871
- * @param separator
872
- */
873
- getPath(includeSelf?: boolean, part?: keyof WunderbaumNode | NodeAnyCallback, separator?: string): string;
874
- /** Return the preceeding node (under the same parent) or null. */
875
- getPrevSibling(): WunderbaumNode | null;
876
- /** Return true if node has children.
877
- * Return undefined if not sure, i.e. the node is lazy and not yet loaded.
878
- */
879
- hasChildren(): boolean;
880
- /** Return true if node has className set. */
881
- hasClass(className: string): boolean;
882
- /** Return true if this node is the currently active tree node. */
883
- isActive(): boolean;
884
- /** Return true if this node is a direct or indirect parent of `other`.
885
- * (See also [[isParentOf]].)
886
- */
887
- isAncestorOf(other: WunderbaumNode): boolean;
888
- /** Return true if this node is a **direct** subnode of `other`.
889
- * (See also [[isDescendantOf]].)
890
- */
891
- isChildOf(other: WunderbaumNode): boolean;
892
- /** Return true if this node's title spans all columns, i.e. the node has no
893
- * grid cells.
894
- */
895
- isColspan(): boolean;
896
- /** Return true if this node is a direct or indirect subnode of `other`.
897
- * (See also [[isChildOf]].)
898
- */
899
- isDescendantOf(other: WunderbaumNode): boolean;
900
- /** Return true if this node has children, i.e. the node is generally expandable.
901
- * If `andCollapsed` is set, we also check if this node is collapsed, i.e.
902
- * an expand operation is currently possible.
903
- */
904
- isExpandable(andCollapsed?: boolean): boolean;
905
- /** Return true if this node is currently in edit-title mode. */
906
- isEditing(): boolean;
907
- /** Return true if this node is currently expanded. */
908
- isExpanded(): boolean;
909
- /** Return true if this node is the first node of its parent's children. */
910
- isFirstSibling(): boolean;
911
- /** Return true if this node is the last node of its parent's children. */
912
- isLastSibling(): boolean;
913
- /** Return true if this node is lazy (even if data was already loaded) */
914
- isLazy(): boolean;
915
- /** Return true if node is lazy and loaded. For non-lazy nodes always return true. */
916
- isLoaded(): boolean;
917
- /** Return true if node is currently loading, i.e. a GET request is pending. */
918
- isLoading(): boolean;
919
- /** Return true if this node is a temporarily generated status node of type 'paging'. */
920
- isPagingNode(): boolean;
921
- /** Return true if this node is a **direct** parent of `other`.
922
- * (See also [[isAncestorOf]].)
971
+ * If true, allow to expand parent nodes, even if `node.children` conatains
972
+ * an empty array (`[]`). This is the the behavior of macOS Finder, for example.
973
+ * Default: false
923
974
  */
924
- isParentOf(other: WunderbaumNode): boolean;
925
- /** (experimental) Return true if this node is partially loaded. */
926
- isPartload(): boolean;
927
- /** Return true if this node is partially selected (tri-state). */
928
- isPartsel(): boolean;
929
- /** Return true if this node has DOM representaion, i.e. is displayed in the viewport. */
930
- isRendered(): boolean;
931
- /** Return true if this node is the (invisible) system root node.
932
- * (See also [[isTopLevel()]].)
975
+ emptyChildListExpandable?: boolean;
976
+ /**
977
+ * Height of a node row div.
978
+ * Default: 22
933
979
  */
934
- isRootNode(): boolean;
935
- /** Return true if this node is selected, i.e. the checkbox is set. */
936
- isSelected(): boolean;
937
- /** Return true if this node is a temporarily generated system node like
938
- * 'loading', 'paging', or 'error' (node.statusNodeType contains the type).
980
+ rowHeightPx?: number;
981
+ /**
982
+ * Collapse siblings when a node is expanded.
983
+ * Default: false
939
984
  */
940
- isStatusNode(): boolean;
941
- /** Return true if this a top level node, i.e. a direct child of the (invisible) system root node. */
942
- isTopLevel(): boolean;
943
- /** Return true if node is marked lazy but not yet loaded.
944
- * For non-lazy nodes always return false.
985
+ autoCollapse?: boolean;
986
+ /**
987
+ * HTMLElement that receives the top nodes breadcrumb.
988
+ * Default: undefined
945
989
  */
946
- isUnloaded(): boolean;
947
- /** Return true if all parent nodes are expanded. Note: this does not check
948
- * whether the node is scrolled into the visible part of the screen or viewport.
990
+ connectTopBreadcrumb?: HTMLElement;
991
+ /**
992
+ * Default: NavModeEnum.startRow
949
993
  */
950
- isVisible(): boolean;
951
- protected _loadSourceObject(source: any, level?: number): void;
952
- _fetchWithOptions(source: any): Promise<any>;
953
- /** Download data from the cloud, then call `.update()`. */
954
- load(source: any): Promise<void>;
955
- /**Load content of a lazy node. */
956
- loadLazy(forceReload?: boolean): Promise<void>;
957
- /** Alias for `logDebug` */
958
- log(...args: any[]): void;
959
- logDebug(...args: any[]): void;
960
- logError(...args: any[]): void;
961
- logInfo(...args: any[]): void;
962
- logWarn(...args: any[]): void;
963
- /** Expand all parents and optionally scroll into visible area as neccessary.
964
- * Promise is resolved, when lazy loading and animations are done.
965
- * @param {object} [options] passed to `setExpanded()`.
966
- * Defaults to {noAnimation: false, noEvents: false, scrollIntoView: true}
994
+ navigationModeOption?: NavModeEnum;
995
+ /**
996
+ * Show/hide header (default: null)
997
+ * null: assume false for plain tree and true for grids.
998
+ * string: use text as header (only for plain trees)
999
+ * true: display a header (use tree's id as text for plain trees)
1000
+ * false: do not display a header
967
1001
  */
968
- makeVisible(options?: MakeVisibleOptions): Promise<any>;
969
- /** Move this node to targetNode. */
970
- moveTo(targetNode: WunderbaumNode, mode?: InsertNodeType, map?: NodeAnyCallback): void;
971
- /** Set focus relative to this node and optionally activate.
972
- *
973
- * 'left' collapses the node if it is expanded, or move to the parent
974
- * otherwise.
975
- * 'right' expands the node if it is collapsed, or move to the first
976
- * child otherwise.
1002
+ header?: boolean | string | null;
1003
+ /**
977
1004
  *
978
- * @param where 'down', 'first', 'last', 'left', 'parent', 'right', or 'up'.
979
- * (Alternatively the `event.key` that would normally trigger this move,
980
- * e.g. `ArrowLeft` = 'left'.
981
- * @param options
982
1005
  */
983
- navigate(where: string, options?: NavigateOptions): Promise<any>;
984
- /** Delete this node and all descendants. */
985
- remove(): void;
986
- /** Remove all descendants of this node. */
987
- removeChildren(): void;
988
- /** Remove all HTML markup from the DOM. */
989
- removeMarkup(): void;
990
- protected _getRenderInfo(): any;
991
- protected _createIcon(parentElem: HTMLElement, replaceChild: HTMLElement | null, showLoading: boolean): HTMLElement | null;
1006
+ showSpinner?: boolean;
992
1007
  /**
993
- * Create a whole new `<div class="wb-row">` element.
994
- * @see {@link WunderbaumNode.render}
1008
+ * If true, render a checkbox before the node tile to allow selection with the
1009
+ * mouse.
1010
+ * Default: false.
995
1011
  */
996
- protected _render_markup(opts: RenderOptions): void;
1012
+ checkbox?: boolean | "radio" | BoolOptionResolver;
997
1013
  /**
998
- * Render `node.title`, `.icon` into an existing row.
999
- *
1000
- * @see {@link WunderbaumNode.render}
1014
+ * Default: true
1001
1015
  */
1002
- protected _render_data(opts: RenderOptions): void;
1016
+ enabled?: boolean;
1003
1017
  /**
1004
- * Update row classes to reflect active, focuses, etc.
1005
- * @see {@link WunderbaumNode.render}
1018
+ * Default: false
1006
1019
  */
1007
- protected _render_status(opts: RenderOptions): void;
1020
+ fixedCol?: boolean;
1008
1021
  /**
1009
- * Create or update node's markup.
1010
- *
1011
- * `options.change` defaults to ChangeType.data, which updates the title,
1012
- * icon, and status. It also triggers the `render` event, that lets the user
1013
- * create or update the content of embeded cell elements.
1014
- *
1015
- * If only the status or other class-only modifications have changed,
1016
- * `options.change` should be set to ChangeType.status instead for best
1017
- * efficiency.
1018
- *
1019
- * Calling `setModified` instead may be a better alternative.
1020
- * @see {@link WunderbaumNode.setModified}
1022
+ * Default: "multi"
1021
1023
  */
1022
- render(options?: RenderOptions): void;
1024
+ selectMode?: SelectModeType;
1023
1025
  /**
1024
- * Remove all children, collapse, and set the lazy-flag, so that the lazyLoad
1025
- * event is triggered on next expand.
1026
+ * Default: true
1026
1027
  */
1027
- resetLazy(): void;
1028
- /** Convert node (or whole branch) into a plain object.
1028
+ quicksearch?: boolean;
1029
+ dnd?: DndOptionsType;
1030
+ edit?: any;
1031
+ filter?: any;
1032
+ grid?: any;
1033
+ /**
1029
1034
  *
1030
- * The result is compatible with node.addChildren().
1035
+ * @category Callback
1036
+ */
1037
+ activate?: (e: WbActivateEventType) => void;
1038
+ /**
1031
1039
  *
1032
- * @param include child nodes
1033
- * @param callback(dict, node) is called for every node, in order to allow
1034
- * modifications.
1035
- * Return `false` to ignore this node or `"skip"` to include this node
1036
- * without its children.
1037
- * @returns {NodeData}
1040
+ * Return `false` to prevent default handling, e.g. activating the node.
1041
+ * @category Callback
1038
1042
  */
1039
- toDict(recursive?: boolean, callback?: any): any;
1040
- /** Return an option value that has a default, but may be overridden by a
1041
- * callback or a node instance attribute.
1043
+ beforeActivate?: (e: WbActivateEventType) => void;
1044
+ /**
1042
1045
  *
1043
- * Evaluation sequence:
1046
+ * @category Callback
1047
+ */
1048
+ change?: (e: WbChangeEventType) => void;
1049
+ /**
1044
1050
  *
1045
- * - If `tree.options.<name>` is a callback that returns something, use that.
1046
- * - Else if `node.<name>` is defined, use that.
1047
- * - Else if `tree.types[<node.type>]` is a value, use that.
1048
- * - Else if `tree.options.<name>` is a value, use that.
1049
- * - Else use `defaultValue`.
1051
+ * Return `false` to prevent default handling, e.g. activating the node.
1052
+ * @category Callback
1053
+ */
1054
+ click?: (e: WbClickEventType) => void;
1055
+ /**
1050
1056
  *
1051
- * @param name name of the option property (on node and tree)
1052
- * @param defaultValue return this if nothing else matched
1053
- * {@link Wunderbaum.getOption|Wunderbaum.getOption()}
1057
+ * @category Callback
1054
1058
  */
1055
- getOption(name: string, defaultValue?: any): any;
1056
- /** Make sure that this node is visible in the viewport.
1057
- * @see {@link Wunderbaum.scrollTo|Wunderbaum.scrollTo()}
1059
+ dblclick?: (e: WbClickEventType) => void;
1060
+ /**
1061
+ *
1062
+ * Return `false` to prevent default handling, e.g. deactivating the node
1063
+ * and activating the next.
1064
+ * @category Callback
1058
1065
  */
1059
- scrollIntoView(options?: ScrollIntoViewOptions): Promise<void>;
1066
+ deactivate?: (e: WbDeactivateEventType) => void;
1060
1067
  /**
1061
- * Activate this node, deactivate previous, send events, activate column and scroll int viewport.
1068
+ *
1069
+ * @category Callback
1062
1070
  */
1063
- setActive(flag?: boolean, options?: SetActiveOptions): Promise<any>;
1071
+ discard?: (e: WbNodeEventType) => void;
1064
1072
  /**
1065
- * Expand or collapse this node.
1073
+ *
1074
+ * @category Callback
1066
1075
  */
1067
- setExpanded(flag?: boolean, options?: SetExpandedOptions): Promise<void>;
1076
+ enhanceTitle?: (e: WbEnhanceTitleEventType) => void;
1068
1077
  /**
1069
- * Set keyboard focus here.
1070
- * @see {@link setActive}
1078
+ *
1079
+ * @category Callback
1071
1080
  */
1072
- setFocus(flag?: boolean): void;
1073
- /** Set a new icon path or class. */
1074
- setIcon(icon: string): void;
1075
- /** Change node's {@link key} and/or {@link refKey}. */
1076
- setKey(key: string | null, refKey: string | null): void;
1081
+ error?: (e: WbErrorEventType) => void;
1077
1082
  /**
1078
- * Trigger a repaint, typically after a status or data change.
1079
1083
  *
1080
- * `change` defaults to 'data', which handles modifcations of title, icon,
1081
- * and column content. It can be reduced to 'ChangeType.status' if only
1082
- * active/focus/selected state has changed.
1084
+ * Check `e.flag` for status.
1085
+ * @category Callback
1086
+ */
1087
+ focus?: (e: WbTreeEventType) => void;
1088
+ /**
1089
+ * Fires when the tree markup was created and the initial source data was loaded.
1090
+ * Typical use cases would be activating a node, setting focus, enabling other
1091
+ * controls on the page, etc.<br>
1092
+ * Check `e.error` for status.
1093
+ * @category Callback
1094
+ */
1095
+ init?: (e: WbInitEventType) => void;
1096
+ /**
1083
1097
  *
1084
- * This method will eventually call {@link WunderbaumNode.render()} with
1085
- * default options, but may be more consistent with the tree's
1086
- * {@link Wunderbaum.setModified()} API.
1098
+ * @category Callback
1087
1099
  */
1088
- setModified(change?: ChangeType): void;
1089
- /** Modify the check/uncheck state. */
1090
- setSelected(flag?: boolean, options?: SetSelectedOptions): void;
1091
- /** Display node status (ok, loading, error, noData) using styles and a dummy child node. */
1092
- setStatus(status: NodeStatusType, options?: SetStatusOptions): WunderbaumNode | null;
1093
- /** Rename this node. */
1094
- setTitle(title: string): void;
1095
- _sortChildren(cmp: SortCallback, deep: boolean): void;
1100
+ keydown?: (e: WbKeydownEventType) => void;
1096
1101
  /**
1097
- * Sort child list by title or custom criteria.
1098
- * @param {function} cmp custom compare function(a, b) that returns -1, 0, or 1
1099
- * (defaults to sorting by title).
1100
- * @param {boolean} deep pass true to sort all descendant nodes recursively
1102
+ * Fires when a node that was marked 'lazy', is expanded for the first time.
1103
+ * Typically we return an endpoint URL or the Promise of a fetch request that
1104
+ * provides a (potentially nested) list of child nodes.
1105
+ * @category Callback
1101
1106
  */
1102
- sortChildren(cmp?: SortCallback | null, deep?: boolean): void;
1107
+ lazyLoad?: (e: WbNodeEventType) => void;
1103
1108
  /**
1104
- * Trigger `modifyChild` event on a parent to signal that a child was modified.
1105
- * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ...
1109
+ * Fires when data was loaded (initial request, reload, or lazy loading),
1110
+ * after the data is applied and rendered.
1111
+ * @category Callback
1106
1112
  */
1107
- triggerModifyChild(operation: string, child: WunderbaumNode | null, extra?: any): void;
1113
+ load?: (e: WbNodeEventType) => void;
1108
1114
  /**
1109
- * Trigger `modifyChild` event on node.parent(!).
1110
- * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ...
1111
- * @param {object} [extra]
1115
+ * @category Callback
1112
1116
  */
1113
- triggerModify(operation: string, extra?: any): void;
1117
+ modifyChild?: (e: WbNodeEventType) => void;
1114
1118
  /**
1115
- * Call `callback(node)` for all child nodes in hierarchical order (depth-first, pre-order).
1116
- *
1117
- * Stop iteration, if fn() returns false. Skip current branch, if fn()
1118
- * returns "skip".<br>
1119
- * Return false if iteration was stopped.
1120
- *
1121
- * @param {function} callback the callback function.
1122
- * Return false to stop iteration, return "skip" to skip this node and
1123
- * its children only.
1124
- * @see {@link IterableIterator<WunderbaumNode>}, {@link Wunderbaum.visit}.
1119
+ * Fires when data was fetched (initial request, reload, or lazy loading),
1120
+ * but before the data is applied and rendered.
1121
+ * Here we can modify and adjust the received data, for example to convert an
1122
+ * external response to native Wunderbaum syntax.
1123
+ * @category Callback
1125
1124
  */
1126
- visit(callback: NodeVisitCallback, includeSelf?: boolean): NodeVisitResponse;
1127
- /** Call fn(node) for all parent nodes, bottom-up, including invisible system root.<br>
1128
- * Stop iteration, if callback() returns false.<br>
1129
- * Return false if iteration was stopped.
1125
+ receive?: (e: WbReceiveEventType) => void;
1126
+ /**
1127
+ * Fires when a node is about to be displayed.
1128
+ * The default HTML markup is already created, but not yet added to the DOM.
1129
+ * Now we can tweak the markup, create HTML elements in this node's column
1130
+ * cells, etc.
1131
+ * See also `Custom Rendering` for details.
1132
+ * @category Callback
1133
+ */
1134
+ render?: (e: WbRenderEventType) => void;
1135
+ /**
1130
1136
  *
1131
- * @param callback the callback function. Return false to stop iteration
1137
+ * @category Callback
1132
1138
  */
1133
- visitParents(callback: (node: WunderbaumNode) => boolean | void, includeSelf?: boolean): boolean;
1139
+ renderStatusNode?: (e: WbRenderEventType) => void;
1134
1140
  /**
1135
- * Call fn(node) for all sibling nodes.<br>
1136
- * Stop iteration, if fn() returns false.<br>
1137
- * Return false if iteration was stopped.
1138
1141
  *
1139
- * @param {function} fn the callback function.
1140
- * Return false to stop iteration.
1142
+ * Check `e.flag` for status.
1143
+ * @category Callback
1141
1144
  */
1142
- visitSiblings(callback: (node: WunderbaumNode) => boolean | void, includeSelf?: boolean): boolean;
1145
+ select?: (e: WbNodeEventType) => void;
1143
1146
  /**
1144
- * [ext-filter] Return true if this node is matched by current filter (or no filter is active).
1147
+ * Fires when the viewport content was updated, after scroling, expanding etc.
1148
+ * @category Callback
1145
1149
  */
1146
- isMatched(): boolean;
1150
+ update?: (e: WbTreeEventType) => void;
1147
1151
  }
1148
1152
  }
1149
1153
  declare module "types" {
@@ -1154,6 +1158,8 @@ declare module "types" {
1154
1158
  */
1155
1159
  import { WunderbaumNode } from "wb_node";
1156
1160
  import { Wunderbaum } from "wunderbaum";
1161
+ /** A value that can either be true, false, or undefined. */
1162
+ export type TristateType = boolean | undefined;
1157
1163
  /** Passed to `find...()` methods. Should return true if node matches. */
1158
1164
  export type MatcherCallback = (node: WunderbaumNode) => boolean;
1159
1165
  /** Passed to `sortChildren()` methods. Should return -1, 0, or 1. */
@@ -1162,10 +1168,30 @@ declare module "types" {
1162
1168
  export type BoolOptionResolver = (node: WunderbaumNode) => boolean;
1163
1169
  /** When set as option, called when the value is needed (e.g. `icon` type definition). */
1164
1170
  export type BoolOrStringOptionResolver = (node: WunderbaumNode) => boolean | string;
1171
+ /** A callback that receives a node instance and returns an arbitrary value type. */
1165
1172
  export type NodeAnyCallback = (node: WunderbaumNode) => any;
1173
+ /** A callback that receives a node instance and returns a string value. */
1166
1174
  export type NodeStringCallback = (node: WunderbaumNode) => string;
1167
- export type NodeVisitResponse = "skip" | boolean | void;
1175
+ /** A callback that receives a node instance and returns an iteration modifier. */
1168
1176
  export type NodeVisitCallback = (node: WunderbaumNode) => NodeVisitResponse;
1177
+ /** A callback that receives a node instance and returns a string value. */
1178
+ export type NodeVisitResponse = "skip" | boolean | void;
1179
+ /** A callback that receives a node-data dictionary and a node instance and returns an iteration modifier. */
1180
+ export type NodeToDictCallback = (dict: WbNodeData, node: WunderbaumNode) => NodeVisitResponse;
1181
+ /** A callback that receives a node instance and returns a string value. */
1182
+ export type NodeSelectCallback = (node: WunderbaumNode) => boolean | void;
1183
+ /** A plain object (dictionary) that represents a node instance. */
1184
+ export interface WbNodeData {
1185
+ title: string;
1186
+ key?: string;
1187
+ refKey?: string;
1188
+ expanded?: boolean;
1189
+ selected?: boolean;
1190
+ checkbox?: boolean | string;
1191
+ colspan?: boolean;
1192
+ children?: Array<WbNodeData>;
1193
+ treeId?: string;
1194
+ }
1169
1195
  export interface WbTreeEventType {
1170
1196
  /** Name of the event. */
1171
1197
  type: string;
@@ -1225,8 +1251,6 @@ declare module "types" {
1225
1251
  event: KeyboardEvent;
1226
1252
  node: WunderbaumNode;
1227
1253
  info: WbEventInfo;
1228
- /** Canical name of the key including modifiers. @see {@link util.eventToString} */
1229
- eventName: string;
1230
1254
  }
1231
1255
  export interface WbInitEventType extends WbTreeEventType {
1232
1256
  error?: any;
@@ -1237,7 +1261,7 @@ declare module "types" {
1237
1261
  export interface WbRenderEventType extends WbNodeEventType {
1238
1262
  /**
1239
1263
  * True if the node's markup was not yet created. In this case the render
1240
- * event should create embeddeb input controls (in addition to update the
1264
+ * event should create embedded input controls (in addition to update the
1241
1265
  * values according to to current node data).
1242
1266
  */
1243
1267
  isNew: boolean;
@@ -1264,7 +1288,7 @@ declare module "types" {
1264
1288
  */
1265
1289
  export interface NodeTypeDefinition {
1266
1290
  /** En/disable checkbox for matching nodes. */
1267
- checkbox?: boolean | BoolOrStringOptionResolver;
1291
+ checkbox?: boolean | "radio" | BoolOrStringOptionResolver;
1268
1292
  /** Optional class names that are added to all `div.wb-row` elements of matching nodes. */
1269
1293
  classes?: string;
1270
1294
  /** Only show title and hide other columns if any. */
@@ -1301,8 +1325,14 @@ declare module "types" {
1301
1325
  * Default: `4px`.
1302
1326
  */
1303
1327
  minWidth?: string | number;
1304
- /** Optional class names that are added to all `span.wb-col` elements of that column.*/
1328
+ /** Optional class names that are added to all `span.wb-col` header AND data
1329
+ * elements of that column.
1330
+ */
1305
1331
  classes?: string;
1332
+ /** If `headerClasses` is a string, it will be used for the header element,
1333
+ * while `classes` is used for data elements.
1334
+ */
1335
+ headerClasses?: string;
1306
1336
  /** Optional HTML content that is rendered into all `span.wb-col` elements of that column.*/
1307
1337
  html?: string;
1308
1338
  _weight?: number;
@@ -1331,6 +1361,12 @@ declare module "types" {
1331
1361
  * @see {@link Wunderbaum.getEventInfo}
1332
1362
  */
1333
1363
  export interface WbEventInfo {
1364
+ /** The original HTTP Event.*/
1365
+ event: MouseEvent | KeyboardEvent;
1366
+ /** Canonical descriptive string of the event type including modifiers,
1367
+ * e.g. `Ctrl+Down`. @see {@link util.eventToString}
1368
+ */
1369
+ canonicalName: string;
1334
1370
  /** The tree instance. */
1335
1371
  tree: Wunderbaum;
1336
1372
  /** The affected node instance instance if any. */
@@ -1347,11 +1383,12 @@ declare module "types" {
1347
1383
  colElem?: HTMLSpanElement;
1348
1384
  }
1349
1385
  export type FilterModeType = null | "dim" | "hide";
1386
+ export type SelectModeType = "single" | "multi" | "hier";
1350
1387
  export type ApplyCommandType = "addChild" | "addSibling" | "copy" | "cut" | "down" | "first" | "indent" | "last" | "left" | "moveDown" | "moveUp" | "outdent" | "pageDown" | "pageUp" | "parent" | "paste" | "remove" | "rename" | "right" | "up";
1351
1388
  export type NodeFilterResponse = "skip" | "branch" | boolean | void;
1352
1389
  export type NodeFilterCallback = (node: WunderbaumNode) => NodeFilterResponse;
1353
1390
  /**
1354
- * Possible values for {@link WunderbaumNode.setModified()} and {@link Wunderbaum.setModified()}.
1391
+ * Possible values for {@link WunderbaumNode.update()} and {@link Wunderbaum.update()}.
1355
1392
  */
1356
1393
  export enum ChangeType {
1357
1394
  /** Re-render the whole viewport, headers, and all rows. */
@@ -1455,7 +1492,7 @@ declare module "types" {
1455
1492
  /** Originating event (e.g. KeyboardEvent) if any. */
1456
1493
  event?: Event;
1457
1494
  }
1458
- /** Possible values for {@link WunderbaumNode.render()}. */
1495
+ /** Possible values for {@link WunderbaumNode._render()}. */
1459
1496
  export interface RenderOptions {
1460
1497
  /** Which parts need update? @default ChangeType.data */
1461
1498
  change?: ChangeType;
@@ -1516,17 +1553,21 @@ declare module "types" {
1516
1553
  /** Scroll up to bring expanded nodes into viewport. @default false */
1517
1554
  scrollIntoView?: boolean;
1518
1555
  }
1519
- /** Possible values for {@link WunderbaumNode.setModified()} `options` argument. */
1520
- export interface SetModifiedOptions {
1556
+ /** Possible values for {@link WunderbaumNode.update()} `options` argument. */
1557
+ export interface UpdateOptions {
1521
1558
  /** Force immediate redraw instead of throttled/async mode. @default false */
1522
1559
  immediate?: boolean;
1523
1560
  }
1524
1561
  /** Possible values for {@link WunderbaumNode.setSelected()} `options` argument. */
1525
1562
  export interface SetSelectedOptions {
1526
- /** Ignore restrictions. @default false */
1563
+ /** Ignore restrictions, e.g. (`unselectable`). @default false */
1527
1564
  force?: boolean;
1528
- /** Do not send events. @default false */
1565
+ /** Do not send `beforeSelect` or `select` events. @default false */
1529
1566
  noEvents?: boolean;
1567
+ /** Apply to all descendant nodes (only for `selectMode: 'multi'`). @default false */
1568
+ propagateDown?: boolean;
1569
+ /** Called for every node. May return false to prevent action. @default null */
1570
+ callback?: NodeSelectCallback;
1530
1571
  }
1531
1572
  /** Possible values for {@link WunderbaumNode.setStatus()} `options` argument. */
1532
1573
  export interface SetStatusOptions {
@@ -1876,6 +1917,7 @@ declare module "wb_ext_dnd" {
1876
1917
  import { WunderbaumExtension } from "wb_extension_base";
1877
1918
  import { WunderbaumNode } from "wb_node";
1878
1919
  import { DropRegionType, DropRegionTypeSet } from "types";
1920
+ import { DebouncedFunction } from "debounce";
1879
1921
  export class DndExtension extends WunderbaumExtension {
1880
1922
  protected srcNode: WunderbaumNode | null;
1881
1923
  protected lastTargetNode: WunderbaumNode | null;
@@ -1883,6 +1925,8 @@ declare module "wb_ext_dnd" {
1883
1925
  protected lastAllowedDropRegions: DropRegionTypeSet | null;
1884
1926
  protected lastDropEffect: string | null;
1885
1927
  protected lastDropRegion: DropRegionType | false;
1928
+ protected currentScrollDir: number;
1929
+ protected applyScrollDirThrottled: DebouncedFunction<() => void>;
1886
1930
  constructor(tree: Wunderbaum);
1887
1931
  init(): void;
1888
1932
  /** Cleanup classes after target node is no longer hovered. */
@@ -1891,7 +1935,10 @@ declare module "wb_ext_dnd" {
1891
1935
  protected unifyDragover(res: any): DropRegionTypeSet | false;
1892
1936
  /** */
1893
1937
  protected _calcDropRegion(e: DragEvent, allowed: DropRegionTypeSet | null): DropRegionType | false;
1894
- protected autoScroll(event: DragEvent): number;
1938
+ protected applyScrollDir(): void;
1939
+ protected autoScroll(viewportY: number): number;
1940
+ /** Return true if a drag operation currently in progress. */
1941
+ isDragging(): boolean;
1895
1942
  protected onDragEvent(e: DragEvent): boolean;
1896
1943
  protected onDropEvent(e: DragEvent): boolean;
1897
1944
  }
@@ -1981,8 +2028,7 @@ declare module "wb_ext_edit" {
1981
2028
  import { Wunderbaum } from "wunderbaum";
1982
2029
  import { WunderbaumExtension } from "wb_extension_base";
1983
2030
  import { WunderbaumNode } from "wb_node";
1984
- import { InsertNodeType } from "types";
1985
- import { WbNodeData } from "wb_options";
2031
+ import { InsertNodeType, WbNodeData } from "types";
1986
2032
  export class EditExtension extends WunderbaumExtension {
1987
2033
  protected debouncedOnChange: (e: Event) => void;
1988
2034
  protected curEditNode: WunderbaumNode | null;
@@ -2022,10 +2068,9 @@ declare module "wunderbaum" {
2022
2068
  * @version @VERSION
2023
2069
  * @date @DATE
2024
2070
  */
2025
- import "./wunderbaum.scss";
2026
2071
  import * as util from "util";
2027
2072
  import { ExtensionsDict, WunderbaumExtension } from "wb_extension_base";
2028
- import { ApplyCommandType, ChangeType, ColumnDefinitionList, ExpandAllOptions, FilterModeType, MatcherCallback, NavModeEnum, NodeStatusType, NodeStringCallback, NodeTypeDefinitionMap, ScrollToOptions, SetActiveOptions, SetModifiedOptions, SetStatusOptions, WbEventInfo, ApplyCommandOptions, AddChildrenOptions, VisitRowsOptions, NodeFilterCallback, FilterNodesOptions, RenderFlag, NodeVisitCallback, SortCallback } from "types";
2073
+ import { ApplyCommandType, ChangeType, ColumnDefinitionList, ExpandAllOptions, FilterModeType, MatcherCallback, NavModeEnum, NodeStatusType, NodeStringCallback, NodeTypeDefinitionMap, ScrollToOptions, SetActiveOptions, UpdateOptions, SetStatusOptions, WbEventInfo, ApplyCommandOptions, AddChildrenOptions, VisitRowsOptions, NodeFilterCallback, FilterNodesOptions, RenderFlag, NodeVisitCallback, SortCallback, NodeToDictCallback, WbNodeData } from "types";
2029
2074
  import { WunderbaumNode } from "wb_node";
2030
2075
  import { WunderbaumOptions } from "wb_options";
2031
2076
  /**
@@ -2208,13 +2253,30 @@ declare module "wunderbaum" {
2208
2253
  * option is a string or `true`.
2209
2254
  */
2210
2255
  hasHeader(): boolean;
2211
- /** Run code, but defer rendering of viewport until done. */
2212
- runWithoutUpdate(func: () => any, hint?: any): void;
2213
- /** Recursively expand all expandable nodes (triggers lazy load id needed). */
2256
+ /** Run code, but defer rendering of viewport until done.
2257
+ *
2258
+ * ```
2259
+ * tree.runWithDeferredUpdate(() => {
2260
+ * return someFuncThatWouldUpdateManyNodes();
2261
+ * });
2262
+ * ```
2263
+ */
2264
+ runWithDeferredUpdate(func: () => any, hint?: any): void;
2265
+ /** Recursively expand all expandable nodes (triggers lazy load if needed). */
2214
2266
  expandAll(flag?: boolean, options?: ExpandAllOptions): Promise<void>;
2215
2267
  /** Recursively select all nodes. */
2216
- selectAll(flag?: boolean): void;
2217
- /** Return the number of nodes in the data model.*/
2268
+ selectAll(flag?: boolean): import("types").TristateType;
2269
+ /** Toggle select all nodes. */
2270
+ toggleSelect(): void;
2271
+ /**
2272
+ * Return an array of selected nodes.
2273
+ * @param stopOnParents only return the topmost selected node (useful with selectMode 'hier')
2274
+ */
2275
+ getSelectedNodes(stopOnParents?: boolean): WunderbaumNode[];
2276
+ protected _selectRange(eventInfo: WbEventInfo): false | void;
2277
+ /** Return the number of nodes in the data model.
2278
+ * @param visible if true, nodes that are hidden due to collapsed parents are ignored.
2279
+ */
2218
2280
  count(visible?: boolean): number;
2219
2281
  /** @internal sanity check. */
2220
2282
  _check(): void;
@@ -2352,20 +2414,24 @@ declare module "wunderbaum" {
2352
2414
  setActiveNode(key: string, flag?: boolean, options?: SetActiveOptions): void;
2353
2415
  /** Set or remove keybaord focus to the tree container. */
2354
2416
  setFocus(flag?: boolean): void;
2417
+ /**
2418
+ * @deprecated since v0.3.6: use `update()` instead.
2419
+ */
2420
+ setModified(change: ChangeType, ...args: any[]): void;
2355
2421
  /**
2356
2422
  * Schedule an update request to reflect a tree change.
2357
2423
  * The render operation is async and debounced unless the `immediate` option
2358
2424
  * is set.
2359
- * Use {@link WunderbaumNode.setModified()} if only a single node has changed,
2360
- * or {@link WunderbaumNode.render()}) to pass special options.
2425
+ * Use {@link WunderbaumNode.update()} if only a single node has changed,
2426
+ * or {@link WunderbaumNode._render()}) to pass special options.
2361
2427
  */
2362
- setModified(change: ChangeType, options?: SetModifiedOptions): void;
2428
+ update(change: ChangeType, options?: UpdateOptions): void;
2363
2429
  /**
2364
2430
  * Update a row to reflect a single node's modification.
2365
2431
  *
2366
- * @see {@link WunderbaumNode.setModified()}, {@link WunderbaumNode.render()}
2432
+ * @see {@link WunderbaumNode.update()}, {@link WunderbaumNode._render()}
2367
2433
  */
2368
- setModified(change: ChangeType, node: WunderbaumNode, options?: SetModifiedOptions): void;
2434
+ update(change: ChangeType, node: WunderbaumNode, options?: UpdateOptions): void;
2369
2435
  /** Disable mouse and keyboard interaction (return prev. state). */
2370
2436
  setEnabled(flag?: boolean): boolean;
2371
2437
  /** Return false if tree is disabled. */
@@ -2391,6 +2457,15 @@ declare module "wunderbaum" {
2391
2457
  * @param {boolean} deep pass true to sort all descendant nodes recursively
2392
2458
  */
2393
2459
  sortChildren(cmp?: SortCallback | null, deep?: boolean): void;
2460
+ /** Convert tree to an array of plain objects.
2461
+ *
2462
+ * @param callback(dict, node) is called for every node, in order to allow
2463
+ * modifications.
2464
+ * Return `false` to ignore this node or `"skip"` to include this node
2465
+ * without its children.
2466
+ * @see {@link WunderbaumNode.toDict}.
2467
+ */
2468
+ toDictArray(callback?: NodeToDictCallback): Array<WbNodeData>;
2394
2469
  /**
2395
2470
  * Update column headers and column width.
2396
2471
  * Return true if at least one column width changed.
@@ -2401,11 +2476,11 @@ declare module "wunderbaum" {
2401
2476
  */
2402
2477
  protected _renderHeaderMarkup(): void;
2403
2478
  /**
2404
- * Render pending changes that were scheduled using {@link WunderbaumNode.setModified} if any.
2479
+ * Render pending changes that were scheduled using {@link WunderbaumNode.update} if any.
2405
2480
  *
2406
2481
  * This is hardly ever neccessary, since we normally either
2407
- * - call `setModified(ChangeType.TYPE)` (async, throttled), or
2408
- * - call `setModified(ChangeType.TYPE, {immediate: true})` (synchronous)
2482
+ * - call `update(ChangeType.TYPE)` (async, throttled), or
2483
+ * - call `update(ChangeType.TYPE, {immediate: true})` (synchronous)
2409
2484
  *
2410
2485
  * `updatePendingModifications()` will only force immediate execution of
2411
2486
  * pending async changes if any.
@@ -2416,7 +2491,7 @@ declare module "wunderbaum" {
2416
2491
  * It calls `updateColumns()` and `_updateRows()`.
2417
2492
  *
2418
2493
  * This protected method should not be called directly but via
2419
- * {@link WunderbaumNode.setModified}`, {@link Wunderbaum.setModified},
2494
+ * {@link WunderbaumNode.update}`, {@link Wunderbaum.update},
2420
2495
  * or {@link Wunderbaum.updatePendingModifications}.
2421
2496
  * @internal
2422
2497
  */