Skip to content

Commit 9a0bb60

Browse files
feat(tree): Add editable state to the nodes
1 parent b0d8167 commit 9a0bb60

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

core/src/components/tree/tree.spec.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,15 @@ describe(`Tree`, () => {
6262
ariaLabel: 'root',
6363
level: 0,
6464
isExpanded: false,
65+
isEdited: false,
6566
children: [
6667
{
6768
label: 'child',
6869
ariaLabel: 'child',
6970
level: 1,
7071
isExpanded: undefined,
7172
children: [],
73+
isEdited: false,
7274
},
7375
],
7476
},
@@ -87,4 +89,10 @@ describe(`Tree`, () => {
8789
expect(state.normalizedNodes[0].isExpanded).toBe(true);
8890
expect(itemExpands.length).toEqual(1);
8991
});
92+
93+
test(`should return the TreeItem based on the NormalizedTreeItem`, () => {
94+
const newNodes = [{label: 'root', ariaLabel: 'root', children: [{label: 'child', ariaLabel: 'child'}]}];
95+
tree.patch({nodes: newNodes});
96+
expect(tree.api.getOriginalNode(state.normalizedNodes[0])).toEqual(newNodes[0]);
97+
});
9098
});

core/src/components/tree/tree.ts

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ export interface NormalizedTreeItem extends TreeItem {
5050
* An array of children nodes
5151
*/
5252
children: NormalizedTreeItem[];
53+
/**
54+
* Flag whether the item is being currently edited
55+
*/
56+
isEdited: boolean;
5357
}
5458

5559
/**
@@ -58,6 +62,7 @@ export interface NormalizedTreeItem extends TreeItem {
5862
interface TreeItemInfo {
5963
parent: NormalizedTreeItem | undefined;
6064
htmlElement?: HTMLElement;
65+
originalNode: TreeItem;
6166
}
6267

6368
interface TreeCommonPropsAndState extends WidgetsCommonPropsAndState {}
@@ -121,8 +126,13 @@ export interface TreeState extends TreeCommonPropsAndState {
121126
/**
122127
* Interface representing the API for a Tree component.
123128
*/
124-
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
125-
export interface TreeApi {}
129+
export interface TreeApi {
130+
/**
131+
* Method to get the TreeItem from the input from the NormalizedTreeItem
132+
* @returns TreeItem that corresponds to the given NormalizedTreeItem
133+
*/
134+
getOriginalNode(normalizedItem: NormalizedTreeItem): TreeItem | undefined;
135+
}
126136

127137
/**
128138
* Interface representing various directives used in the Tree component.
@@ -224,10 +234,12 @@ export const createTree: WidgetFactory<TreeWidget> = createWidgetFactory('tree',
224234
ariaLabel: node.ariaLabel ?? node.label,
225235
level,
226236
children: [],
237+
isEdited: false,
227238
isExpanded: node.children?.length ? (node.isExpanded ?? false) : undefined,
228239
};
229240
treeMap.set(copyNode, {
230241
parent,
242+
originalNode: node,
231243
});
232244

233245
if (node.children) {
@@ -306,6 +318,13 @@ export const createTree: WidgetFactory<TreeWidget> = createWidgetFactory('tree',
306318
keydown: (event: KeyboardEvent) => {
307319
const {key} = event;
308320
const {item} = treeItemContext$();
321+
322+
// Don't handle keyboard shortcuts if user is editing in an input
323+
const target = event.target as HTMLElement;
324+
if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') {
325+
return;
326+
}
327+
309328
const isExpanded = item.isExpanded;
310329
refreshElements(); // collapsed items were added to the dom
311330
switch (key) {
@@ -372,7 +391,11 @@ export const createTree: WidgetFactory<TreeWidget> = createWidgetFactory('tree',
372391
const widget: TreeWidget = {
373392
...stateStores({normalizedNodes$, expandedMap$, ...stateProps}),
374393
patch,
375-
api: {},
394+
api: {
395+
getOriginalNode(normalizedItem: NormalizedTreeItem) {
396+
return treeMap.get(normalizedItem)?.originalNode;
397+
},
398+
},
376399
directives: {
377400
navigationDirective: bindDirective(navDirective, navManagerConfig$),
378401
itemToggleDirective: mergeDirectives(treeItemElementDirective, itemToggleAttributesDirective),

0 commit comments

Comments
 (0)