@tailng-ui/primitives 0.1.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -3
- package/src/index.d.ts +5 -0
- package/src/index.d.ts.map +1 -1
- package/src/index.js +5 -0
- package/src/index.js.map +1 -1
- package/src/lib/feedback/progress-bar/tng-progress-bar.d.ts.map +1 -1
- package/src/lib/feedback/progress-bar/tng-progress-bar.js +2 -1
- package/src/lib/feedback/progress-bar/tng-progress-bar.js.map +1 -1
- package/src/lib/feedback/progress-spinner/tng-progress-spinner.d.ts.map +1 -1
- package/src/lib/feedback/progress-spinner/tng-progress-spinner.js +2 -1
- package/src/lib/feedback/progress-spinner/tng-progress-spinner.js.map +1 -1
- package/src/lib/feedback/skeleton/tng-skeleton.d.ts +1 -0
- package/src/lib/feedback/skeleton/tng-skeleton.d.ts.map +1 -1
- package/src/lib/feedback/skeleton/tng-skeleton.js +4 -0
- package/src/lib/feedback/skeleton/tng-skeleton.js.map +1 -1
- package/src/lib/form/chips/tng-chips.d.ts +53 -1
- package/src/lib/form/chips/tng-chips.d.ts.map +1 -1
- package/src/lib/form/chips/tng-chips.js +281 -1
- package/src/lib/form/chips/tng-chips.js.map +1 -1
- package/src/lib/form/input-otp/tng-input-otp.d.ts +22 -0
- package/src/lib/form/input-otp/tng-input-otp.d.ts.map +1 -1
- package/src/lib/form/input-otp/tng-input-otp.js +105 -1
- package/src/lib/form/input-otp/tng-input-otp.js.map +1 -1
- package/src/lib/form/label/tng-label.d.ts +2 -0
- package/src/lib/form/label/tng-label.d.ts.map +1 -1
- package/src/lib/form/label/tng-label.js +9 -0
- package/src/lib/form/label/tng-label.js.map +1 -1
- package/src/lib/form/multi-autocomplete/tng-multi-autocomplete.trigger.d.ts +1 -0
- package/src/lib/form/multi-autocomplete/tng-multi-autocomplete.trigger.d.ts.map +1 -1
- package/src/lib/form/multi-autocomplete/tng-multi-autocomplete.trigger.js +26 -0
- package/src/lib/form/multi-autocomplete/tng-multi-autocomplete.trigger.js.map +1 -1
- package/src/lib/form/radio/tng-radio.d.ts +26 -0
- package/src/lib/form/radio/tng-radio.d.ts.map +1 -1
- package/src/lib/form/radio/tng-radio.js +129 -1
- package/src/lib/form/radio/tng-radio.js.map +1 -1
- package/src/lib/form/textarea/tng-textarea.d.ts +6 -14
- package/src/lib/form/textarea/tng-textarea.d.ts.map +1 -1
- package/src/lib/form/textarea/tng-textarea.js +42 -85
- package/src/lib/form/textarea/tng-textarea.js.map +1 -1
- package/src/lib/layout/accordion/tng-accordion.d.ts +9 -0
- package/src/lib/layout/accordion/tng-accordion.d.ts.map +1 -1
- package/src/lib/layout/accordion/tng-accordion.js +113 -0
- package/src/lib/layout/accordion/tng-accordion.js.map +1 -1
- package/src/lib/layout/tree/__tests__/tng-tree.test-harness.d.ts +20 -0
- package/src/lib/layout/tree/__tests__/tng-tree.test-harness.d.ts.map +1 -0
- package/src/lib/layout/tree/__tests__/tng-tree.test-harness.js +106 -0
- package/src/lib/layout/tree/__tests__/tng-tree.test-harness.js.map +1 -0
- package/src/lib/layout/tree/index.d.ts +5 -0
- package/src/lib/layout/tree/index.d.ts.map +1 -0
- package/src/lib/layout/tree/index.js +5 -0
- package/src/lib/layout/tree/index.js.map +1 -0
- package/src/lib/layout/tree/tng-tree-group.d.ts +10 -0
- package/src/lib/layout/tree/tng-tree-group.d.ts.map +1 -0
- package/src/lib/layout/tree/tng-tree-group.js +29 -0
- package/src/lib/layout/tree/tng-tree-group.js.map +1 -0
- package/src/lib/layout/tree/tng-tree-indicator.d.ts +8 -0
- package/src/lib/layout/tree/tng-tree-indicator.d.ts.map +1 -0
- package/src/lib/layout/tree/tng-tree-indicator.js +36 -0
- package/src/lib/layout/tree/tng-tree-indicator.js.map +1 -0
- package/src/lib/layout/tree/tng-tree-item.d.ts +36 -0
- package/src/lib/layout/tree/tng-tree-item.d.ts.map +1 -0
- package/src/lib/layout/tree/tng-tree-item.js +139 -0
- package/src/lib/layout/tree/tng-tree-item.js.map +1 -0
- package/src/lib/layout/tree/tng-tree.d.ts +64 -1
- package/src/lib/layout/tree/tng-tree.d.ts.map +1 -1
- package/src/lib/layout/tree/tng-tree.js +536 -1
- package/src/lib/layout/tree/tng-tree.js.map +1 -1
- package/src/lib/layout/tree/tng-tree.transforms.d.ts +10 -0
- package/src/lib/layout/tree/tng-tree.transforms.d.ts.map +1 -0
- package/src/lib/layout/tree/tng-tree.transforms.js +46 -0
- package/src/lib/layout/tree/tng-tree.transforms.js.map +1 -0
- package/src/lib/overlay/dialog/tng-dialog.d.ts +158 -0
- package/src/lib/overlay/dialog/tng-dialog.d.ts.map +1 -0
- package/src/lib/overlay/dialog/tng-dialog.js +854 -0
- package/src/lib/overlay/dialog/tng-dialog.js.map +1 -0
- package/src/lib/overlay/popover/tng-popover.d.ts +121 -0
- package/src/lib/overlay/popover/tng-popover.d.ts.map +1 -0
- package/src/lib/overlay/popover/tng-popover.js +614 -0
- package/src/lib/overlay/popover/tng-popover.js.map +1 -0
- package/src/lib/overlay/tng-overlay-runtime.d.ts +11 -0
- package/src/lib/overlay/tng-overlay-runtime.d.ts.map +1 -0
- package/src/lib/overlay/tng-overlay-runtime.js +6 -0
- package/src/lib/overlay/tng-overlay-runtime.js.map +1 -0
- package/src/lib/overlay/tooltip/tng-tooltip.d.ts +92 -3
- package/src/lib/overlay/tooltip/tng-tooltip.d.ts.map +1 -1
- package/src/lib/overlay/tooltip/tng-tooltip.js +474 -3
- package/src/lib/overlay/tooltip/tng-tooltip.js.map +1 -1
- package/src/lib/utility/badge/tng-badge.d.ts +6 -0
- package/src/lib/utility/badge/tng-badge.d.ts.map +1 -1
- package/src/lib/utility/badge/tng-badge.js +65 -0
- package/src/lib/utility/badge/tng-badge.js.map +1 -1
- package/src/lib/utility/copy/tng-copy.d.ts +21 -10
- package/src/lib/utility/copy/tng-copy.d.ts.map +1 -1
- package/src/lib/utility/copy/tng-copy.js +117 -88
- package/src/lib/utility/copy/tng-copy.js.map +1 -1
- package/src/lib/utility/tag/tng-tag.d.ts +37 -0
- package/src/lib/utility/tag/tng-tag.d.ts.map +1 -1
- package/src/lib/utility/tag/tng-tag.js +195 -1
- package/src/lib/utility/tag/tng-tag.js.map +1 -1
|
@@ -1,15 +1,550 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
|
-
import { Directive, HostBinding } from '@angular/core';
|
|
2
|
+
import { Directive, ElementRef, HostBinding, HostListener, inject, input, output, } from '@angular/core';
|
|
3
|
+
import { createRovingFocusController, createTreeModel, createTypeaheadController, resolveListNavigationKeyAction, } from '@tailng-ui/cdk';
|
|
4
|
+
import { normalizeTreeBooleanInput, normalizeTreeOrientation, normalizeTreeSelectionMode, normalizeTreeValue, normalizeTreeValueInput, } from './tng-tree.transforms';
|
|
5
|
+
function setsEqual(a, b) {
|
|
6
|
+
if (a.size !== b.size)
|
|
7
|
+
return false;
|
|
8
|
+
for (const value of a) {
|
|
9
|
+
if (!b.has(value))
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
function isPrintableCharacter(value) {
|
|
15
|
+
return value.length === 1 && value.trim().length > 0;
|
|
16
|
+
}
|
|
17
|
+
function normalizeTypeaheadText(value) {
|
|
18
|
+
return value.replace(/\s+/g, ' ').trim();
|
|
19
|
+
}
|
|
20
|
+
function hasDisallowedNavigationModifiers(event) {
|
|
21
|
+
return event.altKey === true || event.ctrlKey === true || event.metaKey === true;
|
|
22
|
+
}
|
|
23
|
+
function resolveHorizontalTreeKeyAction(event) {
|
|
24
|
+
if (hasDisallowedNavigationModifiers(event)) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
if (event.key === 'ArrowLeft') {
|
|
28
|
+
return 'collapse-or-parent';
|
|
29
|
+
}
|
|
30
|
+
if (event.key === 'ArrowRight') {
|
|
31
|
+
return 'expand-or-child';
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
3
35
|
let TngTree = class TngTree {
|
|
36
|
+
hostRef = inject(ElementRef);
|
|
37
|
+
items = new Set();
|
|
38
|
+
modelIdByItem = new Map();
|
|
39
|
+
emptyModelNodes = Object.freeze([]);
|
|
40
|
+
emptyTypeaheadItems = Object.freeze([]);
|
|
41
|
+
model = createTreeModel({ nodes: this.emptyModelNodes });
|
|
42
|
+
modelState = this.model.getState();
|
|
43
|
+
roving = createRovingFocusController({
|
|
44
|
+
itemIds: Object.freeze([]),
|
|
45
|
+
});
|
|
46
|
+
typeahead = createTypeaheadController({
|
|
47
|
+
items: this.emptyTypeaheadItems,
|
|
48
|
+
});
|
|
49
|
+
itemByModelId = new Map();
|
|
50
|
+
childModelIdsByParentId = new Map();
|
|
51
|
+
nextModelId = 0;
|
|
52
|
+
uncontrolledSelection = new Set();
|
|
53
|
+
initialized = false;
|
|
54
|
+
selectionMode = input('none', {
|
|
55
|
+
transform: normalizeTreeSelectionMode,
|
|
56
|
+
});
|
|
57
|
+
orientation = input('vertical', {
|
|
58
|
+
transform: normalizeTreeOrientation,
|
|
59
|
+
});
|
|
60
|
+
value = input(undefined, { transform: normalizeTreeValueInput });
|
|
61
|
+
defaultValue = input(undefined, { transform: normalizeTreeValueInput });
|
|
62
|
+
disabled = input(false, {
|
|
63
|
+
transform: normalizeTreeBooleanInput,
|
|
64
|
+
});
|
|
65
|
+
valueChange = output();
|
|
4
66
|
dataSlot = 'tree';
|
|
67
|
+
role = 'tree';
|
|
68
|
+
get ariaOrientation() {
|
|
69
|
+
return this.orientation();
|
|
70
|
+
}
|
|
71
|
+
get ariaMultiselectable() {
|
|
72
|
+
const mode = this.selectionMode();
|
|
73
|
+
if (mode === 'none')
|
|
74
|
+
return null;
|
|
75
|
+
return mode === 'multiple' ? 'true' : 'false';
|
|
76
|
+
}
|
|
77
|
+
get tabIndex() {
|
|
78
|
+
if (this.disabled())
|
|
79
|
+
return '-1';
|
|
80
|
+
const activeElement = document.activeElement;
|
|
81
|
+
if (activeElement instanceof HTMLElement &&
|
|
82
|
+
this.hostRef.nativeElement.contains(activeElement) &&
|
|
83
|
+
activeElement !== this.hostRef.nativeElement) {
|
|
84
|
+
return '-1';
|
|
85
|
+
}
|
|
86
|
+
return '0';
|
|
87
|
+
}
|
|
88
|
+
ngOnDestroy() {
|
|
89
|
+
this.items.clear();
|
|
90
|
+
this.modelIdByItem.clear();
|
|
91
|
+
this.itemByModelId.clear();
|
|
92
|
+
this.childModelIdsByParentId.clear();
|
|
93
|
+
}
|
|
94
|
+
registerItem(item) {
|
|
95
|
+
this.items.add(item);
|
|
96
|
+
this.ensureModelId(item);
|
|
97
|
+
if (!this.initialized && this.items.size > 0 && !this.isControlled()) {
|
|
98
|
+
this.initializeUncontrolledState();
|
|
99
|
+
}
|
|
100
|
+
this.rebuildModel(this.resolvePreferredActiveId());
|
|
101
|
+
}
|
|
102
|
+
unregisterItem(item) {
|
|
103
|
+
const wasSelected = this.getEffectiveSelectionSet().has(item.getValue());
|
|
104
|
+
this.items.delete(item);
|
|
105
|
+
const modelId = this.modelIdByItem.get(item);
|
|
106
|
+
if (modelId !== undefined) {
|
|
107
|
+
this.modelIdByItem.delete(item);
|
|
108
|
+
this.itemByModelId.delete(modelId);
|
|
109
|
+
}
|
|
110
|
+
if (wasSelected && !this.isControlled()) {
|
|
111
|
+
const next = new Set(this.uncontrolledSelection);
|
|
112
|
+
next.delete(item.getValue());
|
|
113
|
+
this.uncontrolledSelection = next;
|
|
114
|
+
}
|
|
115
|
+
this.rebuildModel(this.resolvePreferredActiveId());
|
|
116
|
+
}
|
|
117
|
+
isItemSelected(item) {
|
|
118
|
+
if (this.selectionMode() === 'none') {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
return this.getEffectiveSelectionSet().has(item.getValue());
|
|
122
|
+
}
|
|
123
|
+
isItemDisabled(item) {
|
|
124
|
+
return this.disabled() || item.disabled();
|
|
125
|
+
}
|
|
126
|
+
getTriggerTabIndex(item) {
|
|
127
|
+
if (this.isItemDisabled(item)) {
|
|
128
|
+
return '-1';
|
|
129
|
+
}
|
|
130
|
+
const modelId = this.resolveModelId(item);
|
|
131
|
+
return modelId !== null && this.roving.getActiveId() === modelId ? '0' : '-1';
|
|
132
|
+
}
|
|
133
|
+
onItemFocused(item) {
|
|
134
|
+
if (this.isItemDisabled(item)) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const modelId = this.resolveModelId(item);
|
|
138
|
+
if (modelId !== null) {
|
|
139
|
+
this.applyModelState(this.model.setActiveId(modelId));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
onItemClicked(item) {
|
|
143
|
+
if (this.isItemDisabled(item))
|
|
144
|
+
return;
|
|
145
|
+
if (this.selectionMode() !== 'none') {
|
|
146
|
+
this.requestToggleSelection(item);
|
|
147
|
+
}
|
|
148
|
+
const modelId = this.resolveModelId(item);
|
|
149
|
+
if (modelId !== null) {
|
|
150
|
+
this.applyModelState(this.model.setActiveId(modelId));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
onIndicatorClicked(item) {
|
|
154
|
+
if (this.isItemDisabled(item))
|
|
155
|
+
return;
|
|
156
|
+
if (item.canExpand()) {
|
|
157
|
+
item.setExpanded(!item.isExpanded());
|
|
158
|
+
const modelId = this.resolveModelId(item);
|
|
159
|
+
this.rebuildModel(modelId);
|
|
160
|
+
}
|
|
161
|
+
item.focusHost();
|
|
162
|
+
}
|
|
163
|
+
isControlled() {
|
|
164
|
+
return this.value() !== undefined;
|
|
165
|
+
}
|
|
166
|
+
initializeUncontrolledState() {
|
|
167
|
+
this.initialized = true;
|
|
168
|
+
const defaultInput = this.defaultValue();
|
|
169
|
+
let initialValues = [];
|
|
170
|
+
if (defaultInput !== undefined && defaultInput !== null) {
|
|
171
|
+
initialValues = Array.isArray(defaultInput)
|
|
172
|
+
? defaultInput.map(normalizeTreeValue)
|
|
173
|
+
: [normalizeTreeValue(defaultInput)];
|
|
174
|
+
}
|
|
175
|
+
this.uncontrolledSelection = new Set(initialValues);
|
|
176
|
+
}
|
|
177
|
+
getEffectiveSelectionSet() {
|
|
178
|
+
if (!this.isControlled()) {
|
|
179
|
+
return this.uncontrolledSelection;
|
|
180
|
+
}
|
|
181
|
+
const val = this.value();
|
|
182
|
+
let controlledValues = [];
|
|
183
|
+
if (val !== undefined && val !== null) {
|
|
184
|
+
controlledValues = Array.isArray(val) ? val.map(normalizeTreeValue) : [normalizeTreeValue(val)];
|
|
185
|
+
}
|
|
186
|
+
return new Set(controlledValues);
|
|
187
|
+
}
|
|
188
|
+
requestToggleSelection(item) {
|
|
189
|
+
const mode = this.selectionMode();
|
|
190
|
+
if (mode === 'none')
|
|
191
|
+
return;
|
|
192
|
+
const previous = this.getEffectiveSelectionSet();
|
|
193
|
+
const next = new Set(previous);
|
|
194
|
+
const itemValue = item.getValue();
|
|
195
|
+
const currentlySelected = previous.has(itemValue);
|
|
196
|
+
if (mode === 'single') {
|
|
197
|
+
next.clear();
|
|
198
|
+
if (!currentlySelected) {
|
|
199
|
+
next.add(itemValue);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
if (!currentlySelected) {
|
|
204
|
+
next.add(itemValue);
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
next.delete(itemValue);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
if (setsEqual(previous, next))
|
|
211
|
+
return;
|
|
212
|
+
if (!this.isControlled()) {
|
|
213
|
+
this.uncontrolledSelection = next;
|
|
214
|
+
}
|
|
215
|
+
const valList = Array.from(next);
|
|
216
|
+
if (mode === 'single') {
|
|
217
|
+
this.valueChange.emit(valList.length > 0 ? valList[0] : null);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
this.valueChange.emit(valList);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
onHostKeydown(event) {
|
|
224
|
+
const activeElement = document.activeElement;
|
|
225
|
+
if (!this.hostRef.nativeElement.contains(activeElement) &&
|
|
226
|
+
activeElement !== this.hostRef.nativeElement) {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
this.rebuildModel(this.resolvePreferredActiveId());
|
|
230
|
+
const horizontalAction = resolveHorizontalTreeKeyAction(event);
|
|
231
|
+
if (horizontalAction !== null) {
|
|
232
|
+
event.preventDefault();
|
|
233
|
+
this.runHorizontalKeyAction(horizontalAction);
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
const action = resolveListNavigationKeyAction(event, {
|
|
237
|
+
multiSelect: this.selectionMode() === 'multiple',
|
|
238
|
+
orientation: 'vertical',
|
|
239
|
+
});
|
|
240
|
+
if (action !== null) {
|
|
241
|
+
if (action.preventDefault) {
|
|
242
|
+
event.preventDefault();
|
|
243
|
+
}
|
|
244
|
+
this.runResolvedNavigationAction(action);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
if (this.handleTypeaheadKey(event)) {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
if (event.key === '*') {
|
|
251
|
+
// Optional: expand all siblings.
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
onHostFocus() {
|
|
255
|
+
this.rebuildModel(this.resolvePreferredActiveId());
|
|
256
|
+
const activeItem = this.resolveItemByModelId(this.roving.getActiveId());
|
|
257
|
+
if (activeItem !== null) {
|
|
258
|
+
this.focusItem(activeItem);
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
this.focusActiveItem();
|
|
262
|
+
}
|
|
263
|
+
applyModelState(state) {
|
|
264
|
+
this.modelState = state;
|
|
265
|
+
this.roving.setItemIds(state.visibleIds);
|
|
266
|
+
this.roving.setDisabledIds(this.resolveDisabledVisibleIds(state.visibleIds));
|
|
267
|
+
this.roving.setActiveId(state.activeId);
|
|
268
|
+
this.typeahead.setItems(this.resolveTypeaheadItems(state.visibleIds));
|
|
269
|
+
this.typeahead.setActiveId(state.activeId);
|
|
270
|
+
}
|
|
271
|
+
ensureModelId(item) {
|
|
272
|
+
const existingId = this.modelIdByItem.get(item);
|
|
273
|
+
if (existingId !== undefined) {
|
|
274
|
+
return existingId;
|
|
275
|
+
}
|
|
276
|
+
const id = `tng-tree-item-${this.nextModelId}`;
|
|
277
|
+
this.nextModelId += 1;
|
|
278
|
+
this.modelIdByItem.set(item, id);
|
|
279
|
+
return id;
|
|
280
|
+
}
|
|
281
|
+
resolveModelId(item) {
|
|
282
|
+
if (item === null) {
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
return this.modelIdByItem.get(item) ?? null;
|
|
286
|
+
}
|
|
287
|
+
resolveActiveItem() {
|
|
288
|
+
return this.resolveItemByModelId(this.modelState.activeId);
|
|
289
|
+
}
|
|
290
|
+
resolveItemByModelId(modelId) {
|
|
291
|
+
if (modelId === null) {
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
return this.itemByModelId.get(modelId) ?? null;
|
|
295
|
+
}
|
|
296
|
+
focusBoundaryItem(boundary) {
|
|
297
|
+
const visibleIds = boundary === 'start'
|
|
298
|
+
? this.modelState.visibleIds
|
|
299
|
+
: [...this.modelState.visibleIds].reverse();
|
|
300
|
+
for (const modelId of visibleIds) {
|
|
301
|
+
const candidate = this.itemByModelId.get(modelId);
|
|
302
|
+
if (candidate !== undefined && !this.isItemDisabled(candidate)) {
|
|
303
|
+
this.focusItem(candidate);
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
focusActiveItem() {
|
|
309
|
+
const item = this.resolveActiveItem();
|
|
310
|
+
if (item !== null) {
|
|
311
|
+
this.focusItem(item);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
focusItem(item) {
|
|
315
|
+
if (this.isItemDisabled(item)) {
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const modelId = this.resolveModelId(item);
|
|
319
|
+
if (modelId !== null) {
|
|
320
|
+
this.applyModelState(this.model.setActiveId(modelId));
|
|
321
|
+
}
|
|
322
|
+
item.focusHost();
|
|
323
|
+
}
|
|
324
|
+
resolveFirstVisibleEnabledChild(parentItem) {
|
|
325
|
+
const parentId = this.resolveModelId(parentItem);
|
|
326
|
+
if (parentId === null) {
|
|
327
|
+
return null;
|
|
328
|
+
}
|
|
329
|
+
const visibleIds = new Set(this.modelState.visibleIds);
|
|
330
|
+
const childIds = this.childModelIdsByParentId.get(parentId) ?? [];
|
|
331
|
+
for (const childId of childIds) {
|
|
332
|
+
if (!visibleIds.has(childId)) {
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
const childItem = this.itemByModelId.get(childId);
|
|
336
|
+
if (childItem !== undefined && !this.isItemDisabled(childItem)) {
|
|
337
|
+
return childItem;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
342
|
+
resolveTypeaheadItems(visibleIds) {
|
|
343
|
+
const items = [];
|
|
344
|
+
for (const modelId of visibleIds) {
|
|
345
|
+
const item = this.itemByModelId.get(modelId);
|
|
346
|
+
if (item === undefined) {
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
items.push({
|
|
350
|
+
disabled: this.isItemDisabled(item),
|
|
351
|
+
id: modelId,
|
|
352
|
+
text: this.resolveTypeaheadText(item),
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
return Object.freeze(items);
|
|
356
|
+
}
|
|
357
|
+
resolveDisabledVisibleIds(visibleIds) {
|
|
358
|
+
const disabledIds = [];
|
|
359
|
+
for (const modelId of visibleIds) {
|
|
360
|
+
const item = this.itemByModelId.get(modelId);
|
|
361
|
+
if (item !== undefined && this.isItemDisabled(item)) {
|
|
362
|
+
disabledIds.push(modelId);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
return Object.freeze(disabledIds);
|
|
366
|
+
}
|
|
367
|
+
resolveTypeaheadText(item) {
|
|
368
|
+
const host = item.getHostElement();
|
|
369
|
+
const ariaLabel = host.getAttribute('aria-label');
|
|
370
|
+
if (ariaLabel !== null && ariaLabel.trim().length > 0) {
|
|
371
|
+
return ariaLabel.trim();
|
|
372
|
+
}
|
|
373
|
+
const text = normalizeTypeaheadText(host.textContent ?? '');
|
|
374
|
+
if (text.length > 0) {
|
|
375
|
+
return text;
|
|
376
|
+
}
|
|
377
|
+
return String(item.getValue());
|
|
378
|
+
}
|
|
379
|
+
handleTypeaheadKey(event) {
|
|
380
|
+
if (!isPrintableCharacter(event.key)) {
|
|
381
|
+
return false;
|
|
382
|
+
}
|
|
383
|
+
const state = this.typeahead.handleKey(event.key);
|
|
384
|
+
if (state.activeId === null || state.activeId === this.modelState.activeId) {
|
|
385
|
+
return false;
|
|
386
|
+
}
|
|
387
|
+
event.preventDefault();
|
|
388
|
+
this.applyModelState(this.model.setActiveId(state.activeId));
|
|
389
|
+
this.focusActiveItem();
|
|
390
|
+
return true;
|
|
391
|
+
}
|
|
392
|
+
runHorizontalKeyAction(action) {
|
|
393
|
+
if (action === 'expand-or-child') {
|
|
394
|
+
this.expandOrMoveToChild();
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
this.collapseOrMoveToParent();
|
|
398
|
+
}
|
|
399
|
+
runResolvedNavigationAction(action) {
|
|
400
|
+
switch (action.type) {
|
|
401
|
+
case 'move-next':
|
|
402
|
+
this.applyModelState(this.model.moveNext());
|
|
403
|
+
this.focusActiveItem();
|
|
404
|
+
return;
|
|
405
|
+
case 'move-prev':
|
|
406
|
+
this.applyModelState(this.model.movePrev());
|
|
407
|
+
this.focusActiveItem();
|
|
408
|
+
return;
|
|
409
|
+
case 'move-first':
|
|
410
|
+
this.focusBoundaryItem('start');
|
|
411
|
+
return;
|
|
412
|
+
case 'move-last':
|
|
413
|
+
this.focusBoundaryItem('end');
|
|
414
|
+
return;
|
|
415
|
+
case 'select-active':
|
|
416
|
+
case 'toggle-active': {
|
|
417
|
+
const item = this.resolveActiveItem();
|
|
418
|
+
if (item !== null) {
|
|
419
|
+
this.onItemClicked(item);
|
|
420
|
+
}
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
case 'exit':
|
|
424
|
+
case 'select-all':
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
expandOrMoveToChild() {
|
|
429
|
+
const item = this.resolveActiveItem();
|
|
430
|
+
if (item === null) {
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
if (item.canExpand() && !item.isExpanded()) {
|
|
434
|
+
item.setExpanded(true);
|
|
435
|
+
this.rebuildModel(this.resolveModelId(item));
|
|
436
|
+
this.focusItem(item);
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
if (item.canExpand() && item.isExpanded()) {
|
|
440
|
+
const firstChild = this.resolveFirstVisibleEnabledChild(item);
|
|
441
|
+
if (firstChild !== null) {
|
|
442
|
+
this.focusItem(firstChild);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
collapseOrMoveToParent() {
|
|
447
|
+
const item = this.resolveActiveItem();
|
|
448
|
+
if (item === null) {
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
if (item.canExpand() && item.isExpanded()) {
|
|
452
|
+
item.setExpanded(false);
|
|
453
|
+
this.rebuildModel(this.resolveModelId(item));
|
|
454
|
+
this.focusItem(item);
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
const parent = item.getParentItem();
|
|
458
|
+
if (parent !== null && !this.isItemDisabled(parent)) {
|
|
459
|
+
this.focusItem(parent);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
rebuildModel(activeId) {
|
|
463
|
+
const ordered = this.buildOrderedModelItems();
|
|
464
|
+
const nodes = ordered.map((entry) => ({
|
|
465
|
+
disabled: entry.item.disabled(),
|
|
466
|
+
id: entry.id,
|
|
467
|
+
parentId: entry.parentId,
|
|
468
|
+
}));
|
|
469
|
+
const expandedIds = [];
|
|
470
|
+
for (const entry of ordered) {
|
|
471
|
+
if (entry.item.canExpand() && entry.item.isExpanded()) {
|
|
472
|
+
expandedIds.push(entry.id);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
this.model = createTreeModel({
|
|
476
|
+
activeId,
|
|
477
|
+
expandedIds,
|
|
478
|
+
nodes,
|
|
479
|
+
});
|
|
480
|
+
this.applyModelState(this.model.getState());
|
|
481
|
+
}
|
|
482
|
+
buildOrderedModelItems() {
|
|
483
|
+
const sortedItems = Array.from(this.items).sort((a, b) => {
|
|
484
|
+
const position = a.getHostElement().compareDocumentPosition(b.getHostElement());
|
|
485
|
+
if (position & Node.DOCUMENT_POSITION_FOLLOWING)
|
|
486
|
+
return -1;
|
|
487
|
+
if (position & Node.DOCUMENT_POSITION_PRECEDING)
|
|
488
|
+
return 1;
|
|
489
|
+
return 0;
|
|
490
|
+
});
|
|
491
|
+
const itemByModelId = new Map();
|
|
492
|
+
const childIdsByParent = new Map();
|
|
493
|
+
const ordered = [];
|
|
494
|
+
for (const item of sortedItems) {
|
|
495
|
+
const id = this.ensureModelId(item);
|
|
496
|
+
const parentItem = item.getParentItem();
|
|
497
|
+
const parentId = parentItem ? this.resolveModelId(parentItem) : null;
|
|
498
|
+
ordered.push({
|
|
499
|
+
id,
|
|
500
|
+
item,
|
|
501
|
+
parentId,
|
|
502
|
+
});
|
|
503
|
+
itemByModelId.set(id, item);
|
|
504
|
+
if (parentId !== null) {
|
|
505
|
+
const childIds = childIdsByParent.get(parentId) ?? [];
|
|
506
|
+
childIds.push(id);
|
|
507
|
+
childIdsByParent.set(parentId, childIds);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
const readonlyChildIdsByParent = new Map();
|
|
511
|
+
for (const [parentId, childIds] of childIdsByParent.entries()) {
|
|
512
|
+
readonlyChildIdsByParent.set(parentId, Object.freeze([...childIds]));
|
|
513
|
+
}
|
|
514
|
+
this.itemByModelId = itemByModelId;
|
|
515
|
+
this.childModelIdsByParentId = readonlyChildIdsByParent;
|
|
516
|
+
return Object.freeze(ordered);
|
|
517
|
+
}
|
|
518
|
+
resolvePreferredActiveId() {
|
|
519
|
+
return this.roving.getActiveId() ?? this.modelState.activeId;
|
|
520
|
+
}
|
|
5
521
|
};
|
|
6
522
|
__decorate([
|
|
7
523
|
HostBinding('attr.data-slot')
|
|
8
524
|
], TngTree.prototype, "dataSlot", void 0);
|
|
525
|
+
__decorate([
|
|
526
|
+
HostBinding('attr.role')
|
|
527
|
+
], TngTree.prototype, "role", void 0);
|
|
528
|
+
__decorate([
|
|
529
|
+
HostBinding('attr.aria-orientation')
|
|
530
|
+
], TngTree.prototype, "ariaOrientation", null);
|
|
531
|
+
__decorate([
|
|
532
|
+
HostBinding('attr.aria-multiselectable')
|
|
533
|
+
], TngTree.prototype, "ariaMultiselectable", null);
|
|
534
|
+
__decorate([
|
|
535
|
+
HostBinding('attr.tabindex')
|
|
536
|
+
], TngTree.prototype, "tabIndex", null);
|
|
537
|
+
__decorate([
|
|
538
|
+
HostListener('keydown', ['$event'])
|
|
539
|
+
], TngTree.prototype, "onHostKeydown", null);
|
|
540
|
+
__decorate([
|
|
541
|
+
HostListener('focus')
|
|
542
|
+
], TngTree.prototype, "onHostFocus", null);
|
|
9
543
|
TngTree = __decorate([
|
|
10
544
|
Directive({
|
|
11
545
|
selector: '[tngTree]',
|
|
12
546
|
exportAs: 'tngTree',
|
|
547
|
+
standalone: true,
|
|
13
548
|
})
|
|
14
549
|
], TngTree);
|
|
15
550
|
export { TngTree };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tng-tree.js","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/layout/tree/tng-tree.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAMhD,IAAM,OAAO,GAAb,MAAM,OAAO;IAEC,QAAQ,GAAG,MAAe,CAAC;CAC/C,CAAA;AADoB;IADlB,WAAW,CAAC,gBAAgB,CAAC;yCACgB;AAFnC,OAAO;IAJnB,SAAS,CAAC;QACT,QAAQ,EAAE,WAAW;QACrB,QAAQ,EAAE,SAAS;KACpB,CAAC;GACW,OAAO,CAGnB","sourcesContent":["import { Directive, HostBinding } from '@angular/core';\n\n@Directive({\n selector: '[tngTree]',\n exportAs: 'tngTree',\n})\nexport class TngTree {\n @HostBinding('attr.data-slot')\n protected readonly dataSlot = 'tree' as const;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tng-tree.js","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/layout/tree/tng-tree.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Directive,\n ElementRef,\n HostBinding,\n HostListener,\n inject,\n input,\n output,\n OnDestroy,\n} from '@angular/core';\nimport {\n createRovingFocusController,\n createTreeModel,\n createTypeaheadController,\n resolveListNavigationKeyAction,\n type TngListNavigationAction,\n type TngRovingFocusController,\n type TngTypeaheadController,\n type TngTypeaheadItem,\n type TngTreeModel,\n type TngTreeModelState,\n type TngTreeNode,\n} from '@tailng-ui/cdk';\nimport { TngTreeItem } from './tng-tree-item';\nimport {\n normalizeTreeBooleanInput,\n normalizeTreeOrientation,\n normalizeTreeSelectionMode,\n normalizeTreeValue,\n normalizeTreeValueInput,\n type TngTreeOrientation,\n type TngTreeSelectionMode,\n type TngTreeValue,\n} from './tng-tree.transforms';\n\nexport type { TngTreeOrientation, TngTreeSelectionMode, TngTreeValue } from './tng-tree.transforms';\n\ntype TngTreeBoundary = 'start' | 'end';\ntype TngTreeHorizontalKeyAction = 'collapse-or-parent' | 'expand-or-child';\n\ntype TngTreeModelItem = Readonly<{\n id: string;\n item: TngTreeItem;\n parentId: string | null;\n}>;\n\nfunction setsEqual(a: ReadonlySet<TngTreeValue>, b: ReadonlySet<TngTreeValue>): boolean {\n if (a.size !== b.size) return false;\n for (const value of a) {\n if (!b.has(value)) return false;\n }\n return true;\n}\n\nfunction isPrintableCharacter(value: string): boolean {\n return value.length === 1 && value.trim().length > 0;\n}\n\nfunction normalizeTypeaheadText(value: string): string {\n return value.replace(/\\s+/g, ' ').trim();\n}\n\nfunction hasDisallowedNavigationModifiers(event: KeyboardEvent): boolean {\n return event.altKey === true || event.ctrlKey === true || event.metaKey === true;\n}\n\nfunction resolveHorizontalTreeKeyAction(event: KeyboardEvent): TngTreeHorizontalKeyAction | null {\n if (hasDisallowedNavigationModifiers(event)) {\n return null;\n }\n\n if (event.key === 'ArrowLeft') {\n return 'collapse-or-parent';\n }\n\n if (event.key === 'ArrowRight') {\n return 'expand-or-child';\n }\n\n return null;\n}\n\n@Directive({\n selector: '[tngTree]',\n exportAs: 'tngTree',\n standalone: true,\n})\nexport class TngTree implements OnDestroy {\n private readonly hostRef = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly items = new Set<TngTreeItem>();\n private readonly modelIdByItem = new Map<TngTreeItem, string>();\n\n private readonly emptyModelNodes: readonly TngTreeNode[] = Object.freeze([]);\n private readonly emptyTypeaheadItems: readonly TngTypeaheadItem[] = Object.freeze([]);\n private model: TngTreeModel = createTreeModel({ nodes: this.emptyModelNodes });\n private modelState: TngTreeModelState = this.model.getState();\n private readonly roving: TngRovingFocusController = createRovingFocusController({\n itemIds: Object.freeze([]),\n });\n private readonly typeahead: TngTypeaheadController = createTypeaheadController({\n items: this.emptyTypeaheadItems,\n });\n\n private itemByModelId = new Map<string, TngTreeItem>();\n private childModelIdsByParentId = new Map<string, readonly string[]>();\n private nextModelId = 0;\n\n private uncontrolledSelection = new Set<TngTreeValue>();\n private initialized = false;\n\n readonly selectionMode = input<TngTreeSelectionMode, unknown>('none', {\n transform: normalizeTreeSelectionMode,\n });\n readonly orientation = input<TngTreeOrientation, unknown>('vertical', {\n transform: normalizeTreeOrientation,\n });\n readonly value = input<TngTreeValue | readonly TngTreeValue[] | null | undefined, unknown>(\n undefined,\n { transform: normalizeTreeValueInput },\n );\n readonly defaultValue = input<TngTreeValue | readonly TngTreeValue[] | null | undefined, unknown>(\n undefined,\n { transform: normalizeTreeValueInput },\n );\n readonly disabled = input<boolean, unknown>(false, {\n transform: normalizeTreeBooleanInput,\n });\n\n readonly valueChange = output<TngTreeValue | readonly TngTreeValue[] | null>();\n\n @HostBinding('attr.data-slot')\n protected readonly dataSlot = 'tree' as const;\n\n @HostBinding('attr.role')\n protected readonly role = 'tree' as const;\n\n @HostBinding('attr.aria-orientation')\n protected get ariaOrientation(): string {\n return this.orientation();\n }\n\n @HostBinding('attr.aria-multiselectable')\n protected get ariaMultiselectable(): string | null {\n const mode = this.selectionMode();\n if (mode === 'none') return null;\n return mode === 'multiple' ? 'true' : 'false';\n }\n\n @HostBinding('attr.tabindex')\n protected get tabIndex(): string {\n if (this.disabled()) return '-1';\n\n const activeElement = document.activeElement;\n if (\n activeElement instanceof HTMLElement &&\n this.hostRef.nativeElement.contains(activeElement) &&\n activeElement !== this.hostRef.nativeElement\n ) {\n return '-1';\n }\n\n return '0';\n }\n\n ngOnDestroy(): void {\n this.items.clear();\n this.modelIdByItem.clear();\n this.itemByModelId.clear();\n this.childModelIdsByParentId.clear();\n }\n\n registerItem(item: TngTreeItem): void {\n this.items.add(item);\n this.ensureModelId(item);\n if (!this.initialized && this.items.size > 0 && !this.isControlled()) {\n this.initializeUncontrolledState();\n }\n this.rebuildModel(this.resolvePreferredActiveId());\n }\n\n unregisterItem(item: TngTreeItem): void {\n const wasSelected = this.getEffectiveSelectionSet().has(item.getValue());\n this.items.delete(item);\n\n const modelId = this.modelIdByItem.get(item);\n if (modelId !== undefined) {\n this.modelIdByItem.delete(item);\n this.itemByModelId.delete(modelId);\n }\n\n if (wasSelected && !this.isControlled()) {\n const next = new Set(this.uncontrolledSelection);\n next.delete(item.getValue());\n this.uncontrolledSelection = next;\n }\n\n this.rebuildModel(this.resolvePreferredActiveId());\n }\n\n isItemSelected(item: TngTreeItem): boolean {\n if (this.selectionMode() === 'none') {\n return false;\n }\n return this.getEffectiveSelectionSet().has(item.getValue());\n }\n\n isItemDisabled(item: TngTreeItem): boolean {\n return this.disabled() || item.disabled();\n }\n\n getTriggerTabIndex(item: TngTreeItem): string {\n if (this.isItemDisabled(item)) {\n return '-1';\n }\n\n const modelId = this.resolveModelId(item);\n return modelId !== null && this.roving.getActiveId() === modelId ? '0' : '-1';\n }\n\n onItemFocused(item: TngTreeItem): void {\n if (this.isItemDisabled(item)) {\n return;\n }\n\n const modelId = this.resolveModelId(item);\n if (modelId !== null) {\n this.applyModelState(this.model.setActiveId(modelId));\n }\n }\n\n onItemClicked(item: TngTreeItem): void {\n if (this.isItemDisabled(item)) return;\n\n if (this.selectionMode() !== 'none') {\n this.requestToggleSelection(item);\n }\n\n const modelId = this.resolveModelId(item);\n if (modelId !== null) {\n this.applyModelState(this.model.setActiveId(modelId));\n }\n }\n\n onIndicatorClicked(item: TngTreeItem): void {\n if (this.isItemDisabled(item)) return;\n\n if (item.canExpand()) {\n item.setExpanded(!item.isExpanded());\n const modelId = this.resolveModelId(item);\n this.rebuildModel(modelId);\n }\n\n item.focusHost();\n }\n\n private isControlled(): boolean {\n return this.value() !== undefined;\n }\n\n private initializeUncontrolledState(): void {\n this.initialized = true;\n const defaultInput = this.defaultValue();\n let initialValues: readonly TngTreeValue[] = [];\n if (defaultInput !== undefined && defaultInput !== null) {\n initialValues = Array.isArray(defaultInput)\n ? defaultInput.map(normalizeTreeValue)\n : [normalizeTreeValue(defaultInput)];\n }\n this.uncontrolledSelection = new Set(initialValues);\n }\n\n private getEffectiveSelectionSet(): ReadonlySet<TngTreeValue> {\n if (!this.isControlled()) {\n return this.uncontrolledSelection;\n }\n\n const val = this.value();\n let controlledValues: readonly TngTreeValue[] = [];\n if (val !== undefined && val !== null) {\n controlledValues = Array.isArray(val) ? val.map(normalizeTreeValue) : [normalizeTreeValue(val)];\n }\n return new Set(controlledValues);\n }\n\n private requestToggleSelection(item: TngTreeItem): void {\n const mode = this.selectionMode();\n if (mode === 'none') return;\n\n const previous = this.getEffectiveSelectionSet();\n const next = new Set(previous);\n const itemValue = item.getValue();\n const currentlySelected = previous.has(itemValue);\n\n if (mode === 'single') {\n next.clear();\n if (!currentlySelected) {\n next.add(itemValue);\n }\n } else {\n if (!currentlySelected) {\n next.add(itemValue);\n } else {\n next.delete(itemValue);\n }\n }\n\n if (setsEqual(previous, next)) return;\n\n if (!this.isControlled()) {\n this.uncontrolledSelection = next;\n }\n\n const valList = Array.from(next);\n if (mode === 'single') {\n this.valueChange.emit(valList.length > 0 ? valList[0] : null);\n } else {\n this.valueChange.emit(valList);\n }\n }\n\n @HostListener('keydown', ['$event'])\n protected onHostKeydown(event: KeyboardEvent): void {\n const activeElement = document.activeElement as HTMLElement;\n if (\n !this.hostRef.nativeElement.contains(activeElement) &&\n activeElement !== this.hostRef.nativeElement\n ) {\n return;\n }\n\n this.rebuildModel(this.resolvePreferredActiveId());\n\n const horizontalAction = resolveHorizontalTreeKeyAction(event);\n if (horizontalAction !== null) {\n event.preventDefault();\n this.runHorizontalKeyAction(horizontalAction);\n return;\n }\n\n const action = resolveListNavigationKeyAction(event, {\n multiSelect: this.selectionMode() === 'multiple',\n orientation: 'vertical',\n });\n\n if (action !== null) {\n if (action.preventDefault) {\n event.preventDefault();\n }\n this.runResolvedNavigationAction(action);\n return;\n }\n\n if (this.handleTypeaheadKey(event)) {\n return;\n }\n\n if (event.key === '*') {\n // Optional: expand all siblings.\n }\n }\n\n @HostListener('focus')\n protected onHostFocus(): void {\n this.rebuildModel(this.resolvePreferredActiveId());\n const activeItem = this.resolveItemByModelId(this.roving.getActiveId());\n if (activeItem !== null) {\n this.focusItem(activeItem);\n return;\n }\n\n this.focusActiveItem();\n }\n\n private applyModelState(state: TngTreeModelState): void {\n this.modelState = state;\n this.roving.setItemIds(state.visibleIds);\n this.roving.setDisabledIds(this.resolveDisabledVisibleIds(state.visibleIds));\n this.roving.setActiveId(state.activeId);\n this.typeahead.setItems(this.resolveTypeaheadItems(state.visibleIds));\n this.typeahead.setActiveId(state.activeId);\n }\n\n private ensureModelId(item: TngTreeItem): string {\n const existingId = this.modelIdByItem.get(item);\n if (existingId !== undefined) {\n return existingId;\n }\n\n const id = `tng-tree-item-${this.nextModelId}`;\n this.nextModelId += 1;\n this.modelIdByItem.set(item, id);\n return id;\n }\n\n private resolveModelId(item: TngTreeItem | null): string | null {\n if (item === null) {\n return null;\n }\n\n return this.modelIdByItem.get(item) ?? null;\n }\n\n private resolveActiveItem(): TngTreeItem | null {\n return this.resolveItemByModelId(this.modelState.activeId);\n }\n\n private resolveItemByModelId(modelId: string | null): TngTreeItem | null {\n if (modelId === null) {\n return null;\n }\n return this.itemByModelId.get(modelId) ?? null;\n }\n\n private focusBoundaryItem(boundary: TngTreeBoundary): void {\n const visibleIds =\n boundary === 'start'\n ? this.modelState.visibleIds\n : [...this.modelState.visibleIds].reverse();\n\n for (const modelId of visibleIds) {\n const candidate = this.itemByModelId.get(modelId);\n if (candidate !== undefined && !this.isItemDisabled(candidate)) {\n this.focusItem(candidate);\n return;\n }\n }\n }\n\n private focusActiveItem(): void {\n const item = this.resolveActiveItem();\n if (item !== null) {\n this.focusItem(item);\n }\n }\n\n private focusItem(item: TngTreeItem): void {\n if (this.isItemDisabled(item)) {\n return;\n }\n\n const modelId = this.resolveModelId(item);\n if (modelId !== null) {\n this.applyModelState(this.model.setActiveId(modelId));\n }\n item.focusHost();\n }\n\n private resolveFirstVisibleEnabledChild(parentItem: TngTreeItem): TngTreeItem | null {\n const parentId = this.resolveModelId(parentItem);\n if (parentId === null) {\n return null;\n }\n\n const visibleIds = new Set(this.modelState.visibleIds);\n const childIds = this.childModelIdsByParentId.get(parentId) ?? [];\n for (const childId of childIds) {\n if (!visibleIds.has(childId)) {\n continue;\n }\n\n const childItem = this.itemByModelId.get(childId);\n if (childItem !== undefined && !this.isItemDisabled(childItem)) {\n return childItem;\n }\n }\n\n return null;\n }\n\n private resolveTypeaheadItems(visibleIds: readonly string[]): readonly TngTypeaheadItem[] {\n const items: TngTypeaheadItem[] = [];\n for (const modelId of visibleIds) {\n const item = this.itemByModelId.get(modelId);\n if (item === undefined) {\n continue;\n }\n\n items.push({\n disabled: this.isItemDisabled(item),\n id: modelId,\n text: this.resolveTypeaheadText(item),\n });\n }\n\n return Object.freeze(items);\n }\n\n private resolveDisabledVisibleIds(visibleIds: readonly string[]): readonly string[] {\n const disabledIds: string[] = [];\n for (const modelId of visibleIds) {\n const item = this.itemByModelId.get(modelId);\n if (item !== undefined && this.isItemDisabled(item)) {\n disabledIds.push(modelId);\n }\n }\n return Object.freeze(disabledIds);\n }\n\n private resolveTypeaheadText(item: TngTreeItem): string {\n const host = item.getHostElement();\n const ariaLabel = host.getAttribute('aria-label');\n if (ariaLabel !== null && ariaLabel.trim().length > 0) {\n return ariaLabel.trim();\n }\n\n const text = normalizeTypeaheadText(host.textContent ?? '');\n if (text.length > 0) {\n return text;\n }\n\n return String(item.getValue());\n }\n\n private handleTypeaheadKey(event: KeyboardEvent): boolean {\n if (!isPrintableCharacter(event.key)) {\n return false;\n }\n\n const state = this.typeahead.handleKey(event.key);\n if (state.activeId === null || state.activeId === this.modelState.activeId) {\n return false;\n }\n\n event.preventDefault();\n this.applyModelState(this.model.setActiveId(state.activeId));\n this.focusActiveItem();\n return true;\n }\n\n private runHorizontalKeyAction(action: TngTreeHorizontalKeyAction): void {\n if (action === 'expand-or-child') {\n this.expandOrMoveToChild();\n return;\n }\n\n this.collapseOrMoveToParent();\n }\n\n private runResolvedNavigationAction(action: TngListNavigationAction): void {\n switch (action.type) {\n case 'move-next':\n this.applyModelState(this.model.moveNext());\n this.focusActiveItem();\n return;\n case 'move-prev':\n this.applyModelState(this.model.movePrev());\n this.focusActiveItem();\n return;\n case 'move-first':\n this.focusBoundaryItem('start');\n return;\n case 'move-last':\n this.focusBoundaryItem('end');\n return;\n case 'select-active':\n case 'toggle-active': {\n const item = this.resolveActiveItem();\n if (item !== null) {\n this.onItemClicked(item);\n }\n return;\n }\n case 'exit':\n case 'select-all':\n return;\n }\n }\n\n private expandOrMoveToChild(): void {\n const item = this.resolveActiveItem();\n if (item === null) {\n return;\n }\n\n if (item.canExpand() && !item.isExpanded()) {\n item.setExpanded(true);\n this.rebuildModel(this.resolveModelId(item));\n this.focusItem(item);\n return;\n }\n\n if (item.canExpand() && item.isExpanded()) {\n const firstChild = this.resolveFirstVisibleEnabledChild(item);\n if (firstChild !== null) {\n this.focusItem(firstChild);\n }\n }\n }\n\n private collapseOrMoveToParent(): void {\n const item = this.resolveActiveItem();\n if (item === null) {\n return;\n }\n\n if (item.canExpand() && item.isExpanded()) {\n item.setExpanded(false);\n this.rebuildModel(this.resolveModelId(item));\n this.focusItem(item);\n return;\n }\n\n const parent = item.getParentItem();\n if (parent !== null && !this.isItemDisabled(parent)) {\n this.focusItem(parent);\n }\n }\n\n private rebuildModel(activeId: string | null): void {\n const ordered = this.buildOrderedModelItems();\n const nodes: TngTreeNode[] = ordered.map((entry) => ({\n disabled: entry.item.disabled(),\n id: entry.id,\n parentId: entry.parentId,\n }));\n\n const expandedIds: string[] = [];\n for (const entry of ordered) {\n if (entry.item.canExpand() && entry.item.isExpanded()) {\n expandedIds.push(entry.id);\n }\n }\n\n this.model = createTreeModel({\n activeId,\n expandedIds,\n nodes,\n });\n this.applyModelState(this.model.getState());\n }\n\n private buildOrderedModelItems(): readonly TngTreeModelItem[] {\n const sortedItems = Array.from(this.items).sort((a, b) => {\n const position = a.getHostElement().compareDocumentPosition(b.getHostElement());\n if (position & Node.DOCUMENT_POSITION_FOLLOWING) return -1;\n if (position & Node.DOCUMENT_POSITION_PRECEDING) return 1;\n return 0;\n });\n\n const itemByModelId = new Map<string, TngTreeItem>();\n const childIdsByParent = new Map<string, string[]>();\n const ordered: TngTreeModelItem[] = [];\n\n for (const item of sortedItems) {\n const id = this.ensureModelId(item);\n const parentItem = item.getParentItem();\n const parentId = parentItem ? this.resolveModelId(parentItem) : null;\n\n ordered.push({\n id,\n item,\n parentId,\n });\n itemByModelId.set(id, item);\n\n if (parentId !== null) {\n const childIds = childIdsByParent.get(parentId) ?? [];\n childIds.push(id);\n childIdsByParent.set(parentId, childIds);\n }\n }\n\n const readonlyChildIdsByParent = new Map<string, readonly string[]>();\n for (const [parentId, childIds] of childIdsByParent.entries()) {\n readonlyChildIdsByParent.set(parentId, Object.freeze([...childIds]));\n }\n\n this.itemByModelId = itemByModelId;\n this.childModelIdsByParentId = readonlyChildIdsByParent;\n\n return Object.freeze(ordered);\n }\n\n private resolvePreferredActiveId(): string | null {\n return this.roving.getActiveId() ?? this.modelState.activeId;\n }\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type TngTreeSelectionMode = 'single' | 'multiple' | 'none';
|
|
2
|
+
export type TngTreeOrientation = 'vertical' | 'horizontal';
|
|
3
|
+
export type TngTreeValue = string | number;
|
|
4
|
+
export declare function normalizeTreeSelectionMode(value: unknown): TngTreeSelectionMode;
|
|
5
|
+
export declare function normalizeTreeOrientation(value: unknown): TngTreeOrientation;
|
|
6
|
+
export declare function normalizeTreeBooleanInput(value: unknown): boolean;
|
|
7
|
+
export declare function normalizeTreeValue(value: unknown): TngTreeValue;
|
|
8
|
+
export declare function normalizeTreeValueInput(value: unknown): TngTreeValue | readonly TngTreeValue[] | null | undefined;
|
|
9
|
+
export declare function normalizeOptionalBooleanAttribute(value: unknown): boolean | undefined;
|
|
10
|
+
//# sourceMappingURL=tng-tree.transforms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tng-tree.transforms.d.ts","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/layout/tree/tng-tree.transforms.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAC;AAClE,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,YAAY,CAAC;AAC3D,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,CAAC;AAE3C,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,oBAAoB,CAI/E;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,CAE3E;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAQjE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAI/D;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,OAAO,GACb,YAAY,GAAG,SAAS,YAAY,EAAE,GAAG,IAAI,GAAG,SAAS,CAK3D;AAED,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAKrF"}
|