Refactor: remove hasSubmenu prop and move submenuTitle prop to submenu component

Signed-off-by: hiba-aldalaty <hibaaldalaty@gmail.com>
This commit is contained in:
hiba-aldalaty
2021-11-22 13:50:32 +00:00
parent 4894049dfe
commit 18b089cdcc
3 changed files with 77 additions and 74 deletions
@@ -25,34 +25,31 @@ import { MiscIcon } from './icons/MiscIcon';
import { Sidebar, SidebarExpandButton } from './Bar';
import { SidebarItem, SidebarSearchField } from './Items';
import { SidebarSubItem } from './SidebarSubItem';
import { Submenu } from './Submenu';
async function renderScalableSidebar() {
await renderInTestApp(
<Sidebar disableExpandOnHover>
<SidebarSearchField onSearch={() => {}} to="/search" />
<SidebarItem
icon={CatalogSidebarLogo}
onClick={() => {}}
text="Catalog"
hasSubMenu
submenuTitle="Catalog"
>
<SidebarSubItem title="Tools" to="/1" icon={BuildRoundedIcon} />
<SidebarSubItem
title="Misc"
to="/6"
icon={MiscIcon}
dropdownItems={[
{
title: 'dropdown item 1',
to: '/dropdownitemlink',
},
{
title: 'dropdown item 2',
to: '/dropdownitemlink2',
},
]}
/>
<SidebarItem icon={CatalogSidebarLogo} onClick={() => {}} text="Catalog">
<Submenu title="Catalog">
<SidebarSubItem title="Tools" to="/1" icon={BuildRoundedIcon} />
<SidebarSubItem
title="Misc"
to="/6"
icon={MiscIcon}
dropdownItems={[
{
title: 'dropdown item 1',
to: '/dropdownitemlink',
},
{
title: 'dropdown item 2',
to: '/dropdownitemlink2',
},
]}
/>
</Submenu>
</SidebarItem>
<SidebarItem icon={CreateComponentIcon} to="create" text="Create..." />
<SidebarExpandButton />
@@ -28,7 +28,6 @@ import React, {
Children,
forwardRef,
KeyboardEventHandler,
PropsWithChildren,
ReactNode,
useContext,
useState,
@@ -170,27 +169,30 @@ const useStyles = makeStyles<BackstageTheme>(
type ItemWithSubmenuProps = {
label?: string;
title?: string;
hasNotifications?: boolean;
icon: IconComponent;
children: ReactNode;
submenu: ReactNode;
};
const ItemWithSubmenu = ({
label,
title,
hasNotifications = false,
icon: Icon,
children,
}: PropsWithChildren<ItemWithSubmenuProps>) => {
submenu,
}: ItemWithSubmenuProps) => {
const classes = useStyles();
const [isHoveredOn, setIsHoveredOn] = useState(false);
const toPathnames: string[] = [];
let submenuItems: ReactNode;
Children.forEach(submenu, element => {
if (!React.isValidElement(element)) return;
submenuItems = element.props.children;
});
const toPathnames: string[] = [];
let isActive;
const { pathname: locationPathname } = useLocation();
// Menu item is active if any of its children have active paths
Children.forEach(children, element => {
// SidebarItem is active if any of submenu items have active paths
Children.forEach(submenuItems, element => {
if (!React.isValidElement(element)) return;
if (element.props.dropdownItems) {
element.props.dropdownItems.map((item: { to: string }) =>
@@ -267,7 +269,7 @@ const ItemWithSubmenu = ({
<ArrowRightIcon fontSize="small" className={classes.submenuArrow} />
)}
</div>
{isHoveredOn && <Submenu title={title}>{children}</Submenu>}
{isHoveredOn && submenu}
</div>
</ItemWithSubmenuContext.Provider>
);
@@ -277,8 +279,6 @@ type SidebarItemBaseProps = {
icon: IconComponent;
text?: string;
hasNotifications?: boolean;
hasSubMenu?: boolean;
submenuTitle?: string;
disableHighlight?: boolean;
children?: ReactNode;
className?: string;
@@ -354,8 +354,6 @@ export const SidebarItem = forwardRef<any, SidebarItemProps>((props, ref) => {
icon: Icon,
text,
hasNotifications = false,
hasSubMenu = false,
submenuTitle,
disableHighlight = false,
onClick,
children,
@@ -409,17 +407,28 @@ export const SidebarItem = forwardRef<any, SidebarItemProps>((props, ref) => {
),
};
// If submenu prop is true, return ItemWithSubmenu
if (hasSubMenu) {
let hasSubmenu = false;
let submenu: any;
const componentType = (
<Submenu>
<></>
</Submenu>
).type;
Children.forEach(children, element => {
if (!React.isValidElement(element)) return;
if (element.type === componentType) {
submenu = element;
hasSubmenu = true;
}
});
if (hasSubmenu) {
return (
<ItemWithSubmenu
label={text}
title={submenuTitle}
icon={Icon}
hasNotifications={hasNotifications}
>
{children}
</ItemWithSubmenu>
submenu={submenu}
/>
);
}
@@ -35,6 +35,7 @@ import { CatalogSidebarLogo } from './icons/CatalogSidebarLogo';
import { APIsIcon } from './icons/APIsIcon';
import { ServicesIcon } from './icons/ServicesIcon';
import { MiscIcon } from './icons/MiscIcon';
import { Submenu } from './Submenu';
export default {
title: 'Layout/Sidebar',
@@ -67,37 +68,33 @@ export const SampleScalableSidebar = () => (
<Sidebar disableExpandOnHover>
<SidebarSearchField onSearch={handleSearch} to="/search" />
<SidebarDivider />
<SidebarItem
icon={CatalogSidebarLogo}
onClick={() => {}}
text="Catalog"
hasSubMenu
submenuTitle="Catalog"
>
<SidebarSubItem title="Tools" to="/1" icon={BuildRoundedIcon} />
<SidebarSubItem title="APIs" to="/2" icon={APIsIcon} />
<SidebarSubItem title="Services" to="/3" icon={ServicesIcon} />
<SidebarSubItem
title="Libraries"
to="/4"
icon={LibraryBooksOutlinedIcon}
/>
<SidebarSubItem title="Websites" to="/5" icon={WebOutlinedIcon} />
<SidebarSubItem
title="Misc"
to="/6"
icon={MiscIcon}
dropdownItems={[
{
title: 'Lorem Ipsum',
to: '/7',
},
{
title: 'Lorem Ipsum',
to: '/8',
},
]}
/>
<SidebarItem icon={CatalogSidebarLogo} onClick={() => {}} text="Catalog">
<Submenu title="Catalog">
<SidebarSubItem title="Tools" to="/1" icon={BuildRoundedIcon} />
<SidebarSubItem title="APIs" to="/2" icon={APIsIcon} />
<SidebarSubItem title="Services" to="/3" icon={ServicesIcon} />
<SidebarSubItem
title="Libraries"
to="/4"
icon={LibraryBooksOutlinedIcon}
/>
<SidebarSubItem title="Websites" to="/5" icon={WebOutlinedIcon} />
<SidebarSubItem
title="Misc"
to="/6"
icon={MiscIcon}
dropdownItems={[
{
title: 'Lorem Ipsum',
to: '/7',
},
{
title: 'Lorem Ipsum',
to: '/8',
},
]}
/>
</Submenu>
</SidebarItem>
<SidebarItem icon={HomeOutlinedIcon} to="#" text="Plugins" />
<SidebarItem icon={AddCircleOutlineIcon} to="#" text="Create..." />