@elavarasanbititude/ng-cwr-sidebar 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -3,8 +3,9 @@ import { Injectable, EventEmitter, inject, Output, Input, ChangeDetectionStrateg
|
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
4
|
import { CommonModule } from '@angular/common';
|
|
5
5
|
import * as i2 from '@angular/router';
|
|
6
|
-
import { RouterModule } from '@angular/router';
|
|
6
|
+
import { Router, NavigationEnd, RouterModule } from '@angular/router';
|
|
7
7
|
import { BehaviorSubject } from 'rxjs';
|
|
8
|
+
import { filter } from 'rxjs/operators';
|
|
8
9
|
|
|
9
10
|
class SidebarService {
|
|
10
11
|
collapsedSubject = new BehaviorSubject(false);
|
|
@@ -83,37 +84,56 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
83
84
|
class Sidebar {
|
|
84
85
|
menuItems = [];
|
|
85
86
|
config = {};
|
|
87
|
+
collapsed = false;
|
|
88
|
+
logoUrl;
|
|
89
|
+
logoAlt = 'Logo';
|
|
90
|
+
showToggle = true;
|
|
86
91
|
menuItemClicked = new EventEmitter();
|
|
87
92
|
collapsedChange = new EventEmitter();
|
|
93
|
+
itemBadgeClick = new EventEmitter();
|
|
88
94
|
sidebarService = inject(SidebarService);
|
|
95
|
+
router = inject(Router);
|
|
89
96
|
get collapsed$() {
|
|
90
97
|
return this.sidebarService.collapsed$;
|
|
91
98
|
}
|
|
92
99
|
expandedItems = new Set();
|
|
100
|
+
isCollapsed = false;
|
|
93
101
|
defaultConfig = {
|
|
94
102
|
collapsed: false,
|
|
95
103
|
position: 'left',
|
|
96
|
-
width: '
|
|
104
|
+
width: '240px',
|
|
97
105
|
collapsedWidth: '60px',
|
|
98
|
-
backgroundColor: '#
|
|
99
|
-
textColor: '#
|
|
100
|
-
hoverColor: '#
|
|
106
|
+
backgroundColor: '#141F2D',
|
|
107
|
+
textColor: '#3A4D63',
|
|
108
|
+
hoverColor: '#FDFDFD',
|
|
101
109
|
toggleButton: true,
|
|
102
110
|
overlayOnMobile: true,
|
|
103
111
|
};
|
|
104
112
|
ngOnInit() {
|
|
113
|
+
this.isCollapsed = this.collapsed;
|
|
105
114
|
this.sidebarService.setMenuItems(this.menuItems);
|
|
106
115
|
const mergedConfig = { ...this.defaultConfig, ...this.config };
|
|
107
116
|
this.sidebarService.setConfig(mergedConfig);
|
|
117
|
+
// Track router navigation for active state
|
|
118
|
+
this.router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe(() => {
|
|
119
|
+
// Trigger change detection for route changes
|
|
120
|
+
});
|
|
108
121
|
}
|
|
109
|
-
ngOnChanges() {
|
|
110
|
-
if (
|
|
122
|
+
ngOnChanges(changes) {
|
|
123
|
+
if (changes['menuItems'] && !changes['menuItems'].firstChange) {
|
|
111
124
|
this.sidebarService.setMenuItems(this.menuItems);
|
|
112
125
|
}
|
|
126
|
+
if (changes['collapsed']) {
|
|
127
|
+
this.isCollapsed = this.collapsed;
|
|
128
|
+
}
|
|
129
|
+
if (changes['config'] && !changes['config'].firstChange) {
|
|
130
|
+
this.sidebarService.setConfig({ ...this.defaultConfig, ...this.config });
|
|
131
|
+
}
|
|
113
132
|
}
|
|
114
133
|
toggleSidebar() {
|
|
134
|
+
this.isCollapsed = !this.isCollapsed;
|
|
115
135
|
this.sidebarService.toggleCollapsed();
|
|
116
|
-
this.collapsedChange.emit(this.
|
|
136
|
+
this.collapsedChange.emit(this.isCollapsed);
|
|
117
137
|
}
|
|
118
138
|
toggleExpand(item) {
|
|
119
139
|
if (item.children && item.children.length > 0) {
|
|
@@ -136,26 +156,51 @@ class Sidebar {
|
|
|
136
156
|
}
|
|
137
157
|
this.menuItemClicked.emit(item);
|
|
138
158
|
}
|
|
139
|
-
|
|
159
|
+
onBadgeClick(event, item) {
|
|
160
|
+
event.stopPropagation();
|
|
161
|
+
this.itemBadgeClick.emit(item);
|
|
162
|
+
}
|
|
163
|
+
hasChildren(item) {
|
|
140
164
|
return !!(item.children && item.children.length > 0);
|
|
141
165
|
}
|
|
166
|
+
isActiveRoute(item) {
|
|
167
|
+
if (item.isActive) {
|
|
168
|
+
return item.isActive();
|
|
169
|
+
}
|
|
170
|
+
return item.route ? this.router.url.includes(`/${item.route}`) : false;
|
|
171
|
+
}
|
|
142
172
|
getConfig() {
|
|
143
173
|
return this.sidebarService.getConfig();
|
|
144
174
|
}
|
|
175
|
+
closeSidebar() {
|
|
176
|
+
if (!this.isCollapsed) {
|
|
177
|
+
this.toggleSidebar();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
145
180
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: Sidebar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
146
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", type: Sidebar, isStandalone: true, selector: "cwr-sidebar", inputs: { menuItems: "menuItems", config: "config" }, outputs: { menuItemClicked: "menuItemClicked", collapsedChange: "collapsedChange" }, usesOnChanges: true, ngImport: i0, template: "<div
|
|
181
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", type: Sidebar, isStandalone: true, selector: "cwr-sidebar", inputs: { menuItems: "menuItems", config: "config", collapsed: "collapsed", logoUrl: "logoUrl", logoAlt: "logoAlt", showToggle: "showToggle" }, outputs: { menuItemClicked: "menuItemClicked", collapsedChange: "collapsedChange", itemBadgeClick: "itemBadgeClick" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"sidebar d-flex flex-column justify-content-between\" [class.isOpen]=\"!isCollapsed\">\n <div>\n <!-- Logo Section -->\n <div class=\"d-flex justify-content-between logo pe-3 w-100\" *ngIf=\"logoUrl || showToggle\">\n <img *ngIf=\"logoUrl\" [src]=\"logoUrl\" [alt]=\"logoAlt\" />\n <span\n class=\"icon-close_big d-md-none\"\n style=\"color: #fff; cursor: pointer\"\n [class.d-none]=\"isCollapsed\"\n (click)=\"closeSidebar()\"></span>\n </div>\n\n <!-- Navigation Wrapper -->\n <div class=\"nav-wrapper\" role=\"navigation\">\n <ul class=\"active\">\n <li \n *ngFor=\"let item of menuItems\"\n [class.active]=\"isActiveRoute(item)\"\n [class.disabled]=\"item.disabled\"\n >\n <a \n class=\"d-flex align-items-center w-100\"\n [routerLink]=\"item.route\"\n [routerLinkActive]=\"item.isActive ? '' : 'active'\"\n [routerLinkActiveOptions]=\"{ exact: false }\"\n (click)=\"onMenuItemClick(item)\"\n >\n <!-- Icon Section -->\n <div class=\"menu-icon-container\" *ngIf=\"item.icon\">\n <div [innerHTML]=\"item.icon\" class=\"svg-icon\"></div>\n </div>\n\n <!-- Label and Badge -->\n <div class=\"d-flex w-100 justify-content-between align-items-center\">\n <span class=\"nav-label\">{{ item.label }}</span>\n \n <!-- Badge -->\n <span \n class=\"badge-chip\"\n *ngIf=\"item.badge\"\n [style.background-color]=\"item.badge.color || '#28B48C'\"\n (click)=\"onBadgeClick($event, item)\"\n >\n {{ item.badge.text }}\n </span>\n </div>\n </a>\n\n <!-- Submenu -->\n <ul \n class=\"submenu-list\"\n *ngIf=\"hasChildren(item) && isExpanded(item)\"\n >\n <li \n *ngFor=\"let child of item.children\"\n [class.active]=\"isActiveRoute(child)\"\n [class.disabled]=\"child.disabled\"\n >\n <a \n class=\"d-flex align-items-center submenu-link\"\n [routerLink]=\"child.route\"\n [routerLinkActive]=\"child.isActive ? '' : 'active'\"\n [routerLinkActiveOptions]=\"{ exact: false }\"\n (click)=\"onMenuItemClick(child)\"\n >\n <span class=\"nav-label\">{{ child.label }}</span>\n </a>\n </li>\n </ul>\n </li>\n </ul>\n </div>\n </div>\n\n <!-- Logout/Footer Section (optional) -->\n <div class=\"sidebar-footer\" *ngIf=\"!isCollapsed\">\n <slot name=\"footer\"></slot>\n </div>\n</div>\n", styles: [".sidebar{background:#141f2d;box-shadow:0 0 4px #0000001a;min-height:100vh;width:240px;border-right:1px solid #2C4057;font-family:Inter,sans-serif;position:fixed;top:0;left:0;z-index:300;transition:.5s;-webkit-transition:.5s;-moz-transition:.5s;display:flex;flex-direction:column;justify-content:space-between}.sidebar .d-flex{display:flex}.sidebar .flex-column{flex-direction:column}.sidebar .justify-content-between{justify-content:space-between}.sidebar .justify-content-center{justify-content:center}.sidebar .align-items-center{align-items:center}.sidebar .w-100{width:100%}.sidebar .pe-3{padding-right:1rem}.sidebar .d-md-none{display:none}.sidebar .d-none{display:none!important}.sidebar .me-12{margin-right:8px}.sidebar .badge-chip{display:flex;height:20px;padding:3px 6px;align-items:center;color:#fdfdfd;border-radius:4.5px;font-size:9px;font-weight:700;letter-spacing:.18px;text-align:center;white-space:nowrap;cursor:pointer;transition:all .3s ease}.sidebar .badge-chip:hover{opacity:.9;transform:scale(1.05)}.sidebar .fill-based-icons{fill:#3a4d63!important}.sidebar li.active .fill-based-icons{fill:#2c2b33!important}.sidebar li:not(.active) a:hover .fill-based-icons{fill:#fdfdfd!important}.sidebar .stroke-based-icons{stroke:#3a4d63!important}.sidebar li.active .stroke-based-icons{stroke:#2c2b33!important}.sidebar li:not(.active) a:hover .stroke-based-icons{stroke:#fdfdfd!important}.sidebar .nav-wrapper a{text-decoration:none;transition:all .3s ease}.sidebar .nav-wrapper .nav-label{font-weight:500;font-size:16px;line-height:19px;color:#3a4d63;transition:color .3s ease}.sidebar .nav-wrapper ul{list-style:none;padding:0;margin:0}.sidebar .nav-wrapper ul li{display:flex;justify-content:space-between;align-items:center;align-self:stretch;padding:8px 14px 8px 24px;height:52px;position:relative;transition:all .3s ease}.sidebar .nav-wrapper ul li.active{background:#28b48c;border-radius:0 8px 8px 0;margin-right:1.5rem}.sidebar .nav-wrapper ul li.active .nav-label,.sidebar .nav-wrapper ul li.active a:hover .nav-label{color:#2c2b33!important}.sidebar .nav-wrapper ul li:not(.active) a:hover .nav-label{color:#fdfdfd!important}.sidebar .nav-wrapper ul li.disabled{opacity:.5;cursor:not-allowed}.sidebar .nav-wrapper ul li.disabled a{pointer-events:none}.sidebar .nav-wrapper ul .submenu-list{list-style:none;padding:0;margin:0;background:#0003}.sidebar .nav-wrapper ul .submenu-list .submenu-item{padding:0;height:auto}.sidebar .nav-wrapper ul .submenu-list .submenu-item .submenu-link{padding:8px 14px 8px 48px;height:40px;display:flex;align-items:center;font-size:14px}.sidebar .nav-wrapper ul .submenu-list .submenu-item .submenu-link .nav-label{font-size:14px}.sidebar .logo{padding-top:36px;padding-left:24px;padding-bottom:66px}.sidebar .logo img{height:20px;object-fit:contain}.sidebar .menu-icon-container{display:flex;align-items:center;justify-content:center;min-width:24px}.sidebar .menu-icon-container .svg-icon{display:flex;align-items:center;justify-content:center}.sidebar .menu-icon-container .svg-icon svg{width:20px;height:20px}.sidebar .support{color:#3a4d63;padding:8px 26px;height:52px;font-weight:500;font-size:16px;cursor:pointer;text-align:center;text-decoration:none;transition:all .3s ease}.sidebar .support path,.sidebar .support circle{stroke:#3a4d63;transition:stroke .3s ease}.sidebar .support:hover{color:#fdfdfd!important}.sidebar .support:hover path,.sidebar .support:hover circle{stroke:#fdfdfd}.sidebar .logout{color:#ff677a;padding:8px 32px;font-weight:500;cursor:pointer;transition:all .3s ease}.sidebar .logout:hover{opacity:.8}.sidebar .icon-logout{color:#ff677a}.sidebar .sidebar-footer{padding:1rem;border-top:1px solid #2C4057}@media(max-width:768px){.sidebar{left:-240px;padding-bottom:50px;width:240px;transition:left .5s ease}.sidebar.isOpen{left:0!important;width:100%}.sidebar .d-md-none{display:block!important}.sidebar .icon-close_big{margin-right:1rem}}.d-flex{display:flex}.flex-column{flex-direction:column}.justify-content-between{justify-content:space-between}.align-items-center{align-items:center}.w-100{width:100%}.pe-3{padding-right:1rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i2.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
147
182
|
}
|
|
148
183
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: Sidebar, decorators: [{
|
|
149
184
|
type: Component,
|
|
150
|
-
args: [{ selector: 'cwr-sidebar', standalone: true, imports: [CommonModule, RouterModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div
|
|
185
|
+
args: [{ selector: 'cwr-sidebar', standalone: true, imports: [CommonModule, RouterModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"sidebar d-flex flex-column justify-content-between\" [class.isOpen]=\"!isCollapsed\">\n <div>\n <!-- Logo Section -->\n <div class=\"d-flex justify-content-between logo pe-3 w-100\" *ngIf=\"logoUrl || showToggle\">\n <img *ngIf=\"logoUrl\" [src]=\"logoUrl\" [alt]=\"logoAlt\" />\n <span\n class=\"icon-close_big d-md-none\"\n style=\"color: #fff; cursor: pointer\"\n [class.d-none]=\"isCollapsed\"\n (click)=\"closeSidebar()\"></span>\n </div>\n\n <!-- Navigation Wrapper -->\n <div class=\"nav-wrapper\" role=\"navigation\">\n <ul class=\"active\">\n <li \n *ngFor=\"let item of menuItems\"\n [class.active]=\"isActiveRoute(item)\"\n [class.disabled]=\"item.disabled\"\n >\n <a \n class=\"d-flex align-items-center w-100\"\n [routerLink]=\"item.route\"\n [routerLinkActive]=\"item.isActive ? '' : 'active'\"\n [routerLinkActiveOptions]=\"{ exact: false }\"\n (click)=\"onMenuItemClick(item)\"\n >\n <!-- Icon Section -->\n <div class=\"menu-icon-container\" *ngIf=\"item.icon\">\n <div [innerHTML]=\"item.icon\" class=\"svg-icon\"></div>\n </div>\n\n <!-- Label and Badge -->\n <div class=\"d-flex w-100 justify-content-between align-items-center\">\n <span class=\"nav-label\">{{ item.label }}</span>\n \n <!-- Badge -->\n <span \n class=\"badge-chip\"\n *ngIf=\"item.badge\"\n [style.background-color]=\"item.badge.color || '#28B48C'\"\n (click)=\"onBadgeClick($event, item)\"\n >\n {{ item.badge.text }}\n </span>\n </div>\n </a>\n\n <!-- Submenu -->\n <ul \n class=\"submenu-list\"\n *ngIf=\"hasChildren(item) && isExpanded(item)\"\n >\n <li \n *ngFor=\"let child of item.children\"\n [class.active]=\"isActiveRoute(child)\"\n [class.disabled]=\"child.disabled\"\n >\n <a \n class=\"d-flex align-items-center submenu-link\"\n [routerLink]=\"child.route\"\n [routerLinkActive]=\"child.isActive ? '' : 'active'\"\n [routerLinkActiveOptions]=\"{ exact: false }\"\n (click)=\"onMenuItemClick(child)\"\n >\n <span class=\"nav-label\">{{ child.label }}</span>\n </a>\n </li>\n </ul>\n </li>\n </ul>\n </div>\n </div>\n\n <!-- Logout/Footer Section (optional) -->\n <div class=\"sidebar-footer\" *ngIf=\"!isCollapsed\">\n <slot name=\"footer\"></slot>\n </div>\n</div>\n", styles: [".sidebar{background:#141f2d;box-shadow:0 0 4px #0000001a;min-height:100vh;width:240px;border-right:1px solid #2C4057;font-family:Inter,sans-serif;position:fixed;top:0;left:0;z-index:300;transition:.5s;-webkit-transition:.5s;-moz-transition:.5s;display:flex;flex-direction:column;justify-content:space-between}.sidebar .d-flex{display:flex}.sidebar .flex-column{flex-direction:column}.sidebar .justify-content-between{justify-content:space-between}.sidebar .justify-content-center{justify-content:center}.sidebar .align-items-center{align-items:center}.sidebar .w-100{width:100%}.sidebar .pe-3{padding-right:1rem}.sidebar .d-md-none{display:none}.sidebar .d-none{display:none!important}.sidebar .me-12{margin-right:8px}.sidebar .badge-chip{display:flex;height:20px;padding:3px 6px;align-items:center;color:#fdfdfd;border-radius:4.5px;font-size:9px;font-weight:700;letter-spacing:.18px;text-align:center;white-space:nowrap;cursor:pointer;transition:all .3s ease}.sidebar .badge-chip:hover{opacity:.9;transform:scale(1.05)}.sidebar .fill-based-icons{fill:#3a4d63!important}.sidebar li.active .fill-based-icons{fill:#2c2b33!important}.sidebar li:not(.active) a:hover .fill-based-icons{fill:#fdfdfd!important}.sidebar .stroke-based-icons{stroke:#3a4d63!important}.sidebar li.active .stroke-based-icons{stroke:#2c2b33!important}.sidebar li:not(.active) a:hover .stroke-based-icons{stroke:#fdfdfd!important}.sidebar .nav-wrapper a{text-decoration:none;transition:all .3s ease}.sidebar .nav-wrapper .nav-label{font-weight:500;font-size:16px;line-height:19px;color:#3a4d63;transition:color .3s ease}.sidebar .nav-wrapper ul{list-style:none;padding:0;margin:0}.sidebar .nav-wrapper ul li{display:flex;justify-content:space-between;align-items:center;align-self:stretch;padding:8px 14px 8px 24px;height:52px;position:relative;transition:all .3s ease}.sidebar .nav-wrapper ul li.active{background:#28b48c;border-radius:0 8px 8px 0;margin-right:1.5rem}.sidebar .nav-wrapper ul li.active .nav-label,.sidebar .nav-wrapper ul li.active a:hover .nav-label{color:#2c2b33!important}.sidebar .nav-wrapper ul li:not(.active) a:hover .nav-label{color:#fdfdfd!important}.sidebar .nav-wrapper ul li.disabled{opacity:.5;cursor:not-allowed}.sidebar .nav-wrapper ul li.disabled a{pointer-events:none}.sidebar .nav-wrapper ul .submenu-list{list-style:none;padding:0;margin:0;background:#0003}.sidebar .nav-wrapper ul .submenu-list .submenu-item{padding:0;height:auto}.sidebar .nav-wrapper ul .submenu-list .submenu-item .submenu-link{padding:8px 14px 8px 48px;height:40px;display:flex;align-items:center;font-size:14px}.sidebar .nav-wrapper ul .submenu-list .submenu-item .submenu-link .nav-label{font-size:14px}.sidebar .logo{padding-top:36px;padding-left:24px;padding-bottom:66px}.sidebar .logo img{height:20px;object-fit:contain}.sidebar .menu-icon-container{display:flex;align-items:center;justify-content:center;min-width:24px}.sidebar .menu-icon-container .svg-icon{display:flex;align-items:center;justify-content:center}.sidebar .menu-icon-container .svg-icon svg{width:20px;height:20px}.sidebar .support{color:#3a4d63;padding:8px 26px;height:52px;font-weight:500;font-size:16px;cursor:pointer;text-align:center;text-decoration:none;transition:all .3s ease}.sidebar .support path,.sidebar .support circle{stroke:#3a4d63;transition:stroke .3s ease}.sidebar .support:hover{color:#fdfdfd!important}.sidebar .support:hover path,.sidebar .support:hover circle{stroke:#fdfdfd}.sidebar .logout{color:#ff677a;padding:8px 32px;font-weight:500;cursor:pointer;transition:all .3s ease}.sidebar .logout:hover{opacity:.8}.sidebar .icon-logout{color:#ff677a}.sidebar .sidebar-footer{padding:1rem;border-top:1px solid #2C4057}@media(max-width:768px){.sidebar{left:-240px;padding-bottom:50px;width:240px;transition:left .5s ease}.sidebar.isOpen{left:0!important;width:100%}.sidebar .d-md-none{display:block!important}.sidebar .icon-close_big{margin-right:1rem}}.d-flex{display:flex}.flex-column{flex-direction:column}.justify-content-between{justify-content:space-between}.align-items-center{align-items:center}.w-100{width:100%}.pe-3{padding-right:1rem}\n"] }]
|
|
151
186
|
}], propDecorators: { menuItems: [{
|
|
152
187
|
type: Input
|
|
153
188
|
}], config: [{
|
|
154
189
|
type: Input
|
|
190
|
+
}], collapsed: [{
|
|
191
|
+
type: Input
|
|
192
|
+
}], logoUrl: [{
|
|
193
|
+
type: Input
|
|
194
|
+
}], logoAlt: [{
|
|
195
|
+
type: Input
|
|
196
|
+
}], showToggle: [{
|
|
197
|
+
type: Input
|
|
155
198
|
}], menuItemClicked: [{
|
|
156
199
|
type: Output
|
|
157
200
|
}], collapsedChange: [{
|
|
158
201
|
type: Output
|
|
202
|
+
}], itemBadgeClick: [{
|
|
203
|
+
type: Output
|
|
159
204
|
}] } });
|
|
160
205
|
|
|
161
206
|
/*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"elavarasanbititude-ng-cwr-sidebar.mjs","sources":["../../../packages/ng-cwr-sidebar/src/lib/services/sidebar.service.ts","../../../packages/ng-cwr-sidebar/src/lib/sidebar/sidebar.ts","../../../packages/ng-cwr-sidebar/src/lib/sidebar/sidebar.html","../../../packages/ng-cwr-sidebar/src/public-api.ts","../../../packages/ng-cwr-sidebar/src/elavarasanbititude-ng-cwr-sidebar.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\nimport { SidebarConfig, SidebarMenuItem } from '../models/sidebar.model';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class SidebarService {\n private collapsedSubject = new BehaviorSubject<boolean>(false);\n private menuItemsSubject = new BehaviorSubject<SidebarMenuItem[]>([]);\n private configSubject = new BehaviorSubject<SidebarConfig>({});\n\n public collapsed$ = this.collapsedSubject.asObservable();\n public menuItems$ = this.menuItemsSubject.asObservable();\n public config$ = this.configSubject.asObservable();\n\n constructor() {}\n\n /**\n * Toggle the sidebar collapsed state\n */\n toggleCollapsed(): void {\n this.collapsedSubject.next(!this.collapsedSubject.value);\n }\n\n /**\n * Set the collapsed state\n */\n setCollapsed(collapsed: boolean): void {\n this.collapsedSubject.next(collapsed);\n }\n\n /**\n * Get current collapsed state\n */\n getCollapsed(): boolean {\n return this.collapsedSubject.value;\n }\n\n /**\n * Set menu items\n */\n setMenuItems(items: SidebarMenuItem[]): void {\n this.menuItemsSubject.next(items);\n }\n\n /**\n * Get menu items\n */\n getMenuItems(): SidebarMenuItem[] {\n return this.menuItemsSubject.value;\n }\n\n /**\n * Add a menu item\n */\n addMenuItem(item: SidebarMenuItem): void {\n const items = this.menuItemsSubject.value;\n this.menuItemsSubject.next([...items, item]);\n }\n\n /**\n * Remove a menu item by id\n */\n removeMenuItem(id: string): void {\n const items = this.menuItemsSubject.value.filter(item => item.id !== id);\n this.menuItemsSubject.next(items);\n }\n\n /**\n * Update sidebar configuration\n */\n setConfig(config: SidebarConfig): void {\n this.configSubject.next(config);\n }\n\n /**\n * Get sidebar configuration\n */\n getConfig(): SidebarConfig {\n return this.configSubject.value;\n }\n}\n","import { Component, OnInit, Input, Output, EventEmitter, ChangeDetectionStrategy, inject } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { RouterModule } from '@angular/router';\nimport { SidebarService } from '../services/sidebar.service';\nimport { SidebarConfig, SidebarMenuItem } from '../models/sidebar.model';\n\n@Component({\n selector: 'cwr-sidebar',\n standalone: true,\n imports: [CommonModule, RouterModule],\n templateUrl: './sidebar.html',\n styleUrl: './sidebar.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class Sidebar implements OnInit {\n @Input() menuItems: SidebarMenuItem[] = [];\n @Input() config: SidebarConfig = {};\n @Output() menuItemClicked = new EventEmitter<SidebarMenuItem>();\n @Output() collapsedChange = new EventEmitter<boolean>();\n\n private sidebarService = inject(SidebarService);\n\n get collapsed$() {\n return this.sidebarService.collapsed$;\n }\n\n expandedItems: Set<string> = new Set();\n\n readonly defaultConfig: SidebarConfig = {\n collapsed: false,\n position: 'left',\n width: '250px',\n collapsedWidth: '60px',\n backgroundColor: '#f5f5f5',\n textColor: '#333',\n hoverColor: '#e0e0e0',\n toggleButton: true,\n overlayOnMobile: true,\n };\n\n ngOnInit(): void {\n this.sidebarService.setMenuItems(this.menuItems);\n const mergedConfig = { ...this.defaultConfig, ...this.config };\n this.sidebarService.setConfig(mergedConfig);\n }\n\n ngOnChanges(): void {\n if (this.menuItems.length > 0) {\n this.sidebarService.setMenuItems(this.menuItems);\n }\n }\n\n toggleSidebar(): void {\n this.sidebarService.toggleCollapsed();\n this.collapsedChange.emit(this.sidebarService.getCollapsed());\n }\n\n toggleExpand(item: SidebarMenuItem): void {\n if (item.children && item.children.length > 0) {\n const itemId = item.id || item.label;\n if (this.expandedItems.has(itemId)) {\n this.expandedItems.delete(itemId);\n } else {\n this.expandedItems.add(itemId);\n }\n }\n }\n\n isExpanded(item: SidebarMenuItem): boolean {\n const itemId = item.id || item.label;\n return this.expandedItems.has(itemId);\n }\n\n onMenuItemClick(item: SidebarMenuItem): void {\n if (item.action) {\n item.action();\n }\n this.menuItemClicked.emit(item);\n }\n\n hasCildren(item: SidebarMenuItem): boolean {\n return !!(item.children && item.children.length > 0);\n }\n\n getConfig(): SidebarConfig {\n return this.sidebarService.getConfig();\n }\n}\n","<div \n class=\"cwr-sidebar\"\n [ngClass]=\"{ 'collapsed': (collapsed$ | async) }\"\n [style.width]=\"(collapsed$ | async) ? getConfig().collapsedWidth : getConfig().width\"\n [style.backgroundColor]=\"getConfig().backgroundColor\"\n [style.color]=\"getConfig().textColor\"\n>\n <!-- Toggle Button -->\n <div class=\"sidebar-header\" *ngIf=\"getConfig().toggleButton\">\n <button \n class=\"toggle-btn\" \n (click)=\"toggleSidebar()\"\n [attr.aria-label]=\"(collapsed$ | async) ? 'Expand sidebar' : 'Collapse sidebar'\"\n >\n <span class=\"toggle-icon\">☰</span>\n </button>\n <span class=\"header-title\" *ngIf=\"!(collapsed$ | async)\">Menu</span>\n </div>\n\n <!-- Menu Items -->\n <nav class=\"sidebar-nav\">\n <ul class=\"menu-list\">\n <li \n *ngFor=\"let item of menuItems\"\n class=\"menu-item\"\n [ngClass]=\"{ \n 'has-children': hasCildren(item),\n 'expanded': isExpanded(item),\n 'disabled': item.disabled\n }\"\n >\n <button \n class=\"menu-link\"\n [routerLink]=\"item.route\"\n (click)=\"onMenuItemClick(item)\"\n [disabled]=\"item.disabled\"\n >\n <span class=\"menu-icon\" *ngIf=\"item.icon\">{{ item.icon }}</span>\n <span class=\"menu-label\" *ngIf=\"!(collapsed$ | async)\">\n {{ item.label }}\n </span>\n <span \n class=\"menu-badge\"\n *ngIf=\"item.badge && !(collapsed$ | async)\"\n [ngStyle]=\"{ 'background-color': item.badge.color || '#ff6b6b' }\"\n >\n {{ item.badge.text }}\n </span>\n <span \n class=\"expand-icon\"\n *ngIf=\"hasCildren(item)\"\n (click)=\"toggleExpand(item)\"\n [ngClass]=\"{ 'expanded': isExpanded(item) }\"\n >\n ▾\n </span>\n </button>\n\n <!-- Nested Menu Items -->\n <ul \n class=\"submenu-list\"\n *ngIf=\"hasCildren(item) && isExpanded(item)\"\n >\n <li \n *ngFor=\"let child of item.children\"\n class=\"submenu-item\"\n [ngClass]=\"{ 'disabled': child.disabled }\"\n >\n <button \n class=\"submenu-link\"\n [routerLink]=\"child.route\"\n (click)=\"onMenuItemClick(child)\"\n [disabled]=\"child.disabled\"\n >\n <span class=\"submenu-icon\" *ngIf=\"child.icon\">{{ child.icon }}</span>\n <span class=\"submenu-label\">{{ child.label }}</span>\n </button>\n </li>\n </ul>\n </li>\n </ul>\n </nav>\n</div>\n","/*\n * Public API Surface of ng-cwr-sidebar\n */\n\nexport * from './lib/sidebar/sidebar';\nexport * from './lib/services/sidebar.service';\nexport * from './lib/models/sidebar.model';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"elavarasanbititude-ng-cwr-sidebar.mjs","sources":["../../../packages/ng-cwr-sidebar/src/lib/services/sidebar.service.ts","../../../packages/ng-cwr-sidebar/src/lib/sidebar/sidebar.ts","../../../packages/ng-cwr-sidebar/src/lib/sidebar/sidebar.html","../../../packages/ng-cwr-sidebar/src/public-api.ts","../../../packages/ng-cwr-sidebar/src/elavarasanbititude-ng-cwr-sidebar.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\nimport { SidebarConfig, SidebarMenuItem } from '../models/sidebar.model';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class SidebarService {\n private collapsedSubject = new BehaviorSubject<boolean>(false);\n private menuItemsSubject = new BehaviorSubject<SidebarMenuItem[]>([]);\n private configSubject = new BehaviorSubject<SidebarConfig>({});\n\n public collapsed$ = this.collapsedSubject.asObservable();\n public menuItems$ = this.menuItemsSubject.asObservable();\n public config$ = this.configSubject.asObservable();\n\n constructor() {}\n\n /**\n * Toggle the sidebar collapsed state\n */\n toggleCollapsed(): void {\n this.collapsedSubject.next(!this.collapsedSubject.value);\n }\n\n /**\n * Set the collapsed state\n */\n setCollapsed(collapsed: boolean): void {\n this.collapsedSubject.next(collapsed);\n }\n\n /**\n * Get current collapsed state\n */\n getCollapsed(): boolean {\n return this.collapsedSubject.value;\n }\n\n /**\n * Set menu items\n */\n setMenuItems(items: SidebarMenuItem[]): void {\n this.menuItemsSubject.next(items);\n }\n\n /**\n * Get menu items\n */\n getMenuItems(): SidebarMenuItem[] {\n return this.menuItemsSubject.value;\n }\n\n /**\n * Add a menu item\n */\n addMenuItem(item: SidebarMenuItem): void {\n const items = this.menuItemsSubject.value;\n this.menuItemsSubject.next([...items, item]);\n }\n\n /**\n * Remove a menu item by id\n */\n removeMenuItem(id: string): void {\n const items = this.menuItemsSubject.value.filter(item => item.id !== id);\n this.menuItemsSubject.next(items);\n }\n\n /**\n * Update sidebar configuration\n */\n setConfig(config: SidebarConfig): void {\n this.configSubject.next(config);\n }\n\n /**\n * Get sidebar configuration\n */\n getConfig(): SidebarConfig {\n return this.configSubject.value;\n }\n}\n","import { Component, OnInit, OnChanges, Input, Output, EventEmitter, ChangeDetectionStrategy, inject, SimpleChanges } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { RouterModule, Router, NavigationEnd } from '@angular/router';\nimport { SidebarService } from '../services/sidebar.service';\nimport { SidebarConfig, SidebarMenuItem } from '../models/sidebar.model';\nimport { filter } from 'rxjs/operators';\n\n@Component({\n selector: 'cwr-sidebar',\n standalone: true,\n imports: [CommonModule, RouterModule],\n templateUrl: './sidebar.html',\n styleUrl: './sidebar.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class Sidebar implements OnInit, OnChanges {\n @Input() menuItems: SidebarMenuItem[] = [];\n @Input() config: SidebarConfig = {};\n @Input() collapsed: boolean = false;\n @Input() logoUrl?: string;\n @Input() logoAlt: string = 'Logo';\n @Input() showToggle: boolean = true;\n @Output() menuItemClicked = new EventEmitter<SidebarMenuItem>();\n @Output() collapsedChange = new EventEmitter<boolean>();\n @Output() itemBadgeClick = new EventEmitter<SidebarMenuItem>();\n\n private sidebarService = inject(SidebarService);\n private router = inject(Router);\n\n get collapsed$() {\n return this.sidebarService.collapsed$;\n }\n\n expandedItems: Set<string> = new Set();\n isCollapsed = false;\n\n readonly defaultConfig: SidebarConfig = {\n collapsed: false,\n position: 'left',\n width: '240px',\n collapsedWidth: '60px',\n backgroundColor: '#141F2D',\n textColor: '#3A4D63',\n hoverColor: '#FDFDFD',\n toggleButton: true,\n overlayOnMobile: true,\n };\n\n ngOnInit(): void {\n this.isCollapsed = this.collapsed;\n this.sidebarService.setMenuItems(this.menuItems);\n const mergedConfig = { ...this.defaultConfig, ...this.config };\n this.sidebarService.setConfig(mergedConfig);\n\n // Track router navigation for active state\n this.router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe(() => {\n // Trigger change detection for route changes\n });\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['menuItems'] && !changes['menuItems'].firstChange) {\n this.sidebarService.setMenuItems(this.menuItems);\n }\n if (changes['collapsed']) {\n this.isCollapsed = this.collapsed;\n }\n if (changes['config'] && !changes['config'].firstChange) {\n this.sidebarService.setConfig({ ...this.defaultConfig, ...this.config });\n }\n }\n\n toggleSidebar(): void {\n this.isCollapsed = !this.isCollapsed;\n this.sidebarService.toggleCollapsed();\n this.collapsedChange.emit(this.isCollapsed);\n }\n\n toggleExpand(item: SidebarMenuItem): void {\n if (item.children && item.children.length > 0) {\n const itemId = item.id || item.label;\n if (this.expandedItems.has(itemId)) {\n this.expandedItems.delete(itemId);\n } else {\n this.expandedItems.add(itemId);\n }\n }\n }\n\n isExpanded(item: SidebarMenuItem): boolean {\n const itemId = item.id || item.label;\n return this.expandedItems.has(itemId);\n }\n\n onMenuItemClick(item: SidebarMenuItem): void {\n if (item.action) {\n item.action();\n }\n this.menuItemClicked.emit(item);\n }\n\n onBadgeClick(event: Event, item: SidebarMenuItem): void {\n event.stopPropagation();\n this.itemBadgeClick.emit(item);\n }\n\n hasChildren(item: SidebarMenuItem): boolean {\n return !!(item.children && item.children.length > 0);\n }\n\n isActiveRoute(item: SidebarMenuItem): boolean {\n if (item.isActive) {\n return item.isActive();\n }\n return item.route ? this.router.url.includes(`/${item.route}`) : false;\n }\n\n getConfig(): SidebarConfig {\n return this.sidebarService.getConfig();\n }\n\n closeSidebar(): void {\n if (!this.isCollapsed) {\n this.toggleSidebar();\n }\n }\n}\n","<div class=\"sidebar d-flex flex-column justify-content-between\" [class.isOpen]=\"!isCollapsed\">\n <div>\n <!-- Logo Section -->\n <div class=\"d-flex justify-content-between logo pe-3 w-100\" *ngIf=\"logoUrl || showToggle\">\n <img *ngIf=\"logoUrl\" [src]=\"logoUrl\" [alt]=\"logoAlt\" />\n <span\n class=\"icon-close_big d-md-none\"\n style=\"color: #fff; cursor: pointer\"\n [class.d-none]=\"isCollapsed\"\n (click)=\"closeSidebar()\"></span>\n </div>\n\n <!-- Navigation Wrapper -->\n <div class=\"nav-wrapper\" role=\"navigation\">\n <ul class=\"active\">\n <li \n *ngFor=\"let item of menuItems\"\n [class.active]=\"isActiveRoute(item)\"\n [class.disabled]=\"item.disabled\"\n >\n <a \n class=\"d-flex align-items-center w-100\"\n [routerLink]=\"item.route\"\n [routerLinkActive]=\"item.isActive ? '' : 'active'\"\n [routerLinkActiveOptions]=\"{ exact: false }\"\n (click)=\"onMenuItemClick(item)\"\n >\n <!-- Icon Section -->\n <div class=\"menu-icon-container\" *ngIf=\"item.icon\">\n <div [innerHTML]=\"item.icon\" class=\"svg-icon\"></div>\n </div>\n\n <!-- Label and Badge -->\n <div class=\"d-flex w-100 justify-content-between align-items-center\">\n <span class=\"nav-label\">{{ item.label }}</span>\n \n <!-- Badge -->\n <span \n class=\"badge-chip\"\n *ngIf=\"item.badge\"\n [style.background-color]=\"item.badge.color || '#28B48C'\"\n (click)=\"onBadgeClick($event, item)\"\n >\n {{ item.badge.text }}\n </span>\n </div>\n </a>\n\n <!-- Submenu -->\n <ul \n class=\"submenu-list\"\n *ngIf=\"hasChildren(item) && isExpanded(item)\"\n >\n <li \n *ngFor=\"let child of item.children\"\n [class.active]=\"isActiveRoute(child)\"\n [class.disabled]=\"child.disabled\"\n >\n <a \n class=\"d-flex align-items-center submenu-link\"\n [routerLink]=\"child.route\"\n [routerLinkActive]=\"child.isActive ? '' : 'active'\"\n [routerLinkActiveOptions]=\"{ exact: false }\"\n (click)=\"onMenuItemClick(child)\"\n >\n <span class=\"nav-label\">{{ child.label }}</span>\n </a>\n </li>\n </ul>\n </li>\n </ul>\n </div>\n </div>\n\n <!-- Logout/Footer Section (optional) -->\n <div class=\"sidebar-footer\" *ngIf=\"!isCollapsed\">\n <slot name=\"footer\"></slot>\n </div>\n</div>\n","/*\n * Public API Surface of ng-cwr-sidebar\n */\n\nexport * from './lib/sidebar/sidebar';\nexport * from './lib/services/sidebar.service';\nexport * from './lib/models/sidebar.model';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as rxjs from 'rxjs';
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { OnInit, EventEmitter } from '@angular/core';
|
|
4
|
+
import { OnInit, OnChanges, EventEmitter, SimpleChanges } from '@angular/core';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Represents a menu item in the sidebar
|
|
@@ -18,6 +18,11 @@ interface SidebarMenuItem {
|
|
|
18
18
|
text: string;
|
|
19
19
|
color?: string;
|
|
20
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* Custom function to determine if this item is active
|
|
23
|
+
* If provided, takes precedence over route-based active detection
|
|
24
|
+
*/
|
|
25
|
+
isActive?: () => boolean;
|
|
21
26
|
}
|
|
22
27
|
/**
|
|
23
28
|
* Configuration for the sidebar component
|
|
@@ -30,29 +35,40 @@ interface SidebarConfig {
|
|
|
30
35
|
backgroundColor?: string;
|
|
31
36
|
textColor?: string;
|
|
32
37
|
hoverColor?: string;
|
|
38
|
+
activeColor?: string;
|
|
33
39
|
toggleButton?: boolean;
|
|
34
40
|
overlayOnMobile?: boolean;
|
|
35
41
|
}
|
|
36
42
|
|
|
37
|
-
declare class Sidebar implements OnInit {
|
|
43
|
+
declare class Sidebar implements OnInit, OnChanges {
|
|
38
44
|
menuItems: SidebarMenuItem[];
|
|
39
45
|
config: SidebarConfig;
|
|
46
|
+
collapsed: boolean;
|
|
47
|
+
logoUrl?: string;
|
|
48
|
+
logoAlt: string;
|
|
49
|
+
showToggle: boolean;
|
|
40
50
|
menuItemClicked: EventEmitter<SidebarMenuItem>;
|
|
41
51
|
collapsedChange: EventEmitter<boolean>;
|
|
52
|
+
itemBadgeClick: EventEmitter<SidebarMenuItem>;
|
|
42
53
|
private sidebarService;
|
|
54
|
+
private router;
|
|
43
55
|
get collapsed$(): rxjs.Observable<boolean>;
|
|
44
56
|
expandedItems: Set<string>;
|
|
57
|
+
isCollapsed: boolean;
|
|
45
58
|
readonly defaultConfig: SidebarConfig;
|
|
46
59
|
ngOnInit(): void;
|
|
47
|
-
ngOnChanges(): void;
|
|
60
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
48
61
|
toggleSidebar(): void;
|
|
49
62
|
toggleExpand(item: SidebarMenuItem): void;
|
|
50
63
|
isExpanded(item: SidebarMenuItem): boolean;
|
|
51
64
|
onMenuItemClick(item: SidebarMenuItem): void;
|
|
52
|
-
|
|
65
|
+
onBadgeClick(event: Event, item: SidebarMenuItem): void;
|
|
66
|
+
hasChildren(item: SidebarMenuItem): boolean;
|
|
67
|
+
isActiveRoute(item: SidebarMenuItem): boolean;
|
|
53
68
|
getConfig(): SidebarConfig;
|
|
69
|
+
closeSidebar(): void;
|
|
54
70
|
static ɵfac: i0.ɵɵFactoryDeclaration<Sidebar, never>;
|
|
55
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<Sidebar, "cwr-sidebar", never, { "menuItems": { "alias": "menuItems"; "required": false; }; "config": { "alias": "config"; "required": false; }; }, { "menuItemClicked": "menuItemClicked"; "collapsedChange": "collapsedChange"; }, never, never, true, never>;
|
|
71
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<Sidebar, "cwr-sidebar", never, { "menuItems": { "alias": "menuItems"; "required": false; }; "config": { "alias": "config"; "required": false; }; "collapsed": { "alias": "collapsed"; "required": false; }; "logoUrl": { "alias": "logoUrl"; "required": false; }; "logoAlt": { "alias": "logoAlt"; "required": false; }; "showToggle": { "alias": "showToggle"; "required": false; }; }, { "menuItemClicked": "menuItemClicked"; "collapsedChange": "collapsedChange"; "itemBadgeClick": "itemBadgeClick"; }, never, never, true, never>;
|
|
56
72
|
}
|
|
57
73
|
|
|
58
74
|
declare class SidebarService {
|