wunderbaum 0.11.1 → 0.12.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wunderbaum",
3
- "version": "0.11.1",
3
+ "version": "0.12.0",
4
4
  "title": "A treegrid control.",
5
5
  "description": "JavaScript tree/grid/treegrid control.",
6
6
  "homepage": "https://github.com/mar10/wunderbaum",
package/src/types.ts CHANGED
@@ -594,12 +594,34 @@ export interface ApplyCommandOptions {
594
594
 
595
595
  /** Possible values for {@link Wunderbaum.expandAll} and {@link WunderbaumNode.expandAll}. */
596
596
  export interface ExpandAllOptions {
597
- /** Restrict expand level @default 99 */
598
- depth?: number;
599
597
  /** Expand and load lazy nodes @default false */
600
598
  loadLazy?: boolean;
601
- /** Ignore `minExpandLevel` option @default false */
599
+ /** Unload lazily loaded children if any (if collapsing). @default false */
600
+ resetLazy?: boolean;
601
+ /** Ignore tree's `minExpandLevel` option @default false */
602
602
  force?: boolean;
603
+ /** Restrict expand level.
604
+ * Pass 0 to make only toplevel nodes visible, 1 to expand one level deeper, etc.
605
+ * @default unset (unlimited)
606
+ */
607
+ depth?: number;
608
+ /**
609
+ * Also collapse child nodes beyond the `depth` level.
610
+ * Otherwise only the `depth` level is collapsed and the expand state of the
611
+ * descendants is retained.
612
+ * Only in combination with collapse and `depth`.
613
+ * Expanding with `deep` option is not supported as recursion depth implied by
614
+ * the `depth` option. However a `deep` option will be considered if
615
+ * `collapseOthers` is set.
616
+ * @default false
617
+ */
618
+ deep?: boolean;
619
+ /**
620
+ * Expand up to level=depth and collapse all other branches.
621
+ * Only in combination with `flag == true`, `depth > 0`.
622
+ * @default false
623
+ */
624
+ collapseOthers?: boolean;
603
625
  /** Keep active node visible @default true */
604
626
  keepActiveNodeVisible?: boolean;
605
627
  }
@@ -723,7 +745,7 @@ export interface SetColumnOptions {
723
745
 
724
746
  /** Possible values for {@link WunderbaumNode.setExpanded} `options` argument. */
725
747
  export interface SetExpandedOptions {
726
- /** Ignore {@link WunderbaumOptions.minExpandLevel}. @default false */
748
+ /** Ignore {@link WunderbaumOptions}.minExpandLevel. @default false */
727
749
  force?: boolean;
728
750
  /** Immediately update viewport (async otherwise). @default false */
729
751
  immediate?: boolean;
@@ -731,6 +753,8 @@ export interface SetExpandedOptions {
731
753
  noAnimation?: boolean;
732
754
  /** Do not send events. @default false */
733
755
  noEvents?: boolean;
756
+ /** Unload lazily loaded children if any (if collapsing). @default false */
757
+ resetLazy?: boolean;
734
758
  /** Scroll up to bring expanded nodes into viewport. @default false */
735
759
  scrollIntoView?: boolean;
736
760
  }
package/src/wb_node.ts CHANGED
@@ -470,58 +470,78 @@ export class WunderbaumNode {
470
470
  this.tree._callMethod("edit.startEditTitle", this);
471
471
  }
472
472
 
473
- /** Call `setExpanded()` on all descendant nodes. */
473
+ /**
474
+ * Call `setExpanded()` on all descendant nodes.
475
+ *
476
+ * @param flag true to expand, false to collapse.
477
+ * @param options Additional options.
478
+ * @see {@link Wunderbaum.expandAll}
479
+ * @see {@link WunderbaumNode.setExpanded}
480
+ */
474
481
  async expandAll(flag: boolean = true, options?: ExpandAllOptions) {
475
482
  const tree = this.tree;
476
- const minExpandLevel = this.tree.options.minExpandLevel;
477
483
  const {
478
- depth = 99,
479
- loadLazy,
484
+ collapseOthers,
485
+ deep,
486
+ depth,
480
487
  force,
481
488
  keepActiveNodeVisible = true,
489
+ loadLazy,
490
+ resetLazy,
482
491
  } = options ?? {};
483
-
492
+ // limit expansion level to `depth` (or tree.minExpandLevel). Default: unlimited
493
+ const treeLevel = this.tree.options.minExpandLevel || null; // 0 -> null
494
+ const minLevel = depth ?? (force ? null : treeLevel);
484
495
  const expandOpts = {
485
- scrollIntoView: false, // don't scroll very node on iteration
496
+ deep: deep,
486
497
  force: force,
487
498
  loadLazy: loadLazy,
499
+ resetLazy: resetLazy,
500
+ scrollIntoView: false, // don't scroll every node while iterating
488
501
  };
489
502
 
490
- // this.logInfo(`expandAll(${flag})`);
503
+ this.logInfo(`expandAll(${flag}, depth=${depth}, minLevel=${minLevel})`);
504
+
505
+ util.assert(
506
+ !(flag && deep != null && !collapseOthers),
507
+ "Expanding with `deep` option is not supported (implied by the `depth` option)."
508
+ );
509
+
491
510
  // Expand all direct children in parallel:
492
- async function _iter(n: WunderbaumNode, level: number | null) {
493
- // n.logInfo(` _iter(${level})`);
494
- if (level === 0) {
495
- return;
496
- }
497
- // if (!flag && minExpandLevel && !force && n.getLevel() <= minExpandLevel) {
498
- // return; // Do not collapse until minExpandLevel
499
- // }
500
- const level_1 = level == null ? null : level - 1;
511
+ async function _iter(n: WunderbaumNode, level: number) {
512
+ // n.logInfo(` _iter(level=${level})`);
501
513
  const promises: Promise<unknown>[] = [];
502
514
  n.children?.forEach((cn) => {
503
515
  if (flag) {
504
- if (!cn.expanded && (cn.children || (loadLazy && cn.lazy))) {
516
+ if (
517
+ !cn.expanded &&
518
+ (minLevel == null || level < minLevel) &&
519
+ (cn.children || (loadLazy && cn.lazy))
520
+ ) {
505
521
  // Node is collapsed and may be expanded (i.e. has children or is lazy)
506
522
  // Expanding may be async, so we store the promise.
507
523
  // Also the recursion is delayed until expansion finished.
508
524
  const p = cn.setExpanded(true, expandOpts);
509
525
  promises.push(p);
510
- p.then(async () => {
511
- await _iter(cn, level_1);
512
- });
526
+ if (depth == null) {
527
+ p.then(async () => {
528
+ await _iter(cn, level + 1);
529
+ });
530
+ }
513
531
  } else {
514
532
  // We don't expand the node, but still visit descendants.
515
533
  // There we may find lazy nodes, so we
516
- promises.push(_iter(cn, level_1));
534
+ promises.push(_iter(cn, level + 1));
517
535
  }
518
536
  } else {
519
537
  // Collapsing is always synchronous, so no promises required
520
- if (!minExpandLevel || force || cn.getLevel() > minExpandLevel) {
521
- // Do not collapse until minExpandLevel
538
+ // Do not collapse until minExpandLevel
539
+ if (minLevel == null || level >= minLevel) {
522
540
  cn.setExpanded(false, expandOpts);
523
541
  }
524
- _iter(cn, level_1); // recursion, even if cn was already collapsed
542
+ if ((minLevel != null && level < minLevel) || deep) {
543
+ _iter(cn, level + 1); // recursion, even if cn was already collapsed
544
+ }
525
545
  }
526
546
  });
527
547
  return new Promise((resolve) => {
@@ -531,10 +551,20 @@ export class WunderbaumNode {
531
551
  });
532
552
  }
533
553
 
534
- const tag = tree.logTime(`${this}.expandAll(${flag})`);
554
+ const tag = tree.logTime(`${this}.expandAll(${flag}, depth=${depth})`);
535
555
  try {
536
556
  tree.enableUpdate(false);
537
- await _iter(this, depth);
557
+
558
+ await _iter(this, 0);
559
+
560
+ if (collapseOthers) {
561
+ util.assert(flag, "Option `collapseOthers` requires flag=true");
562
+ util.assert(
563
+ minLevel != null,
564
+ "Option `collapseOthers` requires `depth` or `minExpandLevel`"
565
+ );
566
+ this.expandAll(false, { depth: minLevel! });
567
+ }
538
568
  } finally {
539
569
  tree.enableUpdate(true);
540
570
  tree.logTimeEnd(tag);
@@ -2199,7 +2229,7 @@ export class WunderbaumNode {
2199
2229
  const colIdx = options?.colIdx; // Default: null
2200
2230
  const edit = options?.edit; // Default: false
2201
2231
 
2202
- util.assert(!colIdx || tree.isCellNav(), "colIdx requires cellNav");
2232
+ // util.assert(!colIdx || tree.isCellNav(), "colIdx requires cellNav");
2203
2233
  util.assert(!edit || colIdx != null, "edit requires colIdx");
2204
2234
 
2205
2235
  if (!noEvents) {
@@ -2257,7 +2287,7 @@ export class WunderbaumNode {
2257
2287
  * Expand or collapse this node.
2258
2288
  */
2259
2289
  async setExpanded(flag: boolean = true, options?: SetExpandedOptions) {
2260
- const { force, scrollIntoView, immediate } = options ?? {};
2290
+ const { force, scrollIntoView, immediate, resetLazy } = options ?? {};
2261
2291
  const sendEvents = !options?.noEvents; // Default: send events
2262
2292
  if (
2263
2293
  !flag &&
@@ -2284,6 +2314,8 @@ export class WunderbaumNode {
2284
2314
  }
2285
2315
  if (flag && this.lazy && this.children == null) {
2286
2316
  await this.loadLazy();
2317
+ } else if (!flag && resetLazy && this.lazy && this.children) {
2318
+ this.resetLazy();
2287
2319
  }
2288
2320
  this.expanded = flag;
2289
2321
  const updateOpts = { immediate: immediate };
@@ -4,6 +4,8 @@
4
4
  * @VERSION, @DATE (https://github.com/mar10/wunderbaum)
5
5
  */
6
6
  // @use "sass:meta";
7
+ @use "sass:color";
8
+ @use "sass:list";
7
9
 
8
10
  // ----------------------------------------------------------------------------
9
11
  // --- Define default colors and settings
@@ -22,26 +24,26 @@ $alternate-row-color-hover: #f3f3f3; //#f7fcfe;
22
24
  $focus-border-color: #275dc5;
23
25
 
24
26
  // derived
25
- $drop-source-color: adjust-color($node-text-color, $lightness: 50%);
26
- $drop-target-color: adjust-color($bg-highlight-color, $lightness: 40%);
27
- $dim-color: adjust-color($node-text-color, $lightness: 20%);
28
- $error-background-color: adjust-color($error-color, $lightness: 45%);
27
+ $drop-source-color: color.adjust($node-text-color, $lightness: 50%);
28
+ $drop-target-color: color.adjust($bg-highlight-color, $lightness: 40%);
29
+ $dim-color: color.adjust($node-text-color, $lightness: 20%);
30
+ $error-background-color: color.adjust($error-color, $lightness: 45%);
29
31
  // @debug $dim-color;
30
- $hover-color: adjust-color($bg-highlight-color, $lightness: 48%); // #f7f7f7;
32
+ $hover-color: color.adjust($bg-highlight-color, $lightness: 48%); // #f7f7f7;
31
33
  $hover-border-color: $hover-color;
32
34
  $grid-color: #dedede;
33
35
  $active-color: #e5f3fb;
34
- $active-cell-color: adjust-color($bg-highlight-color, $lightness: 20%);
36
+ $active-cell-color: color.adjust($bg-highlight-color, $lightness: 20%);
35
37
  $active-border-color: #70c0e7;
36
38
  $active-hover-color: #dceff8;
37
39
  $active-hover-border-color: $bg-highlight-color;
38
40
  $active-column-color: $hover-color;
39
- $active-header-column-color: adjust-color($header-color, $lightness: -10%);
40
- $active-color-grayscale: grayscale($active-color);
41
- $active-border-color-grayscale: grayscale($active-border-color);
42
- $active-hover-color-grayscale: grayscale($active-hover-color);
43
- $active-cell-color-grayscale: grayscale($active-cell-color);
44
- $grid-color-grayscale: grayscale($grid-color);
41
+ $active-header-column-color: color.adjust($header-color, $lightness: -10%);
42
+ $active-color-grayscale: color.grayscale($active-color);
43
+ $active-border-color-grayscale: color.grayscale($active-border-color);
44
+ $active-hover-color-grayscale: color.grayscale($active-hover-color);
45
+ $active-cell-color-grayscale: color.grayscale($active-cell-color);
46
+ $grid-color-grayscale: color.grayscale($grid-color);
45
47
  // @debug $active-header-column-color;
46
48
  $filter-dim-color: #dedede;
47
49
  $filter-submatch-color: #868581;
@@ -696,10 +698,10 @@ div.wunderbaum {
696
698
 
697
699
  /* Colorize indentation levels. */
698
700
  &.wb-rainbow {
699
- @for $i from 1 through length($level-rainbow) {
700
- i.wb-expander:nth-child(#{length($level-rainbow)}n + #{$i}),
701
- i.wb-indent:nth-child(#{length($level-rainbow)}n + #{$i}) {
702
- background: nth($level-rainbow, $i);
701
+ @for $i from 1 through list.length($level-rainbow) {
702
+ i.wb-expander:nth-child(#{list.length($level-rainbow)}n + #{$i}),
703
+ i.wb-indent:nth-child(#{list.length($level-rainbow)}n + #{$i}) {
704
+ background: list.nth($level-rainbow, $i);
703
705
  }
704
706
  }
705
707
  }
package/src/wunderbaum.ts CHANGED
@@ -498,7 +498,12 @@ export class Wunderbaum {
498
498
  ) {
499
499
  return false;
500
500
  }
501
- if (node && info.colIdx === 0 && node.isExpandable()) {
501
+ if (
502
+ node &&
503
+ info.colIdx === 0 &&
504
+ node.isExpandable() &&
505
+ info.region !== NodeRegion.expander
506
+ ) {
502
507
  this._callMethod("edit._stopEditTitle");
503
508
  node.setExpanded(!node.isExpanded());
504
509
  }