feat: Sidebar overlay.

This commit is contained in:
a.bouhuolia
2021-08-02 09:36:45 +02:00
parent 9dbd128236
commit 1de166bac4
6 changed files with 274 additions and 48 deletions

View File

@@ -145,9 +145,10 @@ export default class MenuItem extends AbstractPureComponent2 {
tagName = "a",
dropdownType,
caretIconSize = 16,
hasSubmenu,
...htmlProps
} = this.props;
const hasSubmenu = children != null;
const intentClass = Classes.intentClass(intent);
const anchorClasses = classNames(

View File

@@ -8,6 +8,11 @@ import { MenuItemLabel } from 'components';
import classNames from 'classnames';
import SidebarOverlay from 'components/SidebarOverlay';
const DEFAULT_ITEM = {
text: '',
href: '',
}
export default function SidebarMenu() {
const history = useHistory();
const location = useLocation();
@@ -17,18 +22,16 @@ export default function SidebarMenu() {
const menuItemsMapper = (list) => {
return list.map((item, index) => {
const children = Array.isArray(item.children)
? menuItemsMapper(item.children)
: null;
const hasChildren = Array.isArray(item.children);
const matchPath = (pathname, path) => {
return item.matchExact
? pathname === path
: pathname.indexOf(path) !== -1;
};
const isActive = item.children
const isActive = (item.children
? item.children.some((c) => matchPath(location.pathname, c.href))
: item.href && matchPath(location.pathname, item.href);
: item.href && matchPath(location.pathname, item.href)) || currentItem ===item;
const handleItemClick = () => {
if (item.href) {
@@ -69,28 +72,34 @@ export default function SidebarMenu() {
text={item.text}
label={maybeRenderLabel(item)}
disabled={item.disabled}
children={children}
dropdownType={item.dropdownType || 'collapse'}
caretIconSize={16}
onClick={handleItemClick}
callapseActive={!!isActive}
itemClassName={classNames({
'is-active': isActive,
'has-icon': !children && item.icon,
'has-icon': !hasChildren && item.icon,
})}
hasSubmenu={hasChildren}
/>
);
});
};
const items = menuItemsMapper(sidebarMenuList);
const handleSidebarOverlayClose = () => {
setIsOpen(false);
}
return (
<div>
<Menu className="sidebar-menu">{items}</Menu>{' '}
<SidebarOverlay
isOpen={isOpen}
label={currentItem?.text || ''}
items={currentItem?.children || []}
onClose={handleSidebarOverlayClose}
/>
</div>
);

View File

@@ -2,24 +2,24 @@ import React from 'react';
import { Overlay } from '@blueprintjs/core';
import { Link } from 'react-router-dom';
import SidebarOverlayContainer from './SidebarOverlayContainer';
interface ISidebarOverlayItem {
text: string;
href: string;
divider?: boolean;
label?: boolean
label?: boolean;
}
interface ISidebarOverlayProps {
isOpen: boolean;
items: ISidebarOverlayItem[];
overlayProps: any;
overlayContainerRef: any;
label: string;
onClose: Function;
}
interface ISidebarOverlayItemProps {
text: string;
href: string;
onLinkClick: Function;
}
interface ISidebarOverlayItemDivider {
@@ -28,16 +28,25 @@ interface ISidebarOverlayItemDivider {
/**
* Sidebar overlay item.
*/
function SidebarOverlayItem({ text, href }: ISidebarOverlayItemProps) {
function SidebarOverlayItem({
text,
href,
onLinkClick,
}: ISidebarOverlayItemProps) {
const handleLinkClick = () => {
onLinkClick && onLinkClick();
};
return (
<div className="sidebar-overlay__item">
<Link to={href}>{text}</Link>
<Link onClick={handleLinkClick} to={href}>
{text}
</Link>
</div>
);
}
interface ISidebarOverlayItemLabel {
text: string;
text: string;
}
function SidebarOverlayLabel({ text }: ISidebarOverlayItemLabel) {
@@ -52,34 +61,75 @@ function SidebarOverlayDivider() {
* Sidebar overlay component.
*/
export default function SidebarOverlay({
isOpen = false,
label,
isOpen: controllerdIsOpen,
onClose,
items,
}: ISidebarOverlayProps) {
//
if (!isOpen) {
const [isEverOpened, setEverOpened] = React.useState(false);
const [isOpen, setIsOpen] = React.useState(controllerdIsOpen);
React.useEffect(() => {
if (controllerdIsOpen && isOpen !== controllerdIsOpen) {
setIsOpen(controllerdIsOpen);
}
}, [controllerdIsOpen, setIsOpen, isOpen]);
React.useEffect(() => {
if (isOpen && !isEverOpened) {
setEverOpened(true);
}
}, [isEverOpened, isOpen]);
if (!isEverOpened) {
return '';
}
// Handle overlay close event.
const handleOverlayClose = () => {
setIsOpen(false);
onClose && onClose();
};
// Handle overlay open event.
const handleOverlayOpen = () => {
setIsOpen(true);
};
// Handle sidebar item link click.
const handleItemClick = () => {
setIsOpen(false);
onClose && onClose();
};
return (
<Overlay
isOpen={isOpen}
portalContainer={document.getElementById('dashboard') || document.body}
onClose={handleOverlayClose}
onClose={handleOverlayClose}
onOpening={handleOverlayOpen}
transitionDuration={200}
backdropClassName={'sidebar-overlay-backdrop'}
>
<div className="sidebar-overlay">
<div className="sidebar-overlay sidebar-overlay-transition">
<SidebarOverlayContainer>
<div className="sidebar-overlay__menu">
{label && (
<>
<SidebarOverlayLabel text={label} />
<SidebarOverlayDivider />
</>
)}
{items.map((item) =>
item.divider ? (
<SidebarOverlayDivider />
) : item.label ? (
<SidebarOverlayLabel text={item.text} />
) : (
<SidebarOverlayItem text={item.text} href={item.href} />
<SidebarOverlayItem
onLinkClick={handleItemClick}
text={item.text}
href={item.href}
/>
),
)}
</div>