From 8b98c33c4c8ed9cc1dc3964576bad93e33c0e8cb Mon Sep 17 00:00:00 2001 From: Lutz Helm Date: Thu, 13 Feb 2020 14:42:16 +0100 Subject: [PATCH] Toggle nodes with keyboard interaction onClick and onKeyDown should be replaced once material-ui TreeItem has node selection support: https://github.com/mui-org/material-ui/issues/16795 --- src/components/SidebarIndexTableOfContents.js | 13 +++- src/state/selectors/ranges.js | 63 +++++++++++++++---- 2 files changed, 62 insertions(+), 14 deletions(-) diff --git a/src/components/SidebarIndexTableOfContents.js b/src/components/SidebarIndexTableOfContents.js index 8130e83eaf..c018c82ee1 100644 --- a/src/components/SidebarIndexTableOfContents.js +++ b/src/components/SidebarIndexTableOfContents.js @@ -12,15 +12,25 @@ export class SidebarIndexTableOfContents extends Component { /** */ selectTreeItem(node) { const { setCanvas, toggleRange, windowId } = this.props; - toggleRange(node.data.id); // Do not select if there are child nodes if (node.nodes.length > 0) { + toggleRange(node.data.id); return; } const canvas = node.data.getCanvasIds()[0]; setCanvas(windowId, canvas); } + /** */ + handleKeyPressed(event, node) { + if (event.key === 'Enter' + || event.key === ' ' + || event.key === 'ArrowLeft' && this.props.expandedRangeIds.indexOf(node.data.id) !== -1 + || event.key === 'ArrowRight' && this.props.expandedRangeIds.indexOf(node.data.id) === -1) { + this.selectTreeItem(node); + } + } + /** */ buildTreeItems(nodes, canvasIds, visibleRangeIds, containerRef) { return ( @@ -42,6 +52,7 @@ export class SidebarIndexTableOfContents extends Component { )} onClick={() => this.selectTreeItem(node)} + onKeyDown={e => this.handleKeyPressed(e, node)} > {node.nodes.length > 0 ? this.buildTreeItems(node.nodes, canvasIds, visibleRangeIds, containerRef) : null} diff --git a/src/state/selectors/ranges.js b/src/state/selectors/ranges.js index 13056c78ab..e141ffd4b8 100644 --- a/src/state/selectors/ranges.js +++ b/src/state/selectors/ranges.js @@ -6,40 +6,77 @@ import { getCompanionWindow } from './companionWindows'; /** */ function getVisibleRangeIdsInSubTree(nodes, canvasIds) { - return nodes.reduce((rangeIds, node) => { - const currentRangeIds = []; + return nodes.reduce((rangeIdAcc, node) => { + const currentBranchRangeIds = []; + const currentLeafRangeIds = []; const nodeContainsVisibleCanvas = canvasIds.reduce( (acc, canvasId) => acc || node.data.getCanvasIds().indexOf(canvasId) !== -1, false, ); if (node.nodes.length > 0) { const subTreeVisibleRangeIds = node.nodes.length > 0 - ? getVisibleRangeIdsInSubTree(node.nodes, canvasIds) : []; - currentRangeIds.push(...subTreeVisibleRangeIds); + ? getVisibleRangeIdsInSubTree(node.nodes, canvasIds) : { + branchRangeIds: [], + leafRangeIds: [], + }; + currentBranchRangeIds.push(...subTreeVisibleRangeIds.branchRangeIds); + currentLeafRangeIds.push(...subTreeVisibleRangeIds.leafRangeIds); } - if (currentRangeIds.length > 0 || nodeContainsVisibleCanvas) { - currentRangeIds.push(node.data.id); + if (currentBranchRangeIds.length > 0 + || currentLeafRangeIds.length > 0 + || nodeContainsVisibleCanvas) { + if (node.nodes.length > 0) { + currentBranchRangeIds.push(node.data.id); + } else { + currentLeafRangeIds.push(node.data.id); + } } - rangeIds.push(...currentRangeIds); - return rangeIds; - }, []); + rangeIdAcc.branchRangeIds.push(...currentBranchRangeIds); + rangeIdAcc.leafRangeIds.push(...currentLeafRangeIds); + return rangeIdAcc; + }, { + branchRangeIds: [], + leafRangeIds: [], + }); } /** */ -export const getVisibleRangeIds = createSelector( +const getVisibleLeafAndBranchRangeIds = createSelector( [ getManifestTreeStructure, getVisibleCanvases, ], (tree, canvases) => { if (!canvases) { - return []; + return { + branchRangeIds: [], + leafRangeIds: [], + }; } const canvasIds = canvases.map(canvas => canvas.id); return getVisibleRangeIdsInSubTree(tree.nodes, canvasIds); }, ); +/** */ +export const getVisibleRangeIds = createSelector( + [ + getVisibleLeafAndBranchRangeIds, + ], + (visibleLeafAndBranchRangeIds) => { + return union(visibleLeafAndBranchRangeIds.leafRangeIds, visibleLeafAndBranchRangeIds.branchRangeIds); + }, +); + +const getVisibleBranchRangeIds = createSelector( + [ + getVisibleLeafAndBranchRangeIds, + ], + (visibleLeafAndBranchRangeIds) => { + return visibleLeafAndBranchRangeIds.branchRangeIds; + }, +); + /** */ export function getManuallyExpandedRangeIds(state, { companionWindowId }) { const companionWindow = getCompanionWindow(state, { companionWindowId }); @@ -48,7 +85,7 @@ export function getManuallyExpandedRangeIds(state, { companionWindowId }) { /** */ export function getExpandedRangeIds(state, { ...args }) { - const visibleRangeIds = getVisibleRangeIds(state, { ...args }); + const visibleBranchRangeIds = getVisibleBranchRangeIds(state, { ...args }); const manuallyExpandedRangeIds = getManuallyExpandedRangeIds(state, { ...args }); - return union(manuallyExpandedRangeIds, visibleRangeIds); + return union(manuallyExpandedRangeIds, visibleBranchRangeIds); }