apply review feedback

Signed-off-by: Anders Näsman <andersn@spotify.com>
This commit is contained in:
Anders Näsman
2022-05-03 23:16:44 +02:00
parent 8767710f1f
commit 206c7ccca0
4 changed files with 84 additions and 21 deletions
@@ -8,7 +8,7 @@
import { BackstagePlugin } from '@backstage/core-plugin-api';
// @public
export const ExpandableNavigation: (props: unknown) => JSX.Element | null;
export const ExpandableNavigation: () => JSX.Element | null;
// @public
export const ReportIssue: (props: ReportIssueProps) => JSX.Element | null;
@@ -14,13 +14,13 @@
* limitations under the License.
*/
import React, { useEffect, useState } from 'react';
import React, { useEffect, useCallback, useState } from 'react';
import { useLocalStorageValue } from '@react-hookz/web';
import { Button, withStyles } from '@material-ui/core';
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import { useShadowRoot } from '@backstage/plugin-techdocs-react';
import { useShadowRootElements } from '@backstage/plugin-techdocs-react';
const NESTED_LIST_TOGGLE = '.md-nav__item--nested .md-toggle';
@@ -52,12 +52,15 @@ const ExpandedIcon = withStyles({
})(ExpandMoreIcon);
type expandableNavigationLocalStorage = {
navExpanded: boolean;
expandAllNestedNavs: boolean;
};
/**
* Show expand/collapse navigation button next to site name in main
* navigation menu if documentation site has nested navigation.
*/
export const ExpandableNavigationAddon = () => {
const shadowRoot = useShadowRoot();
const defaultValue = { navExpanded: false };
const defaultValue = { expandAllNestedNavs: false };
const [expanded, setExpanded] =
useLocalStorageValue<expandableNavigationLocalStorage>(
EXPANDABLE_NAVIGATION_LOCAL_STORAGE,
@@ -65,25 +68,43 @@ export const ExpandableNavigationAddon = () => {
);
const [hasNavSubLevels, setHasNavSubLevels] = useState<boolean>(false);
const [...checkboxToggles] = useShadowRootElements<HTMLInputElement>([
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],
);
useEffect(() => {
const checkboxToggles =
shadowRoot?.querySelectorAll<HTMLInputElement>(NESTED_LIST_TOGGLE);
if (!checkboxToggles || (checkboxToggles && checkboxToggles.length === 0))
return;
// There is no nested navs
if (!checkboxToggles?.length) return;
setHasNavSubLevels(true);
checkboxToggles.forEach(item => {
if (
(expanded?.navExpanded && !item.checked) ||
(!expanded?.navExpanded && item.checked)
) {
item.click();
}
if (shouldToggle(item)) item.click();
});
}, [shadowRoot, expanded]);
}, [expanded, shouldToggle, checkboxToggles]);
const handleState = () => {
setExpanded(prevState => ({
navExpanded: !prevState?.navExpanded,
expandAllNestedNavs: !prevState?.expandAllNestedNavs,
}));
};
@@ -93,9 +114,11 @@ export const ExpandableNavigationAddon = () => {
<StyledButton
size="small"
onClick={handleState}
aria-label={expanded?.navExpanded ? 'collapse-nav' : 'expand-nav'}
aria-label={
expanded?.expandAllNestedNavs ? 'collapse-nav' : 'expand-nav'
}
>
{expanded?.navExpanded ? <ExpandedIcon /> : <CollapsedIcon />}
{expanded?.expandAllNestedNavs ? <ExpandedIcon /> : <CollapsedIcon />}
</StyledButton>
) : null}
</>
@@ -34,7 +34,39 @@ export const techdocsModuleAddonsContribPlugin = createPlugin({
});
/**
* TechDocs addon that lets you expand/collapse the TechDocs main navigation.
* TechDocs addon that lets you expand/collapse the TechDocs main navigation
* and keep the preferred state in local storage. The addon will render as
* a button next to the site name if the documentation has nested navigation.
*
* @example
* Here's a simple example:
* ```
* import {
* DefaultTechDocsHome,
* TechDocsIndexPage,
* TechDocsReaderPage,
* } from '@backstage/plugin-techdocs';
* import { TechDocsAddons } from '@backstage/plugin-techdocs-react/alpha';
* import { ExpandableNavigation } from '@backstage/plugin-techdocs-module-addons-contrib';
*
*
* const AppRoutes = () => {
* <FlatRoutes>
* // other plugin routes
* <Route path="/docs" element={<TechDocsIndexPage />}>
* <DefaultTechDocsHome />
* </Route>
* <Route
* path="/docs/:namespace/:kind/:name/*"
* element={<TechDocsReaderPage />}
* >
* <TechDocsAddons>
* <ExpandableNavigation />
* </TechDocsAddons>
* </Route>
* </FlatRoutes>;
* };
* ```
*
* @public
*/
+8
View File
@@ -51,6 +51,14 @@ const getDataKeyByName = (name: string) => {
* Create a TechDocs addon.
* @public
*/
export function createTechDocsAddonExtension(
options: TechDocsAddonOptions,
): Extension<() => JSX.Element | null>;
export function createTechDocsAddonExtension<TComponentProps>(
options: TechDocsAddonOptions<TComponentProps>,
): Extension<(props: TComponentProps) => JSX.Element | null>;
export function createTechDocsAddonExtension<TComponentProps>(
options: TechDocsAddonOptions<TComponentProps>,
): Extension<(props: TComponentProps) => JSX.Element | null> {