Skip to content

Commit d0b5b06

Browse files
authored
Merge pull request #37 from lannodev/refactor/sidebar-menu
Refactor/sidebar menu
2 parents 79cb0ec + 2ba726b commit d0b5b06

File tree

10 files changed

+70
-48
lines changed

10 files changed

+70
-48
lines changed

src/app/core/constants/menu.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@ export class Menu {
1010
icon: 'assets/icons/heroicons/outline/chart-pie.svg',
1111
label: 'Dashboard',
1212
route: '/dashboard',
13-
children: [
14-
{ label: 'Nfts', route: '/dashboard/nfts' },
15-
// { label: 'Podcast', route: '/dashboard/podcast' },
16-
],
13+
children: [{ label: 'Nfts', route: '/dashboard/nfts' }],
1714
},
1815
{
1916
icon: 'assets/icons/heroicons/outline/lock-closed.svg',

src/app/modules/layout/components/navbar/profile-menu/profile-menu.component.html

+11-11
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
<img
66
clickOutside
77
(clickOutside)="isOpen = false"
8-
class="h-9 w-9 rounded-md"
8+
class="size-9 shrink-0 rounded-full border-2 border-green-500"
99
src="https://avatars.githubusercontent.com/u/12519008?v=4"
1010
alt="" />
1111
</button>
1212
<!-- Dropdown -->
1313
<div
1414
[@openClose]="isOpen ? 'open' : 'closed'"
15-
class="bg-background shadow-custom absolute z-20 mt-2 w-60 origin-top-right transform rounded-md py-4 ring-1 ring-transparent ring-opacity-5 transition focus:outline-hidden ltr:right-0 rtl:left-0">
15+
class="bg-background shadow-custom border-muted absolute z-20 mt-2 w-60 origin-top-right transform rounded-md border border-dashed py-4 ring-1 ring-transparent ring-opacity-5 transition focus:outline-hidden ltr:right-0 rtl:left-0">
1616
<div class="flext-row flex items-center px-4 pb-4">
1717
<div class="w-10 shrink-0">
1818
<img class="rounded-md" src="https://avatars.githubusercontent.com/u/12519008?v=4" alt="" />
@@ -25,12 +25,12 @@
2525

2626
<div class="border-border border-b border-dashed"></div>
2727

28-
<ul class="my-2 mx-4 flex flex-col">
28+
<ul class="my-2 mx-2 flex flex-col">
2929
@for (item of profileMenu; track $index) {
3030
<li
3131
routerLink="{{ item.link }}"
3232
:key="$index"
33-
class="text-muted-foreground hover:bg-card hover:text-primary inline-flex cursor-pointer items-center gap-2 rounded-md px-3 py-2 text-xs font-semibold">
33+
class="text-muted-foreground hover:bg-card hover:text-primary inline-flex cursor-pointer items-center gap-2 rounded-md px-2 py-2 text-xs font-semibold">
3434
<svg-icon src="{{ item.icon }}" [svgClass]="'h-5 w-5 text-muted-foreground/50'"> </svg-icon>
3535
{{ item.title }}
3636
</li>
@@ -44,11 +44,11 @@
4444
<div
4545
:key="$index"
4646
(click)="toggleThemeColor(item.name)"
47-
[ngClass]="{ 'border-muted-foreground bg-card': item.name == themeService.theme().color }"
48-
class="focus-visible:ring-ring border-border bg-background text-muted-foreground hover:bg-card hover:text-foreground shadow-xs inline-flex h-8 cursor-pointer items-center justify-start space-x-2 whitespace-nowrap rounded-md border px-3 text-xs font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 disabled:pointer-events-none disabled:opacity-50">
47+
[ngClass]="{ 'border-muted-foreground/30 bg-card': item.name == themeService.theme().color }"
48+
class="focus-visible:ring-ring border-border bg-background text-muted-foreground hover:bg-card hover:text-foreground shadow-xs inline-flex h-8 cursor-pointer items-center justify-start space-x-2 whitespace-nowrap rounded-md border border-dashed px-3 text-xs font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 disabled:pointer-events-none disabled:opacity-50">
4949
<span
5050
[style.backgroundColor]="item.code"
51-
class="flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-rose-500"></span>
51+
class="flex h-5 w-5 shrink-0 items-center justify-center rounded-full"></span>
5252
<p class="capitalize">{{ item.name }}</p>
5353
</div>
5454
}
@@ -61,8 +61,8 @@
6161
<div
6262
:key="$index"
6363
(click)="toggleThemeMode()"
64-
[ngClass]="{ 'border-muted-foreground bg-card': item == themeService.theme().mode }"
65-
class="focus-visible:ring-ring border-border bg-background text-muted-foreground hover:bg-card hover:text-foreground shadow-xs inline-flex h-8 cursor-pointer items-center justify-start space-x-2 whitespace-nowrap rounded-md border px-3 text-xs font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 disabled:pointer-events-none disabled:opacity-50">
64+
[ngClass]="{ 'border-muted-foreground/30 bg-card': item == themeService.theme().mode }"
65+
class="focus-visible:ring-ring border-border bg-background text-muted-foreground hover:bg-card hover:text-foreground shadow-xs inline-flex h-8 cursor-pointer items-center justify-start space-x-2 whitespace-nowrap rounded-md border border-dashed px-3 text-xs font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 disabled:pointer-events-none disabled:opacity-50">
6666
<svg-icon
6767
[src]="
6868
item == 'light' ? 'assets/icons/heroicons/outline/sun.svg' : 'assets/icons/heroicons/outline/moon.svg'
@@ -81,8 +81,8 @@
8181
<div
8282
:key="$index"
8383
(click)="setDirection(item)"
84-
[ngClass]="{ 'border-muted-foreground bg-card': item == themeService.theme().direction }"
85-
class="focus-visible:ring-ring border-border bg-background text-muted-foreground hover:bg-card hover:text-foreground shadow-xs inline-flex h-8 cursor-pointer items-center justify-start space-x-2 whitespace-nowrap rounded-md border px-3 text-xs font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 disabled:pointer-events-none disabled:opacity-50">
84+
[ngClass]="{ 'border-muted-foreground/30 bg-card': item == themeService.theme().direction }"
85+
class="focus-visible:ring-ring border-border bg-background text-muted-foreground hover:bg-card hover:text-foreground shadow-xs inline-flex h-8 cursor-pointer items-center justify-start space-x-2 whitespace-nowrap rounded-md border border-dashed px-3 text-xs font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 disabled:pointer-events-none disabled:opacity-50">
8686
<svg-icon
8787
[src]="
8888
item == 'ltr'

src/app/modules/layout/components/sidebar/sidebar-menu/sidebar-menu.component.html

+11-8
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
{{ menu.group }}
55
</small>
66
</div>
7-
<ul class="flex flex-col space-y-1">
7+
<ul class="flex flex-col">
88
<!-- List items -->
99
<li *ngFor="let item of menu.items">
1010
<!-- Menu List -->
@@ -26,7 +26,7 @@
2626
<ng-template #parentMenu let-item="item">
2727
<div
2828
routerLink="{{ item.route }}"
29-
class="text-muted-foreground hover:bg-card hover:text-foreground flex h-9 cursor-pointer items-center justify-start rounded-sm">
29+
class="text-muted-foreground hover:text-primary flex h-[36px] cursor-pointer items-center justify-start rounded-sm">
3030
<a
3131
routerLinkActive="text-primary"
3232
class="ms-10 truncate text-xs font-semibold tracking-wide focus:outline-hidden">
@@ -37,9 +37,9 @@
3737

3838
<!-- Workaround:: Disable routerLink -->
3939
<ng-template #childMenu let-item="item">
40-
<div class="hover:bg-card flex h-9 cursor-pointer items-center justify-start rounded-sm">
40+
<div class="flex h-[36px] cursor-pointer items-center justify-start rounded-sm">
4141
<a
42-
class="text-muted-foreground group-hover:text-foreground ms-10 truncate text-xs font-semibold tracking-wide focus:outline-hidden">
42+
class="text-muted-foreground group-hover:text-primary ms-10 truncate text-xs font-semibold tracking-wide focus:outline-hidden">
4343
{{ item.label }}
4444
</a>
4545
</div>
@@ -48,10 +48,13 @@
4848
<!-- Arrow Icon -->
4949
<button
5050
*ngIf="item.children"
51-
[ngClass]="{ hidden: !menuService.showSideBar, 'ltr:rotate-90 rtl:rotate-[-90deg]': item.expanded }"
52-
class="text-muted-foreground/50 pointer-events-none absolute top-1 flex items-center p-1 transition-all duration-500 ltr:right-0 rtl:left-0">
53-
<svg-icon src="assets/icons/heroicons/solid/chevron-right.svg" [svgClass]="'h-5 w-5 rtl:rotate-180'">
54-
</svg-icon>
51+
[ngClass]="{ hidden: !menuService.showSideBar }"
52+
class="text-foreground/50 pointer-events-none absolute top-1 mx-1 flex items-center p-1 transition-all duration-500 ltr:right-0 rtl:left-0">
53+
@if(!item.expanded){
54+
<svg-icon src="assets/icons/heroicons/outline/plus.svg" svgClass="h-4 w-4"> </svg-icon>
55+
}@else {
56+
<svg-icon src="assets/icons/heroicons/outline/minus.svg" svgClass="h-4 w-4"> </svg-icon>
57+
}
5558
</button>
5659

5760
<!-- Tooltip -->
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
<div
2-
class="max-h-0 overflow-hidden pt-1 ps-4 transition-all duration-500"
2+
class="ps-4 max-h-0 overflow-hidden pt-1 transition-all duration-500"
33
[ngClass]="{ hidden: !menuService.showSideBar, 'max-h-screen': submenu.expanded }">
4-
<ul class="border-border text-muted-foreground flex flex-col ltr:border-l rtl:border-r border-dashed ps-2">
4+
<ul class="border-border text-muted-foreground relative flex flex-col border-dashed px-2 ltr:border-l rtl:border-r">
55
<li *ngFor="let sub of submenu.children">
6-
<div class="text-muted-foreground hover:bg-card hover:text-foreground flex rounded-sm" (click)="toggleMenu(sub)">
6+
<!-- <span
7+
class="-start-[3px] rtl:start-0 before:size-[6px] bg-primary absolute flex w-[6px] shrink-0 items-center before:absolute before:top-0 before:-translate-y-1/2 before:rounded-full rtl:before:translate-x-1/2">
8+
</span> -->
9+
10+
<div class="text-muted-foreground hover:text-primary flex rounded-sm" (click)="toggleMenu(sub)">
711
<!-- Condition -->
812
<ng-container
913
[ngTemplateOutlet]="sub.children ? childMenu : parentMenu"
@@ -16,25 +20,36 @@
1620
[routerLink]="sub.route"
1721
routerLinkActive="text-primary"
1822
[routerLinkActiveOptions]="{ exact: true }"
19-
class="inline-block w-full px-4 py-2 text-xs font-semibold">
23+
class="hover:bg-card inline-block w-full px-4 py-2 text-xs">
2024
{{ sub.label }}
2125
</a>
26+
@if(menuService.isActive(sub.route)){
27+
<span
28+
class="size-[6px] bg-primary absolute flex w-[6px] translate-y-[13px] items-center rounded-full ltr:-translate-x-[11px] rtl:translate-x-[11px]">
29+
</span>
30+
}
2231
</ng-template>
2332

2433
<!-- Child Menu -->
2534
<ng-template #childMenu let-sub="sub">
26-
<a class="inline-block w-full cursor-pointer px-4 py-2 text-xs font-semibold">
35+
<a class="inline-block w-full cursor-pointer px-4 py-2 text-xs">
2736
{{ sub.label }}
2837
</a>
2938
<button
30-
[ngClass]="{ hidden: !menuService.showSideBar, 'rotate-90': sub.expanded }"
31-
class="text-muted-foreground flex items-center p-1 transition-all duration-500">
32-
<svg-icon src="assets/icons/heroicons/solid/chevron-right.svg" [svgClass]="'h-5 w-5'"> </svg-icon>
39+
[ngClass]="{ hidden: !menuService.showSideBar }"
40+
class="text-foreground/50 mx- mx-1 flex cursor-pointer items-center p-1 transition-all duration-500">
41+
@if(!sub.expanded){
42+
<svg-icon src="assets/icons/heroicons/outline/plus.svg" svgClass="h-4 w-4"> </svg-icon>
43+
}@else {
44+
<svg-icon src="assets/icons/heroicons/outline/minus.svg" svgClass="h-4 w-4"> </svg-icon>
45+
}
3346
</button>
3447
</ng-template>
3548
</div>
3649
<!-- Submenu items -->
50+
@if(sub.children?.length){
3751
<app-sidebar-submenu [submenu]="sub"></app-sidebar-submenu>
52+
}
3853
</li>
3954
</ul>
4055
</div>

src/app/modules/layout/components/sidebar/sidebar-submenu/sidebar-submenu.component.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ export class SidebarSubmenuComponent implements OnInit {
1616

1717
constructor(public menuService: MenuService) {}
1818

19-
ngOnInit(): void {}
19+
ngOnInit(): void {
20+
console.log(this.submenu);
21+
}
2022

2123
public toggleMenu(menu: any) {
2224
this.menuService.toggleSubMenu(menu);

src/app/modules/layout/components/sidebar/sidebar.component.html

+13-14
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,33 @@
11
<nav
2-
[ngClass]="menuService.showSideBar ? 'w-52 xl:w-64' : 'w-[70px]'"
3-
class="scrollbar-thumb--sm scrollbar-track-rounded bg-background scrollbar-thin scrollbar-track-transparent scrollbar-thumb-card hidden h-full flex-col justify-between overflow-auto pt-3 transition-all duration-300 lg:flex">
4-
<div class="px-4">
2+
[ngClass]="menuService.showSideBar ? 'w-[210px] xl:w-[280px]' : 'w-[70px]'"
3+
class="bg-background hidden h-full flex-col justify-between pt-3 transition-all duration-300 lg:flex">
4+
<div class="overflow-hidden">
55
<!-- Logo -->
6-
<div class="relative h-10">
6+
<div class="relative mx-4 h-9">
77
<div class="flex items-center" *ngIf="menuService.showSideBar">
88
<a
99
(click)="toggleSidebar()"
1010
class="bg-primary flex cursor-pointer items-center justify-center rounded-sm p-2 focus:outline-hidden focus:ring-1">
1111
<svg-icon src="assets/icons/logo.svg"> </svg-icon>
1212
</a>
13-
<b class="text-foreground ml-1 ps-2 text-sm font-bold">
13+
<b class="text-foreground ps-2 ml-1 text-sm font-bold">
1414
{{ appJson.displayName }}
1515
</b>
1616
</div>
1717
<button
1818
(click)="toggleSidebar()"
19-
class="text-muted-foreground/50 hover:text-muted-foreground absolute top-2 rtl:left-2 ltr:right-2 flex h-5 w-5 items-center justify-center rounded-sm transition-all duration-200 focus:outline-hidden"
19+
class="text-muted-foreground/50 hover:text-muted-foreground absolute top-2 flex h-5 w-5 items-center justify-center rounded-sm transition-all duration-200 focus:outline-hidden ltr:right-2 rtl:left-2"
2020
[ngClass]="{ 'rotate-180': !menuService.showSideBar }">
2121
<svg-icon src="assets/icons/heroicons/solid/chevron-double-left.svg"> </svg-icon>
2222
</button>
2323
</div>
2424

25-
<!-- Separator -->
26-
<div class="pt-3">
27-
<hr class="border-muted border-dashed" />
28-
</div>
29-
3025
<!-- Menu Items -->
31-
<app-sidebar-menu></app-sidebar-menu>
26+
<!-- <app-sidebar-menu></app-sidebar-menu> -->
27+
<div
28+
class="scrollbar-thumb--sm scrollbar-track-rounded scrollbar-thin scrollbar-track-transparent scrollbar-thumb-card h-full overflow-auto px-4">
29+
<app-sidebar-menu></app-sidebar-menu>
30+
</div>
3231
</div>
3332

3433
<div class="mx-4 my-4 space-y-1">
@@ -43,12 +42,12 @@
4342
</svg-icon>
4443

4544
<div class="ml-3 truncate text-[10px] font-semibold tracking-wide focus:outline-hidden">
46-
<span class="-sm-lg bg-primary/10 text-primary px-2 font-semibold">v{{ appJson.version }}</span>
45+
<span class="bg-primary/10 text-primary px-2 font-semibold">v{{ appJson.version }}</span>
4746
</div>
4847

4948
<div class="fixed w-full" *ngIf="!menuService.showSideBar">
5049
<span
51-
class="z-1 -sm-md bg-foreground text-background absolute left-12 -top-4 w-auto min-w-max origin-left scale-0 p-2 text-xs font-bold shadow-md transition-all duration-200 group-hover:scale-100">
50+
class="z-1 bg-foreground text-background absolute left-12 -top-4 w-auto min-w-max origin-left scale-0 p-2 text-xs font-bold shadow-md transition-all duration-200 group-hover:scale-100">
5251
v{{ appJson.version }}
5352
</span>
5453
</div>

src/app/modules/layout/services/menu.service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export class MenuService implements OnDestroy {
7575
});
7676
}
7777

78-
private isActive(instruction: any): boolean {
78+
public isActive(instruction: any): boolean {
7979
return this.router.isActive(this.router.createUrlTree([instruction]), {
8080
paths: 'subset',
8181
queryParams: 'subset',
Loading
Loading

tests-e2e/sidebar.e2e.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@ test('check toggle sidebar', async ({ page }) => {
2020
await page.getByRole('navigation').getByRole('button').click();
2121
await page.waitForTimeout(500);
2222
const normalSidebarSizes = await sidebar.boundingBox();
23-
expect(normalSidebarSizes?.width).toBe(256);
23+
expect(normalSidebarSizes?.width).toBe(280);
2424
});

0 commit comments

Comments
 (0)