diff --git a/frontend/src/components/Sidebar/Sidebar.tsx b/frontend/src/components/Sidebar/Sidebar.tsx
index 965a20eace..529db8ab55 100644
--- a/frontend/src/components/Sidebar/Sidebar.tsx
+++ b/frontend/src/components/Sidebar/Sidebar.tsx
@@ -5,7 +5,7 @@ import Drawer from '@mui/material/Drawer';
import Grid from '@mui/material/Grid';
import List from '@mui/material/List';
import useMediaQuery from '@mui/material/useMediaQuery';
-import React from 'react';
+import React, { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch } from 'react-redux';
import { useHistory } from 'react-router-dom';
@@ -112,7 +112,7 @@ function SidebarToggleButton() {
);
}
-function DefaultLinkArea(props: { sidebarName: string; isOpen: boolean }) {
+const DefaultLinkArea = memo((props: { sidebarName: string; isOpen: boolean }) => {
const { sidebarName, isOpen } = props;
if (sidebarName === DefaultSidebars.HOME) {
@@ -151,7 +151,7 @@ function DefaultLinkArea(props: { sidebarName: string; isOpen: boolean }) {
);
-}
+});
export default function Sidebar() {
const { t, i18n } = useTranslation(['glossary', 'translation']);
@@ -186,6 +186,15 @@ export default function Sidebar() {
const search = namespaces.size !== 0 ? `?namespace=${[...namespaces].join('+')}` : '';
+ const handleToggleOpen = useCallback(() => {
+ dispatch(setWhetherSidebarOpen(!sidebar.isSidebarOpen));
+ }, [sidebar.isSidebarOpen]);
+
+ const linkArea = useMemo(
+ () => ,
+ [sidebar.selected.sidebar, isOpen]
+ );
+
if (sidebar.selected.sidebar === null || !sidebar?.isVisible) {
return null;
}
@@ -199,10 +208,8 @@ export default function Sidebar() {
isTemporaryDrawer={isTemporaryDrawer}
selectedName={sidebar?.selected.item}
search={search}
- onToggleOpen={() => {
- dispatch(setWhetherSidebarOpen(!sidebar.isSidebarOpen));
- }}
- linkArea={}
+ onToggleOpen={handleToggleOpen}
+ linkArea={linkArea}
/>
);
}
@@ -228,161 +235,163 @@ export interface PureSidebarProps {
linkArea: React.ReactNode;
}
-export function PureSidebar({
- open,
- openUserSelected,
- items,
- selectedName,
- isTemporaryDrawer = false,
- isNarrowOnly = false,
- onToggleOpen,
- search,
- linkArea,
-}: PureSidebarProps) {
- const { t } = useTranslation();
- const temporarySideBarOpen = open === true && isTemporaryDrawer && openUserSelected === true;
-
- // The large sidebar does not open in medium view (600-960px).
- const largeSideBarOpen =
- (open === true && !isNarrowOnly) || (open === true && temporarySideBarOpen);
-
- /**
- * For closing the sidebar if temporaryDrawer on mobile.
- */
- const toggleDrawer = (event: React.KeyboardEvent | React.MouseEvent) => {
- if (
- event.type === 'keydown' &&
- ((event as React.KeyboardEvent).key === 'Tab' ||
- (event as React.KeyboardEvent).key === 'Shift')
- ) {
- return;
- }
- onToggleOpen();
- };
-
- const contents = (
- <>
- ({
- ...theme.mixins.toolbar,
- })}
- />
-
-
-
- {items.map(item => (
-
- ))}
-
-
-
- ({
- '&, & *, & svg': {
- color: theme.palette.sidebarLink.color,
- },
- '& .MuiButton-root': {
- color: theme.palette.sidebarButtonInLinkArea.color,
- '&:hover': {
- background: theme.palette.sidebarButtonInLinkArea.hover.background,
+export const PureSidebar = memo(
+ ({
+ open,
+ openUserSelected,
+ items,
+ selectedName,
+ isTemporaryDrawer = false,
+ isNarrowOnly = false,
+ onToggleOpen,
+ search,
+ linkArea,
+ }: PureSidebarProps) => {
+ const { t } = useTranslation();
+ const temporarySideBarOpen = open === true && isTemporaryDrawer && openUserSelected === true;
+
+ // The large sidebar does not open in medium view (600-960px).
+ const largeSideBarOpen =
+ (open === true && !isNarrowOnly) || (open === true && temporarySideBarOpen);
+
+ /**
+ * For closing the sidebar if temporaryDrawer on mobile.
+ */
+ const toggleDrawer = (event: React.KeyboardEvent | React.MouseEvent) => {
+ if (
+ event.type === 'keydown' &&
+ ((event as React.KeyboardEvent).key === 'Tab' ||
+ (event as React.KeyboardEvent).key === 'Shift')
+ ) {
+ return;
+ }
+ onToggleOpen();
+ };
+
+ const contents = (
+ <>
+ ({
+ ...theme.mixins.toolbar,
+ })}
+ />
+
+
+
+ {items.map(item => (
+
+ ))}
+
+
+
+ ({
+ '&, & *, & svg': {
+ color: theme.palette.sidebarLink.color,
},
- },
- '& .MuiButton-containedPrimary': {
- background: theme.palette.sidebarButtonInLinkArea.primary.background,
- '&:hover': {
- background: theme.palette.sidebarButtonInLinkArea.hover.background,
+ '& .MuiButton-root': {
+ color: theme.palette.sidebarButtonInLinkArea.color,
+ '&:hover': {
+ background: theme.palette.sidebarButtonInLinkArea.hover.background,
+ },
},
- },
- })}
- >
- {linkArea}
-
+ '& .MuiButton-containedPrimary': {
+ background: theme.palette.sidebarButtonInLinkArea.primary.background,
+ '&:hover': {
+ background: theme.palette.sidebarButtonInLinkArea.hover.background,
+ },
+ },
+ })}
+ >
+ {linkArea}
+
+
-
- >
- );
+ >
+ );
- const conditionalProps = isTemporaryDrawer
- ? {
- open: temporarySideBarOpen,
- onClose: onToggleOpen,
- }
- : {};
+ const conditionalProps = isTemporaryDrawer
+ ? {
+ open: temporarySideBarOpen,
+ onClose: onToggleOpen,
+ }
+ : {};
- return (
-
- {
- const drawer = {
- width: drawerWidth,
- flexShrink: 0,
- background: theme.palette.sidebarBg,
- };
-
- const drawerOpen = {
- width: drawerWidth,
- transition: theme.transitions.create('width', {
- easing: theme.transitions.easing.sharp,
- duration: theme.transitions.duration.enteringScreen,
- }),
- background: theme.palette.sidebarBg,
- };
-
- const drawerClose = {
- transition: theme.transitions.create('width', {
- easing: theme.transitions.easing.sharp,
- duration: theme.transitions.duration.leavingScreen,
- }),
- overflowX: 'hidden',
- width: '56px',
- [theme.breakpoints.down('xs')]: {
- background: 'initial',
- },
- [theme.breakpoints.down('sm')]: {
- width: theme.spacing(0),
- },
- [theme.breakpoints.up('sm')]: {
- width: '72px',
- },
- background: theme.palette.sidebarBg,
- };
-
- if (
- (isTemporaryDrawer && temporarySideBarOpen) ||
- (!isTemporaryDrawer && largeSideBarOpen)
- ) {
- return { ...drawer, ...drawerOpen, '& .MuiPaper-root': { ...drawerOpen } };
- } else {
- return { ...drawer, ...drawerClose, '& .MuiPaper-root': { ...drawerClose } };
- }
- }}
- {...conditionalProps}
- >
- {contents}
-
-
- );
-}
+ return (
+
+ {
+ const drawer = {
+ width: drawerWidth,
+ flexShrink: 0,
+ background: theme.palette.sidebarBg,
+ };
+
+ const drawerOpen = {
+ width: drawerWidth,
+ transition: theme.transitions.create('width', {
+ easing: theme.transitions.easing.sharp,
+ duration: theme.transitions.duration.enteringScreen,
+ }),
+ background: theme.palette.sidebarBg,
+ };
+
+ const drawerClose = {
+ transition: theme.transitions.create('width', {
+ easing: theme.transitions.easing.sharp,
+ duration: theme.transitions.duration.leavingScreen,
+ }),
+ overflowX: 'hidden',
+ width: '56px',
+ [theme.breakpoints.down('xs')]: {
+ background: 'initial',
+ },
+ [theme.breakpoints.down('sm')]: {
+ width: theme.spacing(0),
+ },
+ [theme.breakpoints.up('sm')]: {
+ width: '72px',
+ },
+ background: theme.palette.sidebarBg,
+ };
+
+ if (
+ (isTemporaryDrawer && temporarySideBarOpen) ||
+ (!isTemporaryDrawer && largeSideBarOpen)
+ ) {
+ return { ...drawer, ...drawerOpen, '& .MuiPaper-root': { ...drawerOpen } };
+ } else {
+ return { ...drawer, ...drawerClose, '& .MuiPaper-root': { ...drawerClose } };
+ }
+ }}
+ {...conditionalProps}
+ >
+ {contents}
+
+
+ );
+ }
+);
export function useSidebarItem(
sidebarDesc: string | null | { item: string | null; sidebar?: string }