wunderbaum 0.8.0 → 0.8.2

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
@@ -5,6 +5,7 @@
5
5
  */
6
6
 
7
7
  import {
8
+ WbCancelableEventResultType,
8
9
  ColumnDefinitionList,
9
10
  DndOptionsType,
10
11
  DynamicBoolOption,
@@ -13,6 +14,9 @@ import {
13
14
  DynamicIconOption,
14
15
  EditOptionsType,
15
16
  FilterOptionsType,
17
+ // GridOptionsType,
18
+ // KeynavOptionsType,
19
+ // LoggerOptionsType,
16
20
  NavModeEnum,
17
21
  NodeTypeDefinitionMap,
18
22
  SelectModeType,
@@ -21,6 +25,7 @@ import {
21
25
  WbClickEventType,
22
26
  WbDeactivateEventType,
23
27
  WbErrorEventType,
28
+ WbExpandEventType,
24
29
  WbIconBadgeCallback,
25
30
  WbInitEventType,
26
31
  WbKeydownEventType,
@@ -28,7 +33,9 @@ import {
28
33
  WbNodeEventType,
29
34
  WbReceiveEventType,
30
35
  WbRenderEventType,
36
+ WbSelectEventType,
31
37
  WbTreeEventType,
38
+ WbIconBadgeEventResultType,
32
39
  } from "./types";
33
40
 
34
41
  /**
@@ -230,24 +237,40 @@ export interface WunderbaumOptions {
230
237
  scrollIntoViewOnExpandClick?: boolean;
231
238
 
232
239
  // --- Extensions ------------------------------------------------------------
233
- dnd?: DndOptionsType; // = {};
234
- edit?: EditOptionsType; // = {};
235
- filter?: FilterOptionsType; // = {};
236
- grid?: any; // = {};
240
+
241
+ dnd?: DndOptionsType;
242
+ edit?: EditOptionsType;
243
+ filter?: FilterOptionsType;
244
+ // grid?: GridOptionsType;
245
+ // keynav?: KeynavOptionsType;
246
+ // logger?: LoggerOptionsType;
237
247
 
238
248
  // --- Events ----------------------------------------------------------------
239
249
 
240
250
  /**
241
- *
251
+ * `e.node` was activated.
242
252
  * @category Callback
243
253
  */
244
254
  activate?: (e: WbActivateEventType) => void;
255
+ /**
256
+ * `e.node` is about to be activated.
257
+ * Return `false` to prevent default handling, i.e. activating the node.
258
+ * See also `deactivate` event.
259
+ * @category Callback
260
+ */
261
+ beforeActivate?: (e: WbActivateEventType) => WbCancelableEventResultType;
262
+ /**
263
+ * `e.node` is about to be expanded/collapsed.
264
+ * Return `false` to prevent default handling, i.e. expanding/collapsing the node.
265
+ * @category Callback
266
+ */
267
+ beforeExpand?: (e: WbExpandEventType) => WbCancelableEventResultType;
245
268
  /**
246
269
  *
247
- * Return `false` to prevent default handling, e.g. activating the node.
270
+ * Return `false` to prevent default handling, i.e. (de)selecting the node.
248
271
  * @category Callback
249
272
  */
250
- beforeActivate?: (e: WbActivateEventType) => void;
273
+ beforeSelect?: (e: WbSelectEventType) => WbCancelableEventResultType;
251
274
  /**
252
275
  *
253
276
  * @category Callback
@@ -255,44 +278,46 @@ export interface WunderbaumOptions {
255
278
  change?: (e: WbChangeEventType) => void;
256
279
  /**
257
280
  *
258
- * Return `false` to prevent default handling, e.g. activating the node.
281
+ * Return `false` to prevent default behavior, e.g. expand/collapse, (de)selection, or activation.
259
282
  * @category Callback
260
283
  */
261
- click?: (e: WbClickEventType) => void;
284
+ click?: (e: WbClickEventType) => WbCancelableEventResultType;
262
285
  /**
263
- *
286
+ * Return `false` to prevent default behavior, e.g. expand/collapse.
264
287
  * @category Callback
265
288
  */
266
- dblclick?: (e: WbClickEventType) => void;
289
+ dblclick?: (e: WbClickEventType) => WbCancelableEventResultType;
267
290
  /**
291
+ * `e.node` was deactivated.
268
292
  *
269
293
  * Return `false` to prevent default handling, e.g. deactivating the node
270
294
  * and activating the next.
295
+ * See also `activate` event.
271
296
  * @category Callback
272
297
  */
273
- deactivate?: (e: WbDeactivateEventType) => void;
298
+ deactivate?: (e: WbDeactivateEventType) => WbCancelableEventResultType;
274
299
  /**
275
- *
300
+ * `e.node` was discarded from the viewport and its HTML markup removed.
276
301
  * @category Callback
277
302
  */
278
303
  discard?: (e: WbNodeEventType) => void;
279
304
  /**
280
- *
305
+ * `e.node` is about to be rendered. We can add a badge to the icon cell here.
281
306
  * @category Callback
282
307
  */
283
- iconBadge?: WbIconBadgeCallback;
284
- // /**
285
- // *
286
- // * @category Callback
287
- // */
288
- // enhanceTitle?: (e: WbEnhanceTitleEventType) => void;
308
+ iconBadge?: (e: WbIconBadgeCallback) => WbIconBadgeEventResultType;
289
309
  /**
290
- *
310
+ * An error occurred, e.g. during initialization or lazy loading.
291
311
  * @category Callback
292
312
  */
293
313
  error?: (e: WbErrorEventType) => void;
294
314
  /**
295
- *
315
+ * `e.node` was expanded (`e.flag === true`) or collapsed (`e.flag === false`)
316
+ * @category Callback
317
+ */
318
+ expand?: (e: WbTreeEventType) => void;
319
+ /**
320
+ * The tree received or lost focus.
296
321
  * Check `e.flag` for status.
297
322
  * @category Callback
298
323
  */
@@ -301,15 +326,17 @@ export interface WunderbaumOptions {
301
326
  * Fires when the tree markup was created and the initial source data was loaded.
302
327
  * Typical use cases would be activating a node, setting focus, enabling other
303
328
  * controls on the page, etc.<br>
304
- * Check `e.error` for status.
329
+ * Also sent if an error occured during initialization (check `e.error` for status).
305
330
  * @category Callback
306
331
  */
307
332
  init?: (e: WbInitEventType) => void;
308
333
  /**
309
- *
334
+ * Fires when a key was pressed while the tree has focus.
335
+ * `e.node` is set if a node is currently active.
336
+ * Return `false` to prevent default navigation.
310
337
  * @category Callback
311
338
  */
312
- keydown?: (e: WbKeydownEventType) => void;
339
+ keydown?: (e: WbKeydownEventType) => WbCancelableEventResultType;
313
340
  /**
314
341
  * Fires when a node that was marked 'lazy', is expanded for the first time.
315
342
  * Typically we return an endpoint URL or the Promise of a fetch request that
@@ -345,13 +372,12 @@ export interface WunderbaumOptions {
345
372
  */
346
373
  render?: (e: WbRenderEventType) => void;
347
374
  /**
348
- *
375
+ * Same as `render(e)`, but for the status nodes, i.e. `e.node.statusNodeType`.
349
376
  * @category Callback
350
377
  */
351
378
  renderStatusNode?: (e: WbRenderEventType) => void;
352
379
  /**
353
- *
354
- * Check `e.flag` for status.
380
+ *`e.node` was selected (`e.flag === true`) or deselected (`e.flag === false`)
355
381
  * @category Callback
356
382
  */
357
383
  select?: (e: WbNodeEventType) => void;
package/src/wunderbaum.ts CHANGED
@@ -119,10 +119,23 @@ export class Wunderbaum {
119
119
  protected _disableUpdateCount = 0;
120
120
  protected _disableUpdateIgnoreCount = 0;
121
121
 
122
- /** Currently active node if any. */
123
- public activeNode: WunderbaumNode | null = null;
124
- /** Current node hat has keyboard focus if any. */
125
- public focusNode: WunderbaumNode | null = null;
122
+ protected _activeNode: WunderbaumNode | null = null;
123
+ protected _focusNode: WunderbaumNode | null = null;
124
+
125
+ /** Currently active node if any.
126
+ * Use @link {WunderbaumNode.setActive|setActive} to modify.
127
+ */
128
+ public get activeNode() {
129
+ // Check for deleted node, i.e. node.tree === null
130
+ return this._activeNode?.tree ? this._activeNode : null;
131
+ }
132
+ /** Current node hat has keyboard focus if any.
133
+ * Use @link {WunderbaumNode.setFocus|setFocus()} to modify.
134
+ */
135
+ public get focusNode() {
136
+ // Check for deleted node, i.e. node.tree === null
137
+ return this._focusNode?.tree ? this._focusNode : null;
138
+ }
126
139
 
127
140
  /** Shared properties, referenced by `node.type`. */
128
141
  public types: NodeTypeDefinitionMap = {};
@@ -617,10 +630,8 @@ export class Wunderbaum {
617
630
  /** Add node to tree's bookkeeping data structures. */
618
631
  _registerNode(node: WunderbaumNode): void {
619
632
  const key = node.key;
620
- util.assert(
621
- key != null && !this.keyMap.has(key),
622
- `Missing or duplicate key: '${key}'.`
623
- );
633
+ util.assert(key != null, `Missing key: '${node}'.`);
634
+ util.assert(!this.keyMap.has(key), `Duplicate key: '${key}': ${node}.`);
624
635
  this.keyMap.set(key, node);
625
636
  const rk = node.refKey;
626
637
  if (rk != null) {
@@ -948,8 +959,8 @@ export class Wunderbaum {
948
959
  this.keyMap.clear();
949
960
  this.refKeyMap.clear();
950
961
  this.treeRowCount = 0;
951
- this.activeNode = null;
952
- this.focusNode = null;
962
+ this._activeNode = null;
963
+ this._focusNode = null;
953
964
 
954
965
  // this.types = {};
955
966
  // this. columns =[];
@@ -1392,10 +1403,13 @@ export class Wunderbaum {
1392
1403
  }
1393
1404
 
1394
1405
  /**
1395
- * Return the currently active node or null.
1406
+ * Return the currently active node or null (alias for `tree.activeNode`).
1407
+ * Alias for {@link Wunderbaum.activeNode}.
1408
+ *
1396
1409
  * @see {@link WunderbaumNode.setActive}
1397
1410
  * @see {@link WunderbaumNode.isActive}
1398
- * @see {@link WunderbaumNode.getFocusNode}
1411
+ * @see {@link Wunderbaum.activeNode}
1412
+ * @see {@link Wunderbaum.focusNode}
1399
1413
  */
1400
1414
  getActiveNode() {
1401
1415
  return this.activeNode;
@@ -1410,7 +1424,11 @@ export class Wunderbaum {
1410
1424
 
1411
1425
  /**
1412
1426
  * Return the node that currently has keyboard focus or null.
1413
- * @see {@link WunderbaumNode.getActiveNode}
1427
+ * Alias for {@link Wunderbaum.focusNode}.
1428
+ * @see {@link WunderbaumNode.setFocus}
1429
+ * @see {@link WunderbaumNode.hasFocus}
1430
+ * @see {@link Wunderbaum.activeNode}
1431
+ * @see {@link Wunderbaum.focusNode}
1414
1432
  */
1415
1433
  getFocusNode() {
1416
1434
  return this.focusNode;
@@ -1522,26 +1540,33 @@ export class Wunderbaum {
1522
1540
  return res;
1523
1541
  }
1524
1542
 
1525
- /** Alias for {@link Wunderbaum.logDebug}.
1526
- * @alias Wunderbaum.logDebug
1543
+ /** Write to `console.log` with tree name as prefix if opts.debugLevel >= 4.
1544
+ * @see {@link Wunderbaum.logDebug}
1527
1545
  */
1528
- log = this.logDebug;
1546
+ log(...args: any[]) {
1547
+ if (this.options.debugLevel! >= 4) {
1548
+ console.log(this.toString(), ...args); // eslint-disable-line no-console
1549
+ }
1550
+ }
1529
1551
 
1530
- /** Log to console if opts.debugLevel >= 4 */
1552
+ /** Write to `console.debug` with tree name as prefix if opts.debugLevel >= 4.
1553
+ * and browser console level includes debug/verbose messages.
1554
+ * @see {@link Wunderbaum.log}
1555
+ */
1531
1556
  logDebug(...args: any[]) {
1532
1557
  if (this.options.debugLevel! >= 4) {
1533
- console.log(this.toString(), ...args); // eslint-disable-line no-console
1558
+ console.debug(this.toString(), ...args); // eslint-disable-line no-console
1534
1559
  }
1535
1560
  }
1536
1561
 
1537
- /** Log error to console. */
1562
+ /** Write to `console.error` with tree name as prefix. */
1538
1563
  logError(...args: any[]) {
1539
1564
  if (this.options.debugLevel! >= 1) {
1540
1565
  console.error(this.toString(), ...args); // eslint-disable-line no-console
1541
1566
  }
1542
1567
  }
1543
1568
 
1544
- /** Log to console if opts.debugLevel >= 3 */
1569
+ /** Write to `console.info` with tree name as prefix if opts.debugLevel >= 3. */
1545
1570
  logInfo(...args: any[]) {
1546
1571
  if (this.options.debugLevel! >= 3) {
1547
1572
  console.info(this.toString(), ...args); // eslint-disable-line no-console
@@ -1563,7 +1588,7 @@ export class Wunderbaum {
1563
1588
  }
1564
1589
  }
1565
1590
 
1566
- /** Log to console if opts.debugLevel >= 2 */
1591
+ /** Write to `console.warn` with tree name as prefix with if opts.debugLevel >= 2. */
1567
1592
  logWarn(...args: any[]) {
1568
1593
  if (this.options.debugLevel! >= 2) {
1569
1594
  console.warn(this.toString(), ...args); // eslint-disable-line no-console
@@ -1721,6 +1746,11 @@ export class Wunderbaum {
1721
1746
  }
1722
1747
  }
1723
1748
 
1749
+ /* Set or remove keyboard focus to the tree container. @internal */
1750
+ _setActiveNode(node: WunderbaumNode | null) {
1751
+ this._activeNode = node;
1752
+ }
1753
+
1724
1754
  /** Set or remove keyboard focus to the tree container. */
1725
1755
  setActiveNode(key: string, flag: boolean = true, options?: SetActiveOptions) {
1726
1756
  this.findKey(key)?.setActive(flag, options);
@@ -1735,6 +1765,11 @@ export class Wunderbaum {
1735
1765
  }
1736
1766
  }
1737
1767
 
1768
+ /* Set or remove keyboard focus to the tree container. @internal */
1769
+ _setFocusNode(node: WunderbaumNode | null) {
1770
+ this._focusNode = node;
1771
+ }
1772
+
1738
1773
  /**
1739
1774
  * Schedule an update request to reflect a tree change.
1740
1775
  * The render operation is async and debounced unless the `immediate` option