diff --git a/src/components/TopicElements/TopicElements.js b/src/components/TopicElements/TopicElements.js index 7b266b784..dfbb7cbf5 100644 --- a/src/components/TopicElements/TopicElements.js +++ b/src/components/TopicElements/TopicElements.js @@ -196,8 +196,8 @@ function TopicElements({ history }) { {elements.permalink && } {elements.search && } - {elements.header &&
} {elements.header && } + {elements.header &&
} {elements.popup && } {elements.mapControls && ( ({ wrapperBaseLayerSelect: { @@ -182,6 +183,7 @@ class TopicMenu extends PureComponent {
{ + if (document.activeElement?.id?.startsWith(TOPIC_MENU_ITEM_ID_PREFIX)) { + return ( + document.activeElement.id === + `${TOPIC_MENU_ITEM_ID_PREFIX}-${topic.key}` + ); + } + return false; + }); +} + +function getNextTopic(topicsToDisplay, focusedTopic) { + const nextIndex = + topicsToDisplay.findIndex((t) => t.key === focusedTopic?.key) + 1 || 0; + return topicsToDisplay[nextIndex]; +} + +function getPreviousTopic(topicsToDisplay, focusedTopic) { + const previousIndex = + topicsToDisplay.findIndex((t) => t.key === focusedTopic?.key) - 1 || 0; + return topicsToDisplay[previousIndex]; +} + function TopicsMenu({ children, menuHeight, bodyElementRef }) { const permissionInfos = useSelector((state) => state.app.permissionInfos); const menuOpen = useSelector((state) => state.app.menuOpen); @@ -74,6 +101,36 @@ function TopicsMenu({ children, menuHeight, bodyElementRef }) { }); }, [activeTopic, topics, permissionInfos]); + useEffect(() => { + let handleKeyUp; + if (menuOpen) { + handleKeyUp = (e) => { + const focusedTopic = getFocusedTopic(topicsToDisplay); + if (!focusedTopic) return; + e.stopPropagation(); + e.preventDefault(); + if (e.keyCode === 38) { + const previousTopicMenuItem = document.getElementById( + `${TOPIC_MENU_ITEM_ID_PREFIX}-${getPreviousTopic(topicsToDisplay, focusedTopic)?.key}`, + ); + previousTopicMenuItem?.focus(); + } + if (e.keyCode === 40) { + e.stopPropagation(); + e.preventDefault(); + const nextTopicMenuItem = document.getElementById( + `${TOPIC_MENU_ITEM_ID_PREFIX}-${getNextTopic(topicsToDisplay, focusedTopic)?.key}`, + ); + nextTopicMenuItem?.focus(); + } + }; + document.addEventListener("keyup", handleKeyUp); + } + return () => { + document.removeEventListener("keyup", handleKeyUp); + }; + }, [menuOpen, topicsToDisplay]); + if (!topics || !topics.length) { return null; } diff --git a/src/layerInfos/NetzkarteTopicInfo/NetzkarteTopicInfo.js b/src/layerInfos/NetzkarteTopicInfo/NetzkarteTopicInfo.js index 9ba082498..45d3859e5 100644 --- a/src/layerInfos/NetzkarteTopicInfo/NetzkarteTopicInfo.js +++ b/src/layerInfos/NetzkarteTopicInfo/NetzkarteTopicInfo.js @@ -6,8 +6,6 @@ const propTypes = { t: PropTypes.func.isRequired, }; -const defaultProps = {}; - function NetzkarteTopicInfo({ t }) { return (
@@ -27,6 +25,5 @@ function NetzkarteTopicInfo({ t }) { } NetzkarteTopicInfo.propTypes = propTypes; -NetzkarteTopicInfo.defaultProps = defaultProps; export default withTranslation()(NetzkarteTopicInfo); diff --git a/src/utils/constants.js b/src/utils/constants.js index 24e5a6051..3fc996c22 100644 --- a/src/utils/constants.js +++ b/src/utils/constants.js @@ -61,3 +61,6 @@ export const LS_SIZE_KEY = "tm.max.canvas.size"; // hideInLayerTree values export const ONLY_WHEN_NOT_LOGGED_IN = "onlyWhenNotLoggedIn"; + +// topic menu items +export const TOPIC_MENU_ITEM_ID_PREFIX = "topic-menu-item";