From 31a95e60692cec6d1939c01645da04c0f49b4f10 Mon Sep 17 00:00:00 2001 From: Ewan Roycroft Date: Tue, 31 May 2022 15:45:30 +0100 Subject: [PATCH 1/3] insertTree: Maintain active children if requested If the maintainActiveChildren option is set, any activeChildren set in the subTreeRootNodeConfig will be assigned. --- src/index.ts | 10 +++++++++- src/interfaces.ts | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 0f17557..5aca8e2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1036,7 +1036,7 @@ export class Lrud { * @param {boolean} [options.maintainIndex] - if true, and new tree is replacing an existing branch of the tree, * maintain the original branches relative index; default: true */ - insertTree (subTreeRootNodeConfig: NodeConfig, options: InsertTreeOptions = { maintainIndex: true }): void { + insertTree (subTreeRootNodeConfig: NodeConfig, options: InsertTreeOptions = { maintainIndex: true, maintainActiveChildren: false }): void { if (!subTreeRootNodeConfig) { return } @@ -1051,6 +1051,14 @@ export class Lrud { } this.registerTree(subTreeRootNodeConfig) + + if (options.maintainActiveChildren) { + traverseNodeSubtree(subTreeRootNodeConfig, traversedNodeConfig => { + if (traversedNodeConfig.activeChild) { + this.getNode(traversedNodeConfig.id).activeChild = this.getNode(traversedNodeConfig.activeChild) + } + }) + } } /** diff --git a/src/interfaces.ts b/src/interfaces.ts index b41e7c9..b67d0d5 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -60,6 +60,7 @@ export interface Node extends Tree { export interface NodeConfig extends Tree, Omit { id?: NodeId parent?: NodeId + activeChild?: NodeId } export type NodesBag = { [id in NodeId]: Node } @@ -75,6 +76,7 @@ export interface HandleKeyEventOptions { export interface InsertTreeOptions { maintainIndex?: boolean + maintainActiveChildren?: boolean } export interface UnregisterNodeOptions { From 6c376972b862f69c5f65ab1db12504af730e5e81 Mon Sep 17 00:00:00 2001 From: Ewan Roycroft Date: Tue, 31 May 2022 15:56:22 +0100 Subject: [PATCH 2/3] NodeConfig: Allow activeChild to be of type Node --- src/index.ts | 5 ++++- src/interfaces.ts | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 5aca8e2..8b322fa 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1055,7 +1055,10 @@ export class Lrud { if (options.maintainActiveChildren) { traverseNodeSubtree(subTreeRootNodeConfig, traversedNodeConfig => { if (traversedNodeConfig.activeChild) { - this.getNode(traversedNodeConfig.id).activeChild = this.getNode(traversedNodeConfig.activeChild) + this.getNode(traversedNodeConfig.id).activeChild = this.getNode( + typeof traversedNodeConfig.activeChild === 'string' + ? traversedNodeConfig.activeChild + : traversedNodeConfig.activeChild.id) } }) } diff --git a/src/interfaces.ts b/src/interfaces.ts index b67d0d5..fb02cf8 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -60,7 +60,7 @@ export interface Node extends Tree { export interface NodeConfig extends Tree, Omit { id?: NodeId parent?: NodeId - activeChild?: NodeId + activeChild?: NodeId | Node } export type NodesBag = { [id in NodeId]: Node } From 60707e489c55f228d62f1fb6d554d96b217aec3e Mon Sep 17 00:00:00 2001 From: Ewan Roycroft Date: Tue, 31 May 2022 16:47:16 +0100 Subject: [PATCH 3/3] Add tests for insertTree/maintainActiveChildren --- src/insert-tree.test.js | 63 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/src/insert-tree.test.js b/src/insert-tree.test.js index 8ce0fec..114c4e8 100644 --- a/src/insert-tree.test.js +++ b/src/insert-tree.test.js @@ -233,4 +233,67 @@ describe('insertTree()', () => { expect(() => navigation.insertTree(undefined)).not.toThrow() }) + + test('should not maintain active children if maintainActiveChildren not enabled', () => { + const navigation = new Lrud() + .registerNode('root') + .registerNode('a') + .registerNode('b') + + const subTree = { + id: 'c', + orientation: 'vertical', + activeChild: 'c_1', + children: [ + { id: 'c_1', isFocusable: true }, + { id: 'c_2', isFocusable: true } + ] + } + + navigation.insertTree(subTree) + + expect(navigation.getNode('c').activeChild).not.toBeDefined() + }) + + test('should maintain active children if maintainActiveChildren enabled', () => { + const navigation = new Lrud() + .registerNode('root') + .registerNode('a') + .registerNode('b') + + const subTree = { + id: 'c', + orientation: 'vertical', + activeChild: 'c_1', + children: [ + { id: 'c_1', isFocusable: true }, + { id: 'c_2', isFocusable: true } + ] + } + + navigation.insertTree(subTree, { maintainActiveChildren: true }) + + expect(navigation.getNode('c').activeChild.id).toEqual('c_1') + }) + + test('should maintain active children if Node supplied', () => { + const navigation = new Lrud() + .registerNode('root') + .registerNode('a') + .registerNode('b') + + const subTree = { + id: 'c', + orientation: 'vertical', + activeChild: { id: 'c_1' }, + children: [ + { id: 'c_1', isFocusable: true }, + { id: 'c_2', isFocusable: true } + ] + } + + navigation.insertTree(subTree, { maintainActiveChildren: true }) + + expect(navigation.getNode('c').activeChild.id).toEqual('c_1') + }) })