Skip to content

Commit 918e65b

Browse files
authored
Export standalone Navbar and add possibility to do not render Sidebar (#72)
1 parent ac5d060 commit 918e65b

10 files changed

Lines changed: 83 additions & 195 deletions

File tree

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,7 @@ yarn-error.log*
2525

2626
coverage
2727

28-
storybook-static
28+
storybook-static
29+
30+
# Ignore vs folder
31+
.vs

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Possibility to render the whole PanelSidebarLayout hiding completely the SidebarNav.
13+
- Export for `PanelSidebarNavbar` component. It can be used to render only the Navbar without need of context.
14+
1015
## [5.1.0] - 2025-06-11
1116

1217
### Changed

package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
"copy-sass": "shx cp -r styles dist/scss",
4040
"lint": "eslint --cache",
4141
"prepack": "yarn build",
42-
"prepare-pr": "yarn prettier . --write && yarn lint && yarn build && yarn test\"",
42+
"prepare-pr": "yarn prettier . --write && yarn lint && yarn build",
4343
"prettier-check": "prettier --check .",
4444
"start": "rollup -c -w",
4545
"start-all": "concurrently \"yarn start\" \"yarn start-yalc\"",
@@ -62,8 +62,6 @@
6262
"@types/node": "^18.16.3",
6363
"@types/react": "^18.2.5",
6464
"@types/react-dom": "^18.2.3",
65-
"@typescript-eslint/eslint-plugin": "^5.59.2",
66-
"@typescript-eslint/parser": "^5.59.2",
6765
"bootstrap": "^5.2.3",
6866
"concurrently": "^8.0.1",
6967
"cross-env": "^7.0.3",

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export * from "./lib/Layout/AuthenticationLayout";
22
export * from "./lib/Paging/Paging";
33

44
// Panel sidebar layout
5+
export { PanelSidebarNavbar, PanelSidebarNavbarProps } from "./lib/Layout/PanelSideBarLayout/PanelSideBarNavbar";
56
export * from "./lib/Layout/PanelSideBarLayout/PanelSideBarLayout";
67
export * from "./lib/Layout/PanelSideBarLayout/PanelSideBar/Context/PanelSideBarContext";
78
export * from "./lib/Layout/PanelSideBarLayout/PanelSideBar/Definitions/PanelItem";

src/lib/Layout/PanelSideBarLayout/PanelSideBar/Context/PanelSideBarContextProps.ts

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,24 @@ import { PanelItem } from "../Definitions/PanelItem";
33
import { PanelLinkRenderer } from "../Definitions/PanelLinkRenderer";
44
import { MenuItemToggleFn } from "./PanelSideBarContext";
55

6-
export interface PanelSideBarContextProps<TPanelItemId extends string, TPanelItem> {
6+
export interface SidebarProps {
7+
/**
8+
* If the sidebar is currently open or not
9+
*/
10+
isSidebarOpen: boolean;
11+
12+
/**
13+
* Function for toggling sidebar
14+
*/
15+
toggleSidebar: () => void;
16+
17+
/**
18+
* The theme
19+
*/
20+
theme?: "light" | "dark" | "blue";
21+
}
22+
23+
export interface PanelSideBarContextProps<TPanelItemId extends string, TPanelItem> extends SidebarProps {
724
/**
825
* The active panel id.
926
*/
@@ -37,20 +54,6 @@ export interface PanelSideBarContextProps<TPanelItemId extends string, TPanelIte
3754
*/
3855
untoggleMenuItems: () => void;
3956

40-
/**
41-
* If the sidebar is currently open or not
42-
*/
43-
isSidebarOpen: boolean;
44-
/**
45-
* Function for toggling sidebar
46-
*/
47-
toggleSidebar: () => void;
48-
49-
/**
50-
* The theme
51-
*/
52-
theme?: "light" | "dark" | "blue";
53-
5457
/**
5558
* Boolean indicating if you want to render first items level as icons or directly as menu entries
5659
*/

src/lib/Layout/PanelSideBarLayout/PanelSideBarLayout.tsx

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import "../../../../styles/Layout/index.scss";
44
import { PanelSideBar } from "./PanelSideBar/PanelSidebar";
55
import { PanelSideBarLayoutContent } from "./PanelSideBarLayoutContent";
66
import { PanelSideBarToggle } from "./PanelSideBar/PanelSideBarToggle";
7-
import { PanelSidebarNavbar } from "./PanelSideBarNavbar";
7+
import { PanelSidebarNavbarInternal, PanelSidebarNavbarInternalProps } from "./PanelSideBarNavbar";
88
import { usePanelSideBarContext } from "./PanelSideBar/Context/PanelSideBarContext";
99

1010
export interface PanelSideBarLayoutProps extends PropsWithChildren {
@@ -38,8 +38,19 @@ export interface PanelSideBarLayoutProps extends PropsWithChildren {
3838
* If use the responsive layout when the screen is sm in order to remove the sidebar overlay.
3939
*/
4040
useResponsiveLayout?: boolean;
41+
42+
/**
43+
* If true, exclude the sidebar menu.
44+
*/
45+
excludeSibebarMenu?: boolean;
4146
}
4247

48+
const PanelSidebarNavbar = (props: Omit<PanelSidebarNavbarInternalProps, "toggleSidebar" | "theme">) => {
49+
const { toggleSidebar, theme } = usePanelSideBarContext();
50+
51+
return <PanelSidebarNavbarInternal toggleSidebar={toggleSidebar} theme={theme} {...props} />;
52+
};
53+
4354
export const PanelSideBarLayout = <TPanelItemId extends string, TPanelItem>(props: PanelSideBarLayoutProps) => {
4455
const {
4556
brand,
@@ -50,6 +61,7 @@ export const PanelSideBarLayout = <TPanelItemId extends string, TPanelItem>(prop
5061
collapsible = true,
5162
useToggleButton = false,
5263
useResponsiveLayout = false,
64+
excludeSibebarMenu = false,
5365
} = props;
5466

5567
const { isSidebarOpen, toggleSidebar, renderFirstItemsLevelAsTiles, menuItems, activePanelId } = usePanelSideBarContext<
@@ -83,15 +95,23 @@ export const PanelSideBarLayout = <TPanelItemId extends string, TPanelItem>(prop
8395
{ "section-tiles": renderFirstItemsLevelAsTiles },
8496
)}
8597
>
86-
<PanelSideBar<TPanelItemId, TPanelItem> isIconShownOnSidebarCollapse={isIconShownOnSidebarCollapse} />
87-
{collapsible && !useToggleButton && (
88-
<PanelSideBarToggle
89-
onClick={toggleSidebar}
90-
toggled={!isSidebarOpen}
91-
isIconShownOnSidebarCollapse={isIconShownOnSidebarCollapse}
92-
/>
98+
{!excludeSibebarMenu && (
99+
<>
100+
<PanelSideBar<TPanelItemId, TPanelItem> isIconShownOnSidebarCollapse={isIconShownOnSidebarCollapse} />
101+
{collapsible && !useToggleButton && (
102+
<PanelSideBarToggle
103+
onClick={toggleSidebar}
104+
toggled={!isSidebarOpen}
105+
isIconShownOnSidebarCollapse={isIconShownOnSidebarCollapse}
106+
/>
107+
)}
108+
</>
93109
)}
94-
<PanelSideBarLayoutContent footer={footer} isIconShownOnSidebarCollapse={isIconShownOnSidebarCollapse}>
110+
<PanelSideBarLayoutContent
111+
excludeSibebarMenu={excludeSibebarMenu}
112+
footer={footer}
113+
isIconShownOnSidebarCollapse={isIconShownOnSidebarCollapse}
114+
>
95115
{children}
96116
</PanelSideBarLayoutContent>
97117
</section>

src/lib/Layout/PanelSideBarLayout/PanelSideBarLayoutContent.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,18 @@ import { usePanelSideBarContext } from "./PanelSideBar/Context/PanelSideBarConte
55
interface PanelSideBarLayoutContentProps extends PropsWithChildren {
66
footer?: ReactNode;
77
isIconShownOnSidebarCollapse: boolean;
8+
excludeSibebarMenu: boolean;
89
}
910

1011
export const PanelSideBarLayoutContent = (props: PanelSideBarLayoutContentProps) => {
11-
const { children, footer, isIconShownOnSidebarCollapse } = props;
12+
const { children, footer, isIconShownOnSidebarCollapse, excludeSibebarMenu } = props;
1213
const { mainContentBodyRef } = usePanelSideBarContext();
1314

1415
return (
1516
<section
1617
ref={mainContentBodyRef}
1718
id="main-content-body"
18-
className={classNames("content", { "show-icons": isIconShownOnSidebarCollapse })}
19+
className={classNames("content", { "show-icons": isIconShownOnSidebarCollapse }, { "exclude-sidebar-menu": excludeSibebarMenu })}
1920
>
2021
<main className="container-fluid">{children}</main>
2122
<footer hidden={!footer} className="py-4 bg-light mt-auto">

src/lib/Layout/PanelSideBarLayout/PanelSideBarNavbar.tsx

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import { faBars } from "@fortawesome/free-solid-svg-icons";
22
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
33
import { ReactNode } from "react";
44
import { Nav, NavItem } from "reactstrap";
5-
import { usePanelSideBarContext } from "./PanelSideBar/Context/PanelSideBarContext";
65
import classNames from "classnames";
6+
import { SidebarProps } from "./PanelSideBar/Context/PanelSideBarContextProps";
77

8-
interface PanelSidebarNavbarProps {
8+
export interface PanelSidebarNavbarInternalProps extends Pick<Partial<SidebarProps>, "theme" | "toggleSidebar"> {
99
/**
1010
* The brand content shown on the top navigation bar.
1111
*/
@@ -25,9 +25,13 @@ interface PanelSidebarNavbarProps {
2525
useToggleButton?: boolean;
2626
}
2727

28-
const PanelSidebarNavbar = (props: PanelSidebarNavbarProps) => {
29-
const { brand, navbarRightItems, navbarLeftItems, useToggleButton } = props;
30-
const { toggleSidebar, theme } = usePanelSideBarContext();
28+
const PanelSidebarNavbarInternal = (props: PanelSidebarNavbarInternalProps) => {
29+
const { brand, navbarRightItems, navbarLeftItems, useToggleButton, toggleSidebar, theme } = props;
30+
31+
if (useToggleButton && !toggleSidebar) {
32+
throw new Error("You must provide the toggleSidebar function when useToggleButton is true.");
33+
}
34+
3135
return (
3236
<nav
3337
id="nav-top"
@@ -40,7 +44,7 @@ const PanelSidebarNavbar = (props: PanelSidebarNavbarProps) => {
4044
>
4145
<div className="navbar-brand">{brand}</div>
4246
{useToggleButton && (
43-
<button id="sidebar-toggle" className="btn btn-link btn-sm order-0 me-lg-0" onClick={() => toggleSidebar()}>
47+
<button id="sidebar-toggle" className="btn btn-link btn-sm order-0 me-lg-0" onClick={() => toggleSidebar && toggleSidebar()}>
4448
<FontAwesomeIcon icon={faBars} size="2x" />
4549
</button>
4650
)}
@@ -64,4 +68,10 @@ const PanelSidebarNavbar = (props: PanelSidebarNavbarProps) => {
6468
);
6569
};
6670

67-
export { PanelSidebarNavbar };
71+
export type PanelSidebarNavbarProps = Omit<PanelSidebarNavbarInternalProps, "toggleSidebar" | "useToggleButton">;
72+
73+
const PanelSidebarNavbar = (props: PanelSidebarNavbarProps) => {
74+
return <PanelSidebarNavbarInternal {...props} useToggleButton={false} />;
75+
};
76+
77+
export { PanelSidebarNavbarInternal, PanelSidebarNavbar };

styles/Layout/_PanelSideBarLayout.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ section.content:first-of-type {
4747
justify-content: space-between;
4848
display: flex;
4949
position: relative;
50+
51+
&.exclude-sidebar-menu {
52+
margin-left: 0rem;
53+
}
5054
}
5155

5256
#side-nav.panel-layout {

0 commit comments

Comments
 (0)