Skip to content

Commit c050d19

Browse files
authored
Add possibility do not render tiles or to render tiles as a link, remove unneeded code (#53)
1 parent 6242b4b commit c050d19

7 files changed

Lines changed: 142 additions & 58 deletions

File tree

CHANGELOG.md

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

88
## [Unreleased]
99

10+
### Added
11+
12+
- Possibility to decide if render first nesting level of menuItems as tiles (default) or not
13+
- Possibility to render tiles as button(default) or as links
14+
- Possibility to define a default active panel used if no active panel is found dynamically
15+
1016
## [3.2.1] - 2024-02-01
1117

1218
### Fixed

src/lib/Layout/PanelSideBarLayout/PanelSideBar/Context/PanelSideBarContext.tsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,20 @@ export interface PanelSideBarContextProps<TPanelItem> {
6969
* The context theme
7070
*/
7171
theme?: "light";
72+
/**
73+
* Boolean indicating if you want to render first items level as icons or directly as menu entries
74+
*/
75+
renderFirstItemsLevelAsTiles?: boolean;
76+
77+
/**
78+
* Boolean indicating if you want to render first level items as links or as button
79+
*/
80+
renderTilesAsLinks?: boolean;
81+
82+
/**
83+
* The default active panel id that will be taken if no active panel is dinamically found
84+
*/
85+
defaultActivePanelId?: string;
7286
}
7387

7488
export const PanelSideBarContext = createContext<PanelSideBarContextProps<any> | null>(null);
@@ -86,6 +100,9 @@ export interface PanelSideBarMenuProviderProps<TPanelItem>
86100
| "topBarLeftCustomItems"
87101
| "localItems"
88102
| "theme"
103+
| "renderFirstItemsLevelAsTiles"
104+
| "renderTilesAsLinks"
105+
| "defaultActivePanelId"
89106
> {
90107
/**
91108
* The children elements.
@@ -105,13 +122,16 @@ export const PanelSideBarProvider = <TPanelItem,>(props: PanelSideBarMenuProvide
105122
userDropDownMenuToggle,
106123
topBarRightCustomItems,
107124
topBarLeftCustomItems,
125+
renderFirstItemsLevelAsTiles = true,
126+
renderTilesAsLinks = false,
108127
theme = "light",
128+
defaultActivePanelId,
109129
} = props;
110130

111131
const activePanel = globalItems.find((x) =>
112132
x.children ? x.children.find((y) => (y.children ? y.children.find((s) => s.active) : y.active)) : x.active,
113133
);
114-
const firstActivePanel = activePanel ?? globalItems.find((x) => x.id);
134+
const firstActivePanel = activePanel ?? globalItems.find((x) => (defaultActivePanelId ? x.id === defaultActivePanelId : x.id));
115135

116136
const getActivePanelId = () => localItems?.at(0)?.id ?? firstActivePanel?.id ?? "";
117137

@@ -155,6 +175,8 @@ export const PanelSideBarProvider = <TPanelItem,>(props: PanelSideBarMenuProvide
155175
topBarLeftCustomItems,
156176
brand,
157177
theme,
178+
renderFirstItemsLevelAsTiles,
179+
renderTilesAsLinks,
158180
}}
159181
>
160182
{children}

src/lib/Layout/PanelSideBarLayout/PanelSideBar/PanelSideBarItem.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,10 @@ export interface PanelSideBarItemProps {
1212
depth?: number;
1313
active?: boolean;
1414
toggledItemIds: string[];
15-
toggledSidebar: boolean;
1615
}
1716

1817
const PanelSideBarItem = (props: PanelSideBarItemProps) => {
19-
const { depth = 0, children: item, LinkRenderer, onClick, toggledItemIds = [], toggledSidebar } = props;
18+
const { depth = 0, children: item, LinkRenderer, onClick, toggledItemIds = [] } = props;
2019

2120
const hasitem = !!item.children?.length;
2221
const isActive = item.children?.find((s) => s.active) || item.active;
@@ -88,7 +87,6 @@ const PanelSideBarItem = (props: PanelSideBarItemProps) => {
8887
depth={depth + 1}
8988
active={item.active}
9089
toggledItemIds={toggledItemIds}
91-
toggledSidebar={toggledSidebar}
9290
/>
9391
))}
9492
</Collapse>

src/lib/Layout/PanelSideBarLayout/PanelSideBar/PanelSidebar.tsx

Lines changed: 80 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,7 @@ import { usePanelSideBarContext } from "./Context/PanelSideBarContext";
55
import { PanelItem } from "./Definitions/PanelItem";
66
import { PanelSideBarItem } from "./PanelSideBarItem";
77

8-
interface PanelSidebarProps {
9-
toggledSidebar: boolean;
10-
}
11-
12-
export const PanelSideBar = (props: PanelSidebarProps) => {
13-
const { toggledSidebar } = props;
8+
export const PanelSideBar = () => {
149
const {
1510
activePanelId,
1611
globalItems,
@@ -19,55 +14,90 @@ export const PanelSideBar = (props: PanelSidebarProps) => {
1914
setActivePanel,
2015
toggledMenuItemIds,
2116
toggleMenuItem,
17+
renderFirstItemsLevelAsTiles,
18+
renderTilesAsLinks,
2219
} = usePanelSideBarContext();
2320
const panelItems = localItems.concat(globalItems);
2421

25-
if (globalItems.find((x) => !x.icon) || localItems.find((x) => !x.icon)) {
26-
throw new Error("Outer panel icon is required");
27-
}
22+
if (renderFirstItemsLevelAsTiles) {
23+
if (globalItems.find((x) => !x.icon) || localItems.find((x) => !x.icon)) {
24+
throw new Error("Outer panel icon is required");
25+
}
2826

29-
const activePanel: PanelItem | undefined = panelItems.find((x) => x.id === activePanelId);
27+
const activePanel: PanelItem | undefined = panelItems.find((x) => x.id === activePanelId);
28+
const ButtonIcon = (props: { item: PanelItem }) => {
29+
const {
30+
item: { disabled, icon, onClick, id, title },
31+
} = props;
32+
return (
33+
<Button
34+
key={id}
35+
color="primary"
36+
outline
37+
className={classNames("tile", { active: activePanelId === id })}
38+
onClick={() => {
39+
if (!renderTilesAsLinks) {
40+
if (onClick) {
41+
onClick();
42+
} else {
43+
setActivePanel(id);
44+
}
45+
}
46+
}}
47+
title={typeof title == "string" ? String(title) : ""}
48+
disabled={disabled}
49+
>
50+
{icon && <FontAwesomeIcon icon={icon} size="lg" fixedWidth />}
51+
</Button>
52+
);
53+
};
3054

31-
const panelItemsRenderer = (items: PanelItem[]) =>
32-
items?.map(({ disabled, icon, onClick, id, title }) => (
33-
<Button
34-
key={id}
35-
color="primary"
36-
outline
37-
className={classNames("tile", { active: activePanelId === id })}
38-
onClick={() => {
39-
if (onClick) {
40-
onClick();
41-
} else {
42-
setActivePanel(id);
43-
}
44-
}}
45-
title={typeof title == "string" ? String(title) : ""}
46-
disabled={disabled}
47-
>
48-
{icon && <FontAwesomeIcon icon={icon} size="lg" fixedWidth />}
49-
</Button>
50-
));
55+
const panelItemsRenderer = (items: PanelItem[]) =>
56+
items?.map((item) =>
57+
renderTilesAsLinks ? (
58+
<LinkRenderer item={item}>
59+
<ButtonIcon item={item} />
60+
</LinkRenderer>
61+
) : (
62+
<ButtonIcon item={item} />
63+
),
64+
);
5165

52-
return (
53-
<nav id="side-nav" className="panel-layout">
54-
<div className="side-nav__tiles">
55-
{panelItemsRenderer(globalItems)}
56-
{panelItemsRenderer(localItems)}
57-
</div>
66+
return (
67+
<nav id="side-nav" className="panel-layout">
68+
<div className="side-nav__tiles">
69+
{panelItemsRenderer(globalItems)}
70+
{panelItemsRenderer(localItems)}
71+
</div>
5872

59-
<div className="side-nav__items">
60-
{activePanel?.children?.map((item) => (
61-
<PanelSideBarItem
62-
key={item.id}
63-
children={item}
64-
LinkRenderer={LinkRenderer}
65-
onClick={(menuItem) => toggleMenuItem(menuItem)}
66-
toggledItemIds={toggledMenuItemIds}
67-
toggledSidebar={toggledSidebar}
68-
/>
69-
))}
70-
</div>
71-
</nav>
72-
);
73+
<div className="side-nav__items">
74+
{activePanel?.children?.map((item) => (
75+
<PanelSideBarItem
76+
key={item.id}
77+
children={item}
78+
LinkRenderer={LinkRenderer}
79+
onClick={(menuItem) => toggleMenuItem(menuItem)}
80+
toggledItemIds={toggledMenuItemIds}
81+
/>
82+
))}
83+
</div>
84+
</nav>
85+
);
86+
} else {
87+
return (
88+
<nav id="side-nav" className="panel-layout">
89+
<div className="side-nav__items">
90+
{panelItems?.map((item) => (
91+
<PanelSideBarItem
92+
key={item.id}
93+
children={item}
94+
LinkRenderer={LinkRenderer}
95+
onClick={(menuItem) => toggleMenuItem(menuItem)}
96+
toggledItemIds={toggledMenuItemIds}
97+
/>
98+
))}
99+
</div>
100+
</nav>
101+
);
102+
}
73103
};

src/lib/Layout/PanelSideBarLayout/PanelSideBarLayout.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export const PanelSideBarLayout = (props: PanelSideBarLayoutProps) => {
3737
userDropDownMenuToggle,
3838
topBarRightCustomItems = [],
3939
topBarLeftCustomItems = [],
40+
renderFirstItemsLevelAsTiles,
4041
} = usePanelSideBarContext();
4142

4243
return (
@@ -75,8 +76,14 @@ export const PanelSideBarLayout = (props: PanelSideBarLayoutProps) => {
7576
</Nav>
7677
</nav>
7778

78-
<section className={classNames({ toggled: !isOpen })}>
79-
<PanelSideBar toggledSidebar={isOpen} />
79+
<section
80+
className={classNames(
81+
{ toggled: !isOpen },
82+
{ "section-no-tiles": !renderFirstItemsLevelAsTiles },
83+
{ "section-tiles": renderFirstItemsLevelAsTiles },
84+
)}
85+
>
86+
<PanelSideBar />
8087
{collapsible && <PanelSideBarToggle onClick={toggleSidebar} toggled={!isOpen} />}
8188
<PanelSideBarLayoutContent footer={footer ?? contextFooter}>{children}</PanelSideBarLayoutContent>
8289
</section>

src/lib/Layout/PanelSideBarLayout/PanelSideBarLayoutContent.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export const PanelSideBarLayoutContent = (props: PanelSideBarLayoutContentProps)
88
const { children, footer } = props;
99

1010
return (
11-
<section className="content">
11+
<section id="main-content-body" className="content">
1212
<main className="container-fluid">{children}</main>
1313
<footer className="py-4 bg-light mt-auto">
1414
<div className="mx-4">

styles/Layout/PanelSideBarLayout.scss

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ section.content:first-of-type {
246246
@include media-breakpoint-up(xs) {
247247
$toggled-width: #{$tile-size + $slim-scrollbar-base-width};
248248

249-
section.toggled {
249+
.section-tiles.toggled {
250250
> #side-nav {
251251
transition: $sidebar-transition;
252252
width: #{$tile-size + $slim-scrollbar-base-width};
@@ -266,4 +266,25 @@ section.content:first-of-type {
266266
}
267267
}
268268
}
269+
270+
.section-no-tiles.toggled {
271+
> #side-nav {
272+
transition: $sidebar-transition;
273+
width: #{$slim-scrollbar-base-width};
274+
}
275+
276+
> #side-nav-toggle {
277+
transition: $sidebar-transition;
278+
left: 0px;
279+
}
280+
281+
> section.content:first-of-type {
282+
transition: #{margin $sidebar-transition};
283+
margin-left: #{$toggle-base-width};
284+
285+
.dropdown-toggle::after {
286+
display: none;
287+
}
288+
}
289+
}
269290
}

0 commit comments

Comments
 (0)