Merge pull request #30499 from GabDug/fix/techdocs

fix(techdocs): ExpandableNavigation addon does not work on Firefox
This commit is contained in:
John Philip
2025-11-03 03:32:13 -05:00
committed by GitHub
5 changed files with 48 additions and 53 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-techdocs-module-addons-contrib': patch
---
ExpandableCollapse Techdocs Addon was breaking native sidebar collapse on Firefox
@@ -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
@@ -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!?
@@ -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
@@ -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<HTMLElement>,
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<HTMLDivElement>,
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<HTMLElement>) {
handleKeyPass(event, handleState);
}
return (
<>
{hasNavSubLevels ? (
<StyledButton
size="small"
onClick={handleState}
onKeyDown={event => handleKeyPass(event, handleState)}
onKeyDown={handleButtonKeyDown}
tabIndex={0} // Ensuring keyboard focus
aria-expanded={expanded?.expandAllNestedNavs} // Accessibility
aria-label={