@kanso-protocol/sidebar 0.1.0

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.
@@ -0,0 +1,274 @@
1
+ import * as i0 from '@angular/core';
2
+ import { EventEmitter, Output, Input, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { KpAvatarComponent } from '@kanso-protocol/avatar';
4
+ import { KpIconComponent } from '@kanso-protocol/icon';
5
+ import { KpNavItemComponent } from '@kanso-protocol/nav-item';
6
+
7
+ /**
8
+ * Kanso Protocol — Sidebar
9
+ *
10
+ * App side navigation container. Expanded (240) or collapsed (64).
11
+ * Data-driven sections, each with its own label and NavItems.
12
+ * Optional logo, search slot, user footer with Avatar.
13
+ *
14
+ * Slots:
15
+ * - `[kpSidebarLogo]` — custom logo area
16
+ * - `[kpSidebarSearch]` — search field above sections
17
+ * - each NavItem icon is rendered via `iconTemplateRef` if provided
18
+ * (otherwise a generic placeholder)
19
+ *
20
+ * @example
21
+ * <kp-sidebar
22
+ * widthState="expanded"
23
+ * [sections]="nav"
24
+ * userName="Greg Black"
25
+ * userInitials="GB"
26
+ * userEmail="greg@example.com"
27
+ * />
28
+ */
29
+ class KpSidebarComponent {
30
+ widthState = 'expanded';
31
+ appearance = 'light';
32
+ showLogo = true;
33
+ logoText = 'Kanso Protocol';
34
+ showSearch = false;
35
+ showSectionLabels = true;
36
+ showUserFooter = true;
37
+ sections = [];
38
+ userName = null;
39
+ userEmail = null;
40
+ userInitials = null;
41
+ toggle = new EventEmitter();
42
+ onToggle() {
43
+ this.widthState = this.widthState === 'expanded' ? 'collapsed' : 'expanded';
44
+ this.toggle.emit(this.widthState);
45
+ }
46
+ onItemClick(item) {
47
+ if (item.children?.length) {
48
+ item.expanded = !item.expanded;
49
+ }
50
+ this.itemClick.emit(item);
51
+ }
52
+ itemClick = new EventEmitter();
53
+ userMenuClick = new EventEmitter();
54
+ get hostClasses() {
55
+ return `kp-sidebar kp-sidebar--${this.widthState} kp-sidebar--${this.appearance}`;
56
+ }
57
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: KpSidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
58
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: KpSidebarComponent, isStandalone: true, selector: "kp-sidebar", inputs: { widthState: "widthState", appearance: "appearance", showLogo: "showLogo", logoText: "logoText", showSearch: "showSearch", showSectionLabels: "showSectionLabels", showUserFooter: "showUserFooter", sections: "sections", userName: "userName", userEmail: "userEmail", userInitials: "userInitials" }, outputs: { toggle: "toggle", itemClick: "itemClick", userMenuClick: "userMenuClick" }, host: { attributes: { "role": "navigation" }, properties: { "class": "hostClasses" } }, ngImport: i0, template: `
59
+ <div class="kp-sidebar__top">
60
+ <div class="kp-sidebar__top-row">
61
+ @if (showLogo) {
62
+ <div class="kp-sidebar__logo">
63
+ <ng-content select="[kpSidebarLogo]">
64
+ <span class="kp-sidebar__logo-mark" aria-hidden="true">
65
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round">
66
+ <path d="M3 7l9-4 9 4v10l-9 4-9-4V7zM3 7l9 4 9-4M12 11v10"/>
67
+ </svg>
68
+ </span>
69
+ @if (widthState !== 'collapsed') {
70
+ <span class="kp-sidebar__logo-text">{{ logoText }}</span>
71
+ }
72
+ </ng-content>
73
+ </div>
74
+ }
75
+ <button
76
+ type="button"
77
+ class="kp-sidebar__toggle"
78
+ [attr.aria-label]="widthState === 'collapsed' ? 'Expand sidebar' : 'Collapse sidebar'"
79
+ (click)="onToggle()"
80
+ >
81
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M9 5v14"/></svg>
82
+ </button>
83
+ </div>
84
+ @if (showSearch && widthState !== 'collapsed') {
85
+ <ng-content select="[kpSidebarSearch]"/>
86
+ }
87
+ </div>
88
+
89
+ <nav class="kp-sidebar__nav">
90
+ @for (section of sections; track $index) {
91
+ <div class="kp-sidebar__section">
92
+ @if (showSectionLabels && section.label && widthState !== 'collapsed') {
93
+ <div class="kp-sidebar__section-label">{{ section.label }}</div>
94
+ }
95
+ @for (item of section.items; track item.label) {
96
+ <kp-nav-item
97
+ size="md"
98
+ [label]="item.label"
99
+ [active]="!!item.active"
100
+ [showBadge]="!!item.badge"
101
+ [hasChildren]="!!item.children?.length"
102
+ [expanded]="!!item.expanded"
103
+ [collapsed]="widthState === 'collapsed'"
104
+ (click$)="onItemClick(item)"
105
+ >
106
+ <span kpNavItemIcon>
107
+ <kp-icon [name]="item.icon || 'circle'" />
108
+ </span>
109
+ @if (item.badge) {
110
+ <span kpNavItemBadge class="kp-sidebar__badge">{{ item.badge }}</span>
111
+ }
112
+ </kp-nav-item>
113
+
114
+ @if (item.children?.length && item.expanded && widthState !== 'collapsed') {
115
+ @for (child of item.children; track child.label) {
116
+ <kp-nav-item
117
+ size="md"
118
+ [depth]="1"
119
+ [label]="child.label"
120
+ [active]="!!child.active"
121
+ [showIcon]="false"
122
+ style="--kp-nav-item-indent: 30px"
123
+ (click$)="onItemClick(child)"
124
+ />
125
+ }
126
+ }
127
+ }
128
+ </div>
129
+ }
130
+ </nav>
131
+
132
+ @if (showUserFooter && (userName || userInitials)) {
133
+ <div class="kp-sidebar__footer">
134
+ <kp-avatar size="md" [initials]="userInitials || null" [showStatus]="true" status="online"/>
135
+ @if (widthState !== 'collapsed') {
136
+ <div class="kp-sidebar__footer-text">
137
+ @if (userName) { <span class="kp-sidebar__footer-name">{{ userName }}</span> }
138
+ @if (userEmail) { <span class="kp-sidebar__footer-email">{{ userEmail }}</span> }
139
+ </div>
140
+ <button type="button" class="kp-sidebar__footer-menu" aria-label="User options" (click)="userMenuClick.emit()">
141
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="5" r="1"/><circle cx="12" cy="12" r="1"/><circle cx="12" cy="19" r="1"/></svg>
142
+ </button>
143
+ }
144
+ </div>
145
+ }
146
+ `, isInline: true, styles: [":host{box-sizing:border-box;display:flex;flex-direction:column;width:var(--kp-sidebar-w, 240px);height:100%;min-height:100vh;background:var(--kp-color-sidebar-bg, var(--kp-color-white));border-inline-end:1px solid var(--kp-color-sidebar-border, var(--kp-color-gray-200));font-family:var(--kp-font-family-sans, \"Onest\", system-ui, sans-serif);transition:width var(--kp-motion-duration-fast) ease}:host(.kp-sidebar--expanded){--kp-sidebar-w: 240px}:host(.kp-sidebar--collapsed){--kp-sidebar-w: 64px}:host(.kp-sidebar--dark){background:var(--kp-color-sidebar-bg-dark, var(--kp-color-gray-900));color:var(--kp-color-fg-on-dark-strong);border-right-color:var(--kp-color-gray-800)}.kp-sidebar__top{display:flex;flex-direction:column;gap:16px;padding:16px}.kp-sidebar__top-row{display:flex;align-items:center;gap:12px;min-height:40px}:host(.kp-sidebar--collapsed) .kp-sidebar__top-row{position:relative;justify-content:center}:host(.kp-sidebar--collapsed) .kp-sidebar__logo,:host(.kp-sidebar--collapsed) .kp-sidebar__toggle{transition:opacity var(--kp-motion-duration-fast) ease}:host(.kp-sidebar--collapsed) .kp-sidebar__top-row:has(.kp-sidebar__logo) .kp-sidebar__toggle{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);opacity:0;pointer-events:none}:host(.kp-sidebar--collapsed) .kp-sidebar__top-row:has(.kp-sidebar__logo):hover .kp-sidebar__logo{opacity:0}:host(.kp-sidebar--collapsed) .kp-sidebar__top-row:has(.kp-sidebar__logo):hover .kp-sidebar__toggle{opacity:1;pointer-events:auto}.kp-sidebar__logo{display:flex;align-items:center;gap:12px;flex:1 1 auto;min-width:0}.kp-sidebar__logo-mark{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:8px;background:var(--kp-color-blue-600, var(--kp-color-blue-600));color:var(--kp-color-white);flex:0 0 auto}.kp-sidebar__logo-mark svg{width:60%;height:60%}.kp-sidebar__logo-text{font-size:16px;font-weight:600;flex:1 1 auto;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.kp-sidebar__toggle{all:unset;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:6px;color:var(--kp-color-gray-500, var(--kp-color-gray-500));cursor:pointer;transition:background var(--kp-motion-duration-fast) ease,color .12s ease}.kp-sidebar__toggle:hover{background:var(--kp-color-gray-100, var(--kp-color-gray-100));color:var(--kp-color-gray-900, var(--kp-color-gray-900))}.kp-sidebar__toggle svg{width:16px;height:16px}:host(.kp-sidebar--dark) .kp-sidebar__toggle{color:var(--kp-color-fg-on-dark-muted)}:host(.kp-sidebar--dark) .kp-sidebar__toggle:hover{background:var(--kp-color-gray-800);color:var(--kp-color-white)}:host(.kp-sidebar--collapsed) .kp-sidebar__logo{justify-content:center}.kp-sidebar__nav{display:flex;flex-direction:column;gap:16px;padding:8px;flex:1 1 auto;overflow-y:auto}.kp-sidebar__section{display:flex;flex-direction:column;gap:2px}.kp-sidebar__section-label{padding:8px 12px 4px;font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;color:var(--kp-color-sidebar-section-label, var(--kp-color-gray-500))}.kp-sidebar__badge{display:inline-flex;align-items:center;justify-content:center;padding:1px 8px;height:20px;border-radius:999px;background:var(--kp-color-gray-100, var(--kp-color-gray-100));color:var(--kp-color-gray-700, var(--kp-color-gray-700));font-size:11px;font-weight:500}.kp-sidebar__footer{display:flex;align-items:center;gap:12px;padding:16px;border-top:1px solid var(--kp-color-sidebar-border, var(--kp-color-gray-200))}:host(.kp-sidebar--dark) .kp-sidebar__footer{border-top-color:var(--kp-color-gray-800)}.kp-sidebar__footer-text{display:flex;flex-direction:column;gap:2px;flex:1 1 auto;min-width:0}.kp-sidebar__footer-name{font-size:13px;font-weight:500;color:var(--kp-color-gray-900, var(--kp-color-gray-900));white-space:nowrap;text-overflow:ellipsis;overflow:hidden}:host(.kp-sidebar--dark) .kp-sidebar__footer-name{color:var(--kp-color-white)}.kp-sidebar__footer-email{font-size:11px;color:var(--kp-color-gray-500, var(--kp-color-gray-500));white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.kp-sidebar__footer-menu{all:unset;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:4px;color:var(--kp-color-gray-500, var(--kp-color-gray-500));cursor:pointer}.kp-sidebar__footer-menu:hover{color:var(--kp-color-gray-900, var(--kp-color-gray-900));background:var(--kp-color-gray-100, var(--kp-color-gray-100))}.kp-sidebar__footer-menu svg{width:18px;height:18px}:host(.kp-sidebar--collapsed) .kp-sidebar__footer{justify-content:center;padding-inline:0}\n"], dependencies: [{ kind: "component", type: KpAvatarComponent, selector: "kp-avatar", inputs: ["size", "shape", "appearance", "initials", "src", "alt", "showStatus", "status", "showRing", "ariaLabelOverride"] }, { kind: "component", type: KpIconComponent, selector: "kp-icon", inputs: ["name", "size"] }, { kind: "component", type: KpNavItemComponent, selector: "kp-nav-item", inputs: ["size", "depth", "label", "active", "disabled", "hasChildren", "expanded", "showIcon", "showBadge", "showActiveIndicator", "collapsed"], outputs: ["click$"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
147
+ }
148
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: KpSidebarComponent, decorators: [{
149
+ type: Component,
150
+ args: [{ selector: 'kp-sidebar', imports: [KpAvatarComponent, KpIconComponent, KpNavItemComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: { '[class]': 'hostClasses', role: 'navigation' }, template: `
151
+ <div class="kp-sidebar__top">
152
+ <div class="kp-sidebar__top-row">
153
+ @if (showLogo) {
154
+ <div class="kp-sidebar__logo">
155
+ <ng-content select="[kpSidebarLogo]">
156
+ <span class="kp-sidebar__logo-mark" aria-hidden="true">
157
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round">
158
+ <path d="M3 7l9-4 9 4v10l-9 4-9-4V7zM3 7l9 4 9-4M12 11v10"/>
159
+ </svg>
160
+ </span>
161
+ @if (widthState !== 'collapsed') {
162
+ <span class="kp-sidebar__logo-text">{{ logoText }}</span>
163
+ }
164
+ </ng-content>
165
+ </div>
166
+ }
167
+ <button
168
+ type="button"
169
+ class="kp-sidebar__toggle"
170
+ [attr.aria-label]="widthState === 'collapsed' ? 'Expand sidebar' : 'Collapse sidebar'"
171
+ (click)="onToggle()"
172
+ >
173
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M9 5v14"/></svg>
174
+ </button>
175
+ </div>
176
+ @if (showSearch && widthState !== 'collapsed') {
177
+ <ng-content select="[kpSidebarSearch]"/>
178
+ }
179
+ </div>
180
+
181
+ <nav class="kp-sidebar__nav">
182
+ @for (section of sections; track $index) {
183
+ <div class="kp-sidebar__section">
184
+ @if (showSectionLabels && section.label && widthState !== 'collapsed') {
185
+ <div class="kp-sidebar__section-label">{{ section.label }}</div>
186
+ }
187
+ @for (item of section.items; track item.label) {
188
+ <kp-nav-item
189
+ size="md"
190
+ [label]="item.label"
191
+ [active]="!!item.active"
192
+ [showBadge]="!!item.badge"
193
+ [hasChildren]="!!item.children?.length"
194
+ [expanded]="!!item.expanded"
195
+ [collapsed]="widthState === 'collapsed'"
196
+ (click$)="onItemClick(item)"
197
+ >
198
+ <span kpNavItemIcon>
199
+ <kp-icon [name]="item.icon || 'circle'" />
200
+ </span>
201
+ @if (item.badge) {
202
+ <span kpNavItemBadge class="kp-sidebar__badge">{{ item.badge }}</span>
203
+ }
204
+ </kp-nav-item>
205
+
206
+ @if (item.children?.length && item.expanded && widthState !== 'collapsed') {
207
+ @for (child of item.children; track child.label) {
208
+ <kp-nav-item
209
+ size="md"
210
+ [depth]="1"
211
+ [label]="child.label"
212
+ [active]="!!child.active"
213
+ [showIcon]="false"
214
+ style="--kp-nav-item-indent: 30px"
215
+ (click$)="onItemClick(child)"
216
+ />
217
+ }
218
+ }
219
+ }
220
+ </div>
221
+ }
222
+ </nav>
223
+
224
+ @if (showUserFooter && (userName || userInitials)) {
225
+ <div class="kp-sidebar__footer">
226
+ <kp-avatar size="md" [initials]="userInitials || null" [showStatus]="true" status="online"/>
227
+ @if (widthState !== 'collapsed') {
228
+ <div class="kp-sidebar__footer-text">
229
+ @if (userName) { <span class="kp-sidebar__footer-name">{{ userName }}</span> }
230
+ @if (userEmail) { <span class="kp-sidebar__footer-email">{{ userEmail }}</span> }
231
+ </div>
232
+ <button type="button" class="kp-sidebar__footer-menu" aria-label="User options" (click)="userMenuClick.emit()">
233
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="5" r="1"/><circle cx="12" cy="12" r="1"/><circle cx="12" cy="19" r="1"/></svg>
234
+ </button>
235
+ }
236
+ </div>
237
+ }
238
+ `, styles: [":host{box-sizing:border-box;display:flex;flex-direction:column;width:var(--kp-sidebar-w, 240px);height:100%;min-height:100vh;background:var(--kp-color-sidebar-bg, var(--kp-color-white));border-inline-end:1px solid var(--kp-color-sidebar-border, var(--kp-color-gray-200));font-family:var(--kp-font-family-sans, \"Onest\", system-ui, sans-serif);transition:width var(--kp-motion-duration-fast) ease}:host(.kp-sidebar--expanded){--kp-sidebar-w: 240px}:host(.kp-sidebar--collapsed){--kp-sidebar-w: 64px}:host(.kp-sidebar--dark){background:var(--kp-color-sidebar-bg-dark, var(--kp-color-gray-900));color:var(--kp-color-fg-on-dark-strong);border-right-color:var(--kp-color-gray-800)}.kp-sidebar__top{display:flex;flex-direction:column;gap:16px;padding:16px}.kp-sidebar__top-row{display:flex;align-items:center;gap:12px;min-height:40px}:host(.kp-sidebar--collapsed) .kp-sidebar__top-row{position:relative;justify-content:center}:host(.kp-sidebar--collapsed) .kp-sidebar__logo,:host(.kp-sidebar--collapsed) .kp-sidebar__toggle{transition:opacity var(--kp-motion-duration-fast) ease}:host(.kp-sidebar--collapsed) .kp-sidebar__top-row:has(.kp-sidebar__logo) .kp-sidebar__toggle{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);opacity:0;pointer-events:none}:host(.kp-sidebar--collapsed) .kp-sidebar__top-row:has(.kp-sidebar__logo):hover .kp-sidebar__logo{opacity:0}:host(.kp-sidebar--collapsed) .kp-sidebar__top-row:has(.kp-sidebar__logo):hover .kp-sidebar__toggle{opacity:1;pointer-events:auto}.kp-sidebar__logo{display:flex;align-items:center;gap:12px;flex:1 1 auto;min-width:0}.kp-sidebar__logo-mark{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:8px;background:var(--kp-color-blue-600, var(--kp-color-blue-600));color:var(--kp-color-white);flex:0 0 auto}.kp-sidebar__logo-mark svg{width:60%;height:60%}.kp-sidebar__logo-text{font-size:16px;font-weight:600;flex:1 1 auto;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.kp-sidebar__toggle{all:unset;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:6px;color:var(--kp-color-gray-500, var(--kp-color-gray-500));cursor:pointer;transition:background var(--kp-motion-duration-fast) ease,color .12s ease}.kp-sidebar__toggle:hover{background:var(--kp-color-gray-100, var(--kp-color-gray-100));color:var(--kp-color-gray-900, var(--kp-color-gray-900))}.kp-sidebar__toggle svg{width:16px;height:16px}:host(.kp-sidebar--dark) .kp-sidebar__toggle{color:var(--kp-color-fg-on-dark-muted)}:host(.kp-sidebar--dark) .kp-sidebar__toggle:hover{background:var(--kp-color-gray-800);color:var(--kp-color-white)}:host(.kp-sidebar--collapsed) .kp-sidebar__logo{justify-content:center}.kp-sidebar__nav{display:flex;flex-direction:column;gap:16px;padding:8px;flex:1 1 auto;overflow-y:auto}.kp-sidebar__section{display:flex;flex-direction:column;gap:2px}.kp-sidebar__section-label{padding:8px 12px 4px;font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;color:var(--kp-color-sidebar-section-label, var(--kp-color-gray-500))}.kp-sidebar__badge{display:inline-flex;align-items:center;justify-content:center;padding:1px 8px;height:20px;border-radius:999px;background:var(--kp-color-gray-100, var(--kp-color-gray-100));color:var(--kp-color-gray-700, var(--kp-color-gray-700));font-size:11px;font-weight:500}.kp-sidebar__footer{display:flex;align-items:center;gap:12px;padding:16px;border-top:1px solid var(--kp-color-sidebar-border, var(--kp-color-gray-200))}:host(.kp-sidebar--dark) .kp-sidebar__footer{border-top-color:var(--kp-color-gray-800)}.kp-sidebar__footer-text{display:flex;flex-direction:column;gap:2px;flex:1 1 auto;min-width:0}.kp-sidebar__footer-name{font-size:13px;font-weight:500;color:var(--kp-color-gray-900, var(--kp-color-gray-900));white-space:nowrap;text-overflow:ellipsis;overflow:hidden}:host(.kp-sidebar--dark) .kp-sidebar__footer-name{color:var(--kp-color-white)}.kp-sidebar__footer-email{font-size:11px;color:var(--kp-color-gray-500, var(--kp-color-gray-500));white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.kp-sidebar__footer-menu{all:unset;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:4px;color:var(--kp-color-gray-500, var(--kp-color-gray-500));cursor:pointer}.kp-sidebar__footer-menu:hover{color:var(--kp-color-gray-900, var(--kp-color-gray-900));background:var(--kp-color-gray-100, var(--kp-color-gray-100))}.kp-sidebar__footer-menu svg{width:18px;height:18px}:host(.kp-sidebar--collapsed) .kp-sidebar__footer{justify-content:center;padding-inline:0}\n"] }]
239
+ }], propDecorators: { widthState: [{
240
+ type: Input
241
+ }], appearance: [{
242
+ type: Input
243
+ }], showLogo: [{
244
+ type: Input
245
+ }], logoText: [{
246
+ type: Input
247
+ }], showSearch: [{
248
+ type: Input
249
+ }], showSectionLabels: [{
250
+ type: Input
251
+ }], showUserFooter: [{
252
+ type: Input
253
+ }], sections: [{
254
+ type: Input
255
+ }], userName: [{
256
+ type: Input
257
+ }], userEmail: [{
258
+ type: Input
259
+ }], userInitials: [{
260
+ type: Input
261
+ }], toggle: [{
262
+ type: Output
263
+ }], itemClick: [{
264
+ type: Output
265
+ }], userMenuClick: [{
266
+ type: Output
267
+ }] } });
268
+
269
+ /**
270
+ * Generated bundle index. Do not edit.
271
+ */
272
+
273
+ export { KpSidebarComponent };
274
+ //# sourceMappingURL=kanso-protocol-sidebar.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kanso-protocol-sidebar.mjs","sources":["../../../../../packages/patterns/sidebar/src/sidebar.component.ts","../../../../../packages/patterns/sidebar/src/kanso-protocol-sidebar.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n EventEmitter,\n Input,\n Output,\n} from '@angular/core';\nimport { KpAvatarComponent } from '@kanso-protocol/avatar';\nimport { KpIconComponent } from '@kanso-protocol/icon';\nimport { KpNavItemComponent } from '@kanso-protocol/nav-item';\n\nexport type KpSidebarWidth = 'expanded' | 'collapsed';\nexport type KpSidebarAppearance = 'light' | 'dark';\n\nexport interface KpSidebarNavItem {\n label: string;\n icon?: string; // semantic icon key (consumer resolves)\n href?: string;\n active?: boolean;\n badge?: string;\n /** Nested children — rendered with depth=1 when parent is expanded */\n children?: KpSidebarNavItem[];\n expanded?: boolean;\n}\n\nexport interface KpSidebarSection {\n label?: string;\n items: KpSidebarNavItem[];\n}\n\n/**\n * Kanso Protocol — Sidebar\n *\n * App side navigation container. Expanded (240) or collapsed (64).\n * Data-driven sections, each with its own label and NavItems.\n * Optional logo, search slot, user footer with Avatar.\n *\n * Slots:\n * - `[kpSidebarLogo]` — custom logo area\n * - `[kpSidebarSearch]` — search field above sections\n * - each NavItem icon is rendered via `iconTemplateRef` if provided\n * (otherwise a generic placeholder)\n *\n * @example\n * <kp-sidebar\n * widthState=\"expanded\"\n * [sections]=\"nav\"\n * userName=\"Greg Black\"\n * userInitials=\"GB\"\n * userEmail=\"greg@example.com\"\n * />\n */\n@Component({\n selector: 'kp-sidebar',\n imports: [KpAvatarComponent, KpIconComponent, KpNavItemComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { '[class]': 'hostClasses', role: 'navigation' },\n template: `\n <div class=\"kp-sidebar__top\">\n <div class=\"kp-sidebar__top-row\">\n @if (showLogo) {\n <div class=\"kp-sidebar__logo\">\n <ng-content select=\"[kpSidebarLogo]\">\n <span class=\"kp-sidebar__logo-mark\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.75\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M3 7l9-4 9 4v10l-9 4-9-4V7zM3 7l9 4 9-4M12 11v10\"/>\n </svg>\n </span>\n @if (widthState !== 'collapsed') {\n <span class=\"kp-sidebar__logo-text\">{{ logoText }}</span>\n }\n </ng-content>\n </div>\n }\n <button\n type=\"button\"\n class=\"kp-sidebar__toggle\"\n [attr.aria-label]=\"widthState === 'collapsed' ? 'Expand sidebar' : 'Collapse sidebar'\"\n (click)=\"onToggle()\"\n >\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.75\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\"/><path d=\"M9 5v14\"/></svg>\n </button>\n </div>\n @if (showSearch && widthState !== 'collapsed') {\n <ng-content select=\"[kpSidebarSearch]\"/>\n }\n </div>\n\n <nav class=\"kp-sidebar__nav\">\n @for (section of sections; track $index) {\n <div class=\"kp-sidebar__section\">\n @if (showSectionLabels && section.label && widthState !== 'collapsed') {\n <div class=\"kp-sidebar__section-label\">{{ section.label }}</div>\n }\n @for (item of section.items; track item.label) {\n <kp-nav-item\n size=\"md\"\n [label]=\"item.label\"\n [active]=\"!!item.active\"\n [showBadge]=\"!!item.badge\"\n [hasChildren]=\"!!item.children?.length\"\n [expanded]=\"!!item.expanded\"\n [collapsed]=\"widthState === 'collapsed'\"\n (click$)=\"onItemClick(item)\"\n >\n <span kpNavItemIcon>\n <kp-icon [name]=\"item.icon || 'circle'\" />\n </span>\n @if (item.badge) {\n <span kpNavItemBadge class=\"kp-sidebar__badge\">{{ item.badge }}</span>\n }\n </kp-nav-item>\n\n @if (item.children?.length && item.expanded && widthState !== 'collapsed') {\n @for (child of item.children; track child.label) {\n <kp-nav-item\n size=\"md\"\n [depth]=\"1\"\n [label]=\"child.label\"\n [active]=\"!!child.active\"\n [showIcon]=\"false\"\n style=\"--kp-nav-item-indent: 30px\"\n (click$)=\"onItemClick(child)\"\n />\n }\n }\n }\n </div>\n }\n </nav>\n\n @if (showUserFooter && (userName || userInitials)) {\n <div class=\"kp-sidebar__footer\">\n <kp-avatar size=\"md\" [initials]=\"userInitials || null\" [showStatus]=\"true\" status=\"online\"/>\n @if (widthState !== 'collapsed') {\n <div class=\"kp-sidebar__footer-text\">\n @if (userName) { <span class=\"kp-sidebar__footer-name\">{{ userName }}</span> }\n @if (userEmail) { <span class=\"kp-sidebar__footer-email\">{{ userEmail }}</span> }\n </div>\n <button type=\"button\" class=\"kp-sidebar__footer-menu\" aria-label=\"User options\" (click)=\"userMenuClick.emit()\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.75\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"5\" r=\"1\"/><circle cx=\"12\" cy=\"12\" r=\"1\"/><circle cx=\"12\" cy=\"19\" r=\"1\"/></svg>\n </button>\n }\n </div>\n }\n `,\n styles: [`\n :host {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n width: var(--kp-sidebar-w, 240px);\n height: 100%;\n min-height: 100vh;\n background: var(--kp-color-sidebar-bg, var(--kp-color-white));\n border-inline-end: 1px solid var(--kp-color-sidebar-border, var(--kp-color-gray-200));\n font-family: var(--kp-font-family-sans, 'Onest', system-ui, sans-serif);\n transition: width var(--kp-motion-duration-fast) ease;\n }\n :host(.kp-sidebar--expanded) { --kp-sidebar-w: 240px; }\n :host(.kp-sidebar--collapsed) { --kp-sidebar-w: 64px; }\n\n :host(.kp-sidebar--dark) {\n background: var(--kp-color-sidebar-bg-dark, var(--kp-color-gray-900));\n color: var(--kp-color-fg-on-dark-strong);\n border-right-color: var(--kp-color-gray-800);\n }\n\n .kp-sidebar__top {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 16px;\n }\n .kp-sidebar__top-row {\n display: flex;\n align-items: center;\n gap: 12px;\n min-height: 40px;\n }\n :host(.kp-sidebar--collapsed) .kp-sidebar__top-row {\n position: relative;\n justify-content: center;\n }\n :host(.kp-sidebar--collapsed) .kp-sidebar__logo,\n :host(.kp-sidebar--collapsed) .kp-sidebar__toggle {\n transition: opacity var(--kp-motion-duration-fast) ease;\n }\n /* When collapsed AND logo is present, logo shows by default; toggle reveals on hover */\n :host(.kp-sidebar--collapsed) .kp-sidebar__top-row:has(.kp-sidebar__logo) .kp-sidebar__toggle {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n opacity: 0;\n pointer-events: none;\n }\n :host(.kp-sidebar--collapsed) .kp-sidebar__top-row:has(.kp-sidebar__logo):hover .kp-sidebar__logo { opacity: 0; }\n :host(.kp-sidebar--collapsed) .kp-sidebar__top-row:has(.kp-sidebar__logo):hover .kp-sidebar__toggle {\n opacity: 1;\n pointer-events: auto;\n }\n .kp-sidebar__logo {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1 1 auto;\n min-width: 0;\n }\n .kp-sidebar__logo-mark {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 8px;\n background: var(--kp-color-blue-600, var(--kp-color-blue-600));\n color: var(--kp-color-white);\n flex: 0 0 auto;\n }\n .kp-sidebar__logo-mark svg { width: 60%; height: 60%; }\n .kp-sidebar__logo-text {\n font-size: 16px;\n font-weight: 600;\n flex: 1 1 auto;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n .kp-sidebar__toggle {\n all: unset;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 6px;\n color: var(--kp-color-gray-500, var(--kp-color-gray-500));\n cursor: pointer;\n transition: background var(--kp-motion-duration-fast) ease, color 120ms ease;\n }\n .kp-sidebar__toggle:hover {\n background: var(--kp-color-gray-100, var(--kp-color-gray-100));\n color: var(--kp-color-gray-900, var(--kp-color-gray-900));\n }\n .kp-sidebar__toggle svg { width: 16px; height: 16px; }\n :host(.kp-sidebar--dark) .kp-sidebar__toggle { color: var(--kp-color-fg-on-dark-muted); }\n :host(.kp-sidebar--dark) .kp-sidebar__toggle:hover {\n background: var(--kp-color-gray-800);\n color: var(--kp-color-white);\n }\n\n :host(.kp-sidebar--collapsed) .kp-sidebar__logo { justify-content: center; }\n\n .kp-sidebar__nav {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 8px;\n flex: 1 1 auto;\n overflow-y: auto;\n }\n .kp-sidebar__section {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n .kp-sidebar__section-label {\n padding: 8px 12px 4px;\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.5px;\n text-transform: uppercase;\n color: var(--kp-color-sidebar-section-label, var(--kp-color-gray-500));\n }\n\n .kp-sidebar__badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 1px 8px;\n height: 20px;\n border-radius: 999px;\n background: var(--kp-color-gray-100, var(--kp-color-gray-100));\n color: var(--kp-color-gray-700, var(--kp-color-gray-700));\n font-size: 11px;\n font-weight: 500;\n }\n\n .kp-sidebar__footer {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n border-top: 1px solid var(--kp-color-sidebar-border, var(--kp-color-gray-200));\n }\n :host(.kp-sidebar--dark) .kp-sidebar__footer { border-top-color: var(--kp-color-gray-800); }\n .kp-sidebar__footer-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n flex: 1 1 auto;\n min-width: 0;\n }\n .kp-sidebar__footer-name {\n font-size: 13px;\n font-weight: 500;\n color: var(--kp-color-gray-900, var(--kp-color-gray-900));\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n }\n :host(.kp-sidebar--dark) .kp-sidebar__footer-name { color: var(--kp-color-white); }\n .kp-sidebar__footer-email {\n font-size: 11px;\n color: var(--kp-color-gray-500, var(--kp-color-gray-500));\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n }\n .kp-sidebar__footer-menu {\n all: unset;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n color: var(--kp-color-gray-500, var(--kp-color-gray-500));\n cursor: pointer;\n }\n .kp-sidebar__footer-menu:hover { color: var(--kp-color-gray-900, var(--kp-color-gray-900)); background: var(--kp-color-gray-100, var(--kp-color-gray-100)); }\n .kp-sidebar__footer-menu svg { width: 18px; height: 18px; }\n\n :host(.kp-sidebar--collapsed) .kp-sidebar__footer { justify-content: center; padding-inline: 0; }\n `],\n})\nexport class KpSidebarComponent {\n @Input() widthState: KpSidebarWidth = 'expanded';\n @Input() appearance: KpSidebarAppearance = 'light';\n\n @Input() showLogo = true;\n @Input() logoText = 'Kanso Protocol';\n @Input() showSearch = false;\n @Input() showSectionLabels = true;\n @Input() showUserFooter = true;\n\n @Input() sections: KpSidebarSection[] = [];\n\n @Input() userName: string | null = null;\n @Input() userEmail: string | null = null;\n @Input() userInitials: string | null = null;\n\n @Output() toggle = new EventEmitter<KpSidebarWidth>();\n\n onToggle(): void {\n this.widthState = this.widthState === 'expanded' ? 'collapsed' : 'expanded';\n this.toggle.emit(this.widthState);\n }\n\n onItemClick(item: KpSidebarNavItem): void {\n if (item.children?.length) {\n item.expanded = !item.expanded;\n }\n this.itemClick.emit(item);\n }\n @Output() itemClick = new EventEmitter<KpSidebarNavItem>();\n @Output() userMenuClick = new EventEmitter<void>();\n\n get hostClasses(): string {\n return `kp-sidebar kp-sidebar--${this.widthState} kp-sidebar--${this.appearance}`;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@kanso-protocol/sidebar",
3
+ "version": "0.1.0",
4
+ "license": "MIT",
5
+ "peerDependencies": {
6
+ "@angular/core": "^18.0.0",
7
+ "@angular/common": "^18.0.0",
8
+ "@kanso-protocol/core": "^0.0.1",
9
+ "@kanso-protocol/avatar": ">=0.1.0",
10
+ "@kanso-protocol/nav-item": ">=0.1.0"
11
+ },
12
+ "description": "Kanso Protocol — sidebar (pattern).",
13
+ "author": "GregNBlack",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/GregNBlack/kanso-protocol.git",
17
+ "directory": "packages/patterns/sidebar"
18
+ },
19
+ "homepage": "https://gregnblack.github.io/kanso-protocol/?path=/docs/patterns-sidebar--docs",
20
+ "bugs": "https://github.com/GregNBlack/kanso-protocol/issues",
21
+ "keywords": [
22
+ "design-system",
23
+ "angular",
24
+ "kanso",
25
+ "sidebar"
26
+ ],
27
+ "sideEffects": false,
28
+ "module": "fesm2022/kanso-protocol-sidebar.mjs",
29
+ "typings": "types/kanso-protocol-sidebar.d.ts",
30
+ "exports": {
31
+ "./package.json": {
32
+ "default": "./package.json"
33
+ },
34
+ ".": {
35
+ "types": "./types/kanso-protocol-sidebar.d.ts",
36
+ "default": "./fesm2022/kanso-protocol-sidebar.mjs"
37
+ }
38
+ },
39
+ "type": "module",
40
+ "dependencies": {
41
+ "tslib": "^2.3.0"
42
+ }
43
+ }
@@ -0,0 +1,65 @@
1
+ import * as i0 from '@angular/core';
2
+ import { EventEmitter } from '@angular/core';
3
+
4
+ type KpSidebarWidth = 'expanded' | 'collapsed';
5
+ type KpSidebarAppearance = 'light' | 'dark';
6
+ interface KpSidebarNavItem {
7
+ label: string;
8
+ icon?: string;
9
+ href?: string;
10
+ active?: boolean;
11
+ badge?: string;
12
+ /** Nested children — rendered with depth=1 when parent is expanded */
13
+ children?: KpSidebarNavItem[];
14
+ expanded?: boolean;
15
+ }
16
+ interface KpSidebarSection {
17
+ label?: string;
18
+ items: KpSidebarNavItem[];
19
+ }
20
+ /**
21
+ * Kanso Protocol — Sidebar
22
+ *
23
+ * App side navigation container. Expanded (240) or collapsed (64).
24
+ * Data-driven sections, each with its own label and NavItems.
25
+ * Optional logo, search slot, user footer with Avatar.
26
+ *
27
+ * Slots:
28
+ * - `[kpSidebarLogo]` — custom logo area
29
+ * - `[kpSidebarSearch]` — search field above sections
30
+ * - each NavItem icon is rendered via `iconTemplateRef` if provided
31
+ * (otherwise a generic placeholder)
32
+ *
33
+ * @example
34
+ * <kp-sidebar
35
+ * widthState="expanded"
36
+ * [sections]="nav"
37
+ * userName="Greg Black"
38
+ * userInitials="GB"
39
+ * userEmail="greg@example.com"
40
+ * />
41
+ */
42
+ declare class KpSidebarComponent {
43
+ widthState: KpSidebarWidth;
44
+ appearance: KpSidebarAppearance;
45
+ showLogo: boolean;
46
+ logoText: string;
47
+ showSearch: boolean;
48
+ showSectionLabels: boolean;
49
+ showUserFooter: boolean;
50
+ sections: KpSidebarSection[];
51
+ userName: string | null;
52
+ userEmail: string | null;
53
+ userInitials: string | null;
54
+ toggle: EventEmitter<KpSidebarWidth>;
55
+ onToggle(): void;
56
+ onItemClick(item: KpSidebarNavItem): void;
57
+ itemClick: EventEmitter<KpSidebarNavItem>;
58
+ userMenuClick: EventEmitter<void>;
59
+ get hostClasses(): string;
60
+ static ɵfac: i0.ɵɵFactoryDeclaration<KpSidebarComponent, never>;
61
+ static ɵcmp: i0.ɵɵComponentDeclaration<KpSidebarComponent, "kp-sidebar", never, { "widthState": { "alias": "widthState"; "required": false; }; "appearance": { "alias": "appearance"; "required": false; }; "showLogo": { "alias": "showLogo"; "required": false; }; "logoText": { "alias": "logoText"; "required": false; }; "showSearch": { "alias": "showSearch"; "required": false; }; "showSectionLabels": { "alias": "showSectionLabels"; "required": false; }; "showUserFooter": { "alias": "showUserFooter"; "required": false; }; "sections": { "alias": "sections"; "required": false; }; "userName": { "alias": "userName"; "required": false; }; "userEmail": { "alias": "userEmail"; "required": false; }; "userInitials": { "alias": "userInitials"; "required": false; }; }, { "toggle": "toggle"; "itemClick": "itemClick"; "userMenuClick": "userMenuClick"; }, never, ["[kpSidebarLogo]", "[kpSidebarSearch]"], true, never>;
62
+ }
63
+
64
+ export { KpSidebarComponent };
65
+ export type { KpSidebarAppearance, KpSidebarNavItem, KpSidebarSection, KpSidebarWidth };