@neural-ui/core 1.3.2 → 1.5.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 (103) hide show
  1. package/README.md +14 -7
  2. package/calendar/package.json +4 -0
  3. package/fesm2022/neural-ui-core-accordion.mjs +8 -6
  4. package/fesm2022/neural-ui-core-accordion.mjs.map +1 -1
  5. package/fesm2022/neural-ui-core-autocomplete.mjs +121 -29
  6. package/fesm2022/neural-ui-core-autocomplete.mjs.map +1 -1
  7. package/fesm2022/neural-ui-core-badge.mjs +2 -2
  8. package/fesm2022/neural-ui-core-badge.mjs.map +1 -1
  9. package/fesm2022/neural-ui-core-block-ui.mjs +2 -2
  10. package/fesm2022/neural-ui-core-button.mjs +2 -2
  11. package/fesm2022/neural-ui-core-button.mjs.map +1 -1
  12. package/fesm2022/neural-ui-core-calendar.mjs +551 -0
  13. package/fesm2022/neural-ui-core-calendar.mjs.map +1 -0
  14. package/fesm2022/neural-ui-core-chip.mjs +2 -2
  15. package/fesm2022/neural-ui-core-chip.mjs.map +1 -1
  16. package/fesm2022/neural-ui-core-color-picker.mjs +3 -9
  17. package/fesm2022/neural-ui-core-color-picker.mjs.map +1 -1
  18. package/fesm2022/neural-ui-core-confirm-dialog.mjs +2 -2
  19. package/fesm2022/neural-ui-core-confirm-dialog.mjs.map +1 -1
  20. package/fesm2022/neural-ui-core-dashboard-grid.mjs +2 -2
  21. package/fesm2022/neural-ui-core-dashboard-grid.mjs.map +1 -1
  22. package/fesm2022/neural-ui-core-date-input.mjs +2 -2
  23. package/fesm2022/neural-ui-core-date-input.mjs.map +1 -1
  24. package/fesm2022/neural-ui-core-filter-bar.mjs +2 -2
  25. package/fesm2022/neural-ui-core-filter-bar.mjs.map +1 -1
  26. package/fesm2022/neural-ui-core-image-gallery.mjs +224 -0
  27. package/fesm2022/neural-ui-core-image-gallery.mjs.map +1 -0
  28. package/fesm2022/neural-ui-core-input.mjs +2 -2
  29. package/fesm2022/neural-ui-core-kanban.mjs +270 -0
  30. package/fesm2022/neural-ui-core-kanban.mjs.map +1 -0
  31. package/fesm2022/neural-ui-core-meter-group.mjs +2 -2
  32. package/fesm2022/neural-ui-core-modal.mjs +81 -31
  33. package/fesm2022/neural-ui-core-modal.mjs.map +1 -1
  34. package/fesm2022/neural-ui-core-multiselect.mjs +269 -99
  35. package/fesm2022/neural-ui-core-multiselect.mjs.map +1 -1
  36. package/fesm2022/neural-ui-core-nav.mjs +4 -6
  37. package/fesm2022/neural-ui-core-nav.mjs.map +1 -1
  38. package/fesm2022/neural-ui-core-number-input.mjs +2 -2
  39. package/fesm2022/neural-ui-core-pagination.mjs +2 -2
  40. package/fesm2022/neural-ui-core-pagination.mjs.map +1 -1
  41. package/fesm2022/neural-ui-core-progress-bar.mjs +2 -2
  42. package/fesm2022/neural-ui-core-scheduler-gantt.mjs +289 -0
  43. package/fesm2022/neural-ui-core-scheduler-gantt.mjs.map +1 -0
  44. package/fesm2022/neural-ui-core-select.mjs +276 -101
  45. package/fesm2022/neural-ui-core-select.mjs.map +1 -1
  46. package/fesm2022/neural-ui-core-sidebar.mjs +3 -2
  47. package/fesm2022/neural-ui-core-sidebar.mjs.map +1 -1
  48. package/fesm2022/neural-ui-core-slider.mjs +2 -2
  49. package/fesm2022/neural-ui-core-slider.mjs.map +1 -1
  50. package/fesm2022/neural-ui-core-split-button.mjs +2 -2
  51. package/fesm2022/neural-ui-core-split-button.mjs.map +1 -1
  52. package/fesm2022/neural-ui-core-stepper.mjs +2 -2
  53. package/fesm2022/neural-ui-core-stepper.mjs.map +1 -1
  54. package/fesm2022/neural-ui-core-table.mjs +435 -34
  55. package/fesm2022/neural-ui-core-table.mjs.map +1 -1
  56. package/fesm2022/neural-ui-core-tabs.mjs +11 -4
  57. package/fesm2022/neural-ui-core-tabs.mjs.map +1 -1
  58. package/fesm2022/neural-ui-core-textarea.mjs +2 -2
  59. package/fesm2022/neural-ui-core-timeline-grid.mjs +215 -0
  60. package/fesm2022/neural-ui-core-timeline-grid.mjs.map +1 -0
  61. package/fesm2022/neural-ui-core-toggle-button-group.mjs +2 -2
  62. package/fesm2022/neural-ui-core-toggle-button-group.mjs.map +1 -1
  63. package/fesm2022/neural-ui-core-toolbar.mjs +2 -2
  64. package/fesm2022/neural-ui-core-toolbar.mjs.map +1 -1
  65. package/fesm2022/neural-ui-core-tree-table.mjs +262 -0
  66. package/fesm2022/neural-ui-core-tree-table.mjs.map +1 -0
  67. package/fesm2022/neural-ui-core-tree.mjs +413 -0
  68. package/fesm2022/neural-ui-core-tree.mjs.map +1 -0
  69. package/fesm2022/neural-ui-core-uploader.mjs +624 -0
  70. package/fesm2022/neural-ui-core-uploader.mjs.map +1 -0
  71. package/fesm2022/neural-ui-core-url-state.mjs +90 -10
  72. package/fesm2022/neural-ui-core-url-state.mjs.map +1 -1
  73. package/fesm2022/neural-ui-core-virtual-list.mjs +53 -23
  74. package/fesm2022/neural-ui-core-virtual-list.mjs.map +1 -1
  75. package/fesm2022/neural-ui-core.mjs +3 -1
  76. package/fesm2022/neural-ui-core.mjs.map +1 -1
  77. package/image-gallery/package.json +4 -0
  78. package/kanban/package.json +4 -0
  79. package/package.json +34 -2
  80. package/scheduler-gantt/package.json +4 -0
  81. package/styles/_tokens.scss +13 -4
  82. package/timeline-grid/package.json +4 -0
  83. package/tree/package.json +4 -0
  84. package/tree-table/package.json +4 -0
  85. package/types/neural-ui-core-autocomplete.d.ts +10 -1
  86. package/types/neural-ui-core-calendar.d.ts +79 -0
  87. package/types/neural-ui-core-color-picker.d.ts +0 -1
  88. package/types/neural-ui-core-image-gallery.d.ts +26 -0
  89. package/types/neural-ui-core-kanban.d.ts +52 -0
  90. package/types/neural-ui-core-modal.d.ts +22 -16
  91. package/types/neural-ui-core-multiselect.d.ts +13 -1
  92. package/types/neural-ui-core-scheduler-gantt.d.ts +68 -0
  93. package/types/neural-ui-core-select.d.ts +14 -1
  94. package/types/neural-ui-core-sidebar.d.ts +1 -0
  95. package/types/neural-ui-core-table.d.ts +66 -4
  96. package/types/neural-ui-core-tabs.d.ts +1 -0
  97. package/types/neural-ui-core-timeline-grid.d.ts +55 -0
  98. package/types/neural-ui-core-tree-table.d.ts +72 -0
  99. package/types/neural-ui-core-tree.d.ts +52 -0
  100. package/types/neural-ui-core-uploader.d.ts +98 -0
  101. package/types/neural-ui-core-url-state.d.ts +9 -0
  102. package/types/neural-ui-core-virtual-list.d.ts +17 -1
  103. package/uploader/package.json +4 -0
@@ -0,0 +1,413 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, output, signal, computed, effect, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
3
+ import { NgTemplateOutlet } from '@angular/common';
4
+
5
+ class NeuTreeComponent {
6
+ nodes = input([], ...(ngDevMode ? [{ debugName: "nodes" }] : /* istanbul ignore next */ []));
7
+ selectable = input(false, ...(ngDevMode ? [{ debugName: "selectable" }] : /* istanbul ignore next */ []));
8
+ searchable = input(false, ...(ngDevMode ? [{ debugName: "searchable" }] : /* istanbul ignore next */ []));
9
+ selectionMode = input('single', ...(ngDevMode ? [{ debugName: "selectionMode" }] : /* istanbul ignore next */ []));
10
+ indentSize = input(18, ...(ngDevMode ? [{ debugName: "indentSize" }] : /* istanbul ignore next */ []));
11
+ ariaLabel = input('Tree', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
12
+ searchPlaceholder = input('Search nodes', ...(ngDevMode ? [{ debugName: "searchPlaceholder" }] : /* istanbul ignore next */ []));
13
+ emptyLabel = input('No nodes available', ...(ngDevMode ? [{ debugName: "emptyLabel" }] : /* istanbul ignore next */ []));
14
+ expandLabel = input('Expand node', ...(ngDevMode ? [{ debugName: "expandLabel" }] : /* istanbul ignore next */ []));
15
+ collapseLabel = input('Collapse node', ...(ngDevMode ? [{ debugName: "collapseLabel" }] : /* istanbul ignore next */ []));
16
+ selectionChange = output();
17
+ expansionChange = output();
18
+ nodeClick = output();
19
+ searchQuery = signal('', ...(ngDevMode ? [{ debugName: "searchQuery" }] : /* istanbul ignore next */ []));
20
+ expandedKeys = signal(new Set(), ...(ngDevMode ? [{ debugName: "expandedKeys" }] : /* istanbul ignore next */ []));
21
+ selectedKeys = signal(new Set(), ...(ngDevMode ? [{ debugName: "selectedKeys" }] : /* istanbul ignore next */ []));
22
+ visibleNodes = computed(() => {
23
+ const query = this.searchQuery().trim().toLowerCase();
24
+ if (!query) {
25
+ return this.nodes();
26
+ }
27
+ return this.filterNodes(this.nodes(), query);
28
+ }, ...(ngDevMode ? [{ debugName: "visibleNodes" }] : /* istanbul ignore next */ []));
29
+ constructor() {
30
+ effect(() => {
31
+ const nextExpanded = this.collectExpandedKeys(this.nodes());
32
+ this.expandedKeys.set(nextExpanded);
33
+ this.selectedKeys.set(new Set());
34
+ this.searchQuery.set('');
35
+ });
36
+ }
37
+ hasChildren(node) {
38
+ return !!node.children?.length;
39
+ }
40
+ canSelect(node) {
41
+ return this.selectable() && node.selectable !== false;
42
+ }
43
+ isExpanded(nodeId) {
44
+ return this.expandedKeys().has(nodeId);
45
+ }
46
+ isRenderedExpanded(node) {
47
+ if (this.searchQuery().trim()) {
48
+ return node.expanded ?? this.isExpanded(node.id);
49
+ }
50
+ return this.isExpanded(node.id);
51
+ }
52
+ isSelected(nodeId) {
53
+ return this.selectedKeys().has(nodeId);
54
+ }
55
+ onSearch(event) {
56
+ const target = event.target;
57
+ this.searchQuery.set(target.value);
58
+ }
59
+ toggleNode(node, event) {
60
+ event?.stopPropagation();
61
+ if (node.disabled || !this.hasChildren(node)) {
62
+ return;
63
+ }
64
+ const next = new Set(this.expandedKeys());
65
+ if (next.has(node.id)) {
66
+ next.delete(node.id);
67
+ }
68
+ else {
69
+ next.add(node.id);
70
+ }
71
+ this.expandedKeys.set(next);
72
+ this.expansionChange.emit([...next]);
73
+ }
74
+ activateNode(node) {
75
+ if (node.disabled) {
76
+ return;
77
+ }
78
+ this.nodeClick.emit(node);
79
+ if (!this.canSelect(node)) {
80
+ return;
81
+ }
82
+ if (this.selectionMode() === 'multiple') {
83
+ const checked = !this.isSelected(node.id);
84
+ this.updateSelection(node, checked);
85
+ return;
86
+ }
87
+ this.updateSelection(node, true);
88
+ }
89
+ onCheckboxChange(node, event) {
90
+ const target = event.target;
91
+ this.updateSelection(node, target.checked);
92
+ }
93
+ updateSelection(node, checked) {
94
+ if (node.disabled || !this.canSelect(node)) {
95
+ return;
96
+ }
97
+ const next = new Set(this.selectedKeys());
98
+ if (this.selectionMode() === 'single') {
99
+ next.clear();
100
+ if (checked) {
101
+ next.add(node.id);
102
+ }
103
+ }
104
+ else if (checked) {
105
+ next.add(node.id);
106
+ }
107
+ else {
108
+ next.delete(node.id);
109
+ }
110
+ this.selectedKeys.set(next);
111
+ this.selectionChange.emit(this.collectSelectedNodes(this.nodes(), next));
112
+ }
113
+ collectExpandedKeys(nodes) {
114
+ const expanded = new Set();
115
+ for (const node of nodes) {
116
+ if (node.expanded) {
117
+ expanded.add(node.id);
118
+ }
119
+ if (node.children?.length) {
120
+ for (const childId of this.collectExpandedKeys(node.children)) {
121
+ expanded.add(childId);
122
+ }
123
+ }
124
+ }
125
+ return expanded;
126
+ }
127
+ collectSelectedNodes(nodes, selected) {
128
+ const result = [];
129
+ for (const node of nodes) {
130
+ if (selected.has(node.id)) {
131
+ result.push(node);
132
+ }
133
+ if (node.children?.length) {
134
+ result.push(...this.collectSelectedNodes(node.children, selected));
135
+ }
136
+ }
137
+ return result;
138
+ }
139
+ filterNodes(nodes, query) {
140
+ const filtered = [];
141
+ for (const node of nodes) {
142
+ const children = node.children?.length ? this.filterNodes(node.children, query) : [];
143
+ const matches = node.label.toLowerCase().includes(query) ||
144
+ node.description?.toLowerCase().includes(query) ||
145
+ node.badge?.toLowerCase().includes(query);
146
+ if (matches || children.length) {
147
+ filtered.push({
148
+ ...node,
149
+ children,
150
+ expanded: children.length ? true : node.expanded,
151
+ });
152
+ }
153
+ }
154
+ return filtered;
155
+ }
156
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuTreeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
157
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: NeuTreeComponent, isStandalone: true, selector: "neu-tree", inputs: { nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, indentSize: { classPropertyName: "indentSize", publicName: "indentSize", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, emptyLabel: { classPropertyName: "emptyLabel", publicName: "emptyLabel", isSignal: true, isRequired: false, transformFunction: null }, expandLabel: { classPropertyName: "expandLabel", publicName: "expandLabel", isSignal: true, isRequired: false, transformFunction: null }, collapseLabel: { classPropertyName: "collapseLabel", publicName: "collapseLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange", expansionChange: "expansionChange", nodeClick: "nodeClick" }, ngImport: i0, template: `
158
+ <div class="neu-tree">
159
+ @if (searchable()) {
160
+ <label class="neu-tree__search" [attr.aria-label]="searchPlaceholder()">
161
+ <svg
162
+ class="neu-tree__search-icon"
163
+ viewBox="0 0 24 24"
164
+ fill="none"
165
+ stroke="currentColor"
166
+ stroke-width="2"
167
+ stroke-linecap="round"
168
+ stroke-linejoin="round"
169
+ aria-hidden="true"
170
+ >
171
+ <circle cx="11" cy="11" r="7"></circle>
172
+ <path d="m20 20-3.5-3.5"></path>
173
+ </svg>
174
+ <input
175
+ class="neu-tree__search-input"
176
+ type="search"
177
+ [value]="searchQuery()"
178
+ [attr.placeholder]="searchPlaceholder()"
179
+ (input)="onSearch($event)"
180
+ />
181
+ </label>
182
+ }
183
+
184
+ @if (visibleNodes().length) {
185
+ <ul
186
+ class="neu-tree__list neu-tree__list--root"
187
+ role="tree"
188
+ [attr.aria-label]="ariaLabel()"
189
+ [attr.aria-multiselectable]="
190
+ selectable() && selectionMode() === 'multiple' ? 'true' : null
191
+ "
192
+ >
193
+ <ng-container
194
+ [ngTemplateOutlet]="treeNodes"
195
+ [ngTemplateOutletContext]="{ $implicit: visibleNodes(), level: 1 }"
196
+ />
197
+ </ul>
198
+ } @else {
199
+ <div class="neu-tree__empty">{{ emptyLabel() }}</div>
200
+ }
201
+ </div>
202
+
203
+ <ng-template #treeNodes let-nodes let-level="level">
204
+ @for (node of nodes; track node.id) {
205
+ <li
206
+ class="neu-tree__node"
207
+ role="treeitem"
208
+ [attr.aria-level]="level"
209
+ [attr.aria-expanded]="hasChildren(node) ? isRenderedExpanded(node) : null"
210
+ [attr.aria-selected]="canSelect(node) ? isSelected(node.id) : null"
211
+ [attr.aria-disabled]="node.disabled ? 'true' : null"
212
+ >
213
+ <div
214
+ class="neu-tree__row"
215
+ [class.neu-tree__row--selected]="isSelected(node.id)"
216
+ [class.neu-tree__row--disabled]="node.disabled"
217
+ [style.padding-inline-start.px]="(level - 1) * indentSize() + 6"
218
+ >
219
+ @if (hasChildren(node)) {
220
+ <button
221
+ class="neu-tree__toggle"
222
+ type="button"
223
+ [class.neu-tree__toggle--open]="isRenderedExpanded(node)"
224
+ [attr.aria-label]="isRenderedExpanded(node) ? collapseLabel() : expandLabel()"
225
+ (click)="toggleNode(node, $event)"
226
+ >
227
+ <svg viewBox="0 0 20 20" fill="none" aria-hidden="true">
228
+ <path d="m7 5 6 5-6 5" />
229
+ </svg>
230
+ </button>
231
+ } @else {
232
+ <span
233
+ class="neu-tree__toggle neu-tree__toggle--placeholder"
234
+ aria-hidden="true"
235
+ ></span>
236
+ }
237
+
238
+ @if (canSelect(node) && selectionMode() === 'multiple') {
239
+ <input
240
+ class="neu-tree__checkbox"
241
+ type="checkbox"
242
+ [attr.aria-label]="'Select ' + node.label"
243
+ [checked]="isSelected(node.id)"
244
+ [disabled]="node.disabled"
245
+ (click)="$event.stopPropagation()"
246
+ (change)="onCheckboxChange(node, $event)"
247
+ />
248
+ }
249
+
250
+ <button
251
+ class="neu-tree__content"
252
+ type="button"
253
+ [disabled]="node.disabled"
254
+ (click)="activateNode(node)"
255
+ >
256
+ <span class="neu-tree__main">
257
+ <span class="neu-tree__label">{{ node.label }}</span>
258
+ @if (node.badge) {
259
+ <span class="neu-tree__badge">{{ node.badge }}</span>
260
+ }
261
+ </span>
262
+ @if (node.description) {
263
+ <span class="neu-tree__description">{{ node.description }}</span>
264
+ }
265
+ </button>
266
+ </div>
267
+
268
+ @if (hasChildren(node) && isRenderedExpanded(node)) {
269
+ <ul class="neu-tree__list" role="group">
270
+ <ng-container
271
+ [ngTemplateOutlet]="treeNodes"
272
+ [ngTemplateOutletContext]="{ $implicit: node.children ?? [], level: level + 1 }"
273
+ />
274
+ </ul>
275
+ }
276
+ </li>
277
+ }
278
+ </ng-template>
279
+ `, isInline: true, styles: [".neu-tree{display:flex;flex-direction:column;gap:.75rem;min-width:0}.neu-tree__search{position:relative;display:flex;align-items:center}.neu-tree__search-icon{position:absolute;left:.875rem;width:.9375rem;height:.9375rem;color:var(--neu-text-muted);pointer-events:none}.neu-tree__search-input{width:100%;min-height:2.625rem;border:1px solid var(--neu-border);border-radius:var(--neu-radius-lg, 14px);background:var(--neu-surface);color:var(--neu-text);padding:.6875rem .875rem .6875rem 2.4rem;outline:none;transition:border-color .16s ease,box-shadow .16s ease,background-color .16s ease}.neu-tree__search-input::placeholder{color:var(--neu-text-muted)}.neu-tree__search-input:focus{border-color:color-mix(in srgb,var(--neu-primary) 62%,var(--neu-border));box-shadow:0 0 0 3px color-mix(in srgb,var(--neu-primary) 16%,transparent)}.neu-tree__list{list-style:none;margin:0;padding:0}.neu-tree__list--root{display:flex;flex-direction:column;gap:.375rem}.neu-tree__node{position:relative}.neu-tree__row{display:flex;align-items:flex-start;gap:.5rem;min-width:0;border-radius:calc(var(--neu-radius-lg, 14px) - 2px);transition:background-color .16s ease,border-color .16s ease,box-shadow .16s ease}.neu-tree__row:hover{background:color-mix(in srgb,var(--neu-primary) 5%,var(--neu-surface))}.neu-tree__row--selected{background:color-mix(in srgb,var(--neu-primary) 10%,var(--neu-surface));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--neu-primary) 20%,var(--neu-border))}.neu-tree__row--disabled{opacity:.6}.neu-tree__toggle{flex:0 0 auto;width:1.75rem;height:1.75rem;margin-top:.4rem;border:0;border-radius:999px;background:transparent;color:var(--neu-text-muted);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:background-color .16s ease,color .16s ease,transform .16s ease}.neu-tree__toggle svg{width:.95rem;height:.95rem;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;transition:transform .16s ease}.neu-tree__toggle:hover{background:color-mix(in srgb,var(--neu-primary) 9%,transparent);color:var(--neu-primary)}.neu-tree__toggle--open svg{transform:rotate(90deg)}.neu-tree__toggle--placeholder{cursor:default}.neu-tree__checkbox{flex:0 0 auto;width:1rem;height:1rem;margin:.8rem 0 0;accent-color:var(--neu-primary)}.neu-tree__content{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:.125rem;border:0;background:transparent;text-align:left;padding:.55rem .75rem .6rem 0;color:inherit;cursor:pointer}.neu-tree__main{display:inline-flex;align-items:center;gap:.5rem;min-width:0}.neu-tree__label{font-size:.9375rem;font-weight:600;color:var(--neu-text)}.neu-tree__badge{display:inline-flex;align-items:center;min-height:1.25rem;padding:0 .45rem;border-radius:999px;background:color-mix(in srgb,var(--neu-primary) 12%,transparent);color:var(--neu-primary);font-size:.6875rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase}.neu-tree__description{color:var(--neu-text-muted);font-size:.8125rem;line-height:1.45}.neu-tree__empty{border:1px dashed var(--neu-border);border-radius:var(--neu-radius-lg, 14px);background:color-mix(in srgb,var(--neu-surface-2) 72%,transparent);color:var(--neu-text-muted);padding:1rem 1.125rem;font-size:.875rem}.neu-tree__node>.neu-tree__list{margin-top:.125rem}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
280
+ }
281
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuTreeComponent, decorators: [{
282
+ type: Component,
283
+ args: [{ selector: 'neu-tree', standalone: true, imports: [NgTemplateOutlet], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: `
284
+ <div class="neu-tree">
285
+ @if (searchable()) {
286
+ <label class="neu-tree__search" [attr.aria-label]="searchPlaceholder()">
287
+ <svg
288
+ class="neu-tree__search-icon"
289
+ viewBox="0 0 24 24"
290
+ fill="none"
291
+ stroke="currentColor"
292
+ stroke-width="2"
293
+ stroke-linecap="round"
294
+ stroke-linejoin="round"
295
+ aria-hidden="true"
296
+ >
297
+ <circle cx="11" cy="11" r="7"></circle>
298
+ <path d="m20 20-3.5-3.5"></path>
299
+ </svg>
300
+ <input
301
+ class="neu-tree__search-input"
302
+ type="search"
303
+ [value]="searchQuery()"
304
+ [attr.placeholder]="searchPlaceholder()"
305
+ (input)="onSearch($event)"
306
+ />
307
+ </label>
308
+ }
309
+
310
+ @if (visibleNodes().length) {
311
+ <ul
312
+ class="neu-tree__list neu-tree__list--root"
313
+ role="tree"
314
+ [attr.aria-label]="ariaLabel()"
315
+ [attr.aria-multiselectable]="
316
+ selectable() && selectionMode() === 'multiple' ? 'true' : null
317
+ "
318
+ >
319
+ <ng-container
320
+ [ngTemplateOutlet]="treeNodes"
321
+ [ngTemplateOutletContext]="{ $implicit: visibleNodes(), level: 1 }"
322
+ />
323
+ </ul>
324
+ } @else {
325
+ <div class="neu-tree__empty">{{ emptyLabel() }}</div>
326
+ }
327
+ </div>
328
+
329
+ <ng-template #treeNodes let-nodes let-level="level">
330
+ @for (node of nodes; track node.id) {
331
+ <li
332
+ class="neu-tree__node"
333
+ role="treeitem"
334
+ [attr.aria-level]="level"
335
+ [attr.aria-expanded]="hasChildren(node) ? isRenderedExpanded(node) : null"
336
+ [attr.aria-selected]="canSelect(node) ? isSelected(node.id) : null"
337
+ [attr.aria-disabled]="node.disabled ? 'true' : null"
338
+ >
339
+ <div
340
+ class="neu-tree__row"
341
+ [class.neu-tree__row--selected]="isSelected(node.id)"
342
+ [class.neu-tree__row--disabled]="node.disabled"
343
+ [style.padding-inline-start.px]="(level - 1) * indentSize() + 6"
344
+ >
345
+ @if (hasChildren(node)) {
346
+ <button
347
+ class="neu-tree__toggle"
348
+ type="button"
349
+ [class.neu-tree__toggle--open]="isRenderedExpanded(node)"
350
+ [attr.aria-label]="isRenderedExpanded(node) ? collapseLabel() : expandLabel()"
351
+ (click)="toggleNode(node, $event)"
352
+ >
353
+ <svg viewBox="0 0 20 20" fill="none" aria-hidden="true">
354
+ <path d="m7 5 6 5-6 5" />
355
+ </svg>
356
+ </button>
357
+ } @else {
358
+ <span
359
+ class="neu-tree__toggle neu-tree__toggle--placeholder"
360
+ aria-hidden="true"
361
+ ></span>
362
+ }
363
+
364
+ @if (canSelect(node) && selectionMode() === 'multiple') {
365
+ <input
366
+ class="neu-tree__checkbox"
367
+ type="checkbox"
368
+ [attr.aria-label]="'Select ' + node.label"
369
+ [checked]="isSelected(node.id)"
370
+ [disabled]="node.disabled"
371
+ (click)="$event.stopPropagation()"
372
+ (change)="onCheckboxChange(node, $event)"
373
+ />
374
+ }
375
+
376
+ <button
377
+ class="neu-tree__content"
378
+ type="button"
379
+ [disabled]="node.disabled"
380
+ (click)="activateNode(node)"
381
+ >
382
+ <span class="neu-tree__main">
383
+ <span class="neu-tree__label">{{ node.label }}</span>
384
+ @if (node.badge) {
385
+ <span class="neu-tree__badge">{{ node.badge }}</span>
386
+ }
387
+ </span>
388
+ @if (node.description) {
389
+ <span class="neu-tree__description">{{ node.description }}</span>
390
+ }
391
+ </button>
392
+ </div>
393
+
394
+ @if (hasChildren(node) && isRenderedExpanded(node)) {
395
+ <ul class="neu-tree__list" role="group">
396
+ <ng-container
397
+ [ngTemplateOutlet]="treeNodes"
398
+ [ngTemplateOutletContext]="{ $implicit: node.children ?? [], level: level + 1 }"
399
+ />
400
+ </ul>
401
+ }
402
+ </li>
403
+ }
404
+ </ng-template>
405
+ `, styles: [".neu-tree{display:flex;flex-direction:column;gap:.75rem;min-width:0}.neu-tree__search{position:relative;display:flex;align-items:center}.neu-tree__search-icon{position:absolute;left:.875rem;width:.9375rem;height:.9375rem;color:var(--neu-text-muted);pointer-events:none}.neu-tree__search-input{width:100%;min-height:2.625rem;border:1px solid var(--neu-border);border-radius:var(--neu-radius-lg, 14px);background:var(--neu-surface);color:var(--neu-text);padding:.6875rem .875rem .6875rem 2.4rem;outline:none;transition:border-color .16s ease,box-shadow .16s ease,background-color .16s ease}.neu-tree__search-input::placeholder{color:var(--neu-text-muted)}.neu-tree__search-input:focus{border-color:color-mix(in srgb,var(--neu-primary) 62%,var(--neu-border));box-shadow:0 0 0 3px color-mix(in srgb,var(--neu-primary) 16%,transparent)}.neu-tree__list{list-style:none;margin:0;padding:0}.neu-tree__list--root{display:flex;flex-direction:column;gap:.375rem}.neu-tree__node{position:relative}.neu-tree__row{display:flex;align-items:flex-start;gap:.5rem;min-width:0;border-radius:calc(var(--neu-radius-lg, 14px) - 2px);transition:background-color .16s ease,border-color .16s ease,box-shadow .16s ease}.neu-tree__row:hover{background:color-mix(in srgb,var(--neu-primary) 5%,var(--neu-surface))}.neu-tree__row--selected{background:color-mix(in srgb,var(--neu-primary) 10%,var(--neu-surface));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--neu-primary) 20%,var(--neu-border))}.neu-tree__row--disabled{opacity:.6}.neu-tree__toggle{flex:0 0 auto;width:1.75rem;height:1.75rem;margin-top:.4rem;border:0;border-radius:999px;background:transparent;color:var(--neu-text-muted);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:background-color .16s ease,color .16s ease,transform .16s ease}.neu-tree__toggle svg{width:.95rem;height:.95rem;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;transition:transform .16s ease}.neu-tree__toggle:hover{background:color-mix(in srgb,var(--neu-primary) 9%,transparent);color:var(--neu-primary)}.neu-tree__toggle--open svg{transform:rotate(90deg)}.neu-tree__toggle--placeholder{cursor:default}.neu-tree__checkbox{flex:0 0 auto;width:1rem;height:1rem;margin:.8rem 0 0;accent-color:var(--neu-primary)}.neu-tree__content{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:.125rem;border:0;background:transparent;text-align:left;padding:.55rem .75rem .6rem 0;color:inherit;cursor:pointer}.neu-tree__main{display:inline-flex;align-items:center;gap:.5rem;min-width:0}.neu-tree__label{font-size:.9375rem;font-weight:600;color:var(--neu-text)}.neu-tree__badge{display:inline-flex;align-items:center;min-height:1.25rem;padding:0 .45rem;border-radius:999px;background:color-mix(in srgb,var(--neu-primary) 12%,transparent);color:var(--neu-primary);font-size:.6875rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase}.neu-tree__description{color:var(--neu-text-muted);font-size:.8125rem;line-height:1.45}.neu-tree__empty{border:1px dashed var(--neu-border);border-radius:var(--neu-radius-lg, 14px);background:color-mix(in srgb,var(--neu-surface-2) 72%,transparent);color:var(--neu-text-muted);padding:1rem 1.125rem;font-size:.875rem}.neu-tree__node>.neu-tree__list{margin-top:.125rem}\n"] }]
406
+ }], ctorParameters: () => [], propDecorators: { nodes: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodes", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], indentSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "indentSize", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], emptyLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyLabel", required: false }] }], expandLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandLabel", required: false }] }], collapseLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapseLabel", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], expansionChange: [{ type: i0.Output, args: ["expansionChange"] }], nodeClick: [{ type: i0.Output, args: ["nodeClick"] }] } });
407
+
408
+ /**
409
+ * Generated bundle index. Do not edit.
410
+ */
411
+
412
+ export { NeuTreeComponent };
413
+ //# sourceMappingURL=neural-ui-core-tree.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"neural-ui-core-tree.mjs","sources":["../../../../projects/ui-core/tree/neu-tree.component.ts","../../../../projects/ui-core/tree/neural-ui-core-tree.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n input,\n output,\n signal,\n ViewEncapsulation,\n} from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\n\nexport interface NeuTreeNode<T = unknown> {\n id: string;\n label: string;\n description?: string;\n badge?: string;\n children?: NeuTreeNode<T>[];\n disabled?: boolean;\n expanded?: boolean;\n selectable?: boolean;\n data?: T;\n}\n\nexport type NeuTreeSelectionMode = 'single' | 'multiple';\n\n@Component({\n selector: 'neu-tree',\n standalone: true,\n imports: [NgTemplateOutlet],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"neu-tree\">\n @if (searchable()) {\n <label class=\"neu-tree__search\" [attr.aria-label]=\"searchPlaceholder()\">\n <svg\n class=\"neu-tree__search-icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <circle cx=\"11\" cy=\"11\" r=\"7\"></circle>\n <path d=\"m20 20-3.5-3.5\"></path>\n </svg>\n <input\n class=\"neu-tree__search-input\"\n type=\"search\"\n [value]=\"searchQuery()\"\n [attr.placeholder]=\"searchPlaceholder()\"\n (input)=\"onSearch($event)\"\n />\n </label>\n }\n\n @if (visibleNodes().length) {\n <ul\n class=\"neu-tree__list neu-tree__list--root\"\n role=\"tree\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-multiselectable]=\"\n selectable() && selectionMode() === 'multiple' ? 'true' : null\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"treeNodes\"\n [ngTemplateOutletContext]=\"{ $implicit: visibleNodes(), level: 1 }\"\n />\n </ul>\n } @else {\n <div class=\"neu-tree__empty\">{{ emptyLabel() }}</div>\n }\n </div>\n\n <ng-template #treeNodes let-nodes let-level=\"level\">\n @for (node of nodes; track node.id) {\n <li\n class=\"neu-tree__node\"\n role=\"treeitem\"\n [attr.aria-level]=\"level\"\n [attr.aria-expanded]=\"hasChildren(node) ? isRenderedExpanded(node) : null\"\n [attr.aria-selected]=\"canSelect(node) ? isSelected(node.id) : null\"\n [attr.aria-disabled]=\"node.disabled ? 'true' : null\"\n >\n <div\n class=\"neu-tree__row\"\n [class.neu-tree__row--selected]=\"isSelected(node.id)\"\n [class.neu-tree__row--disabled]=\"node.disabled\"\n [style.padding-inline-start.px]=\"(level - 1) * indentSize() + 6\"\n >\n @if (hasChildren(node)) {\n <button\n class=\"neu-tree__toggle\"\n type=\"button\"\n [class.neu-tree__toggle--open]=\"isRenderedExpanded(node)\"\n [attr.aria-label]=\"isRenderedExpanded(node) ? collapseLabel() : expandLabel()\"\n (click)=\"toggleNode(node, $event)\"\n >\n <svg viewBox=\"0 0 20 20\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"m7 5 6 5-6 5\" />\n </svg>\n </button>\n } @else {\n <span\n class=\"neu-tree__toggle neu-tree__toggle--placeholder\"\n aria-hidden=\"true\"\n ></span>\n }\n\n @if (canSelect(node) && selectionMode() === 'multiple') {\n <input\n class=\"neu-tree__checkbox\"\n type=\"checkbox\"\n [attr.aria-label]=\"'Select ' + node.label\"\n [checked]=\"isSelected(node.id)\"\n [disabled]=\"node.disabled\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"onCheckboxChange(node, $event)\"\n />\n }\n\n <button\n class=\"neu-tree__content\"\n type=\"button\"\n [disabled]=\"node.disabled\"\n (click)=\"activateNode(node)\"\n >\n <span class=\"neu-tree__main\">\n <span class=\"neu-tree__label\">{{ node.label }}</span>\n @if (node.badge) {\n <span class=\"neu-tree__badge\">{{ node.badge }}</span>\n }\n </span>\n @if (node.description) {\n <span class=\"neu-tree__description\">{{ node.description }}</span>\n }\n </button>\n </div>\n\n @if (hasChildren(node) && isRenderedExpanded(node)) {\n <ul class=\"neu-tree__list\" role=\"group\">\n <ng-container\n [ngTemplateOutlet]=\"treeNodes\"\n [ngTemplateOutletContext]=\"{ $implicit: node.children ?? [], level: level + 1 }\"\n />\n </ul>\n }\n </li>\n }\n </ng-template>\n `,\n styleUrl: './neu-tree.component.scss',\n})\nexport class NeuTreeComponent {\n nodes = input<NeuTreeNode[]>([]);\n selectable = input(false);\n searchable = input(false);\n selectionMode = input<NeuTreeSelectionMode>('single');\n indentSize = input(18);\n ariaLabel = input('Tree');\n searchPlaceholder = input('Search nodes');\n emptyLabel = input('No nodes available');\n expandLabel = input('Expand node');\n collapseLabel = input('Collapse node');\n\n selectionChange = output<NeuTreeNode[]>();\n expansionChange = output<string[]>();\n nodeClick = output<NeuTreeNode>();\n\n readonly searchQuery = signal('');\n\n private readonly expandedKeys = signal<Set<string>>(new Set());\n private readonly selectedKeys = signal<Set<string>>(new Set());\n\n readonly visibleNodes = computed(() => {\n const query = this.searchQuery().trim().toLowerCase();\n if (!query) {\n return this.nodes();\n }\n\n return this.filterNodes(this.nodes(), query);\n });\n\n constructor() {\n effect(() => {\n const nextExpanded = this.collectExpandedKeys(this.nodes());\n this.expandedKeys.set(nextExpanded);\n this.selectedKeys.set(new Set());\n this.searchQuery.set('');\n });\n }\n\n hasChildren(node: NeuTreeNode): boolean {\n return !!node.children?.length;\n }\n\n canSelect(node: NeuTreeNode): boolean {\n return this.selectable() && node.selectable !== false;\n }\n\n isExpanded(nodeId: string): boolean {\n return this.expandedKeys().has(nodeId);\n }\n\n isRenderedExpanded(node: NeuTreeNode): boolean {\n if (this.searchQuery().trim()) {\n return node.expanded ?? this.isExpanded(node.id);\n }\n\n return this.isExpanded(node.id);\n }\n\n isSelected(nodeId: string): boolean {\n return this.selectedKeys().has(nodeId);\n }\n\n onSearch(event: Event): void {\n const target = event.target as HTMLInputElement;\n this.searchQuery.set(target.value);\n }\n\n toggleNode(node: NeuTreeNode, event?: Event): void {\n event?.stopPropagation();\n if (node.disabled || !this.hasChildren(node)) {\n return;\n }\n\n const next = new Set(this.expandedKeys());\n if (next.has(node.id)) {\n next.delete(node.id);\n } else {\n next.add(node.id);\n }\n\n this.expandedKeys.set(next);\n this.expansionChange.emit([...next]);\n }\n\n activateNode(node: NeuTreeNode): void {\n if (node.disabled) {\n return;\n }\n\n this.nodeClick.emit(node);\n\n if (!this.canSelect(node)) {\n return;\n }\n\n if (this.selectionMode() === 'multiple') {\n const checked = !this.isSelected(node.id);\n this.updateSelection(node, checked);\n return;\n }\n\n this.updateSelection(node, true);\n }\n\n onCheckboxChange(node: NeuTreeNode, event: Event): void {\n const target = event.target as HTMLInputElement;\n this.updateSelection(node, target.checked);\n }\n\n private updateSelection(node: NeuTreeNode, checked: boolean): void {\n if (node.disabled || !this.canSelect(node)) {\n return;\n }\n\n const next = new Set(this.selectedKeys());\n\n if (this.selectionMode() === 'single') {\n next.clear();\n if (checked) {\n next.add(node.id);\n }\n } else if (checked) {\n next.add(node.id);\n } else {\n next.delete(node.id);\n }\n\n this.selectedKeys.set(next);\n this.selectionChange.emit(this.collectSelectedNodes(this.nodes(), next));\n }\n\n private collectExpandedKeys(nodes: NeuTreeNode[]): Set<string> {\n const expanded = new Set<string>();\n for (const node of nodes) {\n if (node.expanded) {\n expanded.add(node.id);\n }\n if (node.children?.length) {\n for (const childId of this.collectExpandedKeys(node.children)) {\n expanded.add(childId);\n }\n }\n }\n return expanded;\n }\n\n private collectSelectedNodes(nodes: NeuTreeNode[], selected: Set<string>): NeuTreeNode[] {\n const result: NeuTreeNode[] = [];\n for (const node of nodes) {\n if (selected.has(node.id)) {\n result.push(node);\n }\n if (node.children?.length) {\n result.push(...this.collectSelectedNodes(node.children, selected));\n }\n }\n return result;\n }\n\n private filterNodes(nodes: NeuTreeNode[], query: string): NeuTreeNode[] {\n const filtered: NeuTreeNode[] = [];\n for (const node of nodes) {\n const children = node.children?.length ? this.filterNodes(node.children, query) : [];\n const matches =\n node.label.toLowerCase().includes(query) ||\n node.description?.toLowerCase().includes(query) ||\n node.badge?.toLowerCase().includes(query);\n\n if (matches || children.length) {\n filtered.push({\n ...node,\n children,\n expanded: children.length ? true : node.expanded,\n });\n }\n }\n return filtered;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}