wunderbaum 0.3.3 → 0.3.5

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/src/wb_node.ts CHANGED
@@ -31,6 +31,8 @@ import {
31
31
  SetSelectedOptions,
32
32
  SetStatusOptions,
33
33
  SortCallback,
34
+ NodeToDictCallback,
35
+ WbNodeData,
34
36
  } from "./types";
35
37
  import {
36
38
  iconMap,
@@ -45,7 +47,6 @@ import {
45
47
  nodeTitleSorter,
46
48
  } from "./common";
47
49
  import { Deferred } from "./deferred";
48
- import { WbNodeData } from "./wb_options";
49
50
 
50
51
  /** Top-level properties that can be passed with `data`. */
51
52
  const NODE_PROPS = new Set<string>([
@@ -330,7 +331,7 @@ export class WunderbaumNode {
330
331
  *
331
332
  * This a convenience function that calls addChildren()
332
333
  *
333
- * @param {NodeData} node node definition
334
+ * @param nodeData node definition
334
335
  * @param [mode=child] 'before', 'after', 'firstChild', or 'child' ('over' is a synonym for 'child')
335
336
  * @returns new node
336
337
  */
@@ -1857,9 +1858,9 @@ export class WunderbaumNode {
1857
1858
  * modifications.
1858
1859
  * Return `false` to ignore this node or `"skip"` to include this node
1859
1860
  * without its children.
1860
- * @returns {NodeData}
1861
+ * @see {@link Wunderbaum.toDictArray}.
1861
1862
  */
1862
- toDict(recursive = false, callback?: any): any {
1863
+ toDict(recursive = false, callback?: NodeToDictCallback): WbNodeData {
1863
1864
  const dict: any = {};
1864
1865
 
1865
1866
  NODE_ATTRS.forEach((propName: string) => {
@@ -1883,7 +1884,8 @@ export class WunderbaumNode {
1883
1884
  if (callback) {
1884
1885
  const res = callback(dict, this);
1885
1886
  if (res === false) {
1886
- return false; // Don't include this node nor its children
1887
+ // Note: a return value of `false` is only used internally
1888
+ return <any>false; // Don't include this node nor its children
1887
1889
  }
1888
1890
  if (res === "skip") {
1889
1891
  recursive = false; // Include this node, but not the children
@@ -1895,7 +1897,8 @@ export class WunderbaumNode {
1895
1897
  for (let i = 0, l = this.children!.length; i < l; i++) {
1896
1898
  const node = this.children![i];
1897
1899
  if (!node.isStatusNode()) {
1898
- const res = node.toDict(true, callback);
1900
+ // Note: a return value of `false` is only used internally
1901
+ const res = <any>node.toDict(true, callback);
1899
1902
  if (res !== false) {
1900
1903
  dict.children.push(res);
1901
1904
  }
package/src/wb_options.ts CHANGED
@@ -18,24 +18,13 @@ import {
18
18
  WbErrorEventType,
19
19
  WbInitEventType,
20
20
  WbKeydownEventType,
21
+ WbNodeData,
21
22
  WbNodeEventType,
22
23
  WbReceiveEventType,
23
24
  WbRenderEventType,
24
25
  WbTreeEventType,
25
26
  } from "./types";
26
27
 
27
- export interface WbNodeData {
28
- title: string;
29
- key?: string;
30
- refKey?: string;
31
- expanded?: boolean;
32
- selected?: boolean;
33
- checkbox?: boolean | string;
34
- colspan?: boolean;
35
- children?: Array<WbNodeData>;
36
- // ...any?: Any;
37
- }
38
-
39
28
  /**
40
29
  * Available options for [[Wunderbaum]].
41
30
  *
@@ -3,21 +3,25 @@
3
3
  * Copyright (c) 2021-2023, Martin Wendt. Released under the MIT license.
4
4
  * @VERSION, @DATE (https://github.com/mar10/wunderbaum)
5
5
  */
6
+ // @use "sass:meta";
7
+
8
+ // ----------------------------------------------------------------------------
9
+ // --- Define default colors and settings
6
10
 
7
11
  $font-stack: Helvetica, sans-serif;
8
12
 
9
13
  // Basic Theme Colors
10
14
  $error-color: #b5373b;
11
15
  $node-text-color: #56534c;
16
+ $border-color: $node-text-color;
12
17
  $bg-highlight-color: #26a0da;
13
18
  $header-color: #dedede;
14
- $background-color: white;
19
+ $background-color: #ffffff;
15
20
  $alternate-row-color: #f7f7f7; // #fcfcfc;
16
21
  $alternate-row-color-hover: #f3f3f3; //#f7fcfe;
17
22
  $focus-border-color: #275dc5;
18
23
 
19
24
  // derived
20
- $border-color: $node-text-color;
21
25
  $drop-source-color: adjust-color($node-text-color, $lightness: 50%);
22
26
  $drop-target-color: adjust-color($bg-highlight-color, $lightness: 40%);
23
27
  $dim-color: adjust-color($node-text-color, $lightness: 20%);
@@ -33,6 +37,11 @@ $active-hover-color: #dceff8;
33
37
  $active-hover-border-color: $bg-highlight-color;
34
38
  $active-column-color: $hover-color;
35
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);
36
45
  // @debug $active-header-column-color;
37
46
  $filter-dim-color: #dedede;
38
47
  $filter-submatch-color: #868581;
@@ -61,19 +70,82 @@ $header-height: $row-outer-height;
61
70
  $level-rainbow: rgb(255, 255, 201), rgb(218, 255, 218), rgb(255, 217, 254),
62
71
  rgb(204, 250, 250);
63
72
 
64
- div.wunderbaum {
73
+ // ----------------------------------------------------------------------------
74
+ // --- Define CSS variables with calculated default values
75
+
76
+ :root {
77
+ // TODO: do we need to use 'meta.inspect' in case a font name contains spaces?
78
+ // --wb-font-stack: #{meta.inspect($font-stack)};
79
+ --wb-font-stack: #{$font-stack};
80
+
81
+ // Basic Theme Colors
82
+ --wb-error-color: #{$error-color};
83
+ --wb-node-text-color: #{$node-text-color};
84
+ --wb-border-color: #{$border-color};
85
+ --wb-bg-highlight-color: #{$bg-highlight-color};
86
+ --wb-header-color: #{$header-color};
87
+ --wb-background-color: #{$background-color};
88
+ --wb-alternate-row-color: #{$alternate-row-color};
89
+ --wb-alternate-row-color-hover: #{$alternate-row-color-hover};
90
+ --wb-focus-border-color: #{$focus-border-color};
91
+
92
+ // derived
93
+ --wb-drop-source-color: #{$drop-source-color};
94
+ --wb-drop-target-color: #{$drop-target-color};
95
+ --wb-dim-color: #{$dim-color};
96
+ --wb-error-background-color: #{$error-background-color};
97
+ --wb-hover-color: #{$hover-color};
98
+ --wb-hover-border-color: #{$hover-border-color};
99
+ --wb-grid-color: #{$grid-color};
100
+ --wb-active-color: #{$active-color};
101
+ --wb-active-cell-color: #{$active-cell-color};
102
+ --wb-active-border-color: #{$active-border-color};
103
+ --wb-active-hover-color: #{$active-hover-color};
104
+ --wb-active-hover-border-color: #{$active-hover-border-color};
105
+ --wb-active-column-color: #{$active-column-color};
106
+ --wb-active-header-column-color: #{$active-header-column-color};
107
+ --wb-active-color-grayscale: #{$active-color-grayscale};
108
+ --wb-active-border-color-grayscale: #{$active-border-color-grayscale};
109
+ --wb-active-hover-color-grayscale: #{$active-hover-color-grayscale};
110
+ --wb-active-cell-color-grayscale: #{$active-cell-color-grayscale};
111
+ --wb-grid-color-grayscale: #{$grid-color-grayscale};
112
+
113
+ --wb-filter-dim-color: #{$filter-dim-color};
114
+ --wb-filter-submatch-color: #{$filter-submatch-color};
115
+
116
+ --wb-row-outer-height: #{$row-outer-height};
117
+ --wb-row-inner-height: #{$row-inner-height};
118
+ --wb-row-padding-y: #{$row-padding-y};
119
+ --wb-col-padding-x: #{$col-padding-x};
120
+
121
+ --wb-icon-outer-height: #{$icon-outer-height};
122
+ --wb-icon-outer-width: #{$icon-outer-width};
123
+ --wb-icon-height: #{$icon-height};
124
+ --wb-icon-width: #{$icon-width};
125
+ --wb-icon-padding-y: #{$icon-padding-y};
126
+ --wb-icon-padding-x: #{$icon-padding-x};
127
+
128
+ --wb-header-height: #{$header-height};
129
+ }
130
+
131
+ // ----------------------------------------------------------------------------
132
+ // --- SCSS Rules
133
+
134
+ div.wunderbaum * {
65
135
  box-sizing: border-box;
136
+ }
137
+ div.wunderbaum {
66
138
  height: 100%; // fill parent container
67
139
  min-height: 4px;
68
- background-color: $background-color;
140
+ background-color: var(--wb-background-color);
69
141
  margin: 0;
70
142
  padding: 0;
71
143
 
72
- font-family: $font-stack;
144
+ font-family: var(--wb-font-stack);
73
145
  font-size: 14px;
74
146
 
75
- color: $node-text-color;
76
- border: 2px solid $border-color;
147
+ color: var(--wb-node-text-color);
148
+ border: 2px solid var(--wb-border-color);
77
149
  border-radius: 4px;
78
150
  background-clip: content-box; // Keep bg color outside rounded borders?
79
151
  overflow-x: auto;
@@ -85,7 +157,7 @@ div.wunderbaum {
85
157
  // Focus border is generated by the browsers per default:
86
158
  &:focus,
87
159
  &:focus-within {
88
- border-color: $focus-border-color;
160
+ border-color: var(--wb-focus-border-color);
89
161
  // outline-style: none;
90
162
  }
91
163
 
@@ -119,8 +191,8 @@ div.wunderbaum {
119
191
  div.wb-row {
120
192
  position: absolute;
121
193
  width: 100%;
122
- height: $row-outer-height;
123
- line-height: $row-outer-height;
194
+ height: var(--wb-row-outer-height);
195
+ line-height: var(--wb-row-outer-height);
124
196
  border: 1px solid transparent;
125
197
  }
126
198
 
@@ -131,25 +203,25 @@ div.wunderbaum {
131
203
  position: sticky;
132
204
  left: 0;
133
205
  z-index: 1;
134
- background-color: $background-color;
206
+ background-color: var(--wb-background-color);
135
207
  }
136
208
 
137
209
  div.wb-header {
138
210
  span.wb-col:first-of-type {
139
- background-color: $header-color;
211
+ background-color: var(--wb-header-color);
140
212
  }
141
213
  }
142
214
  div.wb-node-list div.wb-row {
143
215
  &.wb-active span.wb-col:first-of-type,
144
216
  &.wb-selected span.wb-col:first-of-type {
145
- background-color: $active-color;
217
+ background-color: var(--wb-active-color);
146
218
  }
147
219
  &.wb-active:hover span.wb-col:first-of-type,
148
220
  &.wb-selected:hover span.wb-col:first-of-type {
149
- background-color: $active-hover-color;
221
+ background-color: var(--wb-active-hover-color);
150
222
  }
151
223
  &:hover span.wb-col:first-of-type {
152
- background-color: $hover-color;
224
+ background-color: var(--wb-hover-color);
153
225
  }
154
226
  }
155
227
 
@@ -158,10 +230,10 @@ div.wunderbaum {
158
230
  div.wb-node-list div.wb-row {
159
231
  &.wb-active span.wb-col:first-of-type,
160
232
  &.wb-selected span.wb-col:first-of-type {
161
- background-color: grayscale($active-color);
162
- border-color: grayscale($active-border-color);
233
+ background-color: var(--wb-active-color-grayscale);
234
+ border-color: var(--wb-active-border-color-grayscale);
163
235
  &:hover span.wb-col:first-of-type {
164
- background-color: grayscale($active-hover-color);
236
+ background-color: var(--wb-active-hover-color-grayscale);
165
237
  }
166
238
  }
167
239
  }
@@ -176,11 +248,11 @@ div.wunderbaum {
176
248
  div.wb-node-list div.wb-row {
177
249
  &.wb-active,
178
250
  &.wb-selected {
179
- background-color: grayscale($active-color);
180
- border-color: grayscale($active-border-color);
251
+ background-color: var(--wb-active-color-grayscale);
252
+ border-color: var(--wb-active-border-color-grayscale);
181
253
 
182
254
  &:hover {
183
- background-color: grayscale($active-hover-color);
255
+ background-color: var(--wb-active-hover-color-grayscale);
184
256
  }
185
257
  }
186
258
  }
@@ -188,10 +260,10 @@ div.wunderbaum {
188
260
 
189
261
  &.wb-alternate div.wb-node-list {
190
262
  div.wb-row:nth-of-type(even):not(.wb-active):not(.wb-selected) {
191
- background-color: $alternate-row-color;
263
+ background-color: var(--wb-alternate-row-color);
192
264
 
193
265
  &:hover {
194
- background-color: $alternate-row-color-hover;
266
+ background-color: var(--wb-alternate-row-color-hover);
195
267
  }
196
268
  }
197
269
  }
@@ -199,33 +271,33 @@ div.wunderbaum {
199
271
  div.wb-node-list {
200
272
  div.wb-row {
201
273
  &:hover {
202
- background-color: $hover-color;
274
+ background-color: var(--wb-hover-color);
203
275
  }
204
276
 
205
277
  &.wb-active,
206
278
  &.wb-selected {
207
- background-color: $active-color;
279
+ background-color: var(--wb-active-color);
208
280
 
209
- // border-color: $active-border-color;
281
+ // border-color: var(--wb-active-border-color);
210
282
  &:hover {
211
- background-color: $active-hover-color;
212
- // border-color: $active-hover-border-color;
283
+ background-color: var(--wb-active-hover-color);
284
+ // border-color: var(--wb-active-hover-border-color);
213
285
  }
214
286
  }
215
287
 
216
288
  &.wb-focus:not(.wb-active) {
217
289
  border-style: dotted;
218
- border-color: $active-border-color;
290
+ border-color: var(--wb-active-border-color);
219
291
  }
220
292
 
221
293
  &.wb-active {
222
- // background-color: $active-hover-color;
294
+ // background-color: var(--wb-active-hover-color);
223
295
  border-style: solid;
224
- border-color: $active-border-color;
296
+ border-color: var(--wb-active-border-color);
225
297
 
226
298
  &:hover {
227
- // background-color: $active-hover-color;
228
- border-color: $active-hover-border-color;
299
+ // background-color: var(--wb-active-hover-color);
300
+ border-color: var(--wb-active-hover-border-color);
229
301
  }
230
302
  }
231
303
 
@@ -264,7 +336,7 @@ div.wunderbaum {
264
336
 
265
337
  &.wb-error,
266
338
  &.wb-status-error {
267
- color: $error-color;
339
+ color: var(--wb-error-color);
268
340
  }
269
341
  }
270
342
  }
@@ -273,10 +345,10 @@ div.wunderbaum {
273
345
 
274
346
  div.wb-header {
275
347
  position: sticky;
276
- height: $header-height;
277
- border-bottom: 1px solid $border-color;
348
+ height: var(--wb-header-height);
349
+ border-bottom: 1px solid var(--wb-border-color);
278
350
  padding: 0;
279
- background-color: $header-color;
351
+ background-color: var(--wb-header-color);
280
352
 
281
353
  span.wb-col {
282
354
  font-weight: bold;
@@ -302,7 +374,7 @@ div.wunderbaum {
302
374
  width: 3px;
303
375
  // float: right;
304
376
  border: none;
305
- border-right: 2px solid $border-color;
377
+ border-right: 2px solid var(--wb-border-color);
306
378
  height: 100%;
307
379
  cursor: col-resize;
308
380
  }
@@ -313,8 +385,8 @@ div.wunderbaum {
313
385
  display: inline-block;
314
386
  // text-overflow: ellipsis;
315
387
  overflow: hidden;
316
- height: $row-inner-height;
317
- line-height: $row-inner-height;
388
+ height: var(--wb-row-inner-height);
389
+ line-height: var(--wb-row-inner-height);
318
390
  padding: 0 $col-padding-x;
319
391
  border-right: 1px solid $grid-color;
320
392
  white-space: nowrap;
@@ -334,9 +406,9 @@ div.wunderbaum {
334
406
  i.wb-expander,
335
407
  i.wb-icon,
336
408
  i.wb-indent {
337
- height: $icon-outer-height;
338
- width: $icon-outer-width;
339
- padding: $icon-padding-y $icon-padding-x;
409
+ height: var(--wb-icon-outer-height);
410
+ width: var(--wb-icon-outer-width);
411
+ padding: var(--wb-icon-padding) var(--wb-icon-padding-x);
340
412
  display: inline-block;
341
413
  }
342
414
 
@@ -346,10 +418,10 @@ div.wunderbaum {
346
418
  }
347
419
 
348
420
  img.wb-icon {
349
- width: $icon-width;
350
- height: $icon-height;
351
- padding: $icon-padding-y $icon-padding-x;
352
- // margin-top: $icon-padding-y;
421
+ width: var(--wb-icon-width);
422
+ height: var(--wb-icon-height);
423
+ padding: var(--wb-icon-padding-y) var(--wb-icon-padding-x);
424
+ // margin-top: var(--wb-icon-padding-y);
353
425
  }
354
426
 
355
427
  i.wb-indent {
@@ -385,7 +457,7 @@ div.wunderbaum {
385
457
  div.wb-row {
386
458
  span.wb-col {
387
459
  &:hover {
388
- background-color: $active-header-column-color;
460
+ background-color: var(--wb-active-header-column-color);
389
461
  }
390
462
  }
391
463
  }
@@ -393,20 +465,20 @@ div.wunderbaum {
393
465
 
394
466
  &.wb-cell-mode div.wb-header div.wb-row span.wb-col {
395
467
  &.wb-active {
396
- background-color: $active-hover-color;
468
+ background-color: var(--wb-active-hover-color);
397
469
  }
398
470
  }
399
471
 
400
472
  div.wb-node-list div.wb-row {
401
- border-bottom-color: $grid-color;
473
+ border-bottom-color: var(--wb-grid-color);
402
474
 
403
475
  &:hover:not(.wb-active):not(.wb-selected) {
404
- background-color: $hover-color;
405
- // border-color: $hover-border-color;
476
+ background-color: var(--wb-hover-color);
477
+ // border-color: var(--wb-hover-border-color);
406
478
  }
407
479
 
408
480
  &.wb-active {
409
- border-bottom-color: $active-border-color;
481
+ border-bottom-color: var(--wb-active-border-color);
410
482
  }
411
483
 
412
484
  span.wb-col {
@@ -429,7 +501,7 @@ div.wunderbaum {
429
501
  > input[type="week"],
430
502
  > select {
431
503
  width: 100%;
432
- max-height: $row-inner-height;
504
+ max-height: var(--wb-row-inner-height);
433
505
  border: none;
434
506
  }
435
507
 
@@ -450,7 +522,7 @@ div.wunderbaum {
450
522
  div.wb-row:not(.wb-colspan) {
451
523
  &.wb-active {
452
524
  span.wb-col.wb-active {
453
- background-color: grayscale($active-cell-color);
525
+ background-color: var(--wb-active-cell-color-grayscale);
454
526
  }
455
527
  }
456
528
  }
@@ -458,17 +530,17 @@ div.wunderbaum {
458
530
  &.wb-cell-mode:focus-within,
459
531
  &.wb-cell-mode:focus {
460
532
  div.wb-row:not(.wb-colspan):not(.wb-selected) {
461
- // background-color: $background-color;
533
+ // background-color: var(--wb-background-color);
462
534
 
463
535
  span.wb-col.wb-active {
464
- background-color: $active-column-color;
536
+ background-color: var(--wb-active-column-color);
465
537
  }
466
538
 
467
539
  &.wb-active {
468
- background-color: $active-column-color;
540
+ background-color: var(--wb-active-column-color);
469
541
 
470
542
  span.wb-col.wb-active {
471
- background-color: $active-cell-color;
543
+ background-color: var(--wb-active-cell-color);
472
544
  }
473
545
  }
474
546
  }
@@ -476,10 +548,10 @@ div.wunderbaum {
476
548
 
477
549
  &.wb-alternate div.wb-node-list {
478
550
  div.wb-row:nth-of-type(even):not(.wb-active):not(.wb-selected) {
479
- background-color: $alternate-row-color;
551
+ background-color: var(--wb-alternate-row-color);
480
552
 
481
553
  &:hover {
482
- background-color: $alternate-row-color-hover;
554
+ background-color: var(--wb-alternate-row-color-hover);
483
555
  }
484
556
  }
485
557
  }
@@ -488,7 +560,7 @@ div.wunderbaum {
488
560
  &:not(:focus-within),
489
561
  &:not(:focus) {
490
562
  div.wb-node-list div.wb-row {
491
- border-bottom-color: grayscale($grid-color);
563
+ border-bottom-color: var(--wb-grid-color-grayscale);
492
564
  }
493
565
  }
494
566
  }
@@ -498,14 +570,14 @@ div.wunderbaum {
498
570
  &.wb-ext-filter-dim,
499
571
  &.wb-ext-filter-hide {
500
572
  div.wb-node-list div.wb-row {
501
- color: $filter-dim-color;
573
+ color: var(--wb-filter-dim-color);
502
574
 
503
575
  &.wb-submatch {
504
- color: $filter-submatch-color;
576
+ color: var(--wb-filter-submatch-color);
505
577
  }
506
578
 
507
579
  &.wb-match {
508
- color: $node-text-color;
580
+ color: var(--wb-node-text-color);
509
581
  }
510
582
  }
511
583
  }
@@ -523,7 +595,7 @@ div.wunderbaum {
523
595
  opacity: 0.5;
524
596
 
525
597
  .wb-node {
526
- background-color: $drop-source-color;
598
+ background-color: var(--wb-drop-source-color);
527
599
  }
528
600
  }
529
601
 
@@ -531,7 +603,7 @@ div.wunderbaum {
531
603
  overflow: visible;
532
604
 
533
605
  .wb-node {
534
- background-color: $drop-target-color;
606
+ background-color: var(--wb-drop-target-color);
535
607
  overflow: visible;
536
608
 
537
609
  // z-index: 1000;
@@ -601,7 +673,7 @@ div.wunderbaum {
601
673
  &:focus-within i.wb-expander,
602
674
  [class*="wb-statusnode-"] i.wb-expander {
603
675
  transition: color 0.6s;
604
- color: $node-text-color;
676
+ color: var(--wb-node-text-color);
605
677
  }
606
678
  }
607
679
 
@@ -644,7 +716,7 @@ div.wunderbaum {
644
716
  }
645
717
 
646
718
  .wb-helper-disabled {
647
- color: $dim-color;
719
+ color: var(--wb-dim-color);
648
720
  }
649
721
 
650
722
  .wb-helper-hidden {
@@ -652,11 +724,11 @@ div.wunderbaum {
652
724
  }
653
725
 
654
726
  .wb-helper-invalid {
655
- color: $error-color;
727
+ color: var(--wb-error-color);
656
728
  }
657
729
 
658
730
  .wb-helper-lazy-expander {
659
- color: $bg-highlight-color;
731
+ color: var(--wb-bg-highlight-color);
660
732
  }
661
733
 
662
734
  .wb-helper-link {
@@ -707,14 +779,14 @@ div.wunderbaum {
707
779
  // }
708
780
  // tri-state checkbox in indeterminate state
709
781
  .wb-col input[type="checkbox"]:indeterminate {
710
- color: $dim-color;
782
+ color: var(--wb-dim-color);
711
783
  background-color: red;
712
784
  }
713
785
 
714
786
  .wb-col input:invalid {
715
- // border-color: $error-color;
716
- color: $error-color;
717
- background-color: $error-background-color;
787
+ // border-color: var(--wb-error-color);
788
+ color: var(--wb-error-color);
789
+ background-color: var(--wb-error-background-color);
718
790
  }
719
791
 
720
792
  @keyframes wb-spin-animation {
package/src/wunderbaum.ts CHANGED
@@ -44,6 +44,8 @@ import {
44
44
  RenderFlag,
45
45
  NodeVisitCallback,
46
46
  SortCallback,
47
+ NodeToDictCallback,
48
+ WbNodeData,
47
49
  } from "./types";
48
50
  import {
49
51
  DEFAULT_DEBUGLEVEL,
@@ -1772,6 +1774,19 @@ export class Wunderbaum {
1772
1774
  this.root.sortChildren(cmp, deep);
1773
1775
  }
1774
1776
 
1777
+ /** Convert tree to an array of plain objects.
1778
+ *
1779
+ * @param callback(dict, node) is called for every node, in order to allow
1780
+ * modifications.
1781
+ * Return `false` to ignore this node or `"skip"` to include this node
1782
+ * without its children.
1783
+ * @see {@link WunderbaumNode.toDict}.
1784
+ */
1785
+ toDictArray(callback?: NodeToDictCallback): Array<WbNodeData> {
1786
+ const res = this.root.toDict(true, callback);
1787
+ return res.children ?? [];
1788
+ }
1789
+
1775
1790
  /**
1776
1791
  * Update column headers and column width.
1777
1792
  * Return true if at least one column width changed.
@@ -1900,6 +1915,14 @@ export class Wunderbaum {
1900
1915
 
1901
1916
  colElem.style.left = col._ofsPx + "px";
1902
1917
  colElem.style.width = col._widthPx + "px";
1918
+ // Add classes from `columns` definition to `<div.wb-col>` cells
1919
+ if (typeof col.headerClasses === "string") {
1920
+ col.headerClasses
1921
+ ? colElem.classList.add(...col.headerClasses.split(" "))
1922
+ : 0;
1923
+ } else {
1924
+ col.classes ? colElem.classList.add(...col.classes.split(" ")) : 0;
1925
+ }
1903
1926
 
1904
1927
  const title = util.escapeHtml(col.title || col.id);
1905
1928
  let tooltip = "";