diff --git a/.changeset/gentle-bikes-relax.md b/.changeset/gentle-bikes-relax.md new file mode 100644 index 0000000000..7a4aeda5f8 --- /dev/null +++ b/.changeset/gentle-bikes-relax.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs-module-addons-contrib': patch +--- + +ExpandableCollapse Techdocs Addon was breaking native sidebar collapse on Firefox diff --git a/plugins/techdocs-backend/examples/documented-component/docs/deeper-nav/even-deeper/index.md b/plugins/techdocs-backend/examples/documented-component/docs/deeper-nav/even-deeper/index.md new file mode 100644 index 0000000000..33f63ea079 --- /dev/null +++ b/plugins/techdocs-backend/examples/documented-component/docs/deeper-nav/even-deeper/index.md @@ -0,0 +1,9 @@ +# Deeper Nav + +Useful to test ExpandableNavigationAddon! + +## I'm in too deep! + +## And I'm trying to keep + +### ...up above my head diff --git a/plugins/techdocs-backend/examples/documented-component/docs/deeper-nav/index.md b/plugins/techdocs-backend/examples/documented-component/docs/deeper-nav/index.md new file mode 100644 index 0000000000..3f3800a1d5 --- /dev/null +++ b/plugins/techdocs-backend/examples/documented-component/docs/deeper-nav/index.md @@ -0,0 +1,11 @@ +# Deeper Nav + +Useful to test ExpandableNavigationAddon! + +## Some nav for TOC + +Yes! + +### Some deeper TOC nav + +## What? A second element with long text!? diff --git a/plugins/techdocs-backend/examples/documented-component/mkdocs.yml b/plugins/techdocs-backend/examples/documented-component/mkdocs.yml index fd954225a3..4632c6eb13 100644 --- a/plugins/techdocs-backend/examples/documented-component/mkdocs.yml +++ b/plugins/techdocs-backend/examples/documented-component/mkdocs.yml @@ -8,6 +8,10 @@ nav: - 'Code Sample': code/code-sample.md - Extensions: extensions.md - 'Inner Component Docs': inner-component-docs/index.md + - 'Deeper Nav': + - deeper-nav/index.md + - 'Inner Deeper Nav': + - 'Inner Inner Deeper Nav': deeper-nav/even-deeper/index.md plugins: - techdocs-core diff --git a/plugins/techdocs-module-addons-contrib/src/ExpandableNavigation/ExpandableNavigation.tsx b/plugins/techdocs-module-addons-contrib/src/ExpandableNavigation/ExpandableNavigation.tsx index 83e34f411a..2a18e642fa 100644 --- a/plugins/techdocs-module-addons-contrib/src/ExpandableNavigation/ExpandableNavigation.tsx +++ b/plugins/techdocs-module-addons-contrib/src/ExpandableNavigation/ExpandableNavigation.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { useEffect, useCallback, useState } from 'react'; +import { useEffect, useState } from 'react'; import { useLocalStorageValue } from '@react-hookz/web'; import { Button, withStyles } from '@material-ui/core'; import ChevronRightIcon from '@material-ui/icons/ChevronRight'; @@ -73,71 +73,33 @@ export const ExpandableNavigationAddon = () => { NESTED_LIST_TOGGLE, ]); - const shouldToggle = useCallback( - (item: HTMLInputElement) => { - const isExpanded = item.checked; - const shouldExpand = expanded?.expandAllNestedNavs; - - // Is collapsed but should expand - if (shouldExpand && !isExpanded) { - return true; - } - - // Is expanded but should collapse - if (!shouldExpand && isExpanded) { - return true; - } - - return false; - }, - [expanded], - ); - const handleKeyPass = ( + // Define handleKeyPass as a named function + function handleKeyPass( event: React.KeyboardEvent, toggleAction: () => void, - ) => { + ) { if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); toggleAction(); } - }; - useEffect(() => { - // There is no nested navs - if (!checkboxToggles?.length) return; + } + useEffect(() => { + if (!checkboxToggles?.length) return; setHasNavSubLevels(true); - checkboxToggles.forEach(item => { - item.tabIndex = 0; - const toggleAction = () => { - if (shouldToggle(item)) { - item.click(); - } - }; - // Add keyboard event listener - const keydownHandler = (event: KeyboardEvent) => { - handleKeyPass( - event as unknown as React.KeyboardEvent, - toggleAction, - ); - }; - item.addEventListener('keydown', keydownHandler); - item.addEventListener('click', toggleAction); + }, [checkboxToggles]); - // Clean up event listener or unmount - return () => { - item.removeEventListener('keydown', keydownHandler); - item.removeEventListener('click', toggleAction); - }; - }); - }, [checkboxToggles, shouldToggle]); useEffect(() => { if (!checkboxToggles?.length) return; - checkboxToggles.forEach(item => { + function shouldToggle(item: HTMLInputElement) { + return expanded?.expandAllNestedNavs !== item.checked; + } + for (const item of checkboxToggles) { if (shouldToggle(item)) { item.click(); } - }); - }, [expanded, checkboxToggles, shouldToggle]); + } + }, [expanded, checkboxToggles]); const handleState = () => { setExpanded(prevState => ({ @@ -145,13 +107,17 @@ export const ExpandableNavigationAddon = () => { })); }; + function handleButtonKeyDown(event: React.KeyboardEvent) { + handleKeyPass(event, handleState); + } + return ( <> {hasNavSubLevels ? ( handleKeyPass(event, handleState)} + onKeyDown={handleButtonKeyDown} tabIndex={0} // Ensuring keyboard focus aria-expanded={expanded?.expandAllNestedNavs} // Accessibility aria-label={