@nvidia-elements/core 2.18.3 → 2.19.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.
Files changed (122) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/accordion/accordion2.js +4 -4
  3. package/dist/alert/alert-group2.js +1 -1
  4. package/dist/alert/alert2.js +1 -1
  5. package/dist/avatar/avatar-group2.js +1 -1
  6. package/dist/avatar/avatar2.js +1 -1
  7. package/dist/badge/badge2.js +1 -1
  8. package/dist/breadcrumb/breadcrumb2.js +1 -1
  9. package/dist/bundles/index.d.ts +6 -0
  10. package/dist/bundles/index.js +7 -7
  11. package/dist/button/button2.js +1 -1
  12. package/dist/button-group/button-group2.js +1 -1
  13. package/dist/card/card2.js +4 -4
  14. package/dist/chat-message/chat-message2.js +1 -1
  15. package/dist/checkbox/checkbox-group2.js +1 -1
  16. package/dist/checkbox/checkbox2.js +1 -1
  17. package/dist/color/color2.js +1 -1
  18. package/dist/combobox/combobox2.js +1 -1
  19. package/dist/copy-button/copy-button2.js +1 -1
  20. package/dist/custom-elements-jsx.d.ts +6 -0
  21. package/dist/custom-elements-vue.d.ts +6 -0
  22. package/dist/custom-elements.json +87 -1
  23. package/dist/data.html.json +10 -0
  24. package/dist/date/date2.js +1 -1
  25. package/dist/datetime/datetime2.js +1 -1
  26. package/dist/dialog/dialog-footer2.js +1 -1
  27. package/dist/dialog/dialog-header2.js +1 -1
  28. package/dist/dialog/dialog2.js +1 -1
  29. package/dist/divider/divider2.js +1 -1
  30. package/dist/dot/dot2.js +1 -1
  31. package/dist/drag-handle/drag-handle2.js +1 -1
  32. package/dist/drawer/drawer-content2.js +1 -1
  33. package/dist/drawer/drawer-footer2.js +1 -1
  34. package/dist/drawer/drawer-header2.js +1 -1
  35. package/dist/drawer/drawer2.js +1 -1
  36. package/dist/dropdown/dropdown-footer2.js +1 -1
  37. package/dist/dropdown/dropdown-header2.js +1 -1
  38. package/dist/dropdown/dropdown2.js +1 -1
  39. package/dist/dropdown-group/dropdown-group.js +1 -1
  40. package/dist/dropzone/dropzone2.js +1 -1
  41. package/dist/file/file2.js +1 -1
  42. package/dist/format-bytes/format-bytes2.js +1 -1
  43. package/dist/format-datetime/format-datetime2.js +1 -1
  44. package/dist/format-number/format-number2.js +1 -1
  45. package/dist/format-relative-time/format-relative-time2.js +1 -1
  46. package/dist/format-truncate/format-truncate2.js +1 -1
  47. package/dist/forms/control/control2.js +1 -1
  48. package/dist/forms/control-group/control-group2.js +1 -1
  49. package/dist/forms/control-message/control-message2.js +1 -1
  50. package/dist/gauge/gauge2.js +1 -1
  51. package/dist/grid/cell/cell2.js +1 -1
  52. package/dist/grid/column/column2.js +1 -1
  53. package/dist/grid/footer/footer2.js +1 -1
  54. package/dist/grid/grid2.js +1 -1
  55. package/dist/grid/header/header2.js +1 -1
  56. package/dist/grid/placeholder/placeholder2.js +1 -1
  57. package/dist/grid/row/row2.js +1 -1
  58. package/dist/icon/icon2.js +2 -2
  59. package/dist/icon-button/icon-button2.js +1 -1
  60. package/dist/iframe/iframe2.js +1 -1
  61. package/dist/index.js +1 -1
  62. package/dist/input/input-group2.js +1 -1
  63. package/dist/input/input2.js +1 -1
  64. package/dist/internal/controllers/audit.controller.js.map +1 -1
  65. package/dist/logo/logo2.js +1 -1
  66. package/dist/menu/menu-group2.js +1 -1
  67. package/dist/menu/menu-item2.js +1 -1
  68. package/dist/menu/menu2.js +1 -1
  69. package/dist/month/month2.js +1 -1
  70. package/dist/notification/notification-group2.js +1 -1
  71. package/dist/notification/notification2.js +1 -1
  72. package/dist/page/page-panel/page-panel-content2.js +1 -1
  73. package/dist/page/page-panel/page-panel-footer2.js +1 -1
  74. package/dist/page/page-panel/page-panel-header2.js +1 -1
  75. package/dist/page/page-panel/page-panel2.js +1 -1
  76. package/dist/page/page2.js +1 -1
  77. package/dist/page-header/page-header2.js +1 -1
  78. package/dist/page-loader/page-loader2.js +1 -1
  79. package/dist/pagination/pagination2.js +1 -1
  80. package/dist/panel/panel2.js +4 -4
  81. package/dist/password/password2.js +1 -1
  82. package/dist/preferences-input/preferences-input2.js +1 -1
  83. package/dist/progress-bar/progress-bar2.js +1 -1
  84. package/dist/progress-dot/progress-dot2.js +1 -1
  85. package/dist/progress-ring/progress-ring2.js +1 -1
  86. package/dist/progressive-filter-chip/progressive-filter-chip.js +1 -1
  87. package/dist/progressive-filter-chip/progressive-filter-chip.js.map +1 -1
  88. package/dist/progressive-filter-chip/progressive-filter-chip2.js +1 -1
  89. package/dist/pulse/pulse2.js +1 -1
  90. package/dist/radio/radio-group2.js +1 -1
  91. package/dist/radio/radio2.js +1 -1
  92. package/dist/range/range2.js +1 -1
  93. package/dist/resize-handle/resize-handle2.js +1 -1
  94. package/dist/search/search2.js +1 -1
  95. package/dist/select/select2.js +1 -1
  96. package/dist/skeleton/skeleton2.js +1 -1
  97. package/dist/sort-button/sort-button2.js +1 -1
  98. package/dist/sparkline/sparkline2.js +1 -1
  99. package/dist/star-rating/star-rating2.js +1 -1
  100. package/dist/steps/steps2.js +2 -2
  101. package/dist/switch/switch-group2.js +1 -1
  102. package/dist/switch/switch2.js +1 -1
  103. package/dist/tabs/tabs-group2.js +1 -1
  104. package/dist/tabs/tabs-item-group2.js +1 -1
  105. package/dist/tabs/tabs2.js +2 -2
  106. package/dist/tag/tag2.js +1 -1
  107. package/dist/textarea/textarea2.js +1 -1
  108. package/dist/time/time2.js +1 -1
  109. package/dist/toast/toast2.js +1 -1
  110. package/dist/toggletip/toggletip-footer2.js +1 -1
  111. package/dist/toggletip/toggletip-header2.js +1 -1
  112. package/dist/toggletip/toggletip2.js +1 -1
  113. package/dist/toolbar/toolbar2.js +1 -1
  114. package/dist/tooltip/tooltip2.js +1 -1
  115. package/dist/tree/tree-node.d.ts +6 -0
  116. package/dist/tree/tree-node2.js +71 -58
  117. package/dist/tree/tree-node2.js.map +1 -1
  118. package/dist/tree/tree.examples.js.map +1 -1
  119. package/dist/tree/tree.examples.json +9 -0
  120. package/dist/tree/tree2.js +1 -1
  121. package/dist/week/week2.js +1 -1
  122. package/package.json +3 -3
@@ -19,7 +19,7 @@ var d = class extends s {
19
19
  static {
20
20
  this.metadata = {
21
21
  tag: "nve-tooltip",
22
- version: "2.18.3"
22
+ version: "2.19.0"
23
23
  };
24
24
  }
25
25
  render() {
@@ -38,6 +38,12 @@ import { Checkbox } from '@nvidia-elements/core/checkbox';
38
38
  */
39
39
  export declare class TreeNode extends LitElement {
40
40
  #private;
41
+ /** Command to invoke on a node title click or Enter on its header. */
42
+ command: string;
43
+ /** ID of the element that receives the command. */
44
+ commandfor: string | null;
45
+ /** Direct command target, taking precedence over commandfor. */
46
+ commandForElement: HTMLElement | null;
41
47
  /**
42
48
  * Determines if node is in an expanded state.
43
49
  */
@@ -1,35 +1,37 @@
1
1
  import { audit as e } from "../internal/controllers/audit.controller.js";
2
2
  import { I18nController as t } from "../internal/controllers/i18n.controller.js";
3
- import { getFlattenedFocusableItems as n } from "../internal/utils/dom.js";
4
- import { attachInternals as r } from "../internal/utils/a11y.js";
5
- import { stateExpanded as i } from "../internal/controllers/state-expanded.controller.js";
6
- import { stateHighlighted as a } from "../internal/controllers/state-highlighted.controller.js";
7
- import { stateSelected as o } from "../internal/controllers/state-selected.controller.js";
8
- import { typeAnchor as s } from "../internal/controllers/type-anchor.controller.js";
9
- import { TypeExpandableController as c } from "../internal/controllers/type-expandable.controller.js";
10
- import { TypeSelectableController as l } from "../internal/controllers/type-selectable.controller.js";
11
- import { typeSSR as u } from "../internal/controllers/type-ssr.controller.js";
12
- import { hostAttr as d } from "../internal/decorators/host-attr.js";
13
- import { scopedRegistry as f } from "../internal/decorators/scoped-registry.js";
14
- import { useStyles as p } from "../internal/styles/index.js";
15
- import m from "../_virtual/_@oxc-project_runtime@0.147.0/helpers/esm/decorate.js";
16
- import { Icon as h } from "../icon/icon2.js";
17
- import { IconButton as g } from "../icon-button/icon-button2.js";
18
- import { updateNodeSelection as _ } from "./utils.js";
19
- import { Checkbox as v } from "../checkbox/checkbox2.js";
20
- import y from "./tree-node.js";
21
- import { LitElement as b, html as x, nothing as S } from "lit";
22
- import { property as C } from "lit/decorators/property.js";
23
- import { state as w } from "lit/decorators/state.js";
24
- import { queryAssignedElements as T } from "lit/decorators/query-assigned-elements.js";
3
+ import { isFocusable as n } from "../internal/utils/focus.js";
4
+ import { getFlattenedFocusableItems as r } from "../internal/utils/dom.js";
5
+ import { attachInternals as i } from "../internal/utils/a11y.js";
6
+ import { stateExpanded as a } from "../internal/controllers/state-expanded.controller.js";
7
+ import { stateHighlighted as o } from "../internal/controllers/state-highlighted.controller.js";
8
+ import { stateSelected as s } from "../internal/controllers/state-selected.controller.js";
9
+ import { typeAnchor as c } from "../internal/controllers/type-anchor.controller.js";
10
+ import { TypeExpandableController as l } from "../internal/controllers/type-expandable.controller.js";
11
+ import { TypeSelectableController as u } from "../internal/controllers/type-selectable.controller.js";
12
+ import { typeSSR as d } from "../internal/controllers/type-ssr.controller.js";
13
+ import { hostAttr as f } from "../internal/decorators/host-attr.js";
14
+ import { scopedRegistry as p } from "../internal/decorators/scoped-registry.js";
15
+ import { useStyles as m } from "../internal/styles/index.js";
16
+ import h from "../_virtual/_@oxc-project_runtime@0.147.0/helpers/esm/decorate.js";
17
+ import { Icon as g } from "../icon/icon2.js";
18
+ import { IconButton as _ } from "../icon-button/icon-button2.js";
19
+ import { updateNodeSelection as v } from "./utils.js";
20
+ import { Checkbox as y } from "../checkbox/checkbox2.js";
21
+ import b from "./tree-node.js";
22
+ import { LitElement as x, html as S, nothing as C } from "lit";
23
+ import { property as w } from "lit/decorators/property.js";
24
+ import { state as T } from "lit/decorators/state.js";
25
+ import { queryAssignedElements as E } from "lit/decorators/query-assigned-elements.js";
26
+ import { TypeCommandController as D } from "@nvidia-elements/forms/internal";
25
27
  //#region src/tree/tree-node.ts
26
- var E = class extends b {
28
+ var O = class extends x {
27
29
  constructor(...e) {
28
- super(...e), this.expanded = !1, this.selected = !1, this.expandable = !1, this.highlighted = !1, this.#e = new t(this), this.i18n = this.#e.i18n, this.slot = "nodes", this.indeterminate = !1, this.behaviorExpand = !1, this.behaviorSelect = !1, this.#n = new c(this), this.#r = new l(this), this.#s = (e) => {
29
- let t = this.selectable && e.code === "Space", n = this.#i && (e.code === "ArrowLeft" || e.code === "ArrowRight");
30
+ super(...e), this.command = "", this.commandfor = null, this.commandForElement = null, this.expanded = !1, this.selected = !1, this.expandable = !1, this.highlighted = !1, this.#e = new t(this), this.i18n = this.#e.i18n, this.slot = "nodes", this.indeterminate = !1, this.behaviorExpand = !1, this.behaviorSelect = !1, this.#n = new l(this), this.#r = new u(this), this.#i = new D(this, { events: [] }), this.#c = (e) => {
31
+ let t = this.selectable && e.code === "Space", n = this.#a && (e.code === "ArrowLeft" || e.code === "ArrowRight");
30
32
  e.target === this && (t || n) && e.preventDefault();
31
- }, this.#c = (e) => {
32
- this.#i && e.code === "ArrowLeft" && e.target === this && this.close(), this.#i && e.code === "ArrowRight" && e.target === this && this.open(), e.code === "Space" && e.target === this && this.selectable && this.#d();
33
+ }, this.#u = (e) => {
34
+ this.#l(e), this.#a && e.code === "ArrowLeft" && e.target === this && this.close(), this.#a && e.code === "ArrowRight" && e.target === this && this.open(), e.code === "Space" && e.target === this && this.selectable && this.#p();
33
35
  };
34
36
  }
35
37
  #e;
@@ -38,34 +40,35 @@ var E = class extends b {
38
40
  }
39
41
  #n;
40
42
  #r;
41
- get #i() {
43
+ #i;
44
+ get #a() {
42
45
  return this.expandable || this.expanded || !!this.nodes?.length;
43
46
  }
44
47
  static {
45
48
  this.metadata = {
46
49
  tag: "nve-tree-node",
47
- version: "2.18.3",
50
+ version: "2.19.0",
48
51
  parents: ["nve-tree", "nve-tree-node"]
49
52
  };
50
53
  }
51
54
  static {
52
55
  this.elementDefinitions = {
56
+ [_.metadata.tag]: _,
53
57
  [g.metadata.tag]: g,
54
- [h.metadata.tag]: h,
55
- [v.metadata.tag]: v
58
+ [y.metadata.tag]: y
56
59
  };
57
60
  }
58
61
  static {
59
- this.styles = p([y]);
62
+ this.styles = m([b]);
60
63
  }
61
64
  render() {
62
- return x`<div internal-host @slotchange="${this.#a}"><div part="_node">${this.#i ? x`<nve-icon-button part="icon-button" exportparts="icon:icon-button-icon" @pointerup="${this.#u}" role="presentation" tabindex="-1" size="sm" container="inline" nofocus><nve-icon part="icon" name="caret" direction="${this.expanded ? "down" : "right"}" size="sm"></nve-icon></nve-icon-button>` : S} ${this.selectable === "multi" ? x`<nve-checkbox part="checkbox" nofocus><input type="checkbox" @change="${this.#p}" .checked="${this.selected}" .indeterminate="${this.indeterminate}" .ariaLabel="${this.i18n.expand}" tabindex="-1"></nve-checkbox>` : S}<div tabindex="0" part="_node-header"><div class="node-title" @click="${this.#l}"><slot name="prefix" part="_prefix"></slot><slot></slot><slot name="suffix" part="_suffix"></slot></div><slot name="content" part="_content"></slot></div></div><div role="group" part="_nodes"><slot name="nodes"></slot></div></div>`;
65
+ return S`<div internal-host @slotchange="${this.#o}"><div part="_node">${this.#a ? S`<nve-icon-button part="icon-button" exportparts="icon:icon-button-icon" @pointerup="${this.#f}" role="presentation" tabindex="-1" size="sm" container="inline" nofocus><nve-icon part="icon" name="caret" direction="${this.expanded ? "down" : "right"}" size="sm"></nve-icon></nve-icon-button>` : C} ${this.selectable === "multi" ? S`<nve-checkbox part="checkbox" nofocus><input type="checkbox" @change="${this.#h}" .checked="${this.selected}" .indeterminate="${this.indeterminate}" .ariaLabel="${this.i18n.expand}" tabindex="-1"></nve-checkbox>` : C}<div tabindex="0" part="_node-header"><div class="node-title" @click="${this.#d}"><slot name="prefix" part="_prefix"></slot><slot></slot><slot name="suffix" part="_suffix"></slot></div><slot name="content" part="_content"></slot></div></div><div role="group" part="_nodes"><slot name="nodes"></slot></div></div>`;
63
66
  }
64
67
  connectedCallback() {
65
- super.connectedCallback(), r(this), this._internals.role = "treeitem", this.addEventListener("keydown", this.#s), this.addEventListener("keyup", this.#c), this.#a();
68
+ super.connectedCallback(), i(this), this._internals.role = "treeitem", this.addEventListener("keydown", this.#c), this.addEventListener("keyup", this.#u), this.#o();
66
69
  }
67
70
  disconnectedCallback() {
68
- super.disconnectedCallback(), this.removeEventListener("keydown", this.#s), this.removeEventListener("keyup", this.#c);
71
+ super.disconnectedCallback(), this.removeEventListener("keydown", this.#c), this.removeEventListener("keyup", this.#u);
69
72
  }
70
73
  open() {
71
74
  this.#n.open();
@@ -73,49 +76,59 @@ var E = class extends b {
73
76
  close() {
74
77
  this.#n.close();
75
78
  }
76
- #a() {
77
- this.requestUpdate(), this.#o();
78
- }
79
79
  #o() {
80
- this.#i ? this._internals.states.add("is-expandable") : this._internals.states.delete("is-expandable");
80
+ this.requestUpdate(), this.#s();
81
+ }
82
+ #s() {
83
+ this.#a ? this._internals.states.add("is-expandable") : this._internals.states.delete("is-expandable");
81
84
  }
82
- #s;
83
85
  #c;
84
86
  #l(e) {
85
- let t = n(e.currentTarget).length;
86
- this.#i && !this.selectable && !t && this.#u(), this.selectable && (!t || e.target.localName === "a") && this.#d();
87
+ if (e.code !== "Enter" || e.defaultPrevented || e.repeat) return;
88
+ let t = e.composedPath()[0];
89
+ (t === this.shadowRoot?.querySelector("[part=\"_node-header\"]") || t === this) && this.#i.invoke();
87
90
  }
88
- #u() {
91
+ #u;
92
+ #d(e) {
93
+ let t = r(e.currentTarget).length;
94
+ this.#a && !this.selectable && !t && this.#f(), this.selectable && (!t || e.target.localName === "a") && this.#p();
95
+ let i = e.composedPath();
96
+ !i.slice(0, i.indexOf(e.currentTarget)).some((e) => e instanceof Element && n(e)) && !e.defaultPrevented && this.#i.invoke();
97
+ }
98
+ #f() {
89
99
  this.#n.toggle();
90
100
  }
91
- #d() {
92
- this.selectable === "single" && this.#f(), this.selectable === "multi" && this.#p();
101
+ #p() {
102
+ this.selectable === "single" && this.#m(), this.selectable === "multi" && this.#h();
93
103
  }
94
- #f() {
104
+ #m() {
95
105
  this.#r.toggle(), this.behaviorSelect && this.#t.nodes.filter((e) => e !== this).forEach((e) => e.selected = !1);
96
106
  }
97
- #p() {
107
+ #h() {
98
108
  this.#r.toggle(), this.behaviorSelect && (this.nodes.forEach((e) => {
99
109
  e.selected = this.selected, e.indeterminate = !1;
100
- }), this.#t.nodes.forEach((e) => _(e)));
110
+ }), this.#t.nodes.forEach((e) => v(e)));
101
111
  }
102
112
  };
103
- m([C({
113
+ h([w({ type: String })], O.prototype, "command", void 0), h([w({
114
+ type: String,
115
+ reflect: !0
116
+ })], O.prototype, "commandfor", void 0), h([w({ attribute: !1 })], O.prototype, "commandForElement", void 0), h([w({
104
117
  type: Boolean,
105
118
  reflect: !0
106
- })], E.prototype, "expanded", void 0), m([C({
119
+ })], O.prototype, "expanded", void 0), h([w({
107
120
  type: Boolean,
108
121
  reflect: !0
109
- })], E.prototype, "selected", void 0), m([C({ type: Boolean })], E.prototype, "expandable", void 0), m([C({ type: String })], E.prototype, "selectable", void 0), m([C({ type: Boolean })], E.prototype, "highlighted", void 0), m([C({ type: Object })], E.prototype, "i18n", void 0), m([d()], E.prototype, "slot", void 0), m([T({ slot: "nodes" })], E.prototype, "nodes", void 0), m([w()], E.prototype, "indeterminate", void 0), m([w()], E.prototype, "behaviorExpand", void 0), m([w()], E.prototype, "behaviorSelect", void 0), E = m([
122
+ })], O.prototype, "selected", void 0), h([w({ type: Boolean })], O.prototype, "expandable", void 0), h([w({ type: String })], O.prototype, "selectable", void 0), h([w({ type: Boolean })], O.prototype, "highlighted", void 0), h([w({ type: Object })], O.prototype, "i18n", void 0), h([f()], O.prototype, "slot", void 0), h([E({ slot: "nodes" })], O.prototype, "nodes", void 0), h([T()], O.prototype, "indeterminate", void 0), h([T()], O.prototype, "behaviorExpand", void 0), h([T()], O.prototype, "behaviorSelect", void 0), O = h([
110
123
  e(),
111
- u({ log: !1 }),
124
+ d({ log: !1 }),
125
+ c(),
112
126
  s(),
113
- o(),
114
- i(),
115
- f(),
116
- a()
117
- ], E);
127
+ a(),
128
+ p(),
129
+ o()
130
+ ], O);
118
131
  //#endregion
119
- export { E as TreeNode };
132
+ export { O as TreeNode };
120
133
 
121
134
  //# sourceMappingURL=tree-node2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tree-node2.js","names":[],"sources":["../../src/tree/tree-node.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { LitElement, html, nothing } from 'lit';\nimport { property } from 'lit/decorators/property.js';\nimport { state } from 'lit/decorators/state.js';\nimport { queryAssignedElements } from 'lit/decorators/query-assigned-elements.js';\nimport {\n I18nController,\n TypeExpandableController,\n TypeSelectableController,\n attachInternals,\n audit,\n getFlattenedFocusableItems,\n hostAttr,\n scopedRegistry,\n stateExpanded,\n stateHighlighted,\n stateSelected,\n typeAnchor,\n typeSSR,\n useStyles\n} from '@nvidia-elements/core/internal';\nimport { IconButton } from '@nvidia-elements/core/icon-button';\nimport { Icon } from '@nvidia-elements/core/icon';\nimport { Checkbox } from '@nvidia-elements/core/checkbox';\nimport type { Tree } from './tree.js';\nimport styles from './tree-node.css?inline';\nimport { updateNodeSelection } from './utils.js';\n\n/**\n * @element nve-tree-node\n * @description A tree view widget presents a hierarchical list. Any item in the hierarchy may have child items, and items that have children can expand or collapse to show or hide the children.\n * @documentation https://nvidia.github.io/elements/docs/elements/tree/\n * @since 1.2.0\n * @entrypoint \\@nvidia-elements/core/tree\n * @event open - Dispatched when the node opens.\n * @event close - Dispatched when the node closes.\n * @event select - Dispatched when the node selection state changes.\n * @command --select - use to select the node\n * @command --deselect - use to deselect the node\n * @command --toggle-select - use to toggle the node selection state\n * @command --open - use to open the node\n * @command --close - use to close the node\n * @command --toggle - use to toggle open / closed state of the node\n * @slot - Use default slot for basic text content or nested <nve-tree-node> elements.\n * @slot prefix - Use for prefix content before the node title.\n * @slot suffix - Use for suffix content after the node title.\n * @slot content - Use only for extended long form content containing interactive elements or form inputs.\n * @cssprop --color\n * @cssprop --border-radius\n * @cssprop --font-size\n * @cssprop --min-height\n * @cssprop --text-wrap\n * @cssprop --font-weight\n * @cssprop --width\n\n * @csspart icon-button - The icon button element\n * @csspart icon - The icon element\n * @csspart checkbox - The checkbox element\n\n * @aria https://www.w3.org/WAI/ARIA/apg/patterns/treeview/\n *\n */\n@audit()\n@typeSSR({ log: false }) // warning about ssr mismatch disabled as tree node will never be a 1:1 match in ssr due to performance constraints and slot complexity\n@typeAnchor()\n@stateSelected()\n@stateExpanded()\n@scopedRegistry()\n@stateHighlighted()\nexport class TreeNode extends LitElement {\n /**\n * Determines if node is in an expanded state.\n */\n @property({ type: Boolean, reflect: true }) expanded = false;\n\n /**\n * Determines whether if node is in a selected state.\n */\n @property({ type: Boolean, reflect: true }) selected = false;\n\n /**\n * Determines whether a node can be expandable. Expandable by default if slotted nodes exist.\n */\n @property({ type: Boolean }) expandable = false;\n\n /**\n * Determines whether a node can be in a selected state. Nodes can be in a single or multi select state.\n */\n @property({ type: String }) selectable: 'single' | 'multi';\n\n /**\n * Determines the highlighted state of the element. Highlighted states serve non-interactive selections where nodes may relate to other selected portions of the UI.\n */\n @property({ type: Boolean }) highlighted = false;\n\n #i18nController: I18nController<this> = new I18nController<this>(this);\n\n /**\n * Updates internal string values for internationalization.\n */\n @property({ type: Object }) i18n = this.#i18nController.i18n;\n\n /** @private */\n @hostAttr() slot = 'nodes';\n\n get #tree() {\n return this.closest<Tree>('nve-tree');\n }\n\n /**\n * Returns the slotted child tree nodes.\n */\n @queryAssignedElements({ slot: 'nodes' }) readonly nodes!: TreeNode[];\n\n /** @private */\n @state() indeterminate = false;\n\n /** @private */\n @state() behaviorExpand = false;\n\n /** @private */\n @state() behaviorSelect = false;\n\n #typeExpandableController = new TypeExpandableController(this);\n\n #typeSelectableController = new TypeSelectableController(this);\n\n get #isExpandable() {\n return this.expandable || this.expanded || !!this.nodes?.length;\n }\n\n static metadata = {\n tag: 'nve-tree-node',\n version: '0.0.0',\n parents: ['nve-tree', 'nve-tree-node']\n };\n\n static elementDefinitions = {\n [IconButton.metadata.tag]: IconButton,\n [Icon.metadata.tag]: Icon,\n [Checkbox.metadata.tag]: Checkbox\n };\n\n static styles = useStyles([styles]);\n\n declare _internals: ElementInternals;\n\n /* eslint-disable @nvidia-elements/lint/no-missing-control-label */\n render() {\n return html`\n <div internal-host @slotchange=${this.#nodeUpdate}>\n <div part=\"_node\">\n ${\n this.#isExpandable\n ? html`\n <nve-icon-button part=\"icon-button\" exportparts=\"icon:icon-button-icon\" @pointerup=${this.#toggleExpand} role=\"presentation\" tabindex=\"-1\" size=\"sm\" container=\"inline\" nofocus>\n <nve-icon part=\"icon\" name=\"caret\" direction=${this.expanded ? 'down' : 'right'} size=\"sm\"></nve-icon>\n </nve-icon-button>`\n : nothing\n }\n ${\n this.selectable === 'multi'\n ? html`\n <nve-checkbox part=\"checkbox\" nofocus>\n <input type=\"checkbox\" @change=${this.#toggleMultiSelection} .checked=${this.selected} .indeterminate=${this.indeterminate} .ariaLabel=${this.i18n.expand} tabindex=\"-1\" />\n </nve-checkbox>`\n : nothing\n }\n <div tabindex=\"0\" part=\"_node-header\">\n <div class=\"node-title\" @click=${this.#nodeHeaderClick}>\n <slot name=\"prefix\" part=\"_prefix\"></slot>\n <slot></slot>\n <slot name=\"suffix\" part=\"_suffix\"></slot>\n </div>\n <slot name=\"content\" part=\"_content\"></slot>\n </div>\n </div>\n <div role=\"group\" part=\"_nodes\"><slot name=\"nodes\"></slot></div>\n </div>\n `;\n }\n\n connectedCallback() {\n super.connectedCallback();\n attachInternals(this);\n this._internals.role = 'treeitem';\n this.addEventListener('keydown', this.#onKeydown);\n this.addEventListener('keyup', this.#onKeyup);\n this.#nodeUpdate();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener('keydown', this.#onKeydown);\n this.removeEventListener('keyup', this.#onKeyup);\n }\n\n /** opens and sets the expanded state automatically if behaviorExpand is true */\n open() {\n this.#typeExpandableController.open();\n }\n\n /** closes and sets the expanded state automatically if behaviorExpand is true */\n close() {\n this.#typeExpandableController.close();\n }\n\n #nodeUpdate() {\n this.requestUpdate();\n this.#toggleExpandableState();\n }\n\n #toggleExpandableState() {\n this.#isExpandable ? this._internals.states.add('is-expandable') : this._internals.states.delete('is-expandable');\n }\n\n #onKeydown = (e: KeyboardEvent) => {\n const isSelectionKey = this.selectable && e.code === 'Space';\n const isExpansionKey = this.#isExpandable && (e.code === 'ArrowLeft' || e.code === 'ArrowRight');\n\n if (e.target === this && (isSelectionKey || isExpansionKey)) {\n e.preventDefault();\n }\n };\n\n #onKeyup = (e: KeyboardEvent) => {\n if (this.#isExpandable && e.code === 'ArrowLeft' && e.target === this) {\n this.close();\n }\n\n if (this.#isExpandable && e.code === 'ArrowRight' && e.target === this) {\n this.open();\n }\n\n if (e.code === 'Space' && e.target === this && this.selectable) {\n this.#toggleSelection();\n }\n };\n\n #nodeHeaderClick(e: Event) {\n const hasFocusableElements = getFlattenedFocusableItems(e.currentTarget as HTMLElement).length;\n if (this.#isExpandable && !this.selectable && !hasFocusableElements) {\n this.#toggleExpand();\n }\n\n if (this.selectable && (!hasFocusableElements || (e.target as HTMLElement).localName === 'a')) {\n this.#toggleSelection();\n }\n }\n\n #toggleExpand() {\n this.#typeExpandableController.toggle();\n }\n\n #toggleSelection() {\n if (this.selectable === 'single') {\n this.#toggleSingleSelection();\n }\n\n if (this.selectable === 'multi') {\n this.#toggleMultiSelection();\n }\n }\n\n #toggleSingleSelection() {\n this.#typeSelectableController.toggle();\n if (this.behaviorSelect) {\n this.#tree!.nodes.filter(n => n !== this).forEach(n => (n.selected = false));\n }\n }\n\n #toggleMultiSelection() {\n this.#typeSelectableController.toggle();\n\n if (this.behaviorSelect) {\n this.nodes.forEach(n => {\n n.selected = this.selected;\n n.indeterminate = false;\n });\n this.#tree!.nodes.forEach(node => updateNodeSelection(node));\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"tree-node2.js","names":[],"sources":["../../src/tree/tree-node.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { LitElement, html, nothing } from 'lit';\nimport { property } from 'lit/decorators/property.js';\nimport { state } from 'lit/decorators/state.js';\nimport { queryAssignedElements } from 'lit/decorators/query-assigned-elements.js';\nimport {\n I18nController,\n TypeExpandableController,\n TypeSelectableController,\n attachInternals,\n audit,\n getFlattenedFocusableItems,\n hostAttr,\n isFocusable,\n scopedRegistry,\n stateExpanded,\n stateHighlighted,\n stateSelected,\n typeAnchor,\n typeSSR,\n useStyles\n} from '@nvidia-elements/core/internal';\nimport { IconButton } from '@nvidia-elements/core/icon-button';\nimport { Icon } from '@nvidia-elements/core/icon';\nimport { Checkbox } from '@nvidia-elements/core/checkbox';\nimport { TypeCommandController } from '@nvidia-elements/forms/internal';\nimport type { Tree } from './tree.js';\nimport styles from './tree-node.css?inline';\nimport { updateNodeSelection } from './utils.js';\n\n/**\n * @element nve-tree-node\n * @description A tree view widget presents a hierarchical list. Any item in the hierarchy may have child items, and items that have children can expand or collapse to show or hide the children.\n * @documentation https://nvidia.github.io/elements/docs/elements/tree/\n * @since 1.2.0\n * @entrypoint \\@nvidia-elements/core/tree\n * @event open - Dispatched when the node opens.\n * @event close - Dispatched when the node closes.\n * @event select - Dispatched when the node selection state changes.\n * @command --select - use to select the node\n * @command --deselect - use to deselect the node\n * @command --toggle-select - use to toggle the node selection state\n * @command --open - use to open the node\n * @command --close - use to close the node\n * @command --toggle - use to toggle open / closed state of the node\n * @slot - Use default slot for basic text content or nested <nve-tree-node> elements.\n * @slot prefix - Use for prefix content before the node title.\n * @slot suffix - Use for suffix content after the node title.\n * @slot content - Use only for extended long form content containing interactive elements or form inputs.\n * @cssprop --color\n * @cssprop --border-radius\n * @cssprop --font-size\n * @cssprop --min-height\n * @cssprop --text-wrap\n * @cssprop --font-weight\n * @cssprop --width\n\n * @csspart icon-button - The icon button element\n * @csspart icon - The icon element\n * @csspart checkbox - The checkbox element\n\n * @aria https://www.w3.org/WAI/ARIA/apg/patterns/treeview/\n *\n */\n@audit()\n@typeSSR({ log: false }) // warning about ssr mismatch disabled as tree node will never be a 1:1 match in ssr due to performance constraints and slot complexity\n@typeAnchor()\n@stateSelected()\n@stateExpanded()\n@scopedRegistry()\n@stateHighlighted()\nexport class TreeNode extends LitElement {\n /** Command to invoke on a node title click or Enter on its header. */\n @property({ type: String }) command = '';\n\n /** ID of the element that receives the command. */\n @property({ type: String, reflect: true }) commandfor: string | null = null;\n\n /** Direct command target, taking precedence over commandfor. */\n @property({ attribute: false }) commandForElement: HTMLElement | null = null;\n\n /**\n * Determines if node is in an expanded state.\n */\n @property({ type: Boolean, reflect: true }) expanded = false;\n\n /**\n * Determines whether if node is in a selected state.\n */\n @property({ type: Boolean, reflect: true }) selected = false;\n\n /**\n * Determines whether a node can be expandable. Expandable by default if slotted nodes exist.\n */\n @property({ type: Boolean }) expandable = false;\n\n /**\n * Determines whether a node can be in a selected state. Nodes can be in a single or multi select state.\n */\n @property({ type: String }) selectable: 'single' | 'multi';\n\n /**\n * Determines the highlighted state of the element. Highlighted states serve non-interactive selections where nodes may relate to other selected portions of the UI.\n */\n @property({ type: Boolean }) highlighted = false;\n\n #i18nController: I18nController<this> = new I18nController<this>(this);\n\n /**\n * Updates internal string values for internationalization.\n */\n @property({ type: Object }) i18n = this.#i18nController.i18n;\n\n /** @private */\n @hostAttr() slot = 'nodes';\n\n get #tree() {\n return this.closest<Tree>('nve-tree');\n }\n\n /**\n * Returns the slotted child tree nodes.\n */\n @queryAssignedElements({ slot: 'nodes' }) readonly nodes!: TreeNode[];\n\n /** @private */\n @state() indeterminate = false;\n\n /** @private */\n @state() behaviorExpand = false;\n\n /** @private */\n @state() behaviorSelect = false;\n\n #typeExpandableController = new TypeExpandableController(this);\n\n #typeSelectableController = new TypeSelectableController(this);\n\n #typeCommandController = new TypeCommandController(this, { events: [] });\n\n get #isExpandable() {\n return this.expandable || this.expanded || !!this.nodes?.length;\n }\n\n static metadata = {\n tag: 'nve-tree-node',\n version: '0.0.0',\n parents: ['nve-tree', 'nve-tree-node']\n };\n\n static elementDefinitions = {\n [IconButton.metadata.tag]: IconButton,\n [Icon.metadata.tag]: Icon,\n [Checkbox.metadata.tag]: Checkbox\n };\n\n static styles = useStyles([styles]);\n\n declare _internals: ElementInternals;\n\n /* eslint-disable @nvidia-elements/lint/no-missing-control-label */\n render() {\n return html`\n <div internal-host @slotchange=${this.#nodeUpdate}>\n <div part=\"_node\">\n ${\n this.#isExpandable\n ? html`\n <nve-icon-button part=\"icon-button\" exportparts=\"icon:icon-button-icon\" @pointerup=${this.#toggleExpand} role=\"presentation\" tabindex=\"-1\" size=\"sm\" container=\"inline\" nofocus>\n <nve-icon part=\"icon\" name=\"caret\" direction=${this.expanded ? 'down' : 'right'} size=\"sm\"></nve-icon>\n </nve-icon-button>`\n : nothing\n }\n ${\n this.selectable === 'multi'\n ? html`\n <nve-checkbox part=\"checkbox\" nofocus>\n <input type=\"checkbox\" @change=${this.#toggleMultiSelection} .checked=${this.selected} .indeterminate=${this.indeterminate} .ariaLabel=${this.i18n.expand} tabindex=\"-1\" />\n </nve-checkbox>`\n : nothing\n }\n <div tabindex=\"0\" part=\"_node-header\">\n <div class=\"node-title\" @click=${this.#nodeHeaderClick}>\n <slot name=\"prefix\" part=\"_prefix\"></slot>\n <slot></slot>\n <slot name=\"suffix\" part=\"_suffix\"></slot>\n </div>\n <slot name=\"content\" part=\"_content\"></slot>\n </div>\n </div>\n <div role=\"group\" part=\"_nodes\"><slot name=\"nodes\"></slot></div>\n </div>\n `;\n }\n\n connectedCallback() {\n super.connectedCallback();\n attachInternals(this);\n this._internals.role = 'treeitem';\n this.addEventListener('keydown', this.#onKeydown);\n this.addEventListener('keyup', this.#onKeyup);\n this.#nodeUpdate();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener('keydown', this.#onKeydown);\n this.removeEventListener('keyup', this.#onKeyup);\n }\n\n /** opens and sets the expanded state automatically if behaviorExpand is true */\n open() {\n this.#typeExpandableController.open();\n }\n\n /** closes and sets the expanded state automatically if behaviorExpand is true */\n close() {\n this.#typeExpandableController.close();\n }\n\n #nodeUpdate() {\n this.requestUpdate();\n this.#toggleExpandableState();\n }\n\n #toggleExpandableState() {\n this.#isExpandable ? this._internals.states.add('is-expandable') : this._internals.states.delete('is-expandable');\n }\n\n #onKeydown = (e: KeyboardEvent) => {\n const isSelectionKey = this.selectable && e.code === 'Space';\n const isExpansionKey = this.#isExpandable && (e.code === 'ArrowLeft' || e.code === 'ArrowRight');\n\n if (e.target === this && (isSelectionKey || isExpansionKey)) {\n e.preventDefault();\n }\n };\n\n #invokeFromKeyboard(e: KeyboardEvent) {\n if (e.code !== 'Enter' || e.defaultPrevented || e.repeat) {\n return;\n }\n const origin = e.composedPath()[0];\n const header = this.shadowRoot?.querySelector('[part=\"_node-header\"]');\n if (origin === header || origin === this) {\n this.#typeCommandController.invoke();\n }\n }\n\n #onKeyup = (e: KeyboardEvent) => {\n this.#invokeFromKeyboard(e);\n if (this.#isExpandable && e.code === 'ArrowLeft' && e.target === this) {\n this.close();\n }\n\n if (this.#isExpandable && e.code === 'ArrowRight' && e.target === this) {\n this.open();\n }\n\n if (e.code === 'Space' && e.target === this && this.selectable) {\n this.#toggleSelection();\n }\n };\n\n #nodeHeaderClick(e: Event) {\n const hasFocusableElements = getFlattenedFocusableItems(e.currentTarget as HTMLElement).length;\n if (this.#isExpandable && !this.selectable && !hasFocusableElements) {\n this.#toggleExpand();\n }\n\n if (this.selectable && (!hasFocusableElements || (e.target as HTMLElement).localName === 'a')) {\n this.#toggleSelection();\n }\n\n const path = e.composedPath();\n const hasInteractiveTarget = path\n .slice(0, path.indexOf(e.currentTarget as HTMLElement))\n .some(target => target instanceof Element && isFocusable(target));\n if (!hasInteractiveTarget && !e.defaultPrevented) {\n this.#typeCommandController.invoke();\n }\n }\n\n #toggleExpand() {\n this.#typeExpandableController.toggle();\n }\n\n #toggleSelection() {\n if (this.selectable === 'single') {\n this.#toggleSingleSelection();\n }\n\n if (this.selectable === 'multi') {\n this.#toggleMultiSelection();\n }\n }\n\n #toggleSingleSelection() {\n this.#typeSelectableController.toggle();\n if (this.behaviorSelect) {\n this.#tree!.nodes.filter(n => n !== this).forEach(n => (n.selected = false));\n }\n }\n\n #toggleMultiSelection() {\n this.#typeSelectableController.toggle();\n\n if (this.behaviorSelect) {\n this.nodes.forEach(n => {\n n.selected = this.selected;\n n.indeterminate = false;\n });\n this.#tree!.nodes.forEach(node => updateNodeSelection(node));\n }\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"tree.examples.js","names":[],"sources":["../../src/tree/tree.examples.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { html, LitElement, nothing } from 'lit';\nimport { state } from 'lit/decorators/state.js';\nimport '@nvidia-elements/core/tree/define.js';\nimport '@nvidia-elements/core/checkbox/define.js';\nimport '@nvidia-elements/core/input/define.js';\nimport '@nvidia-elements/core/radio/define.js';\nimport '@nvidia-elements/core/progress-ring/define.js';\n\nexport default {\n title: 'Elements/Tree',\n component: 'nve-tree',\n};\n\n/**\n * @summary Basic tree component with expandable nodes, providing hierarchical data display and navigation for structured content organization.\n */\nexport const Default = {\n render: () => html`\n <nve-tree behavior-expand>\n <nve-tree-node expanded>\n node 1\n <nve-tree-node>node 1-1</nve-tree-node>\n <nve-tree-node>node 1-2</nve-tree-node>\n <nve-tree-node>\n node 1-3\n <nve-tree-node>node 1-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-2</nve-tree-node>\n <nve-tree-node>node 1-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 2\n <nve-tree-node>node 2-1</nve-tree-node>\n <nve-tree-node>node 2-2</nve-tree-node>\n <nve-tree-node>node 2-3</nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 3\n <nve-tree-node>node 3-1</nve-tree-node>\n <nve-tree-node>node 3-2</nve-tree-node>\n <nve-tree-node>\n node 3-3\n <nve-tree-node>node 3-3-1</nve-tree-node>\n <nve-tree-node>node 3-3-2</nve-tree-node>\n <nve-tree-node>node 3-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree>\n `\n};\n\n/**\n * @summary Tree with border styling for enhanced visual separation and container definition, improving content structure perception.\n */\nexport const Border = {\n render: () => html`\n <nve-tree behavior-expand border>\n <nve-tree-node expanded>\n node 1\n <nve-tree-node>node 1-1</nve-tree-node>\n <nve-tree-node>node 1-2</nve-tree-node>\n <nve-tree-node>\n node 1-3\n <nve-tree-node>node 1-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-2</nve-tree-node>\n <nve-tree-node>node 1-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 2\n <nve-tree-node>node 2-1</nve-tree-node>\n <nve-tree-node>node 2-2</nve-tree-node>\n <nve-tree-node>node 2-3</nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 3\n <nve-tree-node>node 3-1</nve-tree-node>\n <nve-tree-node>node 3-2</nve-tree-node>\n <nve-tree-node>\n node 3-3\n <nve-tree-node>node 3-3-1</nve-tree-node>\n <nve-tree-node>node 3-3-2</nve-tree-node>\n <nve-tree-node>node 3-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree>\n `\n};\n\n/**\n * @summary Single-selection tree for choosing one item from hierarchical options, enabling focused navigation and content selection.\n */\nexport const Selectable = {\n render: () => html`\n <nve-tree selectable=\"single\" behavior-expand behavior-select border>\n <nve-tree-node expanded>\n node 1\n <nve-tree-node selected>node 1-1</nve-tree-node>\n <nve-tree-node>node 1-2</nve-tree-node>\n <nve-tree-node>\n node 1-3\n <nve-tree-node>node 1-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-2</nve-tree-node>\n <nve-tree-node>node 1-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 2\n <nve-tree-node>node 2-1</nve-tree-node>\n <nve-tree-node>node 2-2</nve-tree-node>\n <nve-tree-node>node 2-3</nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 3\n <nve-tree-node>node 3-1</nve-tree-node>\n <nve-tree-node>node 3-2</nve-tree-node>\n <nve-tree-node>\n node 3-3\n <nve-tree-node>node 3-3-1</nve-tree-node>\n <nve-tree-node>node 3-3-2</nve-tree-node>\n <nve-tree-node>node 3-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree>\n `\n};\n\n/**\n * @summary Multi-selection tree for choosing many items from hierarchical options, enabling bulk operations and comprehensive content management.\n */\nexport const SelectableMultiple = {\n render: () => html`\n <nve-tree selectable=\"multi\" behavior-expand behavior-select border>\n <nve-tree-node expanded>\n node 1\n <nve-tree-node>node 1-1</nve-tree-node>\n <nve-tree-node selected>node 1-2</nve-tree-node>\n <nve-tree-node expanded>\n node 1-3\n <nve-tree-node>node 1-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-2</nve-tree-node>\n <nve-tree-node>node 1-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 2\n <nve-tree-node>node 2-1</nve-tree-node>\n <nve-tree-node>node 2-2</nve-tree-node>\n <nve-tree-node>node 2-3</nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 3\n <nve-tree-node>node 3-1</nve-tree-node>\n <nve-tree-node>node 3-2</nve-tree-node>\n <nve-tree-node>\n node 3-3\n <nve-tree-node>node 3-3-1</nve-tree-node>\n <nve-tree-node>node 3-3-2</nve-tree-node>\n <nve-tree-node>node 3-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree>\n `\n};\n\n/**\n * @summary Interactive selection handling using the select event, with callbacks for node selection changes.\n * @tags test-case\n */\nexport const SelectEvent = {\n render: () => html`\n <div nve-layout=\"column gap:md\">\n <div nve-layout=\"row gap:md\">\n <nve-tree id=\"select-event-tree\" selectable=\"single\" behavior-expand behavior-select border>\n <nve-tree-node expanded>\n Documents\n <nve-tree-node>Annual Report.pdf</nve-tree-node>\n <nve-tree-node>Budget.xlsx</nve-tree-node>\n <nve-tree-node expanded>\n Projects\n <nve-tree-node>Project Alpha</nve-tree-node>\n <nve-tree-node>Project Beta</nve-tree-node>\n <nve-tree-node>Project Gamma</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n Images\n <nve-tree-node>photo-001.jpg</nve-tree-node>\n <nve-tree-node>photo-002.jpg</nve-tree-node>\n <nve-tree-node>screenshot.png</nve-tree-node>\n </nve-tree-node>\n </nve-tree>\n <div nve-layout=\"column gap:sm\">\n <p nve-text=\"body sm\"><strong>Selected:</strong> <span id=\"selected-node\">None</span></p>\n <p nve-text=\"body sm\"><strong>History:</strong></p>\n <ul id=\"selection-history\" nve-text=\"body sm\">\n <li>No selections yet</li>\n </ul>\n </div>\n </div>\n </div>\n <script type=\"module\">\n const tree = document.querySelector('#select-event-tree');\n const selectedDisplay = document.querySelector('#selected-node');\n const historyList = document.querySelector('#selection-history');\n const history = [];\n tree.addEventListener('select', (e) => {\n const node = e.detail;\n const nodeText = node.textContent?.trim().split('\\\\n')[0] ?? 'Unknown';\n selectedDisplay.textContent = nodeText;\n history.push(nodeText);\n if (history.length > 5) history.shift();\n historyList.innerHTML = history.map(item => '<li>' + item + '</li>').join('');\n });\n </script>\n `\n};\n\n/**\n * @summary Tree with highlighted nodes for emphasizing specific items, providing visual focus and search result signal in hierarchical data.\n */\nexport const Highlight = {\n render: () => html`\n <nve-tree behavior-expand border>\n <nve-tree-node expanded>\n node 1\n <nve-tree-node highlighted>node 1-1</nve-tree-node>\n <nve-tree-node>node 1-2</nve-tree-node>\n <nve-tree-node expanded>\n node 1-3\n <nve-tree-node highlighted>node 1-3-1</nve-tree-node>\n <nve-tree-node highlighted>node 1-3-2</nve-tree-node>\n <nve-tree-node>node 1-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 2\n <nve-tree-node>node 2-1</nve-tree-node>\n <nve-tree-node>node 2-2</nve-tree-node>\n <nve-tree-node>node 2-3</nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 3\n <nve-tree-node>node 3-1</nve-tree-node>\n <nve-tree-node>node 3-2</nve-tree-node>\n <nve-tree-node>\n node 3-3\n <nve-tree-node>node 3-3-1</nve-tree-node>\n <nve-tree-node>node 3-3-2</nve-tree-node>\n <nve-tree-node>node 3-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree>\n `\n};\n\n/**\n * @summary Tree with navigation links for hierarchical menu systems, enabling structured site navigation and content discovery.\n */\nexport const Links = {\n render: () => html`\n <nve-tree behavior-expand>\n <nve-tree-node><a href=\"#\">Documentation</a></nve-tree-node>\n <nve-tree-node><a href=\"#\">Support</a></nve-tree-node>\n <nve-tree-node expanded>\n Elements\n <nve-tree-node><a href=\"#\">Alert</a></nve-tree-node>\n <nve-tree-node><a href=\"#\">Badge</a></nve-tree-node>\n <nve-tree-node><a href=\"#\">Dialog</a></nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n Frameworks\n <nve-tree-node><a href=\"#\">Angular</a></nve-tree-node>\n <nve-tree-node><a href=\"#\">React</a></nve-tree-node>\n <nve-tree-node><a href=\"#\">Vue</a></nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n Languages\n <nve-tree-node><a href=\"#\">JavaScript</a></nve-tree-node>\n <nve-tree-node><a href=\"#\">HTML</a></nve-tree-node>\n <nve-tree-node><a href=\"#\">CSS</a></nve-tree-node>\n </nve-tree-node>\n </nve-tree>\n `\n};\n\n/**\n * @summary Tree with loading states for asynchronous data, including progress indicators and dynamic content loading in hierarchical structures.\n */\nexport const Async = {\n render: () => html`\n <nve-tree border>\n <nve-tree-node expanded>\n node 1\n <nve-tree-node>node 1-1</nve-tree-node>\n <nve-tree-node>node 1-2</nve-tree-node>\n <nve-tree-node expanded>\n node 1-3\n <nve-tree-node>\n <div nve-layout=\"row gap:xs\">\n <nve-progress-ring status=\"accent\" size=\"xs\"></nve-progress-ring> loading\n </div>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 2\n <nve-tree-node>node 2-1</nve-tree-node>\n <nve-tree-node>node 2-2</nve-tree-node>\n <nve-tree-node>node 2-3</nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 3\n <nve-tree-node>node 3-1</nve-tree-node>\n <nve-tree-node>node 3-2</nve-tree-node>\n <nve-tree-node>\n node 3-3\n <nve-tree-node>node 3-3-1</nve-tree-node>\n <nve-tree-node>node 3-3-2</nve-tree-node>\n <nve-tree-node>node 3-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree>\n `\n};\n\n/**\n * @summary Tree with prefix and suffix content for each node, enabling flexible content organization and visual hierarchy.\n * @tags test-case\n */\nexport const PrefixSuffix = {\n render: () => html`\n<nve-tree behavior-expand behavior-select selectable=\"single\" aria-label=\"Robot workspace files\">\n <nve-tree-node expanded>\n <nve-icon name=\"folder\" slot=\"prefix\"></nve-icon> src\n <nve-tree-node expanded>\n <nve-icon name=\"folder\" slot=\"prefix\"></nve-icon> navigation\n <nve-tree-node selected><nve-icon name=\"code\" slot=\"prefix\"></nve-icon> controller.py <nve-dot status=\"accent\" size=\"sm\" slot=\"suffix\"></nve-dot></nve-tree-node>\n <nve-tree-node><nve-icon name=\"code\" slot=\"prefix\"></nve-icon> planner.py</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n</nve-tree>\n `\n};\n\n/**\n * @summary Tree with rich node content including forms, controls, and interactive elements, enabling complex data management within hierarchical structures.\n */\nexport const NodeContent = {\n render: () => html`\n <nve-tree selectable=\"multi\" border behavior-expand behavior-select>\n <nve-tree-node expanded>\n text content\n <nve-tree-node>\n <a href=\".\" nve-text=\"link\">node link</a>\n </nve-tree-node>\n <nve-tree-node>\n <nve-icon name=\"code\" slot=\"prefix\"></nve-icon>\n <a href=\".\" nve-text=\"link\">node link</a>\n <nve-dot status=\"accent\" size=\"sm\" slot=\"suffix\"></nve-dot>\n </nve-tree-node>\n <nve-tree-node>\n inline content <nve-dot status=\"success\" size=\"sm\"></nve-dot>\n </nve-tree-node>\n <nve-tree-node>\n <div nve-text=\"body sm muted\" nve-layout=\"pad-bottom:xs\">block</div>\n <p nve-text=\"body sm\">content</p>\n </nve-tree-node>\n <nve-tree-node>\n long form content\n <div slot=\"content\" nve-layout=\"column gap:sm\">\n <a href=\"#\" nve-text=\"link\">This is some longer content in a tree node.</a>\n <a href=\"#\" nve-text=\"link\">This is some longer content in a tree node.</a>\n <a href=\"#\" nve-text=\"link\">This is some longer content in a tree node.</a>\n </div>\n </nve-tree-node>\n <nve-tree-node>\n interactive content\n <div slot=\"content\" nve-layout=\"column gap:sm\">\n <p nve-text=\"body sm\">This is some longer content in a tree node.</p>\n <nve-button>hello there</nve-button>\n </div>\n </nve-tree-node>\n <nve-tree-node>\n input control\n <div slot=\"content\" nve-layout=\"column gap:sm\">\n <nve-input>\n <label>label</label>\n <input type=\"text\" />\n </nve-input>\n <nve-input>\n <label>label</label>\n <input type=\"text\" />\n </nve-input>\n </div>\n </nve-tree-node>\n <nve-tree-node>\n node content checkbox group\n <nve-checkbox-group slot=\"content\">\n <label>label</label>\n <nve-checkbox>\n <label>checkbox 1</label>\n <input type=\"checkbox\" checked />\n </nve-checkbox>\n\n <nve-checkbox>\n <label>checkbox 2</label>\n <input type=\"checkbox\" />\n </nve-checkbox>\n\n <nve-checkbox>\n <label>checkbox 3</label>\n <input type=\"checkbox\" />\n </nve-checkbox>\n </nve-checkbox-group>\n </nve-tree-node>\n <nve-tree-node>\n node content radio group\n <nve-radio-group slot=\"content\">\n <label>label</label>\n <nve-radio>\n <label>radio 1</label>\n <input type=\"radio\" checked />\n </nve-radio>\n\n <nve-radio>\n <label>radio 2</label>\n <input type=\"radio\" />\n </nve-radio>\n\n <nve-radio>\n <label>radio 3</label>\n <input type=\"radio\" />\n </nve-radio>\n </nve-radio-group>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree>\n `\n};\n\n/**\n * @summary Tree with a max width, ensuring the tree does not exceed the specified width.\n * @tags test-case\n */\nexport const MaxWidth = {\n render: () => html`\n<nve-tree style=\"max-width: 500px; outline: 1px dashed red;\">\n <nve-tree-node style=\"outline: 1px dashed blue;\">\n <p nve-text=\"label truncate\">1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890</p>\n </nve-tree-node>\n</nve-tree>\n `\n};\n\n/**\n * @summary Dynamic tree with programmatic node creation and management, for scalable hierarchical data handling with large datasets.\n * @tags test-case\n */\nexport const DynamicTree = {\n render: () => html`<test-dynamic-tree></test-dynamic-tree>`\n};\n\n/**\n * @summary Tree with scrollable container for handling deep hierarchies and large datasets, ensuring optimal space usage and navigation.\n * @tags test-case\n */\nexport const Overflow = {\n render: () => html`\n <div style=\"width: 300px; height: 500px; overflow: auto; outline: 1px solid #ccc; padding: 12px\">\n <nve-tree border behavior-expand>\n <nve-tree-node expanded>\n node 1\n <nve-tree-node>node 1-1</nve-tree-node>\n <nve-tree-node>node 1-2</nve-tree-node>\n <nve-tree-node expanded>\n node 1-3\n <nve-tree-node>node 1-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-2</nve-tree-node>\n <nve-tree-node expanded>\n node 1-3-3\n <nve-tree-node>node 1-3-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-3-2</nve-tree-node>\n <nve-tree-node expanded>\n node 1-3-3-3\n <nve-tree-node>node 1-3-3-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-3-3-2</nve-tree-node>\n <nve-tree-node expanded>\n node 1-3-3-3-3\n <nve-tree-node>node 1-3-3-3-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-3-3-3-2</nve-tree-node>\n <nve-tree-node expanded>\n node 1-3-3-3-3-3\n <nve-tree-node>node 1-3-3-3-3-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-3-3-3-3-2</nve-tree-node>\n <nve-tree-node expanded>\n node 1-3-3-3-3-3-3\n <nve-tree-node>node 1-3-3-3-3-3-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-3-3-3-3-3-2</nve-tree-node>\n <nve-tree-node expanded>\n node 1-3-3-3-3-3-3-3\n <nve-tree-node>node 1-3-3-3-3-3-3-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-3-3-3-3-3-3-2</nve-tree-node>\n <nve-tree-node expanded>\n node 1-3-3-3-3-3-3-3-3\n <nve-tree-node>node 1-3-3-3-3-3-3-3-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-3-3-3-3-3-3-3-2</nve-tree-node>\n <nve-tree-node>node 1-3-3-3-3-3-3-3-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n <nve-tree-node expanded>\n node 2\n <nve-tree-node>node 2-1</nve-tree-node>\n <nve-tree-node>node 2-2</nve-tree-node>\n <nve-tree-node>node 2-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree>\n </div>\n `\n};\n\n/**\n * @summary Tree with bulk node creation for performance testing, verifying efficient handling of large numbers of nodes and dynamic expansion.\n * @tags test-case performance\n */\nexport const BulkCreation = {\n render: () => html`\n <nve-tree>\n <nve-tree-node id=\"root\" expandable>Test</nve-tree-node>\n </nve-tree>\n <script type=\"module\">\n const rootEl = document.querySelector('nve-tree-node#root');\n\n rootEl.addEventListener('open', () => {\n const fragment = document.createDocumentFragment();\n for (let i = 0; i < 400; i++) {\n rootEl.expanded = true;\n const childEl = document.createElement('nve-tree-node');\n childEl.innerText = 'Child ' + i;\n fragment.append(childEl);\n }\n rootEl.append(fragment);\n });\n\n rootEl.addEventListener('close', () => {\n rootEl.expanded = false;\n rootEl.replaceChildren(document.createTextNode('Test'));\n });\n </script>\n `\n};\n\n/* eslint-disable @nvidia-elements/lint/no-invalid-parent-elements -- Intentional invalid parent for audit documentation. */\n/**\n * @summary Examples of invalid tree usage patterns for testing and documentation purposes, showing what not to do when implementing trees.\n * @tags anti-pattern\n */\nexport const Audit = {\n render: () => html`\n <div>\n <nve-tree-node>node</nve-tree-node>\n </div>\n `\n};\n/* eslint-enable @nvidia-elements/lint/no-invalid-parent-elements */\n\nexport class TestDynamicTree extends LitElement {\n @state() nodes = createTree();\n\n render() {\n return html`\n <p nve-text=\"body\">total nodes: 10,000</p>\n <nve-tree border expandable>\n ${this.nodes.map(node => this.#getNodeList(node))}\n </nve-tree>`;\n }\n\n #getNodeList(node) {\n return html`<nve-tree-node .expandable=${node.nodes.length} .expanded=${node.expanded} @open=${e => this.#open(e, node)} @close=${e => this.#close(e, node)}>\n ${node.label} node\n ${node.expanded ? node.nodes.map(n => html`${this.#getNodeList(n)}`) : nothing}\n </nve-tree-node>`\n }\n\n #open(e, node) {\n e.stopPropagation();\n node.expanded = true;\n this.nodes = [...this.nodes];\n this.requestUpdate();\n }\n\n #close(e, node) {\n e.stopPropagation();\n node.expanded = false;\n this.nodes = [...this.nodes];\n this.requestUpdate();\n }\n}\n\n/** generates a tree with 10 nodes with 4 layers */\nfunction createTree() {\n return createNodeList(10).map(i => {\n i.nodes = createNodeList(10);\n i.nodes.forEach(j => {\n j.nodes = createNodeList(10);\n j.nodes.forEach(k => {\n k.nodes = createNodeList(10);\n })\n })\n return i;\n });\n}\n\nfunction createNodeList(nodes: number) {\n return new Array(nodes).fill('').map((_, i) => ({ label: `${i}`, expanded: false, nodes: [] }));\n}\n\ncustomElements.get('test-dynamic-tree') || customElements.define('test-dynamic-tree', TestDynamicTree);\n"],"mappings":";AAGA,IAAA,IAAe"}
1
+ {"version":3,"file":"tree.examples.js","names":[],"sources":["../../src/tree/tree.examples.ts"],"sourcesContent":["// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { html, LitElement, nothing } from 'lit';\nimport { state } from 'lit/decorators/state.js';\nimport '@nvidia-elements/core/tree/define.js';\nimport '@nvidia-elements/core/checkbox/define.js';\nimport '@nvidia-elements/core/input/define.js';\nimport '@nvidia-elements/core/radio/define.js';\nimport '@nvidia-elements/core/progress-ring/define.js';\n\nexport default {\n title: 'Elements/Tree',\n component: 'nve-tree',\n};\n\n/**\n * @summary Basic tree component with expandable nodes, providing hierarchical data display and navigation for structured content organization.\n */\nexport const Default = {\n render: () => html`\n <nve-tree behavior-expand>\n <nve-tree-node expanded>\n node 1\n <nve-tree-node>node 1-1</nve-tree-node>\n <nve-tree-node>node 1-2</nve-tree-node>\n <nve-tree-node>\n node 1-3\n <nve-tree-node>node 1-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-2</nve-tree-node>\n <nve-tree-node>node 1-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 2\n <nve-tree-node>node 2-1</nve-tree-node>\n <nve-tree-node>node 2-2</nve-tree-node>\n <nve-tree-node>node 2-3</nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 3\n <nve-tree-node>node 3-1</nve-tree-node>\n <nve-tree-node>node 3-2</nve-tree-node>\n <nve-tree-node>\n node 3-3\n <nve-tree-node>node 3-3-1</nve-tree-node>\n <nve-tree-node>node 3-3-2</nve-tree-node>\n <nve-tree-node>node 3-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree>\n `\n};\n\n/**\n * @summary Invoke commands from tree node titles to control another tree without event handlers. Click a title or press Enter on its header to open or close the target node.\n */\nexport const InvokerCommands = {\n render: () => html`\n <nve-tree>\n <nve-tree-node command=\"--open\" commandfor=\"tree-command-details\">Show details</nve-tree-node>\n <nve-tree-node command=\"--close\" commandfor=\"tree-command-details\">Hide details</nve-tree-node>\n </nve-tree>\n <nve-tree>\n <nve-tree-node id=\"tree-command-details\">\n Details\n <nve-tree-node>Model configuration</nve-tree-node>\n <nve-tree-node>Training results</nve-tree-node>\n </nve-tree-node>\n </nve-tree>\n `\n};\n\n/**\n * @summary Tree with border styling for enhanced visual separation and container definition, improving content structure perception.\n */\nexport const Border = {\n render: () => html`\n <nve-tree behavior-expand border>\n <nve-tree-node expanded>\n node 1\n <nve-tree-node>node 1-1</nve-tree-node>\n <nve-tree-node>node 1-2</nve-tree-node>\n <nve-tree-node>\n node 1-3\n <nve-tree-node>node 1-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-2</nve-tree-node>\n <nve-tree-node>node 1-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 2\n <nve-tree-node>node 2-1</nve-tree-node>\n <nve-tree-node>node 2-2</nve-tree-node>\n <nve-tree-node>node 2-3</nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 3\n <nve-tree-node>node 3-1</nve-tree-node>\n <nve-tree-node>node 3-2</nve-tree-node>\n <nve-tree-node>\n node 3-3\n <nve-tree-node>node 3-3-1</nve-tree-node>\n <nve-tree-node>node 3-3-2</nve-tree-node>\n <nve-tree-node>node 3-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree>\n `\n};\n\n/**\n * @summary Single-selection tree for choosing one item from hierarchical options, enabling focused navigation and content selection.\n */\nexport const Selectable = {\n render: () => html`\n <nve-tree selectable=\"single\" behavior-expand behavior-select border>\n <nve-tree-node expanded>\n node 1\n <nve-tree-node selected>node 1-1</nve-tree-node>\n <nve-tree-node>node 1-2</nve-tree-node>\n <nve-tree-node>\n node 1-3\n <nve-tree-node>node 1-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-2</nve-tree-node>\n <nve-tree-node>node 1-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 2\n <nve-tree-node>node 2-1</nve-tree-node>\n <nve-tree-node>node 2-2</nve-tree-node>\n <nve-tree-node>node 2-3</nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 3\n <nve-tree-node>node 3-1</nve-tree-node>\n <nve-tree-node>node 3-2</nve-tree-node>\n <nve-tree-node>\n node 3-3\n <nve-tree-node>node 3-3-1</nve-tree-node>\n <nve-tree-node>node 3-3-2</nve-tree-node>\n <nve-tree-node>node 3-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree>\n `\n};\n\n/**\n * @summary Multi-selection tree for choosing many items from hierarchical options, enabling bulk operations and comprehensive content management.\n */\nexport const SelectableMultiple = {\n render: () => html`\n <nve-tree selectable=\"multi\" behavior-expand behavior-select border>\n <nve-tree-node expanded>\n node 1\n <nve-tree-node>node 1-1</nve-tree-node>\n <nve-tree-node selected>node 1-2</nve-tree-node>\n <nve-tree-node expanded>\n node 1-3\n <nve-tree-node>node 1-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-2</nve-tree-node>\n <nve-tree-node>node 1-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 2\n <nve-tree-node>node 2-1</nve-tree-node>\n <nve-tree-node>node 2-2</nve-tree-node>\n <nve-tree-node>node 2-3</nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 3\n <nve-tree-node>node 3-1</nve-tree-node>\n <nve-tree-node>node 3-2</nve-tree-node>\n <nve-tree-node>\n node 3-3\n <nve-tree-node>node 3-3-1</nve-tree-node>\n <nve-tree-node>node 3-3-2</nve-tree-node>\n <nve-tree-node>node 3-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree>\n `\n};\n\n/**\n * @summary Interactive selection handling using the select event, with callbacks for node selection changes.\n * @tags test-case\n */\nexport const SelectEvent = {\n render: () => html`\n <div nve-layout=\"column gap:md\">\n <div nve-layout=\"row gap:md\">\n <nve-tree id=\"select-event-tree\" selectable=\"single\" behavior-expand behavior-select border>\n <nve-tree-node expanded>\n Documents\n <nve-tree-node>Annual Report.pdf</nve-tree-node>\n <nve-tree-node>Budget.xlsx</nve-tree-node>\n <nve-tree-node expanded>\n Projects\n <nve-tree-node>Project Alpha</nve-tree-node>\n <nve-tree-node>Project Beta</nve-tree-node>\n <nve-tree-node>Project Gamma</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n Images\n <nve-tree-node>photo-001.jpg</nve-tree-node>\n <nve-tree-node>photo-002.jpg</nve-tree-node>\n <nve-tree-node>screenshot.png</nve-tree-node>\n </nve-tree-node>\n </nve-tree>\n <div nve-layout=\"column gap:sm\">\n <p nve-text=\"body sm\"><strong>Selected:</strong> <span id=\"selected-node\">None</span></p>\n <p nve-text=\"body sm\"><strong>History:</strong></p>\n <ul id=\"selection-history\" nve-text=\"body sm\">\n <li>No selections yet</li>\n </ul>\n </div>\n </div>\n </div>\n <script type=\"module\">\n const tree = document.querySelector('#select-event-tree');\n const selectedDisplay = document.querySelector('#selected-node');\n const historyList = document.querySelector('#selection-history');\n const history = [];\n tree.addEventListener('select', (e) => {\n const node = e.detail;\n const nodeText = node.textContent?.trim().split('\\\\n')[0] ?? 'Unknown';\n selectedDisplay.textContent = nodeText;\n history.push(nodeText);\n if (history.length > 5) history.shift();\n historyList.innerHTML = history.map(item => '<li>' + item + '</li>').join('');\n });\n </script>\n `\n};\n\n/**\n * @summary Tree with highlighted nodes for emphasizing specific items, providing visual focus and search result signal in hierarchical data.\n */\nexport const Highlight = {\n render: () => html`\n <nve-tree behavior-expand border>\n <nve-tree-node expanded>\n node 1\n <nve-tree-node highlighted>node 1-1</nve-tree-node>\n <nve-tree-node>node 1-2</nve-tree-node>\n <nve-tree-node expanded>\n node 1-3\n <nve-tree-node highlighted>node 1-3-1</nve-tree-node>\n <nve-tree-node highlighted>node 1-3-2</nve-tree-node>\n <nve-tree-node>node 1-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 2\n <nve-tree-node>node 2-1</nve-tree-node>\n <nve-tree-node>node 2-2</nve-tree-node>\n <nve-tree-node>node 2-3</nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 3\n <nve-tree-node>node 3-1</nve-tree-node>\n <nve-tree-node>node 3-2</nve-tree-node>\n <nve-tree-node>\n node 3-3\n <nve-tree-node>node 3-3-1</nve-tree-node>\n <nve-tree-node>node 3-3-2</nve-tree-node>\n <nve-tree-node>node 3-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree>\n `\n};\n\n/**\n * @summary Tree with navigation links for hierarchical menu systems, enabling structured site navigation and content discovery.\n */\nexport const Links = {\n render: () => html`\n <nve-tree behavior-expand>\n <nve-tree-node><a href=\"#\">Documentation</a></nve-tree-node>\n <nve-tree-node><a href=\"#\">Support</a></nve-tree-node>\n <nve-tree-node expanded>\n Elements\n <nve-tree-node><a href=\"#\">Alert</a></nve-tree-node>\n <nve-tree-node><a href=\"#\">Badge</a></nve-tree-node>\n <nve-tree-node><a href=\"#\">Dialog</a></nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n Frameworks\n <nve-tree-node><a href=\"#\">Angular</a></nve-tree-node>\n <nve-tree-node><a href=\"#\">React</a></nve-tree-node>\n <nve-tree-node><a href=\"#\">Vue</a></nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n Languages\n <nve-tree-node><a href=\"#\">JavaScript</a></nve-tree-node>\n <nve-tree-node><a href=\"#\">HTML</a></nve-tree-node>\n <nve-tree-node><a href=\"#\">CSS</a></nve-tree-node>\n </nve-tree-node>\n </nve-tree>\n `\n};\n\n/**\n * @summary Tree with loading states for asynchronous data, including progress indicators and dynamic content loading in hierarchical structures.\n */\nexport const Async = {\n render: () => html`\n <nve-tree border>\n <nve-tree-node expanded>\n node 1\n <nve-tree-node>node 1-1</nve-tree-node>\n <nve-tree-node>node 1-2</nve-tree-node>\n <nve-tree-node expanded>\n node 1-3\n <nve-tree-node>\n <div nve-layout=\"row gap:xs\">\n <nve-progress-ring status=\"accent\" size=\"xs\"></nve-progress-ring> loading\n </div>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 2\n <nve-tree-node>node 2-1</nve-tree-node>\n <nve-tree-node>node 2-2</nve-tree-node>\n <nve-tree-node>node 2-3</nve-tree-node>\n </nve-tree-node>\n <nve-tree-node>\n node 3\n <nve-tree-node>node 3-1</nve-tree-node>\n <nve-tree-node>node 3-2</nve-tree-node>\n <nve-tree-node>\n node 3-3\n <nve-tree-node>node 3-3-1</nve-tree-node>\n <nve-tree-node>node 3-3-2</nve-tree-node>\n <nve-tree-node>node 3-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree>\n `\n};\n\n/**\n * @summary Tree with prefix and suffix content for each node, enabling flexible content organization and visual hierarchy.\n * @tags test-case\n */\nexport const PrefixSuffix = {\n render: () => html`\n<nve-tree behavior-expand behavior-select selectable=\"single\" aria-label=\"Robot workspace files\">\n <nve-tree-node expanded>\n <nve-icon name=\"folder\" slot=\"prefix\"></nve-icon> src\n <nve-tree-node expanded>\n <nve-icon name=\"folder\" slot=\"prefix\"></nve-icon> navigation\n <nve-tree-node selected><nve-icon name=\"code\" slot=\"prefix\"></nve-icon> controller.py <nve-dot status=\"accent\" size=\"sm\" slot=\"suffix\"></nve-dot></nve-tree-node>\n <nve-tree-node><nve-icon name=\"code\" slot=\"prefix\"></nve-icon> planner.py</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n</nve-tree>\n `\n};\n\n/**\n * @summary Tree with rich node content including forms, controls, and interactive elements, enabling complex data management within hierarchical structures.\n */\nexport const NodeContent = {\n render: () => html`\n <nve-tree selectable=\"multi\" border behavior-expand behavior-select>\n <nve-tree-node expanded>\n text content\n <nve-tree-node>\n <a href=\".\" nve-text=\"link\">node link</a>\n </nve-tree-node>\n <nve-tree-node>\n <nve-icon name=\"code\" slot=\"prefix\"></nve-icon>\n <a href=\".\" nve-text=\"link\">node link</a>\n <nve-dot status=\"accent\" size=\"sm\" slot=\"suffix\"></nve-dot>\n </nve-tree-node>\n <nve-tree-node>\n inline content <nve-dot status=\"success\" size=\"sm\"></nve-dot>\n </nve-tree-node>\n <nve-tree-node>\n <div nve-text=\"body sm muted\" nve-layout=\"pad-bottom:xs\">block</div>\n <p nve-text=\"body sm\">content</p>\n </nve-tree-node>\n <nve-tree-node>\n long form content\n <div slot=\"content\" nve-layout=\"column gap:sm\">\n <a href=\"#\" nve-text=\"link\">This is some longer content in a tree node.</a>\n <a href=\"#\" nve-text=\"link\">This is some longer content in a tree node.</a>\n <a href=\"#\" nve-text=\"link\">This is some longer content in a tree node.</a>\n </div>\n </nve-tree-node>\n <nve-tree-node>\n interactive content\n <div slot=\"content\" nve-layout=\"column gap:sm\">\n <p nve-text=\"body sm\">This is some longer content in a tree node.</p>\n <nve-button>hello there</nve-button>\n </div>\n </nve-tree-node>\n <nve-tree-node>\n input control\n <div slot=\"content\" nve-layout=\"column gap:sm\">\n <nve-input>\n <label>label</label>\n <input type=\"text\" />\n </nve-input>\n <nve-input>\n <label>label</label>\n <input type=\"text\" />\n </nve-input>\n </div>\n </nve-tree-node>\n <nve-tree-node>\n node content checkbox group\n <nve-checkbox-group slot=\"content\">\n <label>label</label>\n <nve-checkbox>\n <label>checkbox 1</label>\n <input type=\"checkbox\" checked />\n </nve-checkbox>\n\n <nve-checkbox>\n <label>checkbox 2</label>\n <input type=\"checkbox\" />\n </nve-checkbox>\n\n <nve-checkbox>\n <label>checkbox 3</label>\n <input type=\"checkbox\" />\n </nve-checkbox>\n </nve-checkbox-group>\n </nve-tree-node>\n <nve-tree-node>\n node content radio group\n <nve-radio-group slot=\"content\">\n <label>label</label>\n <nve-radio>\n <label>radio 1</label>\n <input type=\"radio\" checked />\n </nve-radio>\n\n <nve-radio>\n <label>radio 2</label>\n <input type=\"radio\" />\n </nve-radio>\n\n <nve-radio>\n <label>radio 3</label>\n <input type=\"radio\" />\n </nve-radio>\n </nve-radio-group>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree>\n `\n};\n\n/**\n * @summary Tree with a max width, ensuring the tree does not exceed the specified width.\n * @tags test-case\n */\nexport const MaxWidth = {\n render: () => html`\n<nve-tree style=\"max-width: 500px; outline: 1px dashed red;\">\n <nve-tree-node style=\"outline: 1px dashed blue;\">\n <p nve-text=\"label truncate\">1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890</p>\n </nve-tree-node>\n</nve-tree>\n `\n};\n\n/**\n * @summary Dynamic tree with programmatic node creation and management, for scalable hierarchical data handling with large datasets.\n * @tags test-case\n */\nexport const DynamicTree = {\n render: () => html`<test-dynamic-tree></test-dynamic-tree>`\n};\n\n/**\n * @summary Tree with scrollable container for handling deep hierarchies and large datasets, ensuring optimal space usage and navigation.\n * @tags test-case\n */\nexport const Overflow = {\n render: () => html`\n <div style=\"width: 300px; height: 500px; overflow: auto; outline: 1px solid #ccc; padding: 12px\">\n <nve-tree border behavior-expand>\n <nve-tree-node expanded>\n node 1\n <nve-tree-node>node 1-1</nve-tree-node>\n <nve-tree-node>node 1-2</nve-tree-node>\n <nve-tree-node expanded>\n node 1-3\n <nve-tree-node>node 1-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-2</nve-tree-node>\n <nve-tree-node expanded>\n node 1-3-3\n <nve-tree-node>node 1-3-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-3-2</nve-tree-node>\n <nve-tree-node expanded>\n node 1-3-3-3\n <nve-tree-node>node 1-3-3-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-3-3-2</nve-tree-node>\n <nve-tree-node expanded>\n node 1-3-3-3-3\n <nve-tree-node>node 1-3-3-3-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-3-3-3-2</nve-tree-node>\n <nve-tree-node expanded>\n node 1-3-3-3-3-3\n <nve-tree-node>node 1-3-3-3-3-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-3-3-3-3-2</nve-tree-node>\n <nve-tree-node expanded>\n node 1-3-3-3-3-3-3\n <nve-tree-node>node 1-3-3-3-3-3-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-3-3-3-3-3-2</nve-tree-node>\n <nve-tree-node expanded>\n node 1-3-3-3-3-3-3-3\n <nve-tree-node>node 1-3-3-3-3-3-3-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-3-3-3-3-3-3-2</nve-tree-node>\n <nve-tree-node expanded>\n node 1-3-3-3-3-3-3-3-3\n <nve-tree-node>node 1-3-3-3-3-3-3-3-3-1</nve-tree-node>\n <nve-tree-node>node 1-3-3-3-3-3-3-3-3-2</nve-tree-node>\n <nve-tree-node>node 1-3-3-3-3-3-3-3-3-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n </nve-tree-node>\n <nve-tree-node expanded>\n node 2\n <nve-tree-node>node 2-1</nve-tree-node>\n <nve-tree-node>node 2-2</nve-tree-node>\n <nve-tree-node>node 2-3</nve-tree-node>\n </nve-tree-node>\n </nve-tree>\n </div>\n `\n};\n\n/**\n * @summary Tree with bulk node creation for performance testing, verifying efficient handling of large numbers of nodes and dynamic expansion.\n * @tags test-case performance\n */\nexport const BulkCreation = {\n render: () => html`\n <nve-tree>\n <nve-tree-node id=\"root\" expandable>Test</nve-tree-node>\n </nve-tree>\n <script type=\"module\">\n const rootEl = document.querySelector('nve-tree-node#root');\n\n rootEl.addEventListener('open', () => {\n const fragment = document.createDocumentFragment();\n for (let i = 0; i < 400; i++) {\n rootEl.expanded = true;\n const childEl = document.createElement('nve-tree-node');\n childEl.innerText = 'Child ' + i;\n fragment.append(childEl);\n }\n rootEl.append(fragment);\n });\n\n rootEl.addEventListener('close', () => {\n rootEl.expanded = false;\n rootEl.replaceChildren(document.createTextNode('Test'));\n });\n </script>\n `\n};\n\n/* eslint-disable @nvidia-elements/lint/no-invalid-parent-elements -- Intentional invalid parent for audit documentation. */\n/**\n * @summary Examples of invalid tree usage patterns for testing and documentation purposes, showing what not to do when implementing trees.\n * @tags anti-pattern\n */\nexport const Audit = {\n render: () => html`\n <div>\n <nve-tree-node>node</nve-tree-node>\n </div>\n `\n};\n/* eslint-enable @nvidia-elements/lint/no-invalid-parent-elements */\n\nexport class TestDynamicTree extends LitElement {\n @state() nodes = createTree();\n\n render() {\n return html`\n <p nve-text=\"body\">total nodes: 10,000</p>\n <nve-tree border expandable>\n ${this.nodes.map(node => this.#getNodeList(node))}\n </nve-tree>`;\n }\n\n #getNodeList(node) {\n return html`<nve-tree-node .expandable=${node.nodes.length} .expanded=${node.expanded} @open=${e => this.#open(e, node)} @close=${e => this.#close(e, node)}>\n ${node.label} node\n ${node.expanded ? node.nodes.map(n => html`${this.#getNodeList(n)}`) : nothing}\n </nve-tree-node>`\n }\n\n #open(e, node) {\n e.stopPropagation();\n node.expanded = true;\n this.nodes = [...this.nodes];\n this.requestUpdate();\n }\n\n #close(e, node) {\n e.stopPropagation();\n node.expanded = false;\n this.nodes = [...this.nodes];\n this.requestUpdate();\n }\n}\n\n/** generates a tree with 10 nodes with 4 layers */\nfunction createTree() {\n return createNodeList(10).map(i => {\n i.nodes = createNodeList(10);\n i.nodes.forEach(j => {\n j.nodes = createNodeList(10);\n j.nodes.forEach(k => {\n k.nodes = createNodeList(10);\n })\n })\n return i;\n });\n}\n\nfunction createNodeList(nodes: number) {\n return new Array(nodes).fill('').map((_, i) => ({ label: `${i}`, expanded: false, nodes: [] }));\n}\n\ncustomElements.get('test-dynamic-tree') || customElements.define('test-dynamic-tree', TestDynamicTree);\n"],"mappings":";AAGA,IAAA,IAAe"}
@@ -11,6 +11,15 @@
11
11
  "composition": false,
12
12
  "tags": []
13
13
  },
14
+ {
15
+ "id": "tree-invoker-commands",
16
+ "name": "InvokerCommands",
17
+ "template": "<nve-tree>\n <nve-tree-node command=\"--open\" commandfor=\"tree-command-details\">Show details</nve-tree-node>\n <nve-tree-node command=\"--close\" commandfor=\"tree-command-details\">Hide details</nve-tree-node>\n</nve-tree>\n<nve-tree>\n <nve-tree-node id=\"tree-command-details\">\n Details\n <nve-tree-node>Model configuration</nve-tree-node>\n <nve-tree-node>Training results</nve-tree-node>\n </nve-tree-node>\n</nve-tree>\n",
18
+ "summary": "Invoke commands from tree node titles to control another tree without event handlers. Click a title or press Enter on its header to open or close the target node.",
19
+ "description": "",
20
+ "composition": false,
21
+ "tags": []
22
+ },
14
23
  {
15
24
  "id": "tree-border",
16
25
  "name": "Border",
@@ -22,7 +22,7 @@ var m = class extends d {
22
22
  static {
23
23
  this.metadata = {
24
24
  tag: "nve-tree",
25
- version: "2.18.3",
25
+ version: "2.19.0",
26
26
  children: ["nve-tree-node"]
27
27
  };
28
28
  }
@@ -19,7 +19,7 @@ var l = class extends r {
19
19
  static {
20
20
  this.metadata = {
21
21
  tag: "nve-week",
22
- version: "2.18.3"
22
+ version: "2.19.0"
23
23
  };
24
24
  }
25
25
  static {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nvidia-elements/core",
3
- "version": "2.18.3",
3
+ "version": "2.19.0",
4
4
  "release": {
5
5
  "extends": "../../release.config.js"
6
6
  },
@@ -1000,7 +1000,7 @@
1000
1000
  },
1001
1001
  "dependencies": {
1002
1002
  "@nvidia-elements/foundations": "^1.0.2",
1003
- "@nvidia-elements/forms": "^2.0.9",
1003
+ "@nvidia-elements/forms": "^2.0.10",
1004
1004
  "lit": "^3.3.3",
1005
1005
  "lit-html": "^3.3.3"
1006
1006
  },
@@ -1020,7 +1020,7 @@
1020
1020
  "@internals/testing": "0.0.0",
1021
1021
  "@internals/vite": "0.0.0",
1022
1022
  "@lit-labs/virtualizer": "2.1.1",
1023
- "@nvidia-elements/lint": "2.9.0",
1023
+ "@nvidia-elements/lint": "2.9.1",
1024
1024
  "@nvidia-elements/styles": "^2.1.3",
1025
1025
  "@typescript/lib-dom": "npm:@types/web@0.0.312",
1026
1026
  "@vitest/browser": "5.0.0",