@memberjunction/ng-explorer-core 5.51.2 → 5.51.3
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.
- package/dist/lib/command-palette/command-palette.component.d.ts +13 -0
- package/dist/lib/command-palette/command-palette.component.d.ts.map +1 -1
- package/dist/lib/command-palette/command-palette.component.js +105 -41
- package/dist/lib/command-palette/command-palette.component.js.map +1 -1
- package/dist/lib/shell/shell.component.d.ts +23 -0
- package/dist/lib/shell/shell.component.d.ts.map +1 -1
- package/dist/lib/shell/shell.component.js +307 -239
- package/dist/lib/shell/shell.component.js.map +1 -1
- package/package.json +51 -51
|
@@ -20,10 +20,13 @@ export declare class CommandPaletteComponent implements OnInit, OnDestroy {
|
|
|
20
20
|
private cdr;
|
|
21
21
|
private destroy$;
|
|
22
22
|
SearchInput: ElementRef<HTMLInputElement>;
|
|
23
|
+
PaletteModal?: ElementRef<HTMLElement>;
|
|
23
24
|
AppSelected: EventEmitter<string>;
|
|
24
25
|
KnowledgeSearchRequested: EventEmitter<string>;
|
|
25
26
|
IsOpen: boolean;
|
|
26
27
|
SearchQuery: string;
|
|
28
|
+
/** The element focus came from, so closing can hand it back (WCAG 2.4.3). */
|
|
29
|
+
private invoker;
|
|
27
30
|
AllApps: BaseApplication[];
|
|
28
31
|
FilteredApps: BaseApplication[];
|
|
29
32
|
SelectedIndex: number;
|
|
@@ -39,6 +42,16 @@ export declare class CommandPaletteComponent implements OnInit, OnDestroy {
|
|
|
39
42
|
* Called when command palette closes
|
|
40
43
|
*/
|
|
41
44
|
private onClose;
|
|
45
|
+
/**
|
|
46
|
+
* Focusable descendants of the modal, in DOM order — the trap's cycle.
|
|
47
|
+
*/
|
|
48
|
+
private focusableInModal;
|
|
49
|
+
/**
|
|
50
|
+
* Keep Tab inside the dialog (WCAG 2.4.3 / 2.1.2). `aria-modal` tells a screen reader the
|
|
51
|
+
* rest of the page is inert but does NOT stop Tab, so without this a keyboard user tabs
|
|
52
|
+
* straight out of an open palette into the page behind it and cannot see where they are.
|
|
53
|
+
*/
|
|
54
|
+
private trapTab;
|
|
42
55
|
/**
|
|
43
56
|
* Handle search query change
|
|
44
57
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-palette.component.d.ts","sourceRoot":"","sources":["../../../src/lib/command-palette/command-palette.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAa,UAAU,EAAgB,iBAAiB,EAAU,YAAY,EAAE,MAAM,eAAe,CAAC;AAG3I,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAC1F,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;;AAElE;;;;;;;;;;;GAWG;AACH,qBAMa,uBAAwB,YAAW,MAAM,EAAE,SAAS;
|
|
1
|
+
{"version":3,"file":"command-palette.component.d.ts","sourceRoot":"","sources":["../../../src/lib/command-palette/command-palette.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAa,UAAU,EAAgB,iBAAiB,EAAU,YAAY,EAAE,MAAM,eAAe,CAAC;AAG3I,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAC1F,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;;AAElE;;;;;;;;;;;GAWG;AACH,qBAMa,uBAAwB,YAAW,MAAM,EAAE,SAAS;IAkB7D,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,GAAG;IAnBb,OAAO,CAAC,QAAQ,CAAuB;IAEb,WAAW,EAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAC1C,YAAY,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IACxD,WAAW,uBAA8B;IACzC,wBAAwB,uBAA8B;IAEhE,MAAM,UAAS;IACf,WAAW,SAAM;IACjB,6EAA6E;IAC7E,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,EAAE,eAAe,EAAE,CAAM;IAChC,YAAY,EAAE,eAAe,EAAE,CAAM;IACrC,aAAa,SAAK;IAClB,YAAY,UAAS;gBAGX,OAAO,EAAE,qBAAqB,EAC9B,UAAU,EAAE,kBAAkB,EAC9B,GAAG,EAAE,iBAAiB;IAGhC,QAAQ,IAAI,IAAI;IAqBhB,WAAW,IAAI,IAAI;IAKnB;;OAEG;IACH,OAAO,CAAC,MAAM;IAsBd;;OAEG;IACH,OAAO,CAAC,OAAO;IAef;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAaxB;;;;OAIG;IACH,OAAO,CAAC,OAAO;IAoBf;;OAEG;IACH,cAAc,IAAI,IAAI;IAKtB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAyBzB;;;;;;;;;OASG;IACH,OAAO,CAAC,mBAAmB;IA2B3B;;OAEG;IACH,SAAS,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI;IAQrC;;OAEG;IACH,kBAAkB,IAAI,IAAI;IAO1B;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IAEH,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAgDzC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAK1B;;OAEG;IACH,OAAO,CAAC,gBAAgB;yCAzSb,uBAAuB;2CAAvB,uBAAuB;CAiTnC"}
|
|
@@ -8,14 +8,15 @@ import * as i3 from "@angular/forms";
|
|
|
8
8
|
import * as i4 from "@memberjunction/ng-ui-components";
|
|
9
9
|
import * as i5 from "@memberjunction/ng-shared-generic";
|
|
10
10
|
const _c0 = ["searchInput"];
|
|
11
|
+
const _c1 = ["paletteModal"];
|
|
11
12
|
function CommandPaletteComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
12
13
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
13
|
-
i0.ɵɵelementStart(0, "div",
|
|
14
|
+
i0.ɵɵelementStart(0, "div", 4);
|
|
14
15
|
i0.ɵɵlistener("click", function CommandPaletteComponent_Conditional_0_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Close()); });
|
|
15
16
|
i0.ɵɵelementEnd();
|
|
16
17
|
} }
|
|
17
|
-
function
|
|
18
|
-
i0.ɵɵelementStart(0, "div",
|
|
18
|
+
function CommandPaletteComponent_Conditional_1_For_8_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
19
|
+
i0.ɵɵelementStart(0, "div", 16);
|
|
19
20
|
i0.ɵɵtext(1);
|
|
20
21
|
i0.ɵɵelementEnd();
|
|
21
22
|
} if (rf & 2) {
|
|
@@ -23,15 +24,15 @@ function CommandPaletteComponent_Conditional_1_For_7_Conditional_5_Template(rf,
|
|
|
23
24
|
i0.ɵɵadvance();
|
|
24
25
|
i0.ɵɵtextInterpolate(app_r5.Description);
|
|
25
26
|
} }
|
|
26
|
-
function
|
|
27
|
+
function CommandPaletteComponent_Conditional_1_For_8_Template(rf, ctx) { if (rf & 1) {
|
|
27
28
|
const _r4 = i0.ɵɵgetCurrentView();
|
|
28
|
-
i0.ɵɵelementStart(0, "div",
|
|
29
|
-
i0.ɵɵlistener("click", function
|
|
30
|
-
i0.ɵɵelement(1, "i",
|
|
31
|
-
i0.ɵɵelementStart(2, "div",
|
|
29
|
+
i0.ɵɵelementStart(0, "div", 12);
|
|
30
|
+
i0.ɵɵlistener("click", function CommandPaletteComponent_Conditional_1_For_8_Template_div_click_0_listener() { const app_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SelectApp(app_r5)); });
|
|
31
|
+
i0.ɵɵelement(1, "i", 13);
|
|
32
|
+
i0.ɵɵelementStart(2, "div", 14)(3, "div", 15);
|
|
32
33
|
i0.ɵɵtext(4);
|
|
33
34
|
i0.ɵɵelementEnd();
|
|
34
|
-
i0.ɵɵconditionalCreate(5,
|
|
35
|
+
i0.ɵɵconditionalCreate(5, CommandPaletteComponent_Conditional_1_For_8_Conditional_5_Template, 2, 1, "div", 16);
|
|
35
36
|
i0.ɵɵelementEnd()();
|
|
36
37
|
} if (rf & 2) {
|
|
37
38
|
const app_r5 = ctx.$implicit;
|
|
@@ -47,21 +48,21 @@ function CommandPaletteComponent_Conditional_1_For_7_Template(rf, ctx) { if (rf
|
|
|
47
48
|
i0.ɵɵadvance();
|
|
48
49
|
i0.ɵɵconditional(app_r5.Description ? 5 : -1);
|
|
49
50
|
} }
|
|
50
|
-
function
|
|
51
|
+
function CommandPaletteComponent_Conditional_1_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
51
52
|
const _r7 = i0.ɵɵgetCurrentView();
|
|
52
|
-
i0.ɵɵelementStart(0, "div",
|
|
53
|
+
i0.ɵɵelementStart(0, "div", 17)(1, "span", 18);
|
|
53
54
|
i0.ɵɵtext(2, "Knowledge Search");
|
|
54
55
|
i0.ɵɵelementEnd()();
|
|
55
|
-
i0.ɵɵelementStart(3, "div",
|
|
56
|
-
i0.ɵɵlistener("click", function
|
|
57
|
-
i0.ɵɵelement(4, "i",
|
|
58
|
-
i0.ɵɵelementStart(5, "div",
|
|
56
|
+
i0.ɵɵelementStart(3, "div", 19);
|
|
57
|
+
i0.ɵɵlistener("click", function CommandPaletteComponent_Conditional_1_Conditional_9_Template_div_click_3_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SearchKnowledgeHub()); });
|
|
58
|
+
i0.ɵɵelement(4, "i", 20);
|
|
59
|
+
i0.ɵɵelementStart(5, "div", 14)(6, "div", 15);
|
|
59
60
|
i0.ɵɵtext(7, "Search Knowledge Hub");
|
|
60
61
|
i0.ɵɵelementEnd();
|
|
61
|
-
i0.ɵɵelementStart(8, "div",
|
|
62
|
+
i0.ɵɵelementStart(8, "div", 16);
|
|
62
63
|
i0.ɵɵtext(9);
|
|
63
64
|
i0.ɵɵelementEnd()();
|
|
64
|
-
i0.ɵɵelementStart(10, "kbd",
|
|
65
|
+
i0.ɵɵelementStart(10, "kbd", 21);
|
|
65
66
|
i0.ɵɵtext(11, "Enter");
|
|
66
67
|
i0.ɵɵelementEnd()();
|
|
67
68
|
} if (rf & 2) {
|
|
@@ -71,12 +72,12 @@ function CommandPaletteComponent_Conditional_1_Conditional_8_Template(rf, ctx) {
|
|
|
71
72
|
i0.ɵɵadvance(6);
|
|
72
73
|
i0.ɵɵtextInterpolate1("Search \"", ctx_r1.SearchQuery, "\" across entities, documents, and content");
|
|
73
74
|
} }
|
|
74
|
-
function CommandPaletteComponent_Conditional_1_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
75
|
-
i0.ɵɵelement(0, "mj-empty-state", 9);
|
|
76
|
-
} }
|
|
77
75
|
function CommandPaletteComponent_Conditional_1_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
78
|
-
i0.ɵɵ
|
|
79
|
-
|
|
76
|
+
i0.ɵɵelement(0, "mj-empty-state", 10);
|
|
77
|
+
} }
|
|
78
|
+
function CommandPaletteComponent_Conditional_1_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
79
|
+
i0.ɵɵelementStart(0, "div", 11);
|
|
80
|
+
i0.ɵɵelement(1, "mj-loading", 22);
|
|
80
81
|
i0.ɵɵelementEnd();
|
|
81
82
|
} if (rf & 2) {
|
|
82
83
|
i0.ɵɵadvance();
|
|
@@ -84,31 +85,31 @@ function CommandPaletteComponent_Conditional_1_Conditional_10_Template(rf, ctx)
|
|
|
84
85
|
} }
|
|
85
86
|
function CommandPaletteComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
86
87
|
const _r3 = i0.ɵɵgetCurrentView();
|
|
87
|
-
i0.ɵɵelementStart(0, "div",
|
|
88
|
-
i0.ɵɵelement(
|
|
89
|
-
i0.ɵɵelementStart(
|
|
90
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
91
|
-
i0.ɵɵlistener("input", function
|
|
88
|
+
i0.ɵɵelementStart(0, "div", 3, 0)(2, "div", 5);
|
|
89
|
+
i0.ɵɵelement(3, "i", 6);
|
|
90
|
+
i0.ɵɵelementStart(4, "input", 7, 1);
|
|
91
|
+
i0.ɵɵtwoWayListener("ngModelChange", function CommandPaletteComponent_Conditional_1_Template_input_ngModelChange_4_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.SearchQuery, $event) || (ctx_r1.SearchQuery = $event); return i0.ɵɵresetView($event); });
|
|
92
|
+
i0.ɵɵlistener("input", function CommandPaletteComponent_Conditional_1_Template_input_input_4_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnSearchChange()); });
|
|
92
93
|
i0.ɵɵelementEnd()();
|
|
93
|
-
i0.ɵɵelementStart(
|
|
94
|
-
i0.ɵɵrepeaterCreate(
|
|
95
|
-
i0.ɵɵconditionalCreate(
|
|
96
|
-
i0.ɵɵconditionalCreate(
|
|
94
|
+
i0.ɵɵelementStart(6, "div", 8);
|
|
95
|
+
i0.ɵɵrepeaterCreate(7, CommandPaletteComponent_Conditional_1_For_8_Template, 6, 9, "div", 9, i0.ɵɵrepeaterTrackByIdentity);
|
|
96
|
+
i0.ɵɵconditionalCreate(9, CommandPaletteComponent_Conditional_1_Conditional_9_Template, 12, 3);
|
|
97
|
+
i0.ɵɵconditionalCreate(10, CommandPaletteComponent_Conditional_1_Conditional_10_Template, 1, 0, "mj-empty-state", 10);
|
|
97
98
|
i0.ɵɵelementEnd();
|
|
98
|
-
i0.ɵɵconditionalCreate(
|
|
99
|
+
i0.ɵɵconditionalCreate(11, CommandPaletteComponent_Conditional_1_Conditional_11_Template, 2, 1, "div", 11);
|
|
99
100
|
i0.ɵɵelementEnd();
|
|
100
101
|
} if (rf & 2) {
|
|
101
102
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
102
|
-
i0.ɵɵadvance(
|
|
103
|
+
i0.ɵɵadvance(4);
|
|
103
104
|
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.SearchQuery);
|
|
104
105
|
i0.ɵɵadvance(3);
|
|
105
106
|
i0.ɵɵrepeater(ctx_r1.FilteredApps);
|
|
106
107
|
i0.ɵɵadvance(2);
|
|
107
|
-
i0.ɵɵconditional(ctx_r1.SearchQuery.trim().length > 0 ?
|
|
108
|
+
i0.ɵɵconditional(ctx_r1.SearchQuery.trim().length > 0 ? 9 : -1);
|
|
108
109
|
i0.ɵɵadvance();
|
|
109
|
-
i0.ɵɵconditional(ctx_r1.FilteredApps.length === 0 && ctx_r1.SearchQuery ?
|
|
110
|
+
i0.ɵɵconditional(ctx_r1.FilteredApps.length === 0 && ctx_r1.SearchQuery ? 10 : -1);
|
|
110
111
|
i0.ɵɵadvance();
|
|
111
|
-
i0.ɵɵconditional(ctx_r1.IsNavigating ?
|
|
112
|
+
i0.ɵɵconditional(ctx_r1.IsNavigating ? 11 : -1);
|
|
112
113
|
} }
|
|
113
114
|
/**
|
|
114
115
|
* Command Palette Component
|
|
@@ -128,10 +129,13 @@ export class CommandPaletteComponent {
|
|
|
128
129
|
cdr;
|
|
129
130
|
destroy$ = new Subject();
|
|
130
131
|
SearchInput;
|
|
132
|
+
PaletteModal;
|
|
131
133
|
AppSelected = new EventEmitter();
|
|
132
134
|
KnowledgeSearchRequested = new EventEmitter();
|
|
133
135
|
IsOpen = false;
|
|
134
136
|
SearchQuery = '';
|
|
137
|
+
/** The element focus came from, so closing can hand it back (WCAG 2.4.3). */
|
|
138
|
+
invoker = null;
|
|
135
139
|
AllApps = [];
|
|
136
140
|
FilteredApps = [];
|
|
137
141
|
SelectedIndex = 0;
|
|
@@ -167,6 +171,10 @@ export class CommandPaletteComponent {
|
|
|
167
171
|
* Called when command palette opens
|
|
168
172
|
*/
|
|
169
173
|
onOpen() {
|
|
174
|
+
// Remember where focus came from BEFORE we take it, so Close() can hand it back.
|
|
175
|
+
// The palette opens from a global Cmd+K, so the invoker is whatever had focus.
|
|
176
|
+
const active = document.activeElement;
|
|
177
|
+
this.invoker = active instanceof HTMLElement && active !== document.body ? active : null;
|
|
170
178
|
// Reset state
|
|
171
179
|
this.SearchQuery = '';
|
|
172
180
|
this.SelectedIndex = 0;
|
|
@@ -187,6 +195,52 @@ export class CommandPaletteComponent {
|
|
|
187
195
|
this.SearchQuery = '';
|
|
188
196
|
this.SelectedIndex = 0;
|
|
189
197
|
this.IsNavigating = false;
|
|
198
|
+
// Return focus to the invoker. Guarded on the invoker still being in the document —
|
|
199
|
+
// selecting an app tears down the tab the invoker lived in, and focusing a detached
|
|
200
|
+
// node silently drops focus to <body>, which is the very thing this prevents.
|
|
201
|
+
const invoker = this.invoker;
|
|
202
|
+
this.invoker = null;
|
|
203
|
+
if (invoker && invoker.isConnected) {
|
|
204
|
+
invoker.focus();
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Focusable descendants of the modal, in DOM order — the trap's cycle.
|
|
209
|
+
*/
|
|
210
|
+
focusableInModal() {
|
|
211
|
+
const modal = this.PaletteModal?.nativeElement;
|
|
212
|
+
if (!modal) {
|
|
213
|
+
return [];
|
|
214
|
+
}
|
|
215
|
+
// No visibility filter is needed or wanted here: the entire modal lives inside an
|
|
216
|
+
// `@if (IsOpen)`, so everything this matches is genuinely rendered. (An `offsetParent`
|
|
217
|
+
// check would be actively wrong — the modal is positioned, and offsetParent is null for
|
|
218
|
+
// fixed-position subtrees in some engines and for everything under jsdom.)
|
|
219
|
+
const selector = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
220
|
+
return Array.from(modal.querySelectorAll(selector));
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Keep Tab inside the dialog (WCAG 2.4.3 / 2.1.2). `aria-modal` tells a screen reader the
|
|
224
|
+
* rest of the page is inert but does NOT stop Tab, so without this a keyboard user tabs
|
|
225
|
+
* straight out of an open palette into the page behind it and cannot see where they are.
|
|
226
|
+
*/
|
|
227
|
+
trapTab(event) {
|
|
228
|
+
const focusable = this.focusableInModal();
|
|
229
|
+
if (focusable.length === 0) {
|
|
230
|
+
event.preventDefault();
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
const first = focusable[0];
|
|
234
|
+
const last = focusable[focusable.length - 1];
|
|
235
|
+
const active = document.activeElement;
|
|
236
|
+
if (event.shiftKey && (active === first || !active || !this.PaletteModal?.nativeElement.contains(active))) {
|
|
237
|
+
event.preventDefault();
|
|
238
|
+
last.focus();
|
|
239
|
+
}
|
|
240
|
+
else if (!event.shiftKey && (active === last || !active || !this.PaletteModal?.nativeElement.contains(active))) {
|
|
241
|
+
event.preventDefault();
|
|
242
|
+
first.focus();
|
|
243
|
+
}
|
|
190
244
|
}
|
|
191
245
|
/**
|
|
192
246
|
* Handle search query change
|
|
@@ -285,6 +339,12 @@ export class CommandPaletteComponent {
|
|
|
285
339
|
HandleKeyDown(event) {
|
|
286
340
|
if (!this.IsOpen)
|
|
287
341
|
return;
|
|
342
|
+
// Tab is handled first: the INPUT guard below would otherwise let Tab fall through to
|
|
343
|
+
// the browser and walk focus out of the dialog.
|
|
344
|
+
if (event.key === 'Tab') {
|
|
345
|
+
this.trapTab(event);
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
288
348
|
// Skip if user is typing in input (except for navigation keys)
|
|
289
349
|
const target = event.target;
|
|
290
350
|
const navigationKeys = ['Escape', 'Enter', 'ArrowUp', 'ArrowDown'];
|
|
@@ -339,15 +399,16 @@ export class CommandPaletteComponent {
|
|
|
339
399
|
}
|
|
340
400
|
static ɵfac = function CommandPaletteComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CommandPaletteComponent)(i0.ɵɵdirectiveInject(i1.CommandPaletteService), i0.ɵɵdirectiveInject(i2.ApplicationManager), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
|
|
341
401
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: CommandPaletteComponent, selectors: [["mj-command-palette"]], viewQuery: function CommandPaletteComponent_Query(rf, ctx) { if (rf & 1) {
|
|
342
|
-
i0.ɵɵviewQuery(_c0, 5);
|
|
402
|
+
i0.ɵɵviewQuery(_c0, 5)(_c1, 5);
|
|
343
403
|
} if (rf & 2) {
|
|
344
404
|
let _t;
|
|
345
405
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.SearchInput = _t.first);
|
|
406
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.PaletteModal = _t.first);
|
|
346
407
|
} }, hostBindings: function CommandPaletteComponent_HostBindings(rf, ctx) { if (rf & 1) {
|
|
347
408
|
i0.ɵɵlistener("keydown", function CommandPaletteComponent_keydown_HostBindingHandler($event) { return ctx.HandleKeyDown($event); }, i0.ɵɵresolveDocument);
|
|
348
|
-
} }, outputs: { AppSelected: "AppSelected", KnowledgeSearchRequested: "KnowledgeSearchRequested" }, standalone: false, decls: 2, vars: 2, consts: [["searchInput", ""], ["role", "presentation", "aria-hidden", "true", 1, "command-palette-backdrop"], ["role", "dialog", "aria-label", "Search applications", "aria-modal", "true", 1, "command-palette-modal"], ["role", "presentation", "aria-hidden", "true", 1, "command-palette-backdrop", 3, "click"], [1, "search-container"], ["aria-hidden", "true", 1, "fa-solid", "fa-search", "search-icon"], ["type", "text", "placeholder", "Search applications...", "autocomplete", "off", "spellcheck", "false", "aria-label", "Search applications", 1, "search-input", 3, "ngModelChange", "input", "ngModel"], ["role", "listbox", "aria-label", "Application results", 1, "results-list"], ["role", "option", 1, "result-item", 3, "selected"], ["Variant", "no-results", "Size", "compact", "Icon", "fa-solid fa-magnifying-glass", "Title", "No applications found", "Message", "Try a different search term or search the Knowledge Hub", "role", "status", "aria-live", "polite"], ["role", "status", "aria-live", "assertive", "aria-label", "Navigating to application", 1, "loading-overlay"], ["role", "option", 1, "result-item", 3, "click"], ["aria-hidden", "true", 1, "result-icon"], [1, "result-info"], [1, "result-name"], [1, "result-description"], [1, "results-section-divider"], [1, "section-label"], ["role", "option", 1, "result-item", "result-item-action", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-brain", "result-icon", "result-icon-knowledge"], [1, "result-kbd"], ["size", "small", 3, "showText"]], template: function CommandPaletteComponent_Template(rf, ctx) { if (rf & 1) {
|
|
349
|
-
i0.ɵɵconditionalCreate(0, CommandPaletteComponent_Conditional_0_Template, 1, 0, "div",
|
|
350
|
-
i0.ɵɵconditionalCreate(1, CommandPaletteComponent_Conditional_1_Template,
|
|
409
|
+
} }, outputs: { AppSelected: "AppSelected", KnowledgeSearchRequested: "KnowledgeSearchRequested" }, standalone: false, decls: 2, vars: 2, consts: [["paletteModal", ""], ["searchInput", ""], ["role", "presentation", "aria-hidden", "true", 1, "command-palette-backdrop"], ["role", "dialog", "aria-label", "Search applications", "aria-modal", "true", 1, "command-palette-modal"], ["role", "presentation", "aria-hidden", "true", 1, "command-palette-backdrop", 3, "click"], [1, "search-container"], ["aria-hidden", "true", 1, "fa-solid", "fa-search", "search-icon"], ["type", "text", "placeholder", "Search applications...", "autocomplete", "off", "spellcheck", "false", "aria-label", "Search applications", 1, "search-input", 3, "ngModelChange", "input", "ngModel"], ["role", "listbox", "aria-label", "Application results", 1, "results-list"], ["role", "option", 1, "result-item", 3, "selected"], ["Variant", "no-results", "Size", "compact", "Icon", "fa-solid fa-magnifying-glass", "Title", "No applications found", "Message", "Try a different search term or search the Knowledge Hub", "role", "status", "aria-live", "polite"], ["role", "status", "aria-live", "assertive", "aria-label", "Navigating to application", 1, "loading-overlay"], ["role", "option", 1, "result-item", 3, "click"], ["aria-hidden", "true", 1, "result-icon"], [1, "result-info"], [1, "result-name"], [1, "result-description"], [1, "results-section-divider"], [1, "section-label"], ["role", "option", 1, "result-item", "result-item-action", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-brain", "result-icon", "result-icon-knowledge"], [1, "result-kbd"], ["size", "small", 3, "showText"]], template: function CommandPaletteComponent_Template(rf, ctx) { if (rf & 1) {
|
|
410
|
+
i0.ɵɵconditionalCreate(0, CommandPaletteComponent_Conditional_0_Template, 1, 0, "div", 2);
|
|
411
|
+
i0.ɵɵconditionalCreate(1, CommandPaletteComponent_Conditional_1_Template, 12, 4, "div", 3);
|
|
351
412
|
} if (rf & 2) {
|
|
352
413
|
i0.ɵɵconditional(ctx.IsOpen ? 0 : -1);
|
|
353
414
|
i0.ɵɵadvance();
|
|
@@ -356,10 +417,13 @@ export class CommandPaletteComponent {
|
|
|
356
417
|
}
|
|
357
418
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CommandPaletteComponent, [{
|
|
358
419
|
type: Component,
|
|
359
|
-
args: [{ standalone: false, selector: 'mj-command-palette', template: "<!-- Backdrop -->\n@if (IsOpen) {\n <div class=\"command-palette-backdrop\"\n (click)=\"Close()\"\n role=\"presentation\"\n aria-hidden=\"true\">\n </div>\n}\n\n<!-- Modal -->\n@if (IsOpen) {\n <div class=\"command-palette-modal\"\n role=\"dialog\"\n aria-label=\"Search applications\"\n aria-modal=\"true\">\n <!-- Search Input -->\n <div class=\"search-container\">\n <i class=\"fa-solid fa-search search-icon\" aria-hidden=\"true\"></i>\n <input\n #searchInput\n type=\"text\"\n [(ngModel)]=\"SearchQuery\"\n (input)=\"OnSearchChange()\"\n placeholder=\"Search applications...\"\n class=\"search-input\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n aria-label=\"Search applications\">\n </div>\n <!-- Results List -->\n <div class=\"results-list\" role=\"listbox\" aria-label=\"Application results\">\n <!-- All Apps -->\n @for (app of FilteredApps; track app; let i = $index) {\n <div\n class=\"result-item\"\n [class.selected]=\"i === SelectedIndex\"\n (click)=\"SelectApp(app)\"\n role=\"option\"\n [attr.aria-selected]=\"i === SelectedIndex\">\n <i [class]=\"app.Icon\"\n [style.color]=\"app.GetColor()\"\n class=\"result-icon\"\n aria-hidden=\"true\"></i>\n <div class=\"result-info\">\n <div class=\"result-name\">{{ app.Name }}</div>\n @if (app.Description) {\n <div class=\"result-description\">{{ app.Description }}</div>\n }\n </div>\n </div>\n }\n <!-- Search Knowledge Hub Action -->\n @if (SearchQuery.trim().length > 0) {\n <div class=\"results-section-divider\">\n <span class=\"section-label\">Knowledge Search</span>\n </div>\n <div\n class=\"result-item result-item-action\"\n [class.selected]=\"FilteredApps.length === SelectedIndex\"\n (click)=\"SearchKnowledgeHub()\"\n role=\"option\">\n <i class=\"fa-solid fa-brain result-icon result-icon-knowledge\" aria-hidden=\"true\"></i>\n <div class=\"result-info\">\n <div class=\"result-name\">Search Knowledge Hub</div>\n <div class=\"result-description\">Search \"{{ SearchQuery }}\" across entities, documents, and content</div>\n </div>\n <kbd class=\"result-kbd\">Enter</kbd>\n </div>\n }\n <!-- Empty State -->\n @if (FilteredApps.length === 0 && SearchQuery) {\n <mj-empty-state\n Variant=\"no-results\"\n Size=\"compact\"\n Icon=\"fa-solid fa-magnifying-glass\"\n Title=\"No applications found\"\n Message=\"Try a different search term or search the Knowledge Hub\"\n role=\"status\"\n aria-live=\"polite\" />\n }\n </div>\n <!-- Loading State Overlay -->\n @if (IsNavigating) {\n <div class=\"loading-overlay\" role=\"status\" aria-live=\"assertive\" aria-label=\"Navigating to application\">\n <mj-loading size=\"small\" [showText]=\"false\"></mj-loading>\n </div>\n }\n </div>\n}\n", styles: ["/* Backdrop with blur effect */\n.command-palette-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(3px);\n z-index: 10000;\n animation: fadeIn 0.15s ease-out;\n}\n\n/* Modal - centered, Notion-style */\n.command-palette-modal {\n position: fixed;\n top: 20%;\n left: 50%;\n transform: translateX(-50%);\n width: 90%;\n max-width: 640px;\n max-height: 500px;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2);\n overflow: hidden;\n z-index: 10001;\n animation: slideIn 0.2s ease-out;\n display: flex;\n flex-direction: column;\n}\n\n/* Search Container */\n.search-container {\n display: flex;\n align-items: center;\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.search-icon {\n font-size: 18px;\n color: var(--mj-text-disabled);\n margin-right: 12px;\n}\n\n.search-input {\n flex: 1;\n border: none;\n outline: none;\n font-size: 16px;\n padding: 8px 0;\n color: var(--mj-text-primary);\n background: transparent;\n}\n\n.search-input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n/* Results List */\n.results-list {\n overflow-y: auto;\n max-height: 400px;\n flex: 1;\n}\n\n/* Section Header (for \"Recent\") */\n.section-header {\n padding: 12px 16px 8px 16px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n/* Result Item */\n.result-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n cursor: pointer;\n transition: background 0.1s ease-out;\n border-radius: 0;\n}\n\n.result-item:hover,\n.result-item.selected {\n background: var(--mj-bg-surface-card);\n}\n\n.result-item.selected {\n position: relative;\n}\n\n.result-item.selected::before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: var(--mj-brand-primary);\n}\n\n.result-icon {\n font-size: 20px;\n width: 24px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.result-info {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.result-name {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.result-description {\n font-size: 12px;\n color: var(--mj-text-disabled);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Knowledge Search Section */\n.results-section-divider {\n padding: 6px 16px;\n border-top: 1px solid var(--mj-border-subtle);\n margin-top: 4px;\n}\n\n.section-label {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.result-item-action {\n border-top: none;\n}\n\n.result-icon-knowledge {\n color: var(--mj-brand-primary);\n}\n\n.result-kbd {\n display: inline-block;\n padding: 2px 6px;\n border-radius: 4px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n font-size: 11px;\n font-family: inherit;\n flex-shrink: 0;\n}\n\n/* Loading Overlay */\n.loading-overlay {\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, var(--mj-bg-surface) 95%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1;\n animation: fadeIn 0.15s ease-out;\n}\n\n/* Animations */\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes slideIn {\n from {\n opacity: 0;\n transform: translateX(-50%) translateY(-20px);\n }\n to {\n opacity: 1;\n transform: translateX(-50%) translateY(0);\n }\n}\n\n/* Scrollbar Styling (Webkit browsers) */\n.results-list::-webkit-scrollbar {\n width: 8px;\n}\n\n.results-list::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.results-list::-webkit-scrollbar-thumb {\n background: var(--mj-border-default);\n border-radius: 4px;\n}\n\n.results-list::-webkit-scrollbar-thumb:hover {\n background: var(--mj-border-strong);\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .command-palette-modal {\n width: 95%;\n max-width: none;\n top: 10%;\n }\n\n .search-input {\n font-size: 14px;\n }\n\n .result-name {\n font-size: 13px;\n }\n\n .result-description {\n font-size: 11px;\n }\n}\n"] }]
|
|
420
|
+
args: [{ standalone: false, selector: 'mj-command-palette', template: "<!-- Backdrop -->\n@if (IsOpen) {\n <div class=\"command-palette-backdrop\"\n (click)=\"Close()\"\n role=\"presentation\"\n aria-hidden=\"true\">\n </div>\n}\n\n<!-- Modal -->\n@if (IsOpen) {\n <div class=\"command-palette-modal\"\n #paletteModal\n role=\"dialog\"\n aria-label=\"Search applications\"\n aria-modal=\"true\">\n <!-- Search Input -->\n <div class=\"search-container\">\n <i class=\"fa-solid fa-search search-icon\" aria-hidden=\"true\"></i>\n <input\n #searchInput\n type=\"text\"\n [(ngModel)]=\"SearchQuery\"\n (input)=\"OnSearchChange()\"\n placeholder=\"Search applications...\"\n class=\"search-input\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n aria-label=\"Search applications\">\n </div>\n <!-- Results List -->\n <div class=\"results-list\" role=\"listbox\" aria-label=\"Application results\">\n <!-- All Apps -->\n @for (app of FilteredApps; track app; let i = $index) {\n <div\n class=\"result-item\"\n [class.selected]=\"i === SelectedIndex\"\n (click)=\"SelectApp(app)\"\n role=\"option\"\n [attr.aria-selected]=\"i === SelectedIndex\">\n <i [class]=\"app.Icon\"\n [style.color]=\"app.GetColor()\"\n class=\"result-icon\"\n aria-hidden=\"true\"></i>\n <div class=\"result-info\">\n <div class=\"result-name\">{{ app.Name }}</div>\n @if (app.Description) {\n <div class=\"result-description\">{{ app.Description }}</div>\n }\n </div>\n </div>\n }\n <!-- Search Knowledge Hub Action -->\n @if (SearchQuery.trim().length > 0) {\n <div class=\"results-section-divider\">\n <span class=\"section-label\">Knowledge Search</span>\n </div>\n <div\n class=\"result-item result-item-action\"\n [class.selected]=\"FilteredApps.length === SelectedIndex\"\n (click)=\"SearchKnowledgeHub()\"\n role=\"option\">\n <i class=\"fa-solid fa-brain result-icon result-icon-knowledge\" aria-hidden=\"true\"></i>\n <div class=\"result-info\">\n <div class=\"result-name\">Search Knowledge Hub</div>\n <div class=\"result-description\">Search \"{{ SearchQuery }}\" across entities, documents, and content</div>\n </div>\n <kbd class=\"result-kbd\">Enter</kbd>\n </div>\n }\n <!-- Empty State -->\n @if (FilteredApps.length === 0 && SearchQuery) {\n <mj-empty-state\n Variant=\"no-results\"\n Size=\"compact\"\n Icon=\"fa-solid fa-magnifying-glass\"\n Title=\"No applications found\"\n Message=\"Try a different search term or search the Knowledge Hub\"\n role=\"status\"\n aria-live=\"polite\" />\n }\n </div>\n <!-- Loading State Overlay -->\n @if (IsNavigating) {\n <div class=\"loading-overlay\" role=\"status\" aria-live=\"assertive\" aria-label=\"Navigating to application\">\n <mj-loading size=\"small\" [showText]=\"false\"></mj-loading>\n </div>\n }\n </div>\n}\n", styles: ["/* Backdrop with blur effect */\n.command-palette-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(3px);\n z-index: 10000;\n animation: fadeIn 0.15s ease-out;\n}\n\n/* Modal - centered, Notion-style */\n.command-palette-modal {\n position: fixed;\n top: 20%;\n left: 50%;\n transform: translateX(-50%);\n width: 90%;\n max-width: 640px;\n max-height: 500px;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 16px 48px rgba(0, 0, 0, 0.2);\n overflow: hidden;\n z-index: 10001;\n animation: slideIn 0.2s ease-out;\n display: flex;\n flex-direction: column;\n}\n\n/* Search Container */\n.search-container {\n display: flex;\n align-items: center;\n padding: 16px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.search-icon {\n font-size: 18px;\n color: var(--mj-text-disabled);\n margin-right: 12px;\n}\n\n.search-input {\n flex: 1;\n border: none;\n outline: none;\n font-size: 16px;\n padding: 8px 0;\n color: var(--mj-text-primary);\n background: transparent;\n}\n\n.search-input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n/* Results List */\n.results-list {\n overflow-y: auto;\n max-height: 400px;\n flex: 1;\n}\n\n/* Section Header (for \"Recent\") */\n.section-header {\n padding: 12px 16px 8px 16px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n/* Result Item */\n.result-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n cursor: pointer;\n transition: background 0.1s ease-out;\n border-radius: 0;\n}\n\n.result-item:hover,\n.result-item.selected {\n background: var(--mj-bg-surface-card);\n}\n\n.result-item.selected {\n position: relative;\n}\n\n.result-item.selected::before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: var(--mj-brand-primary);\n}\n\n.result-icon {\n font-size: 20px;\n width: 24px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.result-info {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.result-name {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.result-description {\n font-size: 12px;\n color: var(--mj-text-disabled);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Knowledge Search Section */\n.results-section-divider {\n padding: 6px 16px;\n border-top: 1px solid var(--mj-border-subtle);\n margin-top: 4px;\n}\n\n.section-label {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.result-item-action {\n border-top: none;\n}\n\n.result-icon-knowledge {\n color: var(--mj-brand-primary);\n}\n\n.result-kbd {\n display: inline-block;\n padding: 2px 6px;\n border-radius: 4px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n font-size: 11px;\n font-family: inherit;\n flex-shrink: 0;\n}\n\n/* Loading Overlay */\n.loading-overlay {\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, var(--mj-bg-surface) 95%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1;\n animation: fadeIn 0.15s ease-out;\n}\n\n/* Animations */\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes slideIn {\n from {\n opacity: 0;\n transform: translateX(-50%) translateY(-20px);\n }\n to {\n opacity: 1;\n transform: translateX(-50%) translateY(0);\n }\n}\n\n/* Scrollbar Styling (Webkit browsers) */\n.results-list::-webkit-scrollbar {\n width: 8px;\n}\n\n.results-list::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.results-list::-webkit-scrollbar-thumb {\n background: var(--mj-border-default);\n border-radius: 4px;\n}\n\n.results-list::-webkit-scrollbar-thumb:hover {\n background: var(--mj-border-strong);\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .command-palette-modal {\n width: 95%;\n max-width: none;\n top: 10%;\n }\n\n .search-input {\n font-size: 14px;\n }\n\n .result-name {\n font-size: 13px;\n }\n\n .result-description {\n font-size: 11px;\n }\n}\n"] }]
|
|
360
421
|
}], () => [{ type: i1.CommandPaletteService }, { type: i2.ApplicationManager }, { type: i0.ChangeDetectorRef }], { SearchInput: [{
|
|
361
422
|
type: ViewChild,
|
|
362
423
|
args: ['searchInput']
|
|
424
|
+
}], PaletteModal: [{
|
|
425
|
+
type: ViewChild,
|
|
426
|
+
args: ['paletteModal']
|
|
363
427
|
}], AppSelected: [{
|
|
364
428
|
type: Output
|
|
365
429
|
}], KnowledgeSearchRequested: [{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-palette.component.js","sourceRoot":"","sources":["../../../src/lib/command-palette/command-palette.component.ts","../../../src/lib/command-palette/command-palette.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ViewChild, ElementRef, HostListener, ChangeDetectorRef, Output, EventEmitter } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { ApplicationManager, BaseApplication } from '@memberjunction/ng-base-application';\nimport { CommandPaletteService } from './command-palette.service';\n\n/**\n * Command Palette Component\n *\n * Provides a Notion-style command palette for quickly searching and navigating to applications.\n * Triggered by Cmd+K (Mac) or Ctrl+/ (Windows/Linux).\n *\n * Features:\n * - Fuzzy search with relevance scoring\n * - Keyboard navigation (arrow keys, enter, escape)\n * - Loading state during navigation\n * - Empty state with helpful message\n */\n@Component({\n standalone: false,\n selector: 'mj-command-palette',\n templateUrl: './command-palette.component.html',\n styleUrls: ['./command-palette.component.css']\n})\nexport class CommandPaletteComponent implements OnInit, OnDestroy {\n private destroy$ = new Subject<void>();\n\n @ViewChild('searchInput') SearchInput!: ElementRef<HTMLInputElement>;\n @Output() AppSelected = new EventEmitter<string>();\n @Output() KnowledgeSearchRequested = new EventEmitter<string>();\n\n IsOpen = false;\n SearchQuery = '';\n AllApps: BaseApplication[] = [];\n FilteredApps: BaseApplication[] = [];\n SelectedIndex = 0;\n IsNavigating = false;\n\n constructor(\n private service: CommandPaletteService,\n private appManager: ApplicationManager,\n private cdr: ChangeDetectorRef\n ) {}\n\n ngOnInit(): void {\n // Subscribe to service's open/close state\n this.service.IsOpen.pipe(takeUntil(this.destroy$)).subscribe((isOpen) => {\n this.IsOpen = isOpen;\n\n if (isOpen) {\n this.onOpen();\n } else {\n this.onClose();\n }\n\n this.cdr.detectChanges();\n });\n\n // Subscribe to application changes\n this.appManager.AllApplications.pipe(takeUntil(this.destroy$)).subscribe((apps) => {\n this.AllApps = apps;\n this.filterAndSortApps();\n });\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n /**\n * Called when command palette opens\n */\n private onOpen(): void {\n // Reset state\n this.SearchQuery = '';\n this.SelectedIndex = 0;\n this.IsNavigating = false;\n\n // Filter apps (will show all initially)\n this.filterAndSortApps();\n\n // Focus search input after view updates\n setTimeout(() => {\n if (this.SearchInput) {\n this.SearchInput.nativeElement.focus();\n }\n }, 100);\n }\n\n /**\n * Called when command palette closes\n */\n private onClose(): void {\n this.SearchQuery = '';\n this.SelectedIndex = 0;\n this.IsNavigating = false;\n }\n\n /**\n * Handle search query change\n */\n OnSearchChange(): void {\n this.filterAndSortApps();\n this.SelectedIndex = 0; // Reset selection\n }\n\n /**\n * Filter and sort applications based on search query\n */\n private filterAndSortApps(): void {\n const query = this.SearchQuery.toLowerCase().trim();\n\n // If no query, show all apps\n if (!query) {\n this.FilteredApps = [...this.AllApps];\n return;\n }\n\n // Score all apps\n const scored = this.AllApps.map(app => ({\n app,\n score: this.calculateMatchScore(app, query)\n }));\n\n // Filter to only matches (score > 0)\n const matches = scored.filter(item => item.score > 0);\n\n // Sort by score (descending)\n matches.sort((a, b) => b.score - a.score);\n\n // Extract apps\n this.FilteredApps = matches.map(item => item.app);\n }\n\n /**\n * Calculate match score for fuzzy search\n *\n * Scoring:\n * - Exact match: 1000 points\n * - Starts with: 500 points\n * - Contains: 100 points\n * - Description match: 50 points\n * - Initials match: 25 points (e.g., \"de\" matches \"Data Explorer\")\n */\n private calculateMatchScore(app: BaseApplication, query: string): number {\n const name = app.Name.toLowerCase();\n const desc = (app.Description || '').toLowerCase();\n\n // Exact match (highest priority)\n if (name === query) return 1000;\n\n // Starts with query (very high priority)\n if (name.startsWith(query)) return 500;\n\n // Contains query in name (high priority)\n if (name.includes(query)) return 100;\n\n // Description match (medium priority)\n if (desc.includes(query)) return 50;\n\n // Fuzzy match - initials (e.g., \"de\" matches \"Data Explorer\")\n const initials = name\n .split(' ')\n .map(word => word[0] || '')\n .join('')\n .toLowerCase();\n if (initials.includes(query)) return 25;\n\n return 0; // No match\n }\n\n /**\n * Select an application and emit event for shell to handle navigation\n */\n SelectApp(app: BaseApplication): void {\n if (this.IsNavigating) return;\n // Close the palette first\n this.service.Close();\n // Emit event for shell to handle navigation (same pattern as app-switcher)\n this.AppSelected.emit(app.ID);\n }\n\n /**\n * Navigate to Knowledge Hub search with the current query.\n */\n SearchKnowledgeHub(): void {\n if (this.IsNavigating) return;\n const query = this.SearchQuery.trim();\n this.service.Close();\n this.KnowledgeSearchRequested.emit(query);\n }\n\n /**\n * Close the command palette\n */\n Close(): void {\n this.service.Close();\n }\n\n /**\n * Handle keyboard navigation\n */\n @HostListener('document:keydown', ['$event'])\n HandleKeyDown(event: KeyboardEvent): void {\n if (!this.IsOpen) return;\n\n // Skip if user is typing in input (except for navigation keys)\n const target = event.target as HTMLElement;\n const navigationKeys = ['Escape', 'Enter', 'ArrowUp', 'ArrowDown'];\n if (target.tagName === 'INPUT' && !navigationKeys.includes(event.key)) {\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n // Allow selecting up to FilteredApps.length (the Knowledge Hub action is at that index)\n this.SelectedIndex = Math.min(this.SelectedIndex + 1, this.maxSelectableIndex());\n this.scrollToSelected();\n break;\n\n case 'ArrowUp':\n event.preventDefault();\n this.SelectedIndex = Math.max(this.SelectedIndex - 1, 0);\n this.scrollToSelected();\n break;\n\n case 'Enter':\n event.preventDefault();\n if (this.SelectedIndex < this.FilteredApps.length && this.FilteredApps[this.SelectedIndex]) {\n this.SelectApp(this.FilteredApps[this.SelectedIndex]);\n } else if (this.SearchQuery.trim().length > 0 && this.SelectedIndex === this.FilteredApps.length) {\n // Knowledge Hub search action is selected\n this.SearchKnowledgeHub();\n }\n break;\n\n case 'Escape':\n event.preventDefault();\n this.service.Close();\n break;\n }\n }\n\n /**\n * Get the maximum selectable index (apps + knowledge search action if query present)\n */\n private maxSelectableIndex(): number {\n const hasKnowledgeAction = this.SearchQuery.trim().length > 0;\n return hasKnowledgeAction ? this.FilteredApps.length : this.FilteredApps.length - 1;\n }\n\n /**\n * Ensure selected item is visible in results list\n */\n private scrollToSelected(): void {\n setTimeout(() => {\n const selected = document.querySelector('.result-item.selected');\n if (selected) {\n selected.scrollIntoView({ block: 'nearest', behavior: 'smooth' });\n }\n }, 0);\n }\n}\n","<!-- Backdrop -->\n@if (IsOpen) {\n <div class=\"command-palette-backdrop\"\n (click)=\"Close()\"\n role=\"presentation\"\n aria-hidden=\"true\">\n </div>\n}\n\n<!-- Modal -->\n@if (IsOpen) {\n <div class=\"command-palette-modal\"\n role=\"dialog\"\n aria-label=\"Search applications\"\n aria-modal=\"true\">\n <!-- Search Input -->\n <div class=\"search-container\">\n <i class=\"fa-solid fa-search search-icon\" aria-hidden=\"true\"></i>\n <input\n #searchInput\n type=\"text\"\n [(ngModel)]=\"SearchQuery\"\n (input)=\"OnSearchChange()\"\n placeholder=\"Search applications...\"\n class=\"search-input\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n aria-label=\"Search applications\">\n </div>\n <!-- Results List -->\n <div class=\"results-list\" role=\"listbox\" aria-label=\"Application results\">\n <!-- All Apps -->\n @for (app of FilteredApps; track app; let i = $index) {\n <div\n class=\"result-item\"\n [class.selected]=\"i === SelectedIndex\"\n (click)=\"SelectApp(app)\"\n role=\"option\"\n [attr.aria-selected]=\"i === SelectedIndex\">\n <i [class]=\"app.Icon\"\n [style.color]=\"app.GetColor()\"\n class=\"result-icon\"\n aria-hidden=\"true\"></i>\n <div class=\"result-info\">\n <div class=\"result-name\">{{ app.Name }}</div>\n @if (app.Description) {\n <div class=\"result-description\">{{ app.Description }}</div>\n }\n </div>\n </div>\n }\n <!-- Search Knowledge Hub Action -->\n @if (SearchQuery.trim().length > 0) {\n <div class=\"results-section-divider\">\n <span class=\"section-label\">Knowledge Search</span>\n </div>\n <div\n class=\"result-item result-item-action\"\n [class.selected]=\"FilteredApps.length === SelectedIndex\"\n (click)=\"SearchKnowledgeHub()\"\n role=\"option\">\n <i class=\"fa-solid fa-brain result-icon result-icon-knowledge\" aria-hidden=\"true\"></i>\n <div class=\"result-info\">\n <div class=\"result-name\">Search Knowledge Hub</div>\n <div class=\"result-description\">Search \"{{ SearchQuery }}\" across entities, documents, and content</div>\n </div>\n <kbd class=\"result-kbd\">Enter</kbd>\n </div>\n }\n <!-- Empty State -->\n @if (FilteredApps.length === 0 && SearchQuery) {\n <mj-empty-state\n Variant=\"no-results\"\n Size=\"compact\"\n Icon=\"fa-solid fa-magnifying-glass\"\n Title=\"No applications found\"\n Message=\"Try a different search term or search the Knowledge Hub\"\n role=\"status\"\n aria-live=\"polite\" />\n }\n </div>\n <!-- Loading State Overlay -->\n @if (IsNavigating) {\n <div class=\"loading-overlay\" role=\"status\" aria-live=\"assertive\" aria-label=\"Navigating to application\">\n <mj-loading size=\"small\" [showText]=\"false\"></mj-loading>\n </div>\n }\n </div>\n}\n"]}
|
|
1
|
+
{"version":3,"file":"command-palette.component.js","sourceRoot":"","sources":["../../../src/lib/command-palette/command-palette.component.ts","../../../src/lib/command-palette/command-palette.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ViewChild, ElementRef, HostListener, ChangeDetectorRef, Output, EventEmitter } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { ApplicationManager, BaseApplication } from '@memberjunction/ng-base-application';\nimport { CommandPaletteService } from './command-palette.service';\n\n/**\n * Command Palette Component\n *\n * Provides a Notion-style command palette for quickly searching and navigating to applications.\n * Triggered by Cmd+K (Mac) or Ctrl+/ (Windows/Linux).\n *\n * Features:\n * - Fuzzy search with relevance scoring\n * - Keyboard navigation (arrow keys, enter, escape)\n * - Loading state during navigation\n * - Empty state with helpful message\n */\n@Component({\n standalone: false,\n selector: 'mj-command-palette',\n templateUrl: './command-palette.component.html',\n styleUrls: ['./command-palette.component.css']\n})\nexport class CommandPaletteComponent implements OnInit, OnDestroy {\n private destroy$ = new Subject<void>();\n\n @ViewChild('searchInput') SearchInput!: ElementRef<HTMLInputElement>;\n @ViewChild('paletteModal') PaletteModal?: ElementRef<HTMLElement>;\n @Output() AppSelected = new EventEmitter<string>();\n @Output() KnowledgeSearchRequested = new EventEmitter<string>();\n\n IsOpen = false;\n SearchQuery = '';\n /** The element focus came from, so closing can hand it back (WCAG 2.4.3). */\n private invoker: HTMLElement | null = null;\n AllApps: BaseApplication[] = [];\n FilteredApps: BaseApplication[] = [];\n SelectedIndex = 0;\n IsNavigating = false;\n\n constructor(\n private service: CommandPaletteService,\n private appManager: ApplicationManager,\n private cdr: ChangeDetectorRef\n ) {}\n\n ngOnInit(): void {\n // Subscribe to service's open/close state\n this.service.IsOpen.pipe(takeUntil(this.destroy$)).subscribe((isOpen) => {\n this.IsOpen = isOpen;\n\n if (isOpen) {\n this.onOpen();\n } else {\n this.onClose();\n }\n\n this.cdr.detectChanges();\n });\n\n // Subscribe to application changes\n this.appManager.AllApplications.pipe(takeUntil(this.destroy$)).subscribe((apps) => {\n this.AllApps = apps;\n this.filterAndSortApps();\n });\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n /**\n * Called when command palette opens\n */\n private onOpen(): void {\n // Remember where focus came from BEFORE we take it, so Close() can hand it back.\n // The palette opens from a global Cmd+K, so the invoker is whatever had focus.\n const active = document.activeElement;\n this.invoker = active instanceof HTMLElement && active !== document.body ? active : null;\n\n // Reset state\n this.SearchQuery = '';\n this.SelectedIndex = 0;\n this.IsNavigating = false;\n\n // Filter apps (will show all initially)\n this.filterAndSortApps();\n\n // Focus search input after view updates\n setTimeout(() => {\n if (this.SearchInput) {\n this.SearchInput.nativeElement.focus();\n }\n }, 100);\n }\n\n /**\n * Called when command palette closes\n */\n private onClose(): void {\n this.SearchQuery = '';\n this.SelectedIndex = 0;\n this.IsNavigating = false;\n\n // Return focus to the invoker. Guarded on the invoker still being in the document —\n // selecting an app tears down the tab the invoker lived in, and focusing a detached\n // node silently drops focus to <body>, which is the very thing this prevents.\n const invoker = this.invoker;\n this.invoker = null;\n if (invoker && invoker.isConnected) {\n invoker.focus();\n }\n }\n\n /**\n * Focusable descendants of the modal, in DOM order — the trap's cycle.\n */\n private focusableInModal(): HTMLElement[] {\n const modal = this.PaletteModal?.nativeElement;\n if (!modal) {\n return [];\n }\n // No visibility filter is needed or wanted here: the entire modal lives inside an\n // `@if (IsOpen)`, so everything this matches is genuinely rendered. (An `offsetParent`\n // check would be actively wrong — the modal is positioned, and offsetParent is null for\n // fixed-position subtrees in some engines and for everything under jsdom.)\n const selector = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n return Array.from(modal.querySelectorAll<HTMLElement>(selector));\n }\n\n /**\n * Keep Tab inside the dialog (WCAG 2.4.3 / 2.1.2). `aria-modal` tells a screen reader the\n * rest of the page is inert but does NOT stop Tab, so without this a keyboard user tabs\n * straight out of an open palette into the page behind it and cannot see where they are.\n */\n private trapTab(event: KeyboardEvent): void {\n const focusable = this.focusableInModal();\n if (focusable.length === 0) {\n event.preventDefault();\n return;\n }\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const active = document.activeElement as HTMLElement | null;\n\n if (event.shiftKey && (active === first || !active || !this.PaletteModal?.nativeElement.contains(active))) {\n event.preventDefault();\n last.focus();\n }\n else if (!event.shiftKey && (active === last || !active || !this.PaletteModal?.nativeElement.contains(active))) {\n event.preventDefault();\n first.focus();\n }\n }\n\n /**\n * Handle search query change\n */\n OnSearchChange(): void {\n this.filterAndSortApps();\n this.SelectedIndex = 0; // Reset selection\n }\n\n /**\n * Filter and sort applications based on search query\n */\n private filterAndSortApps(): void {\n const query = this.SearchQuery.toLowerCase().trim();\n\n // If no query, show all apps\n if (!query) {\n this.FilteredApps = [...this.AllApps];\n return;\n }\n\n // Score all apps\n const scored = this.AllApps.map(app => ({\n app,\n score: this.calculateMatchScore(app, query)\n }));\n\n // Filter to only matches (score > 0)\n const matches = scored.filter(item => item.score > 0);\n\n // Sort by score (descending)\n matches.sort((a, b) => b.score - a.score);\n\n // Extract apps\n this.FilteredApps = matches.map(item => item.app);\n }\n\n /**\n * Calculate match score for fuzzy search\n *\n * Scoring:\n * - Exact match: 1000 points\n * - Starts with: 500 points\n * - Contains: 100 points\n * - Description match: 50 points\n * - Initials match: 25 points (e.g., \"de\" matches \"Data Explorer\")\n */\n private calculateMatchScore(app: BaseApplication, query: string): number {\n const name = app.Name.toLowerCase();\n const desc = (app.Description || '').toLowerCase();\n\n // Exact match (highest priority)\n if (name === query) return 1000;\n\n // Starts with query (very high priority)\n if (name.startsWith(query)) return 500;\n\n // Contains query in name (high priority)\n if (name.includes(query)) return 100;\n\n // Description match (medium priority)\n if (desc.includes(query)) return 50;\n\n // Fuzzy match - initials (e.g., \"de\" matches \"Data Explorer\")\n const initials = name\n .split(' ')\n .map(word => word[0] || '')\n .join('')\n .toLowerCase();\n if (initials.includes(query)) return 25;\n\n return 0; // No match\n }\n\n /**\n * Select an application and emit event for shell to handle navigation\n */\n SelectApp(app: BaseApplication): void {\n if (this.IsNavigating) return;\n // Close the palette first\n this.service.Close();\n // Emit event for shell to handle navigation (same pattern as app-switcher)\n this.AppSelected.emit(app.ID);\n }\n\n /**\n * Navigate to Knowledge Hub search with the current query.\n */\n SearchKnowledgeHub(): void {\n if (this.IsNavigating) return;\n const query = this.SearchQuery.trim();\n this.service.Close();\n this.KnowledgeSearchRequested.emit(query);\n }\n\n /**\n * Close the command palette\n */\n Close(): void {\n this.service.Close();\n }\n\n /**\n * Handle keyboard navigation\n */\n @HostListener('document:keydown', ['$event'])\n HandleKeyDown(event: KeyboardEvent): void {\n if (!this.IsOpen) return;\n\n // Tab is handled first: the INPUT guard below would otherwise let Tab fall through to\n // the browser and walk focus out of the dialog.\n if (event.key === 'Tab') {\n this.trapTab(event);\n return;\n }\n\n // Skip if user is typing in input (except for navigation keys)\n const target = event.target as HTMLElement;\n const navigationKeys = ['Escape', 'Enter', 'ArrowUp', 'ArrowDown'];\n if (target.tagName === 'INPUT' && !navigationKeys.includes(event.key)) {\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n // Allow selecting up to FilteredApps.length (the Knowledge Hub action is at that index)\n this.SelectedIndex = Math.min(this.SelectedIndex + 1, this.maxSelectableIndex());\n this.scrollToSelected();\n break;\n\n case 'ArrowUp':\n event.preventDefault();\n this.SelectedIndex = Math.max(this.SelectedIndex - 1, 0);\n this.scrollToSelected();\n break;\n\n case 'Enter':\n event.preventDefault();\n if (this.SelectedIndex < this.FilteredApps.length && this.FilteredApps[this.SelectedIndex]) {\n this.SelectApp(this.FilteredApps[this.SelectedIndex]);\n } else if (this.SearchQuery.trim().length > 0 && this.SelectedIndex === this.FilteredApps.length) {\n // Knowledge Hub search action is selected\n this.SearchKnowledgeHub();\n }\n break;\n\n case 'Escape':\n event.preventDefault();\n this.service.Close();\n break;\n }\n }\n\n /**\n * Get the maximum selectable index (apps + knowledge search action if query present)\n */\n private maxSelectableIndex(): number {\n const hasKnowledgeAction = this.SearchQuery.trim().length > 0;\n return hasKnowledgeAction ? this.FilteredApps.length : this.FilteredApps.length - 1;\n }\n\n /**\n * Ensure selected item is visible in results list\n */\n private scrollToSelected(): void {\n setTimeout(() => {\n const selected = document.querySelector('.result-item.selected');\n if (selected) {\n selected.scrollIntoView({ block: 'nearest', behavior: 'smooth' });\n }\n }, 0);\n }\n}\n","<!-- Backdrop -->\n@if (IsOpen) {\n <div class=\"command-palette-backdrop\"\n (click)=\"Close()\"\n role=\"presentation\"\n aria-hidden=\"true\">\n </div>\n}\n\n<!-- Modal -->\n@if (IsOpen) {\n <div class=\"command-palette-modal\"\n #paletteModal\n role=\"dialog\"\n aria-label=\"Search applications\"\n aria-modal=\"true\">\n <!-- Search Input -->\n <div class=\"search-container\">\n <i class=\"fa-solid fa-search search-icon\" aria-hidden=\"true\"></i>\n <input\n #searchInput\n type=\"text\"\n [(ngModel)]=\"SearchQuery\"\n (input)=\"OnSearchChange()\"\n placeholder=\"Search applications...\"\n class=\"search-input\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n aria-label=\"Search applications\">\n </div>\n <!-- Results List -->\n <div class=\"results-list\" role=\"listbox\" aria-label=\"Application results\">\n <!-- All Apps -->\n @for (app of FilteredApps; track app; let i = $index) {\n <div\n class=\"result-item\"\n [class.selected]=\"i === SelectedIndex\"\n (click)=\"SelectApp(app)\"\n role=\"option\"\n [attr.aria-selected]=\"i === SelectedIndex\">\n <i [class]=\"app.Icon\"\n [style.color]=\"app.GetColor()\"\n class=\"result-icon\"\n aria-hidden=\"true\"></i>\n <div class=\"result-info\">\n <div class=\"result-name\">{{ app.Name }}</div>\n @if (app.Description) {\n <div class=\"result-description\">{{ app.Description }}</div>\n }\n </div>\n </div>\n }\n <!-- Search Knowledge Hub Action -->\n @if (SearchQuery.trim().length > 0) {\n <div class=\"results-section-divider\">\n <span class=\"section-label\">Knowledge Search</span>\n </div>\n <div\n class=\"result-item result-item-action\"\n [class.selected]=\"FilteredApps.length === SelectedIndex\"\n (click)=\"SearchKnowledgeHub()\"\n role=\"option\">\n <i class=\"fa-solid fa-brain result-icon result-icon-knowledge\" aria-hidden=\"true\"></i>\n <div class=\"result-info\">\n <div class=\"result-name\">Search Knowledge Hub</div>\n <div class=\"result-description\">Search \"{{ SearchQuery }}\" across entities, documents, and content</div>\n </div>\n <kbd class=\"result-kbd\">Enter</kbd>\n </div>\n }\n <!-- Empty State -->\n @if (FilteredApps.length === 0 && SearchQuery) {\n <mj-empty-state\n Variant=\"no-results\"\n Size=\"compact\"\n Icon=\"fa-solid fa-magnifying-glass\"\n Title=\"No applications found\"\n Message=\"Try a different search term or search the Knowledge Hub\"\n role=\"status\"\n aria-live=\"polite\" />\n }\n </div>\n <!-- Loading State Overlay -->\n @if (IsNavigating) {\n <div class=\"loading-overlay\" role=\"status\" aria-live=\"assertive\" aria-label=\"Navigating to application\">\n <mj-loading size=\"small\" [showText]=\"false\"></mj-loading>\n </div>\n }\n </div>\n}\n"]}
|
|
@@ -97,6 +97,9 @@ export declare class ShellComponent extends BaseAngularComponent implements OnIn
|
|
|
97
97
|
searchableEntities: EntityInfo[];
|
|
98
98
|
selectedEntity: EntityInfo | null;
|
|
99
99
|
searchInput: ElementRef<HTMLInputElement>;
|
|
100
|
+
/** Mobile drawer + its toggle — used to return focus to the toggle when the drawer closes. */
|
|
101
|
+
mobileNavDrawer?: ElementRef<HTMLElement>;
|
|
102
|
+
mobileNavToggle?: ElementRef<HTMLButtonElement>;
|
|
100
103
|
LegacySearchOpen: boolean;
|
|
101
104
|
private _chromeFlags;
|
|
102
105
|
/**
|
|
@@ -352,6 +355,26 @@ export declare class ShellComponent extends BaseAngularComponent implements OnIn
|
|
|
352
355
|
* Close mobile navigation drawer
|
|
353
356
|
*/
|
|
354
357
|
closeMobileNav(): void;
|
|
358
|
+
/**
|
|
359
|
+
* When the drawer closes it becomes `inert`, which drops focus to <body> if focus was
|
|
360
|
+
* inside it — the user's place in the page is gone and the next Tab restarts at the top.
|
|
361
|
+
* Hand focus back to the control that opened it instead. No-op when focus was elsewhere
|
|
362
|
+
* (e.g. the drawer was closed from a keyboard shortcut while the user was in the content).
|
|
363
|
+
*/
|
|
364
|
+
private returnFocusFromMobileNav;
|
|
365
|
+
/**
|
|
366
|
+
* Accessible name for the avatar button. The name must never depend on the avatar image
|
|
367
|
+
* rendering — a Gravatar CORS failure drops to the icon fallback, and an icon carries no
|
|
368
|
+
* name of its own — so it is set on the BUTTON and falls back to a generic label before
|
|
369
|
+
* the user record has loaded.
|
|
370
|
+
*/
|
|
371
|
+
get avatarAriaLabel(): string;
|
|
372
|
+
/**
|
|
373
|
+
* Skip link target handoff (WCAG 2.4.1). Focus is moved programmatically rather than left
|
|
374
|
+
* to the browser's fragment navigation: the shell's main region is a Golden Layout host,
|
|
375
|
+
* and letting the URL hash change here would collide with the deep-link/tab restore path.
|
|
376
|
+
*/
|
|
377
|
+
skipToMainContent(event: Event): void;
|
|
355
378
|
/**
|
|
356
379
|
* Toggle user menu visibility
|
|
357
380
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell.component.d.ts","sourceRoot":"","sources":["../../../src/lib/shell/shell.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,iBAAiB,EAAE,gBAAgB,EAAa,UAAU,EAAgB,MAAM,eAAe,CAAC;AACtJ,OAAO,EAAE,cAAc,EAAE,MAAM,EAAiB,MAAM,iBAAiB,CAAC;AAGxE,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,UAAU,EAIV,OAAO,EACR,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAY,UAAU,EAAqD,MAAM,sBAAsB,CAAC;AAE/G,OAAO,EAAc,iBAAiB,EAAgC,YAAY,EAAE,oBAAoB,EAAE,YAAY,EAAE,iBAAiB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC5M,OAAO,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AAClF,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAE9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,8BAA8B,EAAE,MAAM,+CAA+C,CAAC;AAC/F,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAIzE,OAAO,EAAE,wBAAwB,EAAyB,qBAAqB,EAAE,MAAM,kDAAkD,CAAC;AAC1I,OAAO,EAAE,qBAAqB,EAAE,MAAM,2CAA2C,CAAC;AAClF,OAAO,EAAgB,eAAe,EAAE,YAAY,EAA0D,MAAM,cAAc,CAAC;AAEnI,OAAO,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAGrF,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;;AAwB9E,qBAMa,cAAe,SAAQ,oBAAqB,YAAW,MAAM,EAAE,SAAS,EAAE,aAAa;
|
|
1
|
+
{"version":3,"file":"shell.component.d.ts","sourceRoot":"","sources":["../../../src/lib/shell/shell.component.ts"],"names":[],"mappings":"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"}
|