Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
Michele-Masciave committed Oct 17, 2024
1 parent 5797ddc commit 2fb38e8
Show file tree
Hide file tree
Showing 9 changed files with 56 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ export const PanelSideBarProvider = <TPanelItemId extends string, TPanelItem>(
);
};

const activePanelShowIconsOnCollapse = menuItems.find((x) => x.id === activePanelId)?.showIconsOnCollapse ?? false;

return (
<PanelSideBarContext.Provider
value={{
Expand All @@ -106,6 +108,7 @@ export const PanelSideBarProvider = <TPanelItemId extends string, TPanelItem>(
closeMenuItems,
hiddenMenuItemIds,
setHiddenMenuItemsIds,
activePanelShowIconsOnCollapse,
}}
>
{children}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,9 @@ export interface PanelSideBarContextProps<TPanelItemId extends string, TPanelIte
* @param includeActivePanel whether needs to include the active panel
*/
closeMenuItems: (panelItemIds: TPanelItemId[], includeActivePanel?: boolean) => void;

/**
* Whether the sidebar maintains the active panel item icons visible on collapsing.
*/
activePanelShowIconsOnCollapse?: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,9 @@ export type PanelItem<TPanelItemId extends string, TPanelItem = Record<string, u
* Whether collapse only with icon.
*/
collapseIconOnly?: boolean;

/**
* Whether the sidebar maintains the panel items icons visible on collapsing.
*/
showIconsOnCollapse?: boolean;
};
45 changes: 24 additions & 21 deletions src/lib/Layout/PanelSideBarLayout/PanelSideBar/PanelSideBarItem.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import classNames from "classnames";
import { useRef, useEffect } from "react";
import { useRef, useEffect, ReactNode } from "react";
import { Collapse, NavItem } from "reactstrap";
import { PanelItem } from "./../PanelSideBar/Definitions/PanelItem";
import { usePanelSideBarContext } from "./Context/PanelSideBarContext";
import { hasActiveChildren } from "./Utils/getActivePanel";
import { IconProp } from "@fortawesome/fontawesome-svg-core";

export interface PanelSideBarItemProps<TPanelItemId extends string, TPanelItem> {
children: PanelItem<TPanelItemId, TPanelItem>;
Expand All @@ -13,14 +14,25 @@ export interface PanelSideBarItemProps<TPanelItemId extends string, TPanelItem>
isParentHidden?: boolean;
}

const PanelSidebarItemNavLink = ({ icon, title, collapsedWithIcons }: { icon?: IconProp, title: ReactNode, collapsedWithIcons?: boolean }) => {
const iconClassName = collapsedWithIcons ? "ms-1 me-3 p-1" : "me-2";
return (
<span className="nav-link">
{icon && <FontAwesomeIcon icon={icon} className={iconClassName} />}
{collapsedWithIcons && icon ? "" : title}
</span>
);
}

// eslint-disable-next-line complexity
const PanelSideBarItem = <TPanelItemId extends string, TPanelItem>(props: PanelSideBarItemProps<TPanelItemId, TPanelItem>) => {
const { depth = 0, children: item, isParentHidden = false } = props;
const { LinkRenderer, toggledMenuItemIds, toggleMenuItem, hiddenMenuItemIds } = usePanelSideBarContext<TPanelItemId, TPanelItem>();
const hasitem = !!item.children?.length;
const isActive = (hasitem && item.children && hasActiveChildren(item.children)) || item.active;
const { LinkRenderer, toggledMenuItemIds, toggleMenuItem, hiddenMenuItemIds, activePanelShowIconsOnCollapse, isSidebarOpen } = usePanelSideBarContext<TPanelItemId, TPanelItem>();
const hasItems = !!item.children?.length;
const isActive = (hasItems && item.children && hasActiveChildren(item.children)) || item.active;
const isOpen = toggledMenuItemIds?.includes(item.id);
const scrollToActiveItemRef = useRef<HTMLDivElement>(null);
const collapsedWithIcons = activePanelShowIconsOnCollapse && !isSidebarOpen;

useEffect(() => {
if (scrollToActiveItemRef.current && isActive) {
Expand All @@ -33,55 +45,46 @@ const PanelSideBarItem = <TPanelItemId extends string, TPanelItem>(props: PanelS
<NavItem
hidden={isParentHidden || hiddenMenuItemIds.includes(item.id)}
onClick={() => {
if (hasitem && !item.collapseIconOnly) {
if (hasItems && !item.collapseIconOnly) {
toggleMenuItem(item.id);
}
}}
className={classNames({ "menu-open": isOpen, active: isActive })}
style={{ paddingLeft: depth ? `${depth + 1}rem` : undefined }}
style={{ paddingLeft: !collapsedWithIcons && depth ? `${depth + 1}rem` : undefined }}
>
<div ref={scrollToActiveItemRef}>
{hasitem ? (
{hasItems ? (
<div className={classNames("d-flex flex-row", { "justify-content-between": item.collapseIconOnly })}>
{item.collapseIconOnly && (
<LinkRenderer item={item}>
<span className="nav-link">
{item.icon && <FontAwesomeIcon icon={item.icon} className="me-2" />}
{item.title}
</span>
<PanelSidebarItemNavLink icon={item.icon} title={item.title} collapsedWithIcons={collapsedWithIcons} />
</LinkRenderer>
)}

<a
role="button"
className={classNames("nav-link", { "w-100": !item.collapseIconOnly }, { "dropdown-toggle": hasitem })}
className={classNames("nav-link", { "w-100": !item.collapseIconOnly }, { "dropdown-toggle": hasItems && !collapsedWithIcons })}
onClick={() => {
if (item.collapseIconOnly) {
toggleMenuItem(item.id);
}
}}
>
{!item.collapseIconOnly && (
<span>
{item.icon && <FontAwesomeIcon className="me-2" icon={item.icon} />}
{item.title}
</span>
<PanelSidebarItemNavLink icon={item.icon} title={item.title} collapsedWithIcons={collapsedWithIcons} />
)}
</a>
</div>
) : (
<>
<LinkRenderer item={item}>
<span className="nav-link">
{item.icon && <FontAwesomeIcon icon={item.icon} className="me-2" />}
{item.title}
</span>
<PanelSidebarItemNavLink icon={item.icon} title={item.title} collapsedWithIcons={collapsedWithIcons} />
</LinkRenderer>
</>
)}
</div>
</NavItem>
{hasitem && (
{hasItems && (
<Collapse isOpen={isOpen} navbar className={classNames("item-menu", { "mb-1": isOpen })}>
{item.children?.map((childItem) => (
<PanelSideBarItem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface PanelSideBarToggleProps extends ButtonProps {

export const PanelSideBarToggle = (props: PanelSideBarToggleProps) => {
const { toggled, ...buttonProps } = props;
const { theme } = usePanelSideBarContext();
const { theme, activePanelShowIconsOnCollapse } = usePanelSideBarContext();

return (
<Button
Expand All @@ -19,6 +19,7 @@ export const PanelSideBarToggle = (props: PanelSideBarToggleProps) => {
{ "side-nav-toggle-dark": theme == "dark" },
{ "side-nav-toggle-light": theme == "light" },
{ "side-nav-toggle-blue": theme == "blue" },
{ "show-icons": activePanelShowIconsOnCollapse },
)}
id="side-nav-toggle"
color="primary"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ export const PanelSideBar = <TPanelItemId extends string, TPanelItem>() => {
LinkRenderer,
theme,
hiddenMenuItemIds,
activePanelShowIconsOnCollapse,
} = usePanelSideBarContext<TPanelItemId, TPanelItem>();

const className = classNames(
"panel-layout",
{ "sidenav-dark": theme == "dark" },
{ "sidenav-light": theme == "light" },
{ "sidenav-blue": theme == "blue" },
{ "show-icons": activePanelShowIconsOnCollapse }
);

const activePanel: PanelItem<TPanelItemId, TPanelItem> | undefined = menuItems.find((x) => x.id === activePanelId);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import classNames from "classnames";
import { MutableRefObject, PropsWithChildren, ReactNode } from "react";
import { usePanelSideBarContext } from "./PanelSideBar/Context/PanelSideBarContext";

interface PanelSideBarLayoutContentProps extends PropsWithChildren {
footer?: ReactNode;
Expand All @@ -7,9 +9,10 @@ interface PanelSideBarLayoutContentProps extends PropsWithChildren {

export const PanelSideBarLayoutContent = (props: PanelSideBarLayoutContentProps) => {
const { children, footer, mainContentBodyRef } = props;
const { activePanelShowIconsOnCollapse } = usePanelSideBarContext();

return (
<section ref={mainContentBodyRef} id="main-content-body" className="content">
<section ref={mainContentBodyRef} id="main-content-body" className={classNames("content", { "show-icons": activePanelShowIconsOnCollapse })}>
<main className="container-fluid">{children}</main>
<footer hidden={!footer} className="py-4 bg-light mt-auto">
<div className="mx-4">
Expand Down
13 changes: 10 additions & 3 deletions styles/Layout/_PanelSideBarLayout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -403,12 +403,13 @@ section.content:first-of-type {
}

@include media-breakpoint-up(xs) {
$toggled-width: #{$tile-size + $slim-scrollbar-base-width};

.section-tiles.toggled {
> #side-nav {
transition: $sidebar-transition;
width: $tile-size;
width: #{$tile-size};
&.show-icons {
width: #{$tile-size + $sidenav-items-icon-width};
}

li.nav-item {
&.active {
Expand All @@ -422,11 +423,17 @@ section.content:first-of-type {
> #side-nav-toggle {
transition: $sidebar-transition;
left: #{$tile-size};
&.show-icons {
left: #{$tile-size + $sidenav-items-icon-width};
}
}

> section.content:first-of-type {
transition: #{margin $sidebar-transition};
margin-left: #{$tile-size + $toggle-base-width};
&.show-icons {
margin-left: #{$tile-size + $toggle-base-width + $sidenav-items-icon-width};
}

.dropdown-toggle::after {
display: none;
Expand Down
1 change: 1 addition & 0 deletions styles/Layout/variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ $slim-scrollbar-base-width: 0.25rem;

$sidenav-base-width: 16rem;
$sidenav-max-width: $sidenav-base-width;
$sidenav-items-icon-width: 2.8rem;

$toggle-base-width: 1rem; // used for toggle as bar
$toggle-btn-size: 2.5rem; // used for toggle as button
Expand Down

0 comments on commit 2fb38e8

Please sign in to comment.