Refactor: remove hasSubmenu prop and move submenuTitle prop to submenu component
Signed-off-by: hiba-aldalaty <hibaaldalaty@gmail.com>
This commit is contained in:
@@ -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..." />
|
||||
|
||||
Reference in New Issue
Block a user