@ojiepermana/angular-navigation 22.0.43 → 22.0.45
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/README.md +9 -0
- package/fesm2022/ojiepermana-angular-navigation-navigation-dockbar-menu.component-BQgpBy1I.mjs +432 -0
- package/fesm2022/ojiepermana-angular-navigation-navigation-entry-grid.component-BY-DXx81.mjs +569 -0
- package/fesm2022/ojiepermana-angular-navigation-navigation-flyout-menu.component-CACN0O3T.mjs +637 -0
- package/fesm2022/ojiepermana-angular-navigation-navigation-horizontal.component-SK1lXswT.mjs +423 -0
- package/fesm2022/ojiepermana-angular-navigation-ojiepermana-angular-navigation-SlMGlTuA.mjs +2225 -0
- package/fesm2022/ojiepermana-angular-navigation-service.mjs +3 -3
- package/fesm2022/ojiepermana-angular-navigation.mjs +1 -4022
- package/package.json +2 -2
|
@@ -0,0 +1,637 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, ElementRef, input, output, computed, signal, Component } from '@angular/core';
|
|
3
|
+
import { IconComponent } from '@ojiepermana/angular-component/icon';
|
|
4
|
+
import { cn } from '@ojiepermana/angular-component/utils';
|
|
5
|
+
import { N as NavigationEntryGridComponent } from './ojiepermana-angular-navigation-navigation-entry-grid.component-BY-DXx81.mjs';
|
|
6
|
+
import { N as NavigationItemComponent, a as NavigationItemContentComponent } from './ojiepermana-angular-navigation-ojiepermana-angular-navigation-SlMGlTuA.mjs';
|
|
7
|
+
import { NavigationService } from '@ojiepermana/angular-navigation/service';
|
|
8
|
+
|
|
9
|
+
class NavigationFlyoutMenuComponent {
|
|
10
|
+
nav = inject(NavigationService);
|
|
11
|
+
host = inject(ElementRef);
|
|
12
|
+
navId = input('default', /* @ts-ignore */
|
|
13
|
+
...(ngDevMode ? [{ debugName: "navId" }] : /* istanbul ignore next */ []));
|
|
14
|
+
items = input([], /* @ts-ignore */
|
|
15
|
+
...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
16
|
+
label = input('Menu', /* @ts-ignore */
|
|
17
|
+
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
18
|
+
/** Nama Material Symbols untuk trigger; `null` = label saja (mode normal). */
|
|
19
|
+
icon = input(null, /* @ts-ignore */
|
|
20
|
+
...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
|
|
21
|
+
/** Trigger hanya ikon — label tetap diumumkan via aria-label/title. */
|
|
22
|
+
iconOnly = input(false, /* @ts-ignore */
|
|
23
|
+
...(ngDevMode ? [{ debugName: "iconOnly" }] : /* istanbul ignore next */ []));
|
|
24
|
+
/** Penempatan ikon relatif label: `start` (default) atau `end`. */
|
|
25
|
+
iconPosition = input('start', /* @ts-ignore */
|
|
26
|
+
...(ngDevMode ? [{ debugName: "iconPosition" }] : /* istanbul ignore next */ []));
|
|
27
|
+
/** Bentuk visual tombol trigger: `button` (pil) | `link` | `plain` (ghost). */
|
|
28
|
+
variant = input('button', /* @ts-ignore */
|
|
29
|
+
...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
30
|
+
/** Trigger mengambang (`fixed`) — host menjadi popover lepas, panel menempel ke trigger. */
|
|
31
|
+
floating = input(false, /* @ts-ignore */
|
|
32
|
+
...(ngDevMode ? [{ debugName: "floating" }] : /* istanbul ignore next */ []));
|
|
33
|
+
/** Kelas Tailwind untuk host trigger (posisi pojok floating / styling wrapper in-flow). */
|
|
34
|
+
triggerClass = input('', /* @ts-ignore */
|
|
35
|
+
...(ngDevMode ? [{ debugName: "triggerClass" }] : /* istanbul ignore next */ []));
|
|
36
|
+
/** `bottom` = bar berada di bawah konten; panel menempel sisi bawah container dan tumbuh ke atas. */
|
|
37
|
+
position = input('top', /* @ts-ignore */
|
|
38
|
+
...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
|
|
39
|
+
typeStyle = input('flat', /* @ts-ignore */
|
|
40
|
+
...(ngDevMode ? [{ debugName: "typeStyle" }] : /* istanbul ignore next */ []));
|
|
41
|
+
compact = input(false, /* @ts-ignore */
|
|
42
|
+
...(ngDevMode ? [{ debugName: "compact" }] : /* istanbul ignore next */ []));
|
|
43
|
+
itemClass = input('', /* @ts-ignore */
|
|
44
|
+
...(ngDevMode ? [{ debugName: "itemClass" }] : /* istanbul ignore next */ []));
|
|
45
|
+
/** Kelas Tailwind untuk container `<li>` tiap tab group (mengatur tinggi/border/padding container). */
|
|
46
|
+
groupClass = input('', /* @ts-ignore */
|
|
47
|
+
...(ngDevMode ? [{ debugName: "groupClass" }] : /* istanbul ignore next */ []));
|
|
48
|
+
activeIds = input(new Set(), /* @ts-ignore */
|
|
49
|
+
...(ngDevMode ? [{ debugName: "activeIds" }] : /* istanbul ignore next */ []));
|
|
50
|
+
activeUrl = input(null, /* @ts-ignore */
|
|
51
|
+
...(ngDevMode ? [{ debugName: "activeUrl" }] : /* istanbul ignore next */ []));
|
|
52
|
+
iconTemplate = input(undefined, /* @ts-ignore */
|
|
53
|
+
...(ngDevMode ? [{ debugName: "iconTemplate" }] : /* istanbul ignore next */ []));
|
|
54
|
+
collapseTree = input('stairs', /* @ts-ignore */
|
|
55
|
+
...(ngDevMode ? [{ debugName: "collapseTree" }] : /* istanbul ignore next */ []));
|
|
56
|
+
openedIds = input([], /* @ts-ignore */
|
|
57
|
+
...(ngDevMode ? [{ debugName: "openedIds" }] : /* istanbul ignore next */ []));
|
|
58
|
+
openedIdsChange = output();
|
|
59
|
+
itemSelected = output();
|
|
60
|
+
panelId = computed(() => `nav-flyout-${this.navId()}`, /* @ts-ignore */
|
|
61
|
+
...(ngDevMode ? [{ debugName: "panelId" }] : /* istanbul ignore next */ []));
|
|
62
|
+
isBorderRail = computed(() => this.typeStyle() === 'border-rail', /* @ts-ignore */
|
|
63
|
+
...(ngDevMode ? [{ debugName: "isBorderRail" }] : /* istanbul ignore next */ []));
|
|
64
|
+
isBottom = computed(() => this.position() === 'bottom', /* @ts-ignore */
|
|
65
|
+
...(ngDevMode ? [{ debugName: "isBottom" }] : /* istanbul ignore next */ []));
|
|
66
|
+
/** Compact (mobile) selalu icon-only; selain itu mengikuti input `iconOnly`. */
|
|
67
|
+
showIconOnly = computed(() => this.compact() || this.iconOnly(), /* @ts-ignore */
|
|
68
|
+
...(ngDevMode ? [{ debugName: "showIconOnly" }] : /* istanbul ignore next */ []));
|
|
69
|
+
triggerIcon = computed(() => this.icon() ?? (this.showIconOnly() ? 'menu' : null), /* @ts-ignore */
|
|
70
|
+
...(ngDevMode ? [{ debugName: "triggerIcon" }] : /* istanbul ignore next */ []));
|
|
71
|
+
/** Kelas tambahan untuk NavigationItem di dalam flyout saat style border-rail aktif. */
|
|
72
|
+
navItemClass = computed(() =>
|
|
73
|
+
// h-8 menjaga leaf di row tetap muat dalam tinggi 48px (py-2 + 32px) agar
|
|
74
|
+
// border bawah row tidak terdorong melewati posisi rail layout.
|
|
75
|
+
cn(this.itemClass(), this.isBorderRail() && 'h-8 rounded-none hover:bg-transparent hover:text-primary'), /* @ts-ignore */
|
|
76
|
+
...(ngDevMode ? [{ debugName: "navItemClass" }] : /* istanbul ignore next */ []));
|
|
77
|
+
branches = computed(() => this.items().filter((item) => item.children.length > 0), /* @ts-ignore */
|
|
78
|
+
...(ngDevMode ? [{ debugName: "branches" }] : /* istanbul ignore next */ []));
|
|
79
|
+
activeBranch = computed(() => {
|
|
80
|
+
const key = this.nav.currentPanelKey(this.navId());
|
|
81
|
+
return this.branches().find((branch) => branch.key === key) ?? null;
|
|
82
|
+
}, /* @ts-ignore */
|
|
83
|
+
...(ngDevMode ? [{ debugName: "activeBranch" }] : /* istanbul ignore next */ []));
|
|
84
|
+
/**
|
|
85
|
+
* Floating: sisi popover relatif trigger — `true` = rata kanan (buka ke kiri, untuk trigger di
|
|
86
|
+
* pojok kanan), `false` = rata kiri (buka ke kanan). Diukur dari posisi trigger saat dibuka.
|
|
87
|
+
*/
|
|
88
|
+
floatingAlignEnd = signal(true, /* @ts-ignore */
|
|
89
|
+
...(ngDevMode ? [{ debugName: "floatingAlignEnd" }] : /* istanbul ignore next */ []));
|
|
90
|
+
/**
|
|
91
|
+
* Offset panel terhadap host agar panel menimpa penuh container parent dari
|
|
92
|
+
* `Navigation` (lebar sama persis; posisi atas di mode top, posisi bawah di
|
|
93
|
+
* mode bottom). `null` berarti pengukuran tidak tersedia (mis. SSR/jsdom)
|
|
94
|
+
* dan panel jatuh ke lebar host sendiri.
|
|
95
|
+
*/
|
|
96
|
+
panelPlacement = signal(null, /* @ts-ignore */
|
|
97
|
+
...(ngDevMode ? [{ debugName: "panelPlacement" }] : /* istanbul ignore next */ []));
|
|
98
|
+
panelWrapperClasses = computed(() => {
|
|
99
|
+
if (this.floating()) {
|
|
100
|
+
// Floating: popover menempel ke trigger — atas/bawah ikut nav-position; sisi kiri/kanan
|
|
101
|
+
// ikut posisi trigger (floatingAlignEnd) agar tidak keluar layar saat trigger di pojok kiri.
|
|
102
|
+
return cn('absolute z-50 w-[min(22rem,85vw)] max-w-[85vw]', this.floatingAlignEnd() ? 'right-0' : 'left-0', this.isBottom() ? 'bottom-full mb-2' : 'top-full mt-2');
|
|
103
|
+
}
|
|
104
|
+
// Default: panel menutupi (overlay) container bar persis — posisi & lebar ikut container.
|
|
105
|
+
return cn('absolute z-50', !this.panelPlacement() && cn('inset-x-0', this.isBottom() ? 'bottom-0' : 'top-0'));
|
|
106
|
+
}, /* @ts-ignore */
|
|
107
|
+
...(ngDevMode ? [{ debugName: "panelWrapperClasses" }] : /* istanbul ignore next */ []));
|
|
108
|
+
/**
|
|
109
|
+
* Mode bottom membalik urutan visual: grid entri di atas, bar di bawah (dekat bar trigger).
|
|
110
|
+
* `min-h-0 flex-1` membuat menu mengisi penuh panel card (yang di-clip) sehingga ROW 2
|
|
111
|
+
* bisa jadi satu-satunya area scroll.
|
|
112
|
+
*/
|
|
113
|
+
menuClasses = computed(() => cn('flex min-h-0 flex-1', this.isBottom() ? 'flex-col-reverse' : 'flex-col'), /* @ts-ignore */
|
|
114
|
+
...(ngDevMode ? [{ debugName: "menuClasses" }] : /* istanbul ignore next */ []));
|
|
115
|
+
/**
|
|
116
|
+
* ROW 1 = bar flyout: satu baris horizontal seperti bar navbar —
|
|
117
|
+
* Header (kiri) · menu item (tengah, flex-1) · Footer (kanan). `shrink-0` membuatnya DIAM
|
|
118
|
+
* (tidak ikut scroll) — hanya ROW 2 (grid child) yang punya area scroll sendiri.
|
|
119
|
+
* Border memisahkan bar dari ROW 2 di sisi yang menjauh dari bar (bawah di mode top).
|
|
120
|
+
*/
|
|
121
|
+
barRowClasses = computed(() => cn('flex shrink-0 items-center gap-2 bg-popover px-2 md:px-3', this.isBorderRail()
|
|
122
|
+
? cn('min-h-12 border-border', this.isBottom() ? 'border-t-[1.5px]' : 'border-b-[1.5px]')
|
|
123
|
+
: cn('min-h-[3.25rem] border-[hsl(var(--border)/var(--opacity-60))]', this.isBottom() ? 'border-t' : 'border-b')), /* @ts-ignore */
|
|
124
|
+
...(ngDevMode ? [{ debugName: "barRowClasses" }] : /* istanbul ignore next */ []));
|
|
125
|
+
/**
|
|
126
|
+
* ROW 2 = HANYA area ini yang scroll: children dari nav item aktif. `min-h-0 flex-1`
|
|
127
|
+
* membatasi tingginya ke sisa ruang panel lalu `overflow-y-auto` men-scroll isinya —
|
|
128
|
+
* bar ROW 1 & kontainer panel sendiri tetap diam.
|
|
129
|
+
*/
|
|
130
|
+
scrollRegionClasses = computed(() => cn('min-h-0 flex-1 overflow-x-hidden overflow-y-auto overscroll-contain'), /* @ts-ignore */
|
|
131
|
+
...(ngDevMode ? [{ debugName: "scrollRegionClasses" }] : /* istanbul ignore next */ []));
|
|
132
|
+
isOpen() {
|
|
133
|
+
return this.nav.isDrawerOpen(this.navId());
|
|
134
|
+
}
|
|
135
|
+
onWindowResize() {
|
|
136
|
+
if (this.isOpen()) {
|
|
137
|
+
this.measurePanelPlacement();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
measurePanelPlacement() {
|
|
141
|
+
// Floating: panel anchored ke trigger via CSS, bukan overlay container. Pilih sisi popover
|
|
142
|
+
// (kanan→buka kiri / kiri→buka kanan) dari posisi trigger agar tidak keluar layar.
|
|
143
|
+
if (this.floating()) {
|
|
144
|
+
const triggerEl = this.host.nativeElement.querySelector('[data-navigation-flyout-trigger="true"]');
|
|
145
|
+
const rect = triggerEl?.getBoundingClientRect();
|
|
146
|
+
if (rect && typeof window !== 'undefined' && window.innerWidth > 0) {
|
|
147
|
+
this.floatingAlignEnd.set(rect.left + rect.width / 2 > window.innerWidth / 2);
|
|
148
|
+
}
|
|
149
|
+
this.panelPlacement.set(null);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const hostEl = this.host.nativeElement;
|
|
153
|
+
const navEl = hostEl.closest('[data-navigation-id]');
|
|
154
|
+
let container = navEl?.parentElement ?? hostEl.parentElement;
|
|
155
|
+
// Wrapper display:contents punya rect kosong — naik terus sampai container yang punya box visual.
|
|
156
|
+
while (container && container.getBoundingClientRect().width <= 0 && container.parentElement) {
|
|
157
|
+
container = container.parentElement;
|
|
158
|
+
}
|
|
159
|
+
const containerRect = (container ?? hostEl).getBoundingClientRect();
|
|
160
|
+
const hostRect = hostEl.getBoundingClientRect();
|
|
161
|
+
if (containerRect.width <= 0) {
|
|
162
|
+
this.panelPlacement.set(null);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
this.panelPlacement.set({
|
|
166
|
+
left: containerRect.left - hostRect.left,
|
|
167
|
+
top: containerRect.top - hostRect.top,
|
|
168
|
+
bottom: hostRect.bottom - containerRect.bottom,
|
|
169
|
+
width: containerRect.width,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
toggleFlyout() {
|
|
173
|
+
if (this.isOpen()) {
|
|
174
|
+
this.closeFlyout(false);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
this.measurePanelPlacement();
|
|
178
|
+
this.nav.openDrawer(this.navId());
|
|
179
|
+
const current = this.nav.currentPanelKey(this.navId());
|
|
180
|
+
const branches = this.branches();
|
|
181
|
+
if (!branches.some((branch) => branch.key === current)) {
|
|
182
|
+
const first = branches.find((branch) => !branch.disabled) ?? branches[0];
|
|
183
|
+
if (first) {
|
|
184
|
+
this.nav.openPanel(this.navId(), first);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
queueMicrotask(() => this.focusFirstPanelItem());
|
|
188
|
+
}
|
|
189
|
+
closeFlyout(restoreFocus) {
|
|
190
|
+
this.nav.closeDrawer(this.navId());
|
|
191
|
+
if (restoreFocus) {
|
|
192
|
+
queueMicrotask(() => this.focusTrigger());
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
onEscape(event) {
|
|
196
|
+
if (!this.isOpen()) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
event.preventDefault();
|
|
200
|
+
this.closeFlyout(true);
|
|
201
|
+
}
|
|
202
|
+
onDocumentClick(event) {
|
|
203
|
+
if (!this.isOpen()) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
const target = event.target;
|
|
207
|
+
if (target && !this.host.nativeElement.contains(target)) {
|
|
208
|
+
this.closeFlyout(false);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
isItemActive(item) {
|
|
212
|
+
return this.nav.isItemActive(item, this.activeIds(), this.activeUrl());
|
|
213
|
+
}
|
|
214
|
+
isBranchOpen(item) {
|
|
215
|
+
return this.nav.isPanelOpen(this.navId(), item);
|
|
216
|
+
}
|
|
217
|
+
openBranch(item) {
|
|
218
|
+
this.nav.openPanel(this.navId(), item);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Host trigger+panel. Default `relative block w-full` (mengalir di dalam bar/div). Saat
|
|
222
|
+
* `floating`, jadi `fixed` (mengambang) — default pojok kanan-atas, override via `triggerClass`.
|
|
223
|
+
*/
|
|
224
|
+
hostClasses = computed(() => this.floating()
|
|
225
|
+
? cn('fixed z-50 block w-max', this.triggerClass() || 'right-6 top-6')
|
|
226
|
+
: cn('relative block w-full', this.triggerClass()), /* @ts-ignore */
|
|
227
|
+
...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
|
|
228
|
+
/** Bentuk visual trigger: `button` (pil), `link` (tautan), atau `plain` (ghost); + ikon/teks. */
|
|
229
|
+
triggerClasses() {
|
|
230
|
+
const iconOnly = this.showIconOnly();
|
|
231
|
+
const base = 'nav-trigger group/nav inline-flex min-w-0 items-center font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring';
|
|
232
|
+
if (this.variant() === 'link') {
|
|
233
|
+
return cn(base, 'nav-text underline-offset-4 hover:underline',
|
|
234
|
+
// Icon-only tetap punya target ≥ 36px (WCAG 2.5.8) walau tanpa chrome tautan.
|
|
235
|
+
iconOnly ? 'h-9 w-9 justify-center gap-0' : 'gap-1.5', this.isOpen() ? 'text-primary underline' : 'text-primary/90 hover:text-primary', this.itemClass());
|
|
236
|
+
}
|
|
237
|
+
if (this.variant() === 'plain') {
|
|
238
|
+
return cn(base, 'gap-2 rounded-md nav-text', iconOnly ? 'h-9 w-9 justify-center' : 'h-9 px-3 py-2', this.isOpen()
|
|
239
|
+
? 'bg-accent text-accent-foreground'
|
|
240
|
+
: 'text-foreground/80 hover:bg-accent hover:text-accent-foreground', this.itemClass());
|
|
241
|
+
}
|
|
242
|
+
// button (pil, default)
|
|
243
|
+
return cn(base, 'h-10 gap-2 rounded-full border border-[hsl(var(--border)/var(--opacity-60))] bg-background px-4 py-2 nav-text shadow-sm', iconOnly && 'w-10 justify-center gap-0 px-0', this.isBorderRail()
|
|
244
|
+
? this.isOpen()
|
|
245
|
+
? 'text-primary'
|
|
246
|
+
: 'text-foreground/80 hover:text-primary'
|
|
247
|
+
: this.isOpen()
|
|
248
|
+
? 'bg-accent text-accent-foreground'
|
|
249
|
+
: 'text-foreground/80 hover:bg-accent hover:text-accent-foreground', this.itemClass());
|
|
250
|
+
}
|
|
251
|
+
panelCardClasses() {
|
|
252
|
+
if (this.floating()) {
|
|
253
|
+
// Floating: kartu popover mandiri (rounded penuh + border + shadow), tinggi dibatasi & di-clip;
|
|
254
|
+
// hanya ROW 2 (children) yang scroll.
|
|
255
|
+
return cn('relative flex flex-col rounded-xl border border-[hsl(var(--border)/var(--opacity-70))] bg-popover text-popover-foreground shadow-2xl', 'max-h-[min(28rem,70vh)] overflow-hidden');
|
|
256
|
+
}
|
|
257
|
+
// Border-rail: panel menutup tepat content-box frame layout, jadi garis
|
|
258
|
+
// sisi bar memakai border frame (rail) itu sendiri — panel cukup menggambar
|
|
259
|
+
// border 1.5px senada rail pada sisi yang menjauh dari bar agar sambungan
|
|
260
|
+
// tetap lurus (bawah di mode top, atas di mode bottom).
|
|
261
|
+
return cn('relative flex flex-col bg-popover text-popover-foreground shadow-2xl',
|
|
262
|
+
// Batasi tinggi panel ke viewport lalu CLIP — bukan scroll. Hanya ROW 2 (children, lihat
|
|
263
|
+
// scrollRegionClasses) yang scroll; bar ROW 1 & kontainer panel sendiri tetap diam.
|
|
264
|
+
'max-h-[calc(100dvh-5rem)] overflow-hidden', this.isBorderRail()
|
|
265
|
+
? cn('rounded-none border-border', this.isBottom() ? 'border-t-[1.5px]' : 'border-b-[1.5px]')
|
|
266
|
+
: 'rounded-[var(--layout-frame-radius)] border border-[hsl(var(--border)/var(--opacity-70))]');
|
|
267
|
+
}
|
|
268
|
+
rowClasses() {
|
|
269
|
+
// Menu item = bagian tengah ROW 1: isi ruang antara Footer & Header (flex-1) lalu
|
|
270
|
+
// di-center seperti menubar navbar. Saat jumlah/lebar item melebihi band, band ini
|
|
271
|
+
// scroll horizontal (overflow-x-auto) agar tidak ada item ter-clip & takterjangkau
|
|
272
|
+
// (panel card meng-clip overflow-x). Tinggi & border bar ditangani barRowClasses().
|
|
273
|
+
return cn('m-0 flex min-w-0 flex-1 list-none items-center justify-center gap-1 overflow-x-auto overscroll-x-contain py-2');
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Container `<li>` tab group. Basis `flex -my-2 self-stretch` membuat tab setinggi
|
|
277
|
+
* penuh row (lihat tabClasses); consumer dapat menimpa/menambah lewat `nav-group-class`
|
|
278
|
+
* (global) atau `item.classes.container` (per-group) untuk fleksibilitas.
|
|
279
|
+
*/
|
|
280
|
+
groupContainerClasses(item) {
|
|
281
|
+
return cn('flex -my-2 self-stretch', this.groupClass(), item.classes?.container);
|
|
282
|
+
}
|
|
283
|
+
tabClasses(item) {
|
|
284
|
+
return cn(
|
|
285
|
+
// Tinggi tab group mengikuti tinggi penuh row (parent). Wrapper <li> memakai
|
|
286
|
+
// `-my-2 self-stretch` untuk membatalkan `py-2` row; tombol `h-full` mengisi penuh
|
|
287
|
+
// sehingga sisinya rata dengan border row — sudut pada sisi border dibuat siku
|
|
288
|
+
// agar menyambung (bawah di mode top, atas di mode bottom).
|
|
289
|
+
'nav-trigger nav-text group/nav inline-flex h-full min-h-9 min-w-0 items-center gap-2 rounded-md px-3 font-medium transition-colors', this.isBottom() ? 'rounded-t-none' : 'rounded-b-none', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50', this.isBorderRail()
|
|
290
|
+
? this.isBranchOpen(item) || this.isItemActive(item)
|
|
291
|
+
? 'rounded-none text-primary'
|
|
292
|
+
: 'rounded-none text-foreground/80 hover:text-primary'
|
|
293
|
+
: this.isBranchOpen(item)
|
|
294
|
+
? 'bg-accent text-accent-foreground'
|
|
295
|
+
: this.isItemActive(item)
|
|
296
|
+
? 'font-semibold text-foreground hover:bg-accent hover:text-accent-foreground'
|
|
297
|
+
: 'text-foreground/80 hover:bg-accent hover:text-accent-foreground', item.classes?.wrapper, this.itemClass());
|
|
298
|
+
}
|
|
299
|
+
tabChevronClasses(item) {
|
|
300
|
+
return cn('shrink-0 self-center text-current transition-transform duration-200', this.isBranchOpen(item) && 'rotate-90');
|
|
301
|
+
}
|
|
302
|
+
onRowKeydown(event) {
|
|
303
|
+
if (event.key !== 'ArrowRight' && event.key !== 'ArrowLeft' && event.key !== 'ArrowDown') {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
const rowItems = Array.from(this.host.nativeElement.querySelectorAll('[data-navigation-flyout-row="true"] [role="menuitem"]'));
|
|
307
|
+
const currentIndex = rowItems.indexOf(document.activeElement);
|
|
308
|
+
if (currentIndex === -1) {
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
event.preventDefault();
|
|
312
|
+
if (event.key === 'ArrowDown') {
|
|
313
|
+
const entry = this.host.nativeElement.querySelector('[data-navigation-flyout-content] [role="menuitem"]');
|
|
314
|
+
entry?.focus();
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
const direction = event.key === 'ArrowRight' ? 1 : -1;
|
|
318
|
+
rowItems[(currentIndex + direction + rowItems.length) % rowItems.length]?.focus();
|
|
319
|
+
}
|
|
320
|
+
focusFirstPanelItem() {
|
|
321
|
+
const panel = this.host.nativeElement.querySelector('[data-navigation-flyout-panel="true"]');
|
|
322
|
+
if (!panel) {
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
// Fokus awal ke menu item ROW 1 (lalu grid ROW 2) — BUKAN kontrol Header/Footer yang
|
|
326
|
+
// juga ada di bar (mis. tombol logout). querySelector mengembalikan match pertama dalam
|
|
327
|
+
// urutan DOM, dan Header/Footer bisa mendahului menu, jadi lingkup ke baris menu dulu.
|
|
328
|
+
const target = panel.querySelector('[data-navigation-flyout-row="true"] [role="menuitem"], [data-navigation-flyout-row="true"] a[href]') ?? panel.querySelector('[role="menuitem"], a[href]');
|
|
329
|
+
target?.focus();
|
|
330
|
+
}
|
|
331
|
+
focusTrigger() {
|
|
332
|
+
this.host.nativeElement
|
|
333
|
+
.querySelector('[data-navigation-flyout-trigger="true"]')
|
|
334
|
+
?.focus();
|
|
335
|
+
}
|
|
336
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NavigationFlyoutMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
337
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: NavigationFlyoutMenuComponent, isStandalone: true, selector: "NavigationFlyoutMenu", inputs: { navId: { classPropertyName: "navId", publicName: "navId", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, iconOnly: { classPropertyName: "iconOnly", publicName: "iconOnly", isSignal: true, isRequired: false, transformFunction: null }, iconPosition: { classPropertyName: "iconPosition", publicName: "iconPosition", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, floating: { classPropertyName: "floating", publicName: "floating", isSignal: true, isRequired: false, transformFunction: null }, triggerClass: { classPropertyName: "triggerClass", publicName: "triggerClass", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, typeStyle: { classPropertyName: "typeStyle", publicName: "typeStyle", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, itemClass: { classPropertyName: "itemClass", publicName: "itemClass", isSignal: true, isRequired: false, transformFunction: null }, groupClass: { classPropertyName: "groupClass", publicName: "groupClass", isSignal: true, isRequired: false, transformFunction: null }, activeIds: { classPropertyName: "activeIds", publicName: "activeIds", isSignal: true, isRequired: false, transformFunction: null }, activeUrl: { classPropertyName: "activeUrl", publicName: "activeUrl", isSignal: true, isRequired: false, transformFunction: null }, iconTemplate: { classPropertyName: "iconTemplate", publicName: "iconTemplate", isSignal: true, isRequired: false, transformFunction: null }, collapseTree: { classPropertyName: "collapseTree", publicName: "collapseTree", isSignal: true, isRequired: false, transformFunction: null }, openedIds: { classPropertyName: "openedIds", publicName: "openedIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openedIdsChange: "openedIdsChange", itemSelected: "itemSelected" }, host: { listeners: { "keydown.escape": "onEscape($event)", "document:click": "onDocumentClick($event)", "window:resize": "onWindowResize()" }, properties: { "class": "hostClasses()" } }, ngImport: i0, template: `
|
|
338
|
+
<button
|
|
339
|
+
type="button"
|
|
340
|
+
data-navigation-flyout-trigger="true"
|
|
341
|
+
[class]="triggerClasses()"
|
|
342
|
+
aria-haspopup="menu"
|
|
343
|
+
[attr.aria-expanded]="isOpen()"
|
|
344
|
+
[attr.aria-controls]="isOpen() ? panelId() : null"
|
|
345
|
+
[attr.aria-label]="showIconOnly() ? label() : null"
|
|
346
|
+
[attr.title]="showIconOnly() ? label() : null"
|
|
347
|
+
(click)="toggleFlyout()"
|
|
348
|
+
>
|
|
349
|
+
@if (showIconOnly()) {
|
|
350
|
+
<Icon [name]="triggerIcon() ?? 'menu'" [size]="18" class="text-current" />
|
|
351
|
+
} @else {
|
|
352
|
+
@if (iconPosition() === 'start' && triggerIcon(); as iconName) {
|
|
353
|
+
<Icon [name]="iconName" [size]="18" class="shrink-0 text-current" />
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
<span class="truncate">{{ label() }}</span>
|
|
357
|
+
|
|
358
|
+
@if (iconPosition() === 'end' && triggerIcon(); as iconName) {
|
|
359
|
+
<Icon [name]="iconName" [size]="18" class="shrink-0 text-current" />
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
</button>
|
|
363
|
+
|
|
364
|
+
@if (isOpen()) {
|
|
365
|
+
<div
|
|
366
|
+
[id]="panelId()"
|
|
367
|
+
data-navigation-flyout-panel="true"
|
|
368
|
+
[class]="panelWrapperClasses()"
|
|
369
|
+
[style.left.px]="floating() ? null : panelPlacement()?.left"
|
|
370
|
+
[style.top.px]="floating() || isBottom() ? null : panelPlacement()?.top"
|
|
371
|
+
[style.bottom.px]="!floating() && isBottom() ? panelPlacement()?.bottom : null"
|
|
372
|
+
[style.width.px]="floating() ? null : panelPlacement()?.width"
|
|
373
|
+
>
|
|
374
|
+
<div [class]="panelCardClasses()">
|
|
375
|
+
<div role="menu" [class]="menuClasses()" [attr.aria-label]="label()">
|
|
376
|
+
<!-- ROW 1 = bar (sticky, menutup bar trigger), struktur seperti bar navbar:
|
|
377
|
+
Header (kiri) | menu item (tengah) | Footer (kanan). Hanya ROW 2 (grid child)
|
|
378
|
+
di bawah bar yang ikut scroll. -->
|
|
379
|
+
<div data-navigation-flyout-bar="true" [class]="barRowClasses()">
|
|
380
|
+
<ng-content select="NavigationHeader" />
|
|
381
|
+
|
|
382
|
+
<ul
|
|
383
|
+
role="none"
|
|
384
|
+
data-navigation-flyout-row="true"
|
|
385
|
+
[class]="rowClasses()"
|
|
386
|
+
(keydown)="onRowKeydown($event)"
|
|
387
|
+
>
|
|
388
|
+
@for (item of items(); track item.key) {
|
|
389
|
+
@switch (item.type) {
|
|
390
|
+
@case ('divider') {
|
|
391
|
+
<li role="separator" class="mx-1 h-5 w-px bg-border"></li>
|
|
392
|
+
}
|
|
393
|
+
@case ('spacer') {
|
|
394
|
+
<li role="none" aria-hidden="true" class="flex-1"></li>
|
|
395
|
+
}
|
|
396
|
+
@default {
|
|
397
|
+
@if (item.children.length > 0) {
|
|
398
|
+
<li
|
|
399
|
+
role="none"
|
|
400
|
+
[class]="groupContainerClasses(item)"
|
|
401
|
+
[attr.data-navigation-item-key]="item.key"
|
|
402
|
+
>
|
|
403
|
+
<button
|
|
404
|
+
type="button"
|
|
405
|
+
role="menuitem"
|
|
406
|
+
data-navigation-flyout-tab="true"
|
|
407
|
+
[class]="tabClasses(item)"
|
|
408
|
+
[attr.aria-expanded]="isBranchOpen(item)"
|
|
409
|
+
[attr.aria-controls]="item.panelId"
|
|
410
|
+
[disabled]="item.disabled || null"
|
|
411
|
+
(click)="openBranch(item)"
|
|
412
|
+
>
|
|
413
|
+
<NavigationItemContent
|
|
414
|
+
[item]="item"
|
|
415
|
+
[active]="isItemActive(item)"
|
|
416
|
+
[compact]="false"
|
|
417
|
+
[orientation]="'horizontal'"
|
|
418
|
+
[level]="0"
|
|
419
|
+
[iconTemplate]="iconTemplate()"
|
|
420
|
+
/>
|
|
421
|
+
<Icon
|
|
422
|
+
name="chevron_right"
|
|
423
|
+
[size]="16"
|
|
424
|
+
[class]="tabChevronClasses(item)"
|
|
425
|
+
/>
|
|
426
|
+
</button>
|
|
427
|
+
</li>
|
|
428
|
+
} @else {
|
|
429
|
+
<li
|
|
430
|
+
NavigationItem
|
|
431
|
+
[navId]="navId()"
|
|
432
|
+
[item]="item"
|
|
433
|
+
[level]="0"
|
|
434
|
+
[orientation]="'horizontal'"
|
|
435
|
+
[compact]="false"
|
|
436
|
+
[itemClass]="navItemClass()"
|
|
437
|
+
[activeIds]="activeIds()"
|
|
438
|
+
[activeUrl]="activeUrl()"
|
|
439
|
+
[iconTemplate]="iconTemplate()"
|
|
440
|
+
[collapseTree]="collapseTree()"
|
|
441
|
+
[openedIds]="openedIds()"
|
|
442
|
+
(openedIdsChange)="openedIdsChange.emit($event)"
|
|
443
|
+
(itemSelected)="itemSelected.emit($event)"
|
|
444
|
+
></li>
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
</ul>
|
|
450
|
+
|
|
451
|
+
<ng-content select="NavigationFooter" />
|
|
452
|
+
</div>
|
|
453
|
+
|
|
454
|
+
<!-- ROW 2 = child dari menu item aktif; HANYA area ini yang men-scroll. -->
|
|
455
|
+
<div data-navigation-flyout-scroll="true" [class]="scrollRegionClasses()">
|
|
456
|
+
@if (activeBranch(); as branch) {
|
|
457
|
+
<NavigationEntryGrid
|
|
458
|
+
[navId]="navId()"
|
|
459
|
+
[branch]="branch"
|
|
460
|
+
[typeStyle]="typeStyle()"
|
|
461
|
+
[itemClass]="itemClass()"
|
|
462
|
+
[activeIds]="activeIds()"
|
|
463
|
+
[activeUrl]="activeUrl()"
|
|
464
|
+
[iconTemplate]="iconTemplate()"
|
|
465
|
+
[collapseTree]="collapseTree()"
|
|
466
|
+
[openedIds]="openedIds()"
|
|
467
|
+
(openedIdsChange)="openedIdsChange.emit($event)"
|
|
468
|
+
(itemSelected)="itemSelected.emit($event)"
|
|
469
|
+
/>
|
|
470
|
+
}
|
|
471
|
+
</div>
|
|
472
|
+
</div>
|
|
473
|
+
</div>
|
|
474
|
+
</div>
|
|
475
|
+
}
|
|
476
|
+
`, isInline: true, dependencies: [{ kind: "component", type: IconComponent, selector: "Icon", inputs: ["name", "class", "size", "fill", "weight", "grade", "opticalSize"] }, { kind: "component", type: NavigationEntryGridComponent, selector: "NavigationEntryGrid", inputs: ["navId", "branch", "typeStyle", "itemClass", "activeIds", "activeUrl", "iconTemplate", "collapseTree", "openedIds"], outputs: ["openedIdsChange", "itemSelected"] }, { kind: "component", type: NavigationItemComponent, selector: "li[NavigationItem]", inputs: ["navId", "item", "level", "orientation", "compact", "itemClass", "activeIds", "activeUrl", "iconTemplate", "collapseTree", "straightRail", "straightRailActive", "firstInBranch", "lastInBranch", "openedIds"], outputs: ["openedIdsChange", "itemSelected"] }, { kind: "component", type: NavigationItemContentComponent, selector: "NavigationItemContent", inputs: ["item", "active", "compact", "orientation", "level", "collapseTree", "iconTemplate"] }] });
|
|
477
|
+
}
|
|
478
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NavigationFlyoutMenuComponent, decorators: [{
|
|
479
|
+
type: Component,
|
|
480
|
+
args: [{
|
|
481
|
+
selector: 'NavigationFlyoutMenu',
|
|
482
|
+
imports: [
|
|
483
|
+
IconComponent,
|
|
484
|
+
NavigationEntryGridComponent,
|
|
485
|
+
NavigationItemComponent,
|
|
486
|
+
NavigationItemContentComponent,
|
|
487
|
+
],
|
|
488
|
+
host: {
|
|
489
|
+
'[class]': 'hostClasses()',
|
|
490
|
+
'(keydown.escape)': 'onEscape($event)',
|
|
491
|
+
'(document:click)': 'onDocumentClick($event)',
|
|
492
|
+
'(window:resize)': 'onWindowResize()',
|
|
493
|
+
},
|
|
494
|
+
template: `
|
|
495
|
+
<button
|
|
496
|
+
type="button"
|
|
497
|
+
data-navigation-flyout-trigger="true"
|
|
498
|
+
[class]="triggerClasses()"
|
|
499
|
+
aria-haspopup="menu"
|
|
500
|
+
[attr.aria-expanded]="isOpen()"
|
|
501
|
+
[attr.aria-controls]="isOpen() ? panelId() : null"
|
|
502
|
+
[attr.aria-label]="showIconOnly() ? label() : null"
|
|
503
|
+
[attr.title]="showIconOnly() ? label() : null"
|
|
504
|
+
(click)="toggleFlyout()"
|
|
505
|
+
>
|
|
506
|
+
@if (showIconOnly()) {
|
|
507
|
+
<Icon [name]="triggerIcon() ?? 'menu'" [size]="18" class="text-current" />
|
|
508
|
+
} @else {
|
|
509
|
+
@if (iconPosition() === 'start' && triggerIcon(); as iconName) {
|
|
510
|
+
<Icon [name]="iconName" [size]="18" class="shrink-0 text-current" />
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
<span class="truncate">{{ label() }}</span>
|
|
514
|
+
|
|
515
|
+
@if (iconPosition() === 'end' && triggerIcon(); as iconName) {
|
|
516
|
+
<Icon [name]="iconName" [size]="18" class="shrink-0 text-current" />
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
</button>
|
|
520
|
+
|
|
521
|
+
@if (isOpen()) {
|
|
522
|
+
<div
|
|
523
|
+
[id]="panelId()"
|
|
524
|
+
data-navigation-flyout-panel="true"
|
|
525
|
+
[class]="panelWrapperClasses()"
|
|
526
|
+
[style.left.px]="floating() ? null : panelPlacement()?.left"
|
|
527
|
+
[style.top.px]="floating() || isBottom() ? null : panelPlacement()?.top"
|
|
528
|
+
[style.bottom.px]="!floating() && isBottom() ? panelPlacement()?.bottom : null"
|
|
529
|
+
[style.width.px]="floating() ? null : panelPlacement()?.width"
|
|
530
|
+
>
|
|
531
|
+
<div [class]="panelCardClasses()">
|
|
532
|
+
<div role="menu" [class]="menuClasses()" [attr.aria-label]="label()">
|
|
533
|
+
<!-- ROW 1 = bar (sticky, menutup bar trigger), struktur seperti bar navbar:
|
|
534
|
+
Header (kiri) | menu item (tengah) | Footer (kanan). Hanya ROW 2 (grid child)
|
|
535
|
+
di bawah bar yang ikut scroll. -->
|
|
536
|
+
<div data-navigation-flyout-bar="true" [class]="barRowClasses()">
|
|
537
|
+
<ng-content select="NavigationHeader" />
|
|
538
|
+
|
|
539
|
+
<ul
|
|
540
|
+
role="none"
|
|
541
|
+
data-navigation-flyout-row="true"
|
|
542
|
+
[class]="rowClasses()"
|
|
543
|
+
(keydown)="onRowKeydown($event)"
|
|
544
|
+
>
|
|
545
|
+
@for (item of items(); track item.key) {
|
|
546
|
+
@switch (item.type) {
|
|
547
|
+
@case ('divider') {
|
|
548
|
+
<li role="separator" class="mx-1 h-5 w-px bg-border"></li>
|
|
549
|
+
}
|
|
550
|
+
@case ('spacer') {
|
|
551
|
+
<li role="none" aria-hidden="true" class="flex-1"></li>
|
|
552
|
+
}
|
|
553
|
+
@default {
|
|
554
|
+
@if (item.children.length > 0) {
|
|
555
|
+
<li
|
|
556
|
+
role="none"
|
|
557
|
+
[class]="groupContainerClasses(item)"
|
|
558
|
+
[attr.data-navigation-item-key]="item.key"
|
|
559
|
+
>
|
|
560
|
+
<button
|
|
561
|
+
type="button"
|
|
562
|
+
role="menuitem"
|
|
563
|
+
data-navigation-flyout-tab="true"
|
|
564
|
+
[class]="tabClasses(item)"
|
|
565
|
+
[attr.aria-expanded]="isBranchOpen(item)"
|
|
566
|
+
[attr.aria-controls]="item.panelId"
|
|
567
|
+
[disabled]="item.disabled || null"
|
|
568
|
+
(click)="openBranch(item)"
|
|
569
|
+
>
|
|
570
|
+
<NavigationItemContent
|
|
571
|
+
[item]="item"
|
|
572
|
+
[active]="isItemActive(item)"
|
|
573
|
+
[compact]="false"
|
|
574
|
+
[orientation]="'horizontal'"
|
|
575
|
+
[level]="0"
|
|
576
|
+
[iconTemplate]="iconTemplate()"
|
|
577
|
+
/>
|
|
578
|
+
<Icon
|
|
579
|
+
name="chevron_right"
|
|
580
|
+
[size]="16"
|
|
581
|
+
[class]="tabChevronClasses(item)"
|
|
582
|
+
/>
|
|
583
|
+
</button>
|
|
584
|
+
</li>
|
|
585
|
+
} @else {
|
|
586
|
+
<li
|
|
587
|
+
NavigationItem
|
|
588
|
+
[navId]="navId()"
|
|
589
|
+
[item]="item"
|
|
590
|
+
[level]="0"
|
|
591
|
+
[orientation]="'horizontal'"
|
|
592
|
+
[compact]="false"
|
|
593
|
+
[itemClass]="navItemClass()"
|
|
594
|
+
[activeIds]="activeIds()"
|
|
595
|
+
[activeUrl]="activeUrl()"
|
|
596
|
+
[iconTemplate]="iconTemplate()"
|
|
597
|
+
[collapseTree]="collapseTree()"
|
|
598
|
+
[openedIds]="openedIds()"
|
|
599
|
+
(openedIdsChange)="openedIdsChange.emit($event)"
|
|
600
|
+
(itemSelected)="itemSelected.emit($event)"
|
|
601
|
+
></li>
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
</ul>
|
|
607
|
+
|
|
608
|
+
<ng-content select="NavigationFooter" />
|
|
609
|
+
</div>
|
|
610
|
+
|
|
611
|
+
<!-- ROW 2 = child dari menu item aktif; HANYA area ini yang men-scroll. -->
|
|
612
|
+
<div data-navigation-flyout-scroll="true" [class]="scrollRegionClasses()">
|
|
613
|
+
@if (activeBranch(); as branch) {
|
|
614
|
+
<NavigationEntryGrid
|
|
615
|
+
[navId]="navId()"
|
|
616
|
+
[branch]="branch"
|
|
617
|
+
[typeStyle]="typeStyle()"
|
|
618
|
+
[itemClass]="itemClass()"
|
|
619
|
+
[activeIds]="activeIds()"
|
|
620
|
+
[activeUrl]="activeUrl()"
|
|
621
|
+
[iconTemplate]="iconTemplate()"
|
|
622
|
+
[collapseTree]="collapseTree()"
|
|
623
|
+
[openedIds]="openedIds()"
|
|
624
|
+
(openedIdsChange)="openedIdsChange.emit($event)"
|
|
625
|
+
(itemSelected)="itemSelected.emit($event)"
|
|
626
|
+
/>
|
|
627
|
+
}
|
|
628
|
+
</div>
|
|
629
|
+
</div>
|
|
630
|
+
</div>
|
|
631
|
+
</div>
|
|
632
|
+
}
|
|
633
|
+
`,
|
|
634
|
+
}]
|
|
635
|
+
}], propDecorators: { navId: [{ type: i0.Input, args: [{ isSignal: true, alias: "navId", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], iconOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconOnly", required: false }] }], iconPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconPosition", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], floating: [{ type: i0.Input, args: [{ isSignal: true, alias: "floating", required: false }] }], triggerClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerClass", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], typeStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "typeStyle", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], itemClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemClass", required: false }] }], groupClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupClass", required: false }] }], activeIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeIds", required: false }] }], activeUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeUrl", required: false }] }], iconTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconTemplate", required: false }] }], collapseTree: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapseTree", required: false }] }], openedIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "openedIds", required: false }] }], openedIdsChange: [{ type: i0.Output, args: ["openedIdsChange"] }], itemSelected: [{ type: i0.Output, args: ["itemSelected"] }] } });
|
|
636
|
+
|
|
637
|
+
export { NavigationFlyoutMenuComponent };
|