@kanso-protocol/user-menu 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,174 @@
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
+
5
+ /**
6
+ * Kanso Protocol — UserMenu
7
+ *
8
+ * Preset dropdown shown from the user Avatar in Header. User block
9
+ * at top, main menu, optional theme toggle + help links, Sign out.
10
+ *
11
+ * Slots:
12
+ * - `[kpUserMenuItems]` — main menu items (Profile / Settings / Billing / Team)
13
+ * - `[kpUserMenuHelp]` — help links
14
+ * - `[kpUserMenuTheme]` — theme toggle row (e.g. a SegmentedControl)
15
+ *
16
+ * @example
17
+ * <kp-user-menu
18
+ * userName="Greg Black"
19
+ * userInitials="GB"
20
+ * userEmail="greg@example.com"
21
+ * [showPlanBadge]="true"
22
+ * planName="Pro"
23
+ * >
24
+ * <div kpUserMenuItems>
25
+ * <kp-menu-item icon="user" label="Profile" (click$)="goto('profile')"/>
26
+ * ...
27
+ * </div>
28
+ * </kp-user-menu>
29
+ */
30
+ class KpUserMenuComponent {
31
+ size = 'md';
32
+ userName = 'Greg Black';
33
+ userEmail = 'greg@example.com';
34
+ userInitials = 'GB';
35
+ showEmail = true;
36
+ showPlanBadge = false;
37
+ planName = 'Pro';
38
+ showThemeToggle = false;
39
+ showHelpLink = true;
40
+ signOut = new EventEmitter();
41
+ get avatarSize() {
42
+ return this.size === 'md' ? 'lg' : 'md';
43
+ }
44
+ get hostClasses() {
45
+ return `kp-user-menu kp-user-menu--${this.size}`;
46
+ }
47
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: KpUserMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
48
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.7", type: KpUserMenuComponent, isStandalone: true, selector: "kp-user-menu", inputs: { size: "size", userName: "userName", userEmail: "userEmail", userInitials: "userInitials", showEmail: "showEmail", showPlanBadge: "showPlanBadge", planName: "planName", showThemeToggle: "showThemeToggle", showHelpLink: "showHelpLink" }, outputs: { signOut: "signOut" }, host: { attributes: { "role": "menu" }, properties: { "class": "hostClasses" } }, ngImport: i0, template: `
49
+ <div class="kp-user-menu__info">
50
+ <kp-avatar [size]="avatarSize" [initials]="userInitials || null" [showStatus]="true" status="online"/>
51
+ <div class="kp-user-menu__text">
52
+ <span class="kp-user-menu__name-row">
53
+ <span class="kp-user-menu__name">{{ userName }}</span>
54
+ @if (showPlanBadge) {
55
+ <span class="kp-user-menu__plan">{{ planName }}</span>
56
+ }
57
+ </span>
58
+ @if (showEmail && userEmail) {
59
+ <span class="kp-user-menu__email">{{ userEmail }}</span>
60
+ }
61
+ </div>
62
+ </div>
63
+
64
+ <div class="kp-user-menu__divider" aria-hidden="true"></div>
65
+
66
+ <div class="kp-user-menu__group">
67
+ <ng-content select="[kpUserMenuItems]"/>
68
+ </div>
69
+
70
+ <div class="kp-user-menu__divider" aria-hidden="true"></div>
71
+
72
+ @if (showThemeToggle) {
73
+ <div class="kp-user-menu__theme">
74
+ <span class="kp-user-menu__theme-label">Theme</span>
75
+ <ng-content select="[kpUserMenuTheme]"/>
76
+ </div>
77
+ <div class="kp-user-menu__divider" aria-hidden="true"></div>
78
+ }
79
+
80
+ @if (showHelpLink) {
81
+ <div class="kp-user-menu__group">
82
+ <ng-content select="[kpUserMenuHelp]"/>
83
+ </div>
84
+ <div class="kp-user-menu__divider" aria-hidden="true"></div>
85
+ }
86
+
87
+ <div class="kp-user-menu__group">
88
+ <button type="button" class="kp-user-menu__row kp-user-menu__row--danger" (click)="signOut.emit()">
89
+ <span class="kp-user-menu__row-icon" aria-hidden="true">
90
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M9 12h12l-3-3m0 6 3-3M15 17v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v1"/></svg>
91
+ </span>
92
+ <span>Sign out</span>
93
+ </button>
94
+ </div>
95
+ `, isInline: true, styles: [":host{box-sizing:border-box;display:flex;flex-direction:column;width:var(--kp-user-menu-w, 280px);padding:4px 0;border-radius:12px;background:var(--kp-color-white, var(--kp-color-white));border:1px solid var(--kp-color-gray-200, var(--kp-color-gray-200));box-shadow:var(--kp-elevation-overlay);font-family:var(--kp-font-family-sans, \"Onest\", system-ui, sans-serif)}:host(.kp-user-menu--sm){--kp-user-menu-w: 240px;--kp-user-menu-pad: 8px}:host(.kp-user-menu--md){--kp-user-menu-w: 280px;--kp-user-menu-pad: 12px}.kp-user-menu__info{display:flex;align-items:center;gap:12px;padding:var(--kp-user-menu-pad, 12px) calc(var(--kp-user-menu-pad, 12px) + 4px)}.kp-user-menu__text{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1 1 auto}.kp-user-menu__name-row{display:inline-flex;align-items:center;gap:6px}.kp-user-menu__name{font-size:14px;font-weight:500;color:var(--kp-color-gray-900, var(--kp-color-gray-900))}.kp-user-menu__plan{display:inline-flex;align-items:center;padding:2px 8px;border-radius:999px;background:var(--kp-color-blue-600, var(--kp-color-blue-600));color:var(--kp-color-white);font-size:11px;font-weight:600;line-height:1}.kp-user-menu__email{font-size:12px;color:var(--kp-color-gray-500, var(--kp-color-gray-500));white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kp-user-menu__divider{height:1px;background:var(--kp-color-gray-200, var(--kp-color-gray-200))}.kp-user-menu__group{padding:4px;display:flex;flex-direction:column;gap:0}.kp-user-menu__theme{display:flex;align-items:center;gap:8px;padding:var(--kp-user-menu-pad, 12px) calc(var(--kp-user-menu-pad, 12px) + 4px)}.kp-user-menu__theme-label{flex:1 1 auto;font-size:14px;color:var(--kp-color-gray-700, var(--kp-color-gray-700))}.kp-user-menu__row{all:unset;display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:6px;font-size:13px;color:var(--kp-color-gray-700, var(--kp-color-gray-700));cursor:pointer;transition:background var(--kp-motion-duration-fast) ease}.kp-user-menu__row:hover{background:var(--kp-color-gray-100, var(--kp-color-gray-100));color:var(--kp-color-gray-900, var(--kp-color-gray-900))}.kp-user-menu__row-icon{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;color:var(--kp-color-gray-500, var(--kp-color-gray-500))}.kp-user-menu__row-icon svg{width:100%;height:100%}.kp-user-menu__row--danger{color:var(--kp-color-red-600, var(--kp-color-red-600))}.kp-user-menu__row--danger .kp-user-menu__row-icon{color:var(--kp-color-red-500, var(--kp-color-red-500))}.kp-user-menu__row--danger:hover{background:var(--kp-color-red-50, var(--kp-color-red-50));color:var(--kp-color-red-700, var(--kp-color-red-700))}\n"], dependencies: [{ kind: "component", type: KpAvatarComponent, selector: "kp-avatar", inputs: ["size", "shape", "appearance", "initials", "src", "alt", "showStatus", "status", "showRing", "ariaLabelOverride"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
96
+ }
97
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: KpUserMenuComponent, decorators: [{
98
+ type: Component,
99
+ args: [{ selector: 'kp-user-menu', imports: [KpAvatarComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: { '[class]': 'hostClasses', role: 'menu' }, template: `
100
+ <div class="kp-user-menu__info">
101
+ <kp-avatar [size]="avatarSize" [initials]="userInitials || null" [showStatus]="true" status="online"/>
102
+ <div class="kp-user-menu__text">
103
+ <span class="kp-user-menu__name-row">
104
+ <span class="kp-user-menu__name">{{ userName }}</span>
105
+ @if (showPlanBadge) {
106
+ <span class="kp-user-menu__plan">{{ planName }}</span>
107
+ }
108
+ </span>
109
+ @if (showEmail && userEmail) {
110
+ <span class="kp-user-menu__email">{{ userEmail }}</span>
111
+ }
112
+ </div>
113
+ </div>
114
+
115
+ <div class="kp-user-menu__divider" aria-hidden="true"></div>
116
+
117
+ <div class="kp-user-menu__group">
118
+ <ng-content select="[kpUserMenuItems]"/>
119
+ </div>
120
+
121
+ <div class="kp-user-menu__divider" aria-hidden="true"></div>
122
+
123
+ @if (showThemeToggle) {
124
+ <div class="kp-user-menu__theme">
125
+ <span class="kp-user-menu__theme-label">Theme</span>
126
+ <ng-content select="[kpUserMenuTheme]"/>
127
+ </div>
128
+ <div class="kp-user-menu__divider" aria-hidden="true"></div>
129
+ }
130
+
131
+ @if (showHelpLink) {
132
+ <div class="kp-user-menu__group">
133
+ <ng-content select="[kpUserMenuHelp]"/>
134
+ </div>
135
+ <div class="kp-user-menu__divider" aria-hidden="true"></div>
136
+ }
137
+
138
+ <div class="kp-user-menu__group">
139
+ <button type="button" class="kp-user-menu__row kp-user-menu__row--danger" (click)="signOut.emit()">
140
+ <span class="kp-user-menu__row-icon" aria-hidden="true">
141
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M9 12h12l-3-3m0 6 3-3M15 17v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v1"/></svg>
142
+ </span>
143
+ <span>Sign out</span>
144
+ </button>
145
+ </div>
146
+ `, styles: [":host{box-sizing:border-box;display:flex;flex-direction:column;width:var(--kp-user-menu-w, 280px);padding:4px 0;border-radius:12px;background:var(--kp-color-white, var(--kp-color-white));border:1px solid var(--kp-color-gray-200, var(--kp-color-gray-200));box-shadow:var(--kp-elevation-overlay);font-family:var(--kp-font-family-sans, \"Onest\", system-ui, sans-serif)}:host(.kp-user-menu--sm){--kp-user-menu-w: 240px;--kp-user-menu-pad: 8px}:host(.kp-user-menu--md){--kp-user-menu-w: 280px;--kp-user-menu-pad: 12px}.kp-user-menu__info{display:flex;align-items:center;gap:12px;padding:var(--kp-user-menu-pad, 12px) calc(var(--kp-user-menu-pad, 12px) + 4px)}.kp-user-menu__text{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1 1 auto}.kp-user-menu__name-row{display:inline-flex;align-items:center;gap:6px}.kp-user-menu__name{font-size:14px;font-weight:500;color:var(--kp-color-gray-900, var(--kp-color-gray-900))}.kp-user-menu__plan{display:inline-flex;align-items:center;padding:2px 8px;border-radius:999px;background:var(--kp-color-blue-600, var(--kp-color-blue-600));color:var(--kp-color-white);font-size:11px;font-weight:600;line-height:1}.kp-user-menu__email{font-size:12px;color:var(--kp-color-gray-500, var(--kp-color-gray-500));white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.kp-user-menu__divider{height:1px;background:var(--kp-color-gray-200, var(--kp-color-gray-200))}.kp-user-menu__group{padding:4px;display:flex;flex-direction:column;gap:0}.kp-user-menu__theme{display:flex;align-items:center;gap:8px;padding:var(--kp-user-menu-pad, 12px) calc(var(--kp-user-menu-pad, 12px) + 4px)}.kp-user-menu__theme-label{flex:1 1 auto;font-size:14px;color:var(--kp-color-gray-700, var(--kp-color-gray-700))}.kp-user-menu__row{all:unset;display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:6px;font-size:13px;color:var(--kp-color-gray-700, var(--kp-color-gray-700));cursor:pointer;transition:background var(--kp-motion-duration-fast) ease}.kp-user-menu__row:hover{background:var(--kp-color-gray-100, var(--kp-color-gray-100));color:var(--kp-color-gray-900, var(--kp-color-gray-900))}.kp-user-menu__row-icon{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;color:var(--kp-color-gray-500, var(--kp-color-gray-500))}.kp-user-menu__row-icon svg{width:100%;height:100%}.kp-user-menu__row--danger{color:var(--kp-color-red-600, var(--kp-color-red-600))}.kp-user-menu__row--danger .kp-user-menu__row-icon{color:var(--kp-color-red-500, var(--kp-color-red-500))}.kp-user-menu__row--danger:hover{background:var(--kp-color-red-50, var(--kp-color-red-50));color:var(--kp-color-red-700, var(--kp-color-red-700))}\n"] }]
147
+ }], propDecorators: { size: [{
148
+ type: Input
149
+ }], userName: [{
150
+ type: Input
151
+ }], userEmail: [{
152
+ type: Input
153
+ }], userInitials: [{
154
+ type: Input
155
+ }], showEmail: [{
156
+ type: Input
157
+ }], showPlanBadge: [{
158
+ type: Input
159
+ }], planName: [{
160
+ type: Input
161
+ }], showThemeToggle: [{
162
+ type: Input
163
+ }], showHelpLink: [{
164
+ type: Input
165
+ }], signOut: [{
166
+ type: Output
167
+ }] } });
168
+
169
+ /**
170
+ * Generated bundle index. Do not edit.
171
+ */
172
+
173
+ export { KpUserMenuComponent };
174
+ //# sourceMappingURL=kanso-protocol-user-menu.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kanso-protocol-user-menu.mjs","sources":["../../../../../packages/patterns/user-menu/src/user-menu.component.ts","../../../../../packages/patterns/user-menu/src/kanso-protocol-user-menu.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n EventEmitter,\n Input,\n Output,\n} from '@angular/core';\nimport { KpAvatarComponent } from '@kanso-protocol/avatar';\n\nexport type KpUserMenuSize = 'sm' | 'md';\n\nexport interface KpUserMenuItem {\n id: string;\n label: string;\n danger?: boolean;\n}\n\n/**\n * Kanso Protocol — UserMenu\n *\n * Preset dropdown shown from the user Avatar in Header. User block\n * at top, main menu, optional theme toggle + help links, Sign out.\n *\n * Slots:\n * - `[kpUserMenuItems]` — main menu items (Profile / Settings / Billing / Team)\n * - `[kpUserMenuHelp]` — help links\n * - `[kpUserMenuTheme]` — theme toggle row (e.g. a SegmentedControl)\n *\n * @example\n * <kp-user-menu\n * userName=\"Greg Black\"\n * userInitials=\"GB\"\n * userEmail=\"greg@example.com\"\n * [showPlanBadge]=\"true\"\n * planName=\"Pro\"\n * >\n * <div kpUserMenuItems>\n * <kp-menu-item icon=\"user\" label=\"Profile\" (click$)=\"goto('profile')\"/>\n * ...\n * </div>\n * </kp-user-menu>\n */\n@Component({\n selector: 'kp-user-menu',\n imports: [KpAvatarComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { '[class]': 'hostClasses', role: 'menu' },\n template: `\n <div class=\"kp-user-menu__info\">\n <kp-avatar [size]=\"avatarSize\" [initials]=\"userInitials || null\" [showStatus]=\"true\" status=\"online\"/>\n <div class=\"kp-user-menu__text\">\n <span class=\"kp-user-menu__name-row\">\n <span class=\"kp-user-menu__name\">{{ userName }}</span>\n @if (showPlanBadge) {\n <span class=\"kp-user-menu__plan\">{{ planName }}</span>\n }\n </span>\n @if (showEmail && userEmail) {\n <span class=\"kp-user-menu__email\">{{ userEmail }}</span>\n }\n </div>\n </div>\n\n <div class=\"kp-user-menu__divider\" aria-hidden=\"true\"></div>\n\n <div class=\"kp-user-menu__group\">\n <ng-content select=\"[kpUserMenuItems]\"/>\n </div>\n\n <div class=\"kp-user-menu__divider\" aria-hidden=\"true\"></div>\n\n @if (showThemeToggle) {\n <div class=\"kp-user-menu__theme\">\n <span class=\"kp-user-menu__theme-label\">Theme</span>\n <ng-content select=\"[kpUserMenuTheme]\"/>\n </div>\n <div class=\"kp-user-menu__divider\" aria-hidden=\"true\"></div>\n }\n\n @if (showHelpLink) {\n <div class=\"kp-user-menu__group\">\n <ng-content select=\"[kpUserMenuHelp]\"/>\n </div>\n <div class=\"kp-user-menu__divider\" aria-hidden=\"true\"></div>\n }\n\n <div class=\"kp-user-menu__group\">\n <button type=\"button\" class=\"kp-user-menu__row kp-user-menu__row--danger\" (click)=\"signOut.emit()\">\n <span class=\"kp-user-menu__row-icon\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.75\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M9 12h12l-3-3m0 6 3-3M15 17v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v1\"/></svg>\n </span>\n <span>Sign out</span>\n </button>\n </div>\n `,\n styles: [`\n :host {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n width: var(--kp-user-menu-w, 280px);\n padding: 4px 0;\n border-radius: 12px;\n background: var(--kp-color-white, var(--kp-color-white));\n border: 1px solid var(--kp-color-gray-200, var(--kp-color-gray-200));\n box-shadow: var(--kp-elevation-overlay);\n font-family: var(--kp-font-family-sans, 'Onest', system-ui, sans-serif);\n }\n :host(.kp-user-menu--sm) { --kp-user-menu-w: 240px; --kp-user-menu-pad: 8px; }\n :host(.kp-user-menu--md) { --kp-user-menu-w: 280px; --kp-user-menu-pad: 12px; }\n\n .kp-user-menu__info {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: var(--kp-user-menu-pad, 12px) calc(var(--kp-user-menu-pad, 12px) + 4px);\n }\n .kp-user-menu__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; }\n .kp-user-menu__name-row { display: inline-flex; align-items: center; gap: 6px; }\n .kp-user-menu__name { font-size: 14px; font-weight: 500; color: var(--kp-color-gray-900, var(--kp-color-gray-900)); }\n .kp-user-menu__plan {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 999px;\n background: var(--kp-color-blue-600, var(--kp-color-blue-600));\n color: var(--kp-color-white);\n font-size: 11px;\n font-weight: 600;\n line-height: 1;\n }\n .kp-user-menu__email { font-size: 12px; color: var(--kp-color-gray-500, var(--kp-color-gray-500)); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n\n .kp-user-menu__divider { height: 1px; background: var(--kp-color-gray-200, var(--kp-color-gray-200)); }\n\n .kp-user-menu__group { padding: 4px; display: flex; flex-direction: column; gap: 0; }\n\n .kp-user-menu__theme {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: var(--kp-user-menu-pad, 12px) calc(var(--kp-user-menu-pad, 12px) + 4px);\n }\n .kp-user-menu__theme-label { flex: 1 1 auto; font-size: 14px; color: var(--kp-color-gray-700, var(--kp-color-gray-700)); }\n\n .kp-user-menu__row {\n all: unset;\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 8px;\n border-radius: 6px;\n font-size: 13px;\n color: var(--kp-color-gray-700, var(--kp-color-gray-700));\n cursor: pointer;\n transition: background var(--kp-motion-duration-fast) ease;\n }\n .kp-user-menu__row:hover { background: var(--kp-color-gray-100, var(--kp-color-gray-100)); color: var(--kp-color-gray-900, var(--kp-color-gray-900)); }\n .kp-user-menu__row-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n color: var(--kp-color-gray-500, var(--kp-color-gray-500));\n }\n .kp-user-menu__row-icon svg { width: 100%; height: 100%; }\n\n .kp-user-menu__row--danger {\n color: var(--kp-color-red-600, var(--kp-color-red-600));\n }\n .kp-user-menu__row--danger .kp-user-menu__row-icon { color: var(--kp-color-red-500, var(--kp-color-red-500)); }\n .kp-user-menu__row--danger:hover { background: var(--kp-color-red-50, var(--kp-color-red-50)); color: var(--kp-color-red-700, var(--kp-color-red-700)); }\n `],\n})\nexport class KpUserMenuComponent {\n @Input() size: KpUserMenuSize = 'md';\n\n @Input() userName: string | null = 'Greg Black';\n @Input() userEmail: string | null = 'greg@example.com';\n @Input() userInitials: string | null = 'GB';\n\n @Input() showEmail = true;\n @Input() showPlanBadge = false;\n @Input() planName = 'Pro';\n @Input() showThemeToggle = false;\n @Input() showHelpLink = true;\n\n @Output() signOut = new EventEmitter<void>();\n\n get avatarSize(): 'md' | 'lg' {\n return this.size === 'md' ? 'lg' : 'md';\n }\n\n get hostClasses(): string {\n return `kp-user-menu kp-user-menu--${this.size}`;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAiBA;;;;;;;;;;;;;;;;;;;;;;;;AAwBG;MAsIU,mBAAmB,CAAA;IACrB,IAAI,GAAmB,IAAI;IAE3B,QAAQ,GAAkB,YAAY;IACtC,SAAS,GAAkB,kBAAkB;IAC7C,YAAY,GAAkB,IAAI;IAElC,SAAS,GAAG,IAAI;IAChB,aAAa,GAAG,KAAK;IACrB,QAAQ,GAAG,KAAK;IAChB,eAAe,GAAG,KAAK;IACvB,YAAY,GAAG,IAAI;AAElB,IAAA,OAAO,GAAG,IAAI,YAAY,EAAQ;AAE5C,IAAA,IAAI,UAAU,GAAA;AACZ,QAAA,OAAO,IAAI,CAAC,IAAI,KAAK,IAAI,GAAG,IAAI,GAAG,IAAI;IACzC;AAEA,IAAA,IAAI,WAAW,GAAA;AACb,QAAA,OAAO,CAAA,2BAAA,EAA8B,IAAI,CAAC,IAAI,EAAE;IAClD;uGArBW,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAnB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,mBAAmB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,QAAA,EAAA,UAAA,EAAA,SAAA,EAAA,WAAA,EAAA,YAAA,EAAA,cAAA,EAAA,SAAA,EAAA,WAAA,EAAA,aAAA,EAAA,eAAA,EAAA,QAAA,EAAA,UAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,cAAA,EAAA,EAAA,OAAA,EAAA,EAAA,OAAA,EAAA,SAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,MAAA,EAAA,MAAA,EAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,aAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAhIpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,mnFAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAlDS,iBAAiB,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,OAAA,EAAA,YAAA,EAAA,UAAA,EAAA,KAAA,EAAA,KAAA,EAAA,YAAA,EAAA,QAAA,EAAA,UAAA,EAAA,mBAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAmIhB,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBArI/B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,cAAc,WACf,CAAC,iBAAiB,CAAC,EAAA,eAAA,EACX,uBAAuB,CAAC,MAAM,EAAA,IAAA,EACzC,EAAE,SAAS,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,EAAA,QAAA,EACtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,mnFAAA,CAAA,EAAA;;sBAkFA;;sBAEA;;sBACA;;sBACA;;sBAEA;;sBACA;;sBACA;;sBACA;;sBACA;;sBAEA;;;AC5LH;;AAEG;;;;"}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@kanso-protocol/user-menu",
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
+ },
11
+ "description": "Kanso Protocol — user-menu (pattern).",
12
+ "author": "GregNBlack",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/GregNBlack/kanso-protocol.git",
16
+ "directory": "packages/patterns/user-menu"
17
+ },
18
+ "homepage": "https://gregnblack.github.io/kanso-protocol/?path=/docs/patterns-usermenu--docs",
19
+ "bugs": "https://github.com/GregNBlack/kanso-protocol/issues",
20
+ "keywords": [
21
+ "design-system",
22
+ "angular",
23
+ "kanso",
24
+ "user-menu"
25
+ ],
26
+ "sideEffects": false,
27
+ "module": "fesm2022/kanso-protocol-user-menu.mjs",
28
+ "typings": "types/kanso-protocol-user-menu.d.ts",
29
+ "exports": {
30
+ "./package.json": {
31
+ "default": "./package.json"
32
+ },
33
+ ".": {
34
+ "types": "./types/kanso-protocol-user-menu.d.ts",
35
+ "default": "./fesm2022/kanso-protocol-user-menu.mjs"
36
+ }
37
+ },
38
+ "type": "module",
39
+ "dependencies": {
40
+ "tslib": "^2.3.0"
41
+ }
42
+ }
@@ -0,0 +1,53 @@
1
+ import * as i0 from '@angular/core';
2
+ import { EventEmitter } from '@angular/core';
3
+
4
+ type KpUserMenuSize = 'sm' | 'md';
5
+ interface KpUserMenuItem {
6
+ id: string;
7
+ label: string;
8
+ danger?: boolean;
9
+ }
10
+ /**
11
+ * Kanso Protocol — UserMenu
12
+ *
13
+ * Preset dropdown shown from the user Avatar in Header. User block
14
+ * at top, main menu, optional theme toggle + help links, Sign out.
15
+ *
16
+ * Slots:
17
+ * - `[kpUserMenuItems]` — main menu items (Profile / Settings / Billing / Team)
18
+ * - `[kpUserMenuHelp]` — help links
19
+ * - `[kpUserMenuTheme]` — theme toggle row (e.g. a SegmentedControl)
20
+ *
21
+ * @example
22
+ * <kp-user-menu
23
+ * userName="Greg Black"
24
+ * userInitials="GB"
25
+ * userEmail="greg@example.com"
26
+ * [showPlanBadge]="true"
27
+ * planName="Pro"
28
+ * >
29
+ * <div kpUserMenuItems>
30
+ * <kp-menu-item icon="user" label="Profile" (click$)="goto('profile')"/>
31
+ * ...
32
+ * </div>
33
+ * </kp-user-menu>
34
+ */
35
+ declare class KpUserMenuComponent {
36
+ size: KpUserMenuSize;
37
+ userName: string | null;
38
+ userEmail: string | null;
39
+ userInitials: string | null;
40
+ showEmail: boolean;
41
+ showPlanBadge: boolean;
42
+ planName: string;
43
+ showThemeToggle: boolean;
44
+ showHelpLink: boolean;
45
+ signOut: EventEmitter<void>;
46
+ get avatarSize(): 'md' | 'lg';
47
+ get hostClasses(): string;
48
+ static ɵfac: i0.ɵɵFactoryDeclaration<KpUserMenuComponent, never>;
49
+ static ɵcmp: i0.ɵɵComponentDeclaration<KpUserMenuComponent, "kp-user-menu", never, { "size": { "alias": "size"; "required": false; }; "userName": { "alias": "userName"; "required": false; }; "userEmail": { "alias": "userEmail"; "required": false; }; "userInitials": { "alias": "userInitials"; "required": false; }; "showEmail": { "alias": "showEmail"; "required": false; }; "showPlanBadge": { "alias": "showPlanBadge"; "required": false; }; "planName": { "alias": "planName"; "required": false; }; "showThemeToggle": { "alias": "showThemeToggle"; "required": false; }; "showHelpLink": { "alias": "showHelpLink"; "required": false; }; }, { "signOut": "signOut"; }, never, ["[kpUserMenuItems]", "[kpUserMenuTheme]", "[kpUserMenuHelp]"], true, never>;
50
+ }
51
+
52
+ export { KpUserMenuComponent };
53
+ export type { KpUserMenuItem, KpUserMenuSize };