wunderbaum 0.12.1 → 0.14.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/src/wb_options.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Wunderbaum - utils
2
+ * Wunderbaum - options
3
3
  * Copyright (c) 2021-2025, Martin Wendt. Released under the MIT license.
4
4
  * @VERSION, @DATE (https://github.com/mar10/wunderbaum)
5
5
  */
@@ -13,12 +13,15 @@ import {
13
13
  DynamicIconOption,
14
14
  EditOptionsType,
15
15
  FilterOptionsType,
16
+ IconMapType,
16
17
  // GridOptionsType,
17
18
  // KeynavOptionsType,
18
19
  // LoggerOptionsType,
19
20
  NavModeEnum,
20
21
  NodeTypeDefinitionMap,
21
22
  SelectModeType,
23
+ SourceType,
24
+ TranslationsType,
22
25
  WbActivateEventType,
23
26
  WbButtonClickEventType,
24
27
  WbCancelableEventResultType,
@@ -31,7 +34,6 @@ import {
31
34
  WbIconBadgeEventResultType,
32
35
  WbInitEventType,
33
36
  WbKeydownEventType,
34
- WbNodeData,
35
37
  WbNodeEventType,
36
38
  WbReceiveEventType,
37
39
  WbRenderEventType,
@@ -40,129 +42,73 @@ import {
40
42
  } from "./types";
41
43
 
42
44
  /**
43
- * Available options for {@link wunderbaum.Wunderbaum}.
44
- *
45
- * Options are passed to the constructor as plain object:
45
+ * Properties of {@link wunderbaum.Wunderbaum.options}.
46
46
  *
47
- * ```js
48
- * const tree = new mar10.Wunderbaum({
49
- * id: "demo",
50
- * element: document.getElementById("demo-tree"),
51
- * source: "url/of/data/request",
52
- * ...
53
- * });
54
- * ```
55
- *
56
- * Event handlers are also passed as callbacks
57
- *
58
- * ```js
59
- * const tree = new mar10.Wunderbaum({
60
- * ...
61
- * init: (e) => {
62
- * console.log(`Tree ${e.tree} was initialized and loaded.`)
63
- * },
64
- * activate: (e) => {
65
- * console.log(`Node ${e.node} was activated.`)
66
- * },
67
- * ...
68
- * });
69
- * ```
47
+ * This is similar, but not identical, to the options that can be passed to the
48
+ * constructor(@see {@link InitWunderbaumOptions}).
70
49
  */
71
50
  export interface WunderbaumOptions {
72
- /**
73
- * The target `div` element (or selector) that shall become a Wunderbaum.
74
- */
75
- element: string | HTMLDivElement;
76
- /**
77
- * The identifier of this tree. Used to reference the instance, especially
78
- * when multiple trees are present (e.g. `tree = mar10.Wunderbaum.getTree("demo")`).
79
- *
80
- * Default: `"wb_" + COUNTER`.
81
- */
82
- id?: string;
83
- /**
84
- * Define the initial tree data. Typically a URL of an endpoint that serves
85
- * a JSON formatted structure, but also a callback, Promise, or static data
86
- * is allowed.
87
- *
88
- * Default: `{}`.
89
- */
90
- source?: string | Array<WbNodeData>;
91
- /**
92
- * Define shared attributes for multiple nodes of the same type.
93
- * This allows for more compact data models. Type definitions can be passed
94
- * as tree option, or be part of a `source` response.
95
- *
96
- * Default: `{}`.
97
- */
98
- types?: NodeTypeDefinitionMap;
99
- /**
100
- * A list of maps that define column headers. If this option is set,
101
- * Wunderbaum becomes a treegrid control instead of a plain tree.
102
- * Column definitions can be passed as tree option, or be part of a `source`
103
- * response.
104
- * Default: `[]` meaning this is a plain tree.
105
- */
106
- columns?: ColumnDefinitionList;
107
51
  /**
108
52
  * If true, add a `wb-skeleton` class to all nodes, that will result in a
109
53
  * 'glow' effect. Typically used with initial dummy nodes, while loading the
110
54
  * real data.
111
- * Default: false.
55
+ * @default false.
112
56
  */
113
- skeleton?: boolean;
57
+ skeleton: boolean;
114
58
  /**
115
59
  * Translation map for some system messages.
116
- * Default:
117
- * ```js
118
- * strings: {
119
- * loading: "Loading...",
120
- * loadError: "Error",
121
- * noData: "No data",
122
- * }
123
- * ```
124
60
  */
125
- strings?: any; //[key: string] string;
61
+ strings: TranslationsType;
126
62
  /**
127
63
  * 0:quiet, 1:errors, 2:warnings, 3:info, 4:verbose
128
- * Default: 3 (4 in local debug environment)
64
+ * @default 3 (4 in local debug environment)
129
65
  */
130
- debugLevel?: number;
66
+ debugLevel: number;
131
67
  /**
132
68
  * Number of levels that are forced to be expanded, and have no expander icon.
133
69
  * E.g. 1 would keep all toplevel nodes expanded.
134
- * Default: 0
70
+ * @default 0
135
71
  */
136
- minExpandLevel?: number;
72
+ minExpandLevel: number;
137
73
  /**
138
74
  * If true, allow to expand parent nodes, even if `node.children` conatains
139
75
  * an empty array (`[]`). This is the the behavior of macOS Finder, for example.
140
- * Default: false
76
+ * @default false
141
77
  */
142
- emptyChildListExpandable?: boolean;
78
+ emptyChildListExpandable: boolean;
143
79
  // escapeTitles: boolean;
144
80
  // /**
145
81
  // * Height of the header row div.
146
- // * Default: 22
82
+ // * @default 22
147
83
  // */
148
84
  // headerHeightPx: number;
149
85
  /**
150
86
  * Height of a node row div.
151
- * Default: 22
87
+ * @default 22
152
88
  */
153
- rowHeightPx?: number;
89
+ rowHeightPx: number;
154
90
  /**
155
91
  * Icon font definition. May be a string (e.g. "fontawesome6" or "bootstrap")
156
92
  * or a map of `iconName: iconClass` pairs.
157
93
  * Note: the icon font must be loaded separately.
158
- * Default: "bootstrap"
94
+ * In order to only override some defauöt icons, use this pattern:
95
+ * ```js
96
+ * const tree = new mar10.Wunderbaum({
97
+ * ...
98
+ * iconMap: Object.assign(Wunderbaum.iconMaps.bootstrap, {
99
+ * folder: "bi bi-archive",
100
+ * }),
101
+ * });
102
+ * ```
103
+
104
+ * @default "bootstrap"
159
105
  */
160
- iconMap?: string | { [key: string]: string };
106
+ iconMap: string | IconMapType;
161
107
  /**
162
108
  * Collapse siblings when a node is expanded.
163
- * Default: false
109
+ * @default false
164
110
  */
165
- autoCollapse?: boolean;
111
+ autoCollapse: boolean;
166
112
  /**
167
113
  * If true, the tree will automatically adjust its height to fit the parent
168
114
  * container. This is useful when the tree is embedded in a container with
@@ -176,16 +122,16 @@ export interface WunderbaumOptions {
176
122
  *
177
123
  * @default: true
178
124
  */
179
- adjustHeight?: boolean;
125
+ adjustHeight: boolean;
180
126
  /**
181
- * HTMLElement that receives the top nodes breadcrumb.
182
- * Default: undefined
127
+ * HTMLElement or selector that receives the top nodes breadcrumb.
128
+ * @default undefined
183
129
  */
184
- connectTopBreadcrumb?: HTMLElement;
130
+ connectTopBreadcrumb: HTMLElement | string | null;
185
131
  /**
186
- * Default: NavModeEnum.startRow
132
+ * @default NavModeEnum.startRow
187
133
  */
188
- navigationModeOption?: NavModeEnum;
134
+ navigationModeOption: NavModeEnum;
189
135
  /**
190
136
  * Show/hide header (default: null)
191
137
  * null: assume false for plain tree and true for grids.
@@ -193,17 +139,27 @@ export interface WunderbaumOptions {
193
139
  * true: display a header (use tree's id as text for plain trees)
194
140
  * false: do not display a header
195
141
  */
196
- header?: boolean | string | null;
142
+ header: boolean | string | null;
197
143
  /**
198
- *
144
+ * Show a `<progress>` element while loading data.
145
+ * @default false.
146
+ */
147
+ showSpinner: boolean;
148
+ /**
149
+ * Generate missing keys by hashing a combination of refKey (or title) and
150
+ * the parent key. This is useful when the source data does not contain unique
151
+ * keys but we want stable keys for persisting the active node, selection or
152
+ * expansion state. Note that this still assumes that the same refKey must not
153
+ * appear twice in the same parent node.
154
+ * @default false.
199
155
  */
200
- showSpinner?: boolean;
156
+ autoKeys: boolean;
201
157
  /**
202
158
  * If true, render a checkbox before the node tile to allow selection with the
203
159
  * mouse. Pass `"radio"` to render a radio button instead.
204
- * Default: false.
160
+ * @default false.
205
161
  */
206
- checkbox?: DynamicCheckboxOption;
162
+ checkbox: DynamicCheckboxOption;
207
163
  /** Optional callback to render icons per node. */
208
164
  icon?: DynamicIconOption;
209
165
  /** Optional callback to render a tooltip for the icon. */
@@ -215,65 +171,79 @@ export interface WunderbaumOptions {
215
171
  /** Optional callback to make a node unselectable. */
216
172
  unselectable?: DynamicBoolOption;
217
173
  // /**
218
- // * Default: 200
174
+ // * @default 200
219
175
  // */
220
176
  // updateThrottleWait?: number;
221
177
  /**
222
- * Default: true
178
+ * @default true
223
179
  */
224
- enabled?: boolean;
180
+ enabled: boolean;
225
181
  /**
226
- * Default: false
182
+ *
183
+ * @default false
227
184
  */
228
- fixedCol?: boolean;
185
+ fixedCol: boolean;
229
186
  /**
230
187
  * Default value for ColumnDefinition.filterable option.
231
- * Default: false
188
+ * @default false
232
189
  * @since 0.11.0
233
190
  */
234
- columnsFilterable?: boolean;
191
+ columnsFilterable: boolean;
235
192
  /**
236
193
  * Default value for ColumnDefinition.menu option.
237
- * Default: false
194
+ * @default false
238
195
  * @since 0.11.0
239
196
  */
240
- columnsMenu?: boolean;
197
+ columnsMenu: boolean;
241
198
  /**
242
199
  * Default value for ColumnDefinition.resizable option.
243
- * Default: false
200
+ * @default false
244
201
  * @since 0.10.0
245
202
  */
246
203
  columnsResizable?: boolean;
247
204
  /**
248
205
  * Default value for ColumnDefinition.sortable option.
249
- * Default: false
206
+ * @default false
250
207
  * @since 0.11.0
251
208
  */
252
209
  columnsSortable?: boolean;
210
+ /**
211
+ * Group nodes with children or of `type: 'folder'` at the top when sorting.
212
+ * If a function is passed, it is called with the node as argument to determine
213
+ * whether the node is a folder or not. The function should return `true` for
214
+ * folders.
215
+ * and should return `true` for folders.
216
+ * @default false
217
+ * @since 0.14.0
218
+ */
219
+ sortFoldersFirst?: DynamicBoolOption;
253
220
 
254
221
  // --- Selection ---
255
222
  /**
256
- * Default: "multi"
223
+ * @default "multi"
257
224
  */
258
- selectMode?: SelectModeType;
225
+ selectMode: SelectModeType;
259
226
 
260
227
  // --- KeyNav ---
261
228
  /**
262
- * Default: true
229
+ * @default true
263
230
  */
264
- quicksearch?: boolean;
231
+ quicksearch: boolean;
265
232
 
266
233
  /**
267
234
  * Scroll Node into view on Expand Click
268
235
  * @default true
269
236
  */
270
- scrollIntoViewOnExpandClick?: boolean;
237
+ scrollIntoViewOnExpandClick: boolean;
271
238
 
272
239
  // --- Extensions ------------------------------------------------------------
273
240
 
274
- dnd?: DndOptionsType;
275
- edit?: EditOptionsType;
276
- filter?: FilterOptionsType;
241
+ /** Configuration options for the drag-and-drop extension. */
242
+ dnd: DndOptionsType;
243
+ /** Configuration options for the edit-title extension. */
244
+ edit: EditOptionsType;
245
+ /** Configuration options for the node-filter extension. */
246
+ filter: FilterOptionsType;
277
247
  // grid?: GridOptionsType;
278
248
  // keynav?: KeynavOptionsType;
279
249
  // logger?: LoggerOptionsType;
@@ -424,3 +394,88 @@ export interface WunderbaumOptions {
424
394
  */
425
395
  update?: (e: WbTreeEventType) => void;
426
396
  }
397
+
398
+ /**
399
+ * Available options for {@link wunderbaum.Wunderbaum}.
400
+ *
401
+ * Options are passed to the constructor as plain object:
402
+ *
403
+ * ```js
404
+ * const tree = new mar10.Wunderbaum({
405
+ * id: "demo",
406
+ * element: document.getElementById("demo-tree"),
407
+ * source: "url/of/data/request",
408
+ * ...
409
+ * });
410
+ * ```
411
+ *
412
+ * Event handlers are also passed as callbacks
413
+ *
414
+ * ```js
415
+ * const tree = new mar10.Wunderbaum({
416
+ * ...
417
+ * init: (e) => {
418
+ * console.log(`Tree ${e.tree} was initialized and loaded.`)
419
+ * },
420
+ * activate: (e) => {
421
+ * console.log(`Node ${e.node} was activated.`)
422
+ * },
423
+ * ...
424
+ * });
425
+ * ```
426
+ *
427
+ * Most of the properties are optional and have resonable default.
428
+ * They are then available as {@link Wunderbaum.options} property and can be
429
+ * changed at runtime. <br>
430
+ * Only the `element` option is mandatory.
431
+ *
432
+ * Note that some options passed here, are *not* available as {@link Wunderbaum.options}.
433
+ * They are moved to the `tree` instance instead:
434
+ * - `tree.element`
435
+ * - `tree.id`
436
+ * - `tree.columns`
437
+ * - `tree.types`
438
+ * - ...
439
+ *
440
+ * Some options are only used during initialization and are not stored in the
441
+ * tree instance:
442
+ * - `source`
443
+ *
444
+ */
445
+ export interface InitWunderbaumOptions extends Partial<WunderbaumOptions> {
446
+ /**
447
+ * The target `div` element (or selector) that shall become a Wunderbaum.
448
+ */
449
+ element: string | HTMLDivElement;
450
+ /**
451
+ * The identifier of this tree. Used to reference the instance, especially
452
+ * when multiple trees are present (e.g. `tree = mar10.Wunderbaum.getTree("demo")`).
453
+ *
454
+ * @default `"wb_" + COUNTER`.
455
+ */
456
+ id?: string;
457
+ /**
458
+ * A list of maps that define column headers. If this option is set,
459
+ * Wunderbaum becomes a treegrid control instead of a plain tree.
460
+ * Column definitions can be passed as tree option, or be part of a `source`
461
+ * response.
462
+ * @default `[]` meaning this is a plain tree.
463
+ */
464
+ columns?: ColumnDefinitionList;
465
+ /**
466
+ * Define shared attributes for multiple nodes of the same type.
467
+ * This allows for more compact data models. Type definitions can be passed
468
+ * as tree option, or be part of a `source` response.
469
+ *
470
+ * @default `{}`.
471
+ */
472
+ types?: NodeTypeDefinitionMap;
473
+ /**
474
+ * Define the initial tree data. Typically a URL of an endpoint that serves
475
+ * a JSON formatted structure, but also a callback, Promise, or static data
476
+ * is allowed.
477
+ *
478
+ * @default `[]`.
479
+ */
480
+ source?: SourceType;
481
+ }
@@ -759,6 +759,10 @@ div.wunderbaum {
759
759
  }
760
760
 
761
761
  /* --- TOOL CLASSES --- */
762
+ a.wb-breadcrumb {
763
+ cursor: pointer;
764
+ text-decoration: none;
765
+ }
762
766
 
763
767
  .wb-helper-center {
764
768
  text-align: center;
@@ -797,7 +801,11 @@ div.wunderbaum {
797
801
  // .wb-helper-edit-text {
798
802
  // // content-editable: true;
799
803
  // }
800
-
804
+ button.wb-filter-hide {
805
+ font-weight: bolder;
806
+ // background-color: var(--wb-active-color);
807
+ // -webkit-appearance: auto; /* Removes default Safari styles */
808
+ }
801
809
  /* RTL support */
802
810
  .wb-helper-start,
803
811
  .wb-helper-start > input {