@ojiepermana/angular-navigation 22.0.36 → 22.0.43
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.
|
@@ -4,6 +4,8 @@ import { inject, signal, computed, isDevMode, Service } from '@angular/core';
|
|
|
4
4
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
5
5
|
import { Router, NavigationEnd } from '@angular/router';
|
|
6
6
|
|
|
7
|
+
/** Referensi stabil untuk id yang belum punya data terdaftar (hindari array baru tiap evaluasi). */
|
|
8
|
+
const EMPTY_NAV_DATA = Object.freeze([]);
|
|
7
9
|
const DEFAULT_NAV_ID = 'default';
|
|
8
10
|
const PERSISTED_NAV_ID = 'main';
|
|
9
11
|
const DEFAULT_VERTICAL_TYPE = 'sidebar';
|
|
@@ -26,6 +28,9 @@ class NavigationService {
|
|
|
26
28
|
...(ngDevMode ? [{ debugName: "openPanelKeys" }] : /* istanbul ignore next */ []));
|
|
27
29
|
drawerOpenState = signal({}, /* @ts-ignore */
|
|
28
30
|
...(ngDevMode ? [{ debugName: "drawerOpenState" }] : /* istanbul ignore next */ []));
|
|
31
|
+
/** Data mentah per id, dipublikasikan oleh `<Navigation>` agar surface lain (mis. apps-launcher di `Page`) bisa membaca nav by id tanpa mendaftarkan ulang id yang sama. */
|
|
32
|
+
dataById = signal({}, /* @ts-ignore */
|
|
33
|
+
...(ngDevMode ? [{ debugName: "dataById" }] : /* istanbul ignore next */ []));
|
|
29
34
|
/** id navigasi → token owner instance, untuk menjaga setiap id hanya dipakai satu <Navigation> hidup. */
|
|
30
35
|
idOwners = new Map();
|
|
31
36
|
openPanelKey = computed(() => this.openPanelKeys()[DEFAULT_NAV_ID] ?? null, /* @ts-ignore */
|
|
@@ -92,6 +97,21 @@ class NavigationService {
|
|
|
92
97
|
currentState(id) {
|
|
93
98
|
return this.states()[this.normalizeId(id)] ?? null;
|
|
94
99
|
}
|
|
100
|
+
/** Data terdaftar untuk sebuah id sebagai signal; `[]` bila belum ada `<Navigation>` dengan id tersebut. */
|
|
101
|
+
data(id) {
|
|
102
|
+
const navId = this.normalizeId(id);
|
|
103
|
+
return computed(() => this.dataById()[navId] ?? EMPTY_NAV_DATA);
|
|
104
|
+
}
|
|
105
|
+
/** Dipanggil `<Navigation>` untuk mempublikasikan datanya ke registry by id. */
|
|
106
|
+
publishData(id, data) {
|
|
107
|
+
const navId = this.normalizeId(id);
|
|
108
|
+
this.dataById.update((map) => ({ ...map, [navId]: data }));
|
|
109
|
+
}
|
|
110
|
+
/** Dipanggil `<Navigation>` saat destroy untuk melepas datanya dari registry. */
|
|
111
|
+
clearData(id) {
|
|
112
|
+
const navId = this.normalizeId(id);
|
|
113
|
+
this.dataById.update((map) => this.withoutKey(map, navId));
|
|
114
|
+
}
|
|
95
115
|
currentPanelKey(id) {
|
|
96
116
|
return this.openPanelKeys()[this.normalizeId(id)] ?? null;
|
|
97
117
|
}
|
|
@@ -189,6 +189,7 @@ class NavigationContainerComponent {
|
|
|
189
189
|
...(ngDevMode ? [{ debugName: "openedIds" }] : /* istanbul ignore next */ []));
|
|
190
190
|
itemSelected = output();
|
|
191
191
|
nav = inject(NavigationService);
|
|
192
|
+
destroyRef = inject(DestroyRef);
|
|
192
193
|
hoverPreviewExpanded = signal(false, /* @ts-ignore */
|
|
193
194
|
...(ngDevMode ? [{ debugName: "hoverPreviewExpanded" }] : /* istanbul ignore next */ []));
|
|
194
195
|
/** Konfigurasi type aktif yang didaftarkan wrapper anak (sidebar/dockbar/navbar/flyout). */
|
|
@@ -302,6 +303,12 @@ class NavigationContainerComponent {
|
|
|
302
303
|
? 'overflow-visible'
|
|
303
304
|
: 'overflow-hidden', this.class()), /* @ts-ignore */
|
|
304
305
|
...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
|
|
306
|
+
constructor() {
|
|
307
|
+
// Publikasikan data ke registry by id agar surface lain (mis. apps-launcher di `Page`)
|
|
308
|
+
// bisa membaca nav by id tanpa mendaftarkan ulang `<Navigation>` dengan id yang sama.
|
|
309
|
+
effect(() => this.nav.publishData(this.navId(), this.data()));
|
|
310
|
+
this.destroyRef.onDestroy(() => this.nav.clearData(this.navId()));
|
|
311
|
+
}
|
|
305
312
|
/**
|
|
306
313
|
* Dipanggil komponen type saat dibuat. Satu `<Navigation>` hanya boleh
|
|
307
314
|
* memuat satu type hidup — pendaftaran ganda dianggap salah konfigurasi.
|
|
@@ -352,7 +359,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.3", ngImpor
|
|
|
352
359
|
},
|
|
353
360
|
template: ` <ng-content /> `,
|
|
354
361
|
}]
|
|
355
|
-
}], propDecorators: { navId: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], collapseTree: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapse-tree", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], itemClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemClass", required: false }] }], groupClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "nav-group-class", required: false }] }], activeIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeIds", required: false }] }], activeUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeUrl", required: false }] }], openedIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "openedIds", required: false }] }, { type: i0.Output, args: ["openedIdsChange"] }], itemSelected: [{ type: i0.Output, args: ["itemSelected"] }], iconTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NavigationIconDirective), { isSignal: true }] }] } });
|
|
362
|
+
}], ctorParameters: () => [], propDecorators: { navId: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], collapseTree: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapse-tree", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], itemClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemClass", required: false }] }], groupClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "nav-group-class", required: false }] }], activeIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeIds", required: false }] }], activeUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeUrl", required: false }] }], openedIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "openedIds", required: false }] }, { type: i0.Output, args: ["openedIdsChange"] }], itemSelected: [{ type: i0.Output, args: ["itemSelected"] }], iconTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NavigationIconDirective), { isSignal: true }] }] } });
|
|
356
363
|
|
|
357
364
|
class NavigationItemContentComponent {
|
|
358
365
|
nav = inject(NavigationService);
|
|
@@ -384,7 +391,7 @@ class NavigationItemContentComponent {
|
|
|
384
391
|
...(ngDevMode ? [{ debugName: "subtitleClasses" }] : /* istanbul ignore next */ []));
|
|
385
392
|
compactFallbackClasses = computed(() => cn('inline-flex h-5 min-w-5 items-center justify-center text-xs font-semibold uppercase'), /* @ts-ignore */
|
|
386
393
|
...(ngDevMode ? [{ debugName: "compactFallbackClasses" }] : /* istanbul ignore next */ []));
|
|
387
|
-
defaultBadgeClasses = computed(() => cn('ml-auto inline-flex h-5 shrink-0 items-center rounded-full px-2
|
|
394
|
+
defaultBadgeClasses = computed(() => cn('nav-badge ml-auto inline-flex h-5 shrink-0 items-center rounded-full px-2', this.active() ? 'bg-background text-foreground' : 'bg-muted text-muted-foreground'), /* @ts-ignore */
|
|
388
395
|
...(ngDevMode ? [{ debugName: "defaultBadgeClasses" }] : /* istanbul ignore next */ []));
|
|
389
396
|
defaultIconSize = computed(() => (this.usesStraightVerticalSurface() ? 18 : 16), /* @ts-ignore */
|
|
390
397
|
...(ngDevMode ? [{ debugName: "defaultIconSize" }] : /* istanbul ignore next */ []));
|
|
@@ -587,10 +594,10 @@ class NavigationItemComponent {
|
|
|
587
594
|
this.nav.closeDrawer(this.navId());
|
|
588
595
|
}
|
|
589
596
|
leafClasses(active) {
|
|
590
|
-
return cn('NavigationItem group/nav inline-flex min-w-0 items-center rounded-md
|
|
597
|
+
return cn('NavigationItem nav-text group/nav inline-flex min-w-0 items-center rounded-md font-medium transition-colors', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring', this.orientation() === 'horizontal' && this.level() === 0 ? 'h-9 px-3 py-2' : 'w-full px-3 py-1.5 text-left', this.orientation() === 'horizontal' && this.level() === 0 ? 'gap-3' : 'gap-1.5', this.compact() && 'h-10 w-10 justify-center gap-0 px-0 text-center', this.interactiveStateClasses(active), this.item().disabled && 'pointer-events-none opacity-50', this.item().classes?.wrapper, this.itemClass());
|
|
591
598
|
}
|
|
592
599
|
triggerClasses(active) {
|
|
593
|
-
return cn('nav-trigger group/nav inline-flex min-w-0 items-center rounded-md
|
|
600
|
+
return cn('nav-trigger nav-text group/nav inline-flex min-w-0 items-center rounded-md font-medium transition-colors', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50', this.orientation() === 'horizontal' && this.level() === 0 ? 'h-9 px-3 py-2' : 'w-full px-3 py-1.5 text-left', this.orientation() === 'horizontal' && this.level() === 0 ? 'gap-3' : 'gap-1.5', this.compact() && 'h-10 w-10 justify-center gap-0 px-0 text-center', this.interactiveStateClasses(active), this.item().classes?.wrapper, this.itemClass());
|
|
594
601
|
}
|
|
595
602
|
interactiveStateClasses(active) {
|
|
596
603
|
const showsNestedActiveConnector = active &&
|
|
@@ -619,7 +626,7 @@ class NavigationItemComponent {
|
|
|
619
626
|
return cn(this.orientation() === 'horizontal' && this.level() === 0 ? 'mx-1 h-5 w-px' : 'my-2 w-full px-2');
|
|
620
627
|
}
|
|
621
628
|
groupHeadingClasses() {
|
|
622
|
-
return cn('px-3 py-2 text-
|
|
629
|
+
return cn('nav-heading px-3 py-2 text-muted-foreground', this.item().classes?.title);
|
|
623
630
|
}
|
|
624
631
|
childListClasses() {
|
|
625
632
|
const isGroupedBranch = this.item().type === 'group' || this.item().type === 'mega';
|
|
@@ -1178,12 +1185,13 @@ class NavigationDockbarMenuComponent {
|
|
|
1178
1185
|
// berpindah group lain tanpa menutup drawer lebih dulu.
|
|
1179
1186
|
this.isDrawerMode() && this.openGroup() !== null && 'relative z-50'), /* @ts-ignore */
|
|
1180
1187
|
...(ngDevMode ? [{ debugName: "railClasses" }] : /* istanbul ignore next */ []));
|
|
1181
|
-
asideClasses = computed(() => cn('absolute inset-y-0 flex w-60 flex-col bg-background',
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1188
|
+
asideClasses = computed(() => cn('absolute inset-y-0 flex w-60 flex-col bg-background',
|
|
1189
|
+
// Border only on the CONTENT-facing edge. The dockbar rail already draws the
|
|
1190
|
+
// rail-facing separator, so a rail-facing border here would double up
|
|
1191
|
+
// (right of the mini-dock + left of the aside).
|
|
1192
|
+
this.position() === 'right'
|
|
1193
|
+
? 'right-16 border-l border-[hsl(var(--border)/var(--opacity-70))]'
|
|
1194
|
+
: 'left-16 border-r border-[hsl(var(--border)/var(--opacity-70))]', this.isDrawerMode() && 'z-50 shadow-xl'), /* @ts-ignore */
|
|
1187
1195
|
...(ngDevMode ? [{ debugName: "asideClasses" }] : /* istanbul ignore next */ []));
|
|
1188
1196
|
/**
|
|
1189
1197
|
* Offset backdrop agar kolom navigasi (rail + header/footer) benar-benar bebas
|
|
@@ -1237,7 +1245,7 @@ class NavigationDockbarMenuComponent {
|
|
|
1237
1245
|
return this.nav.isItemActive(entry, this.activeIds(), this.activeUrl());
|
|
1238
1246
|
}
|
|
1239
1247
|
triggerClasses(entry) {
|
|
1240
|
-
return cn('group/nav inline-flex h-10 w-10 items-center justify-center rounded-md
|
|
1248
|
+
return cn('nav-text group/nav inline-flex h-10 w-10 items-center justify-center rounded-md font-medium transition-colors', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50', this.isGroupOpen(entry)
|
|
1241
1249
|
? 'bg-accent text-accent-foreground'
|
|
1242
1250
|
: this.isGroupActive(entry)
|
|
1243
1251
|
? 'font-semibold text-foreground'
|
|
@@ -1624,7 +1632,7 @@ class NavigationEntryGridComponent {
|
|
|
1624
1632
|
return cn('m-0 grid list-none grid-cols-1 gap-1 p-0', columns >= 2 && 'sm:grid-cols-2', columns >= 3 && 'md:grid-cols-3', columns >= 4 && 'lg:grid-cols-4');
|
|
1625
1633
|
}
|
|
1626
1634
|
entryClasses(item, active) {
|
|
1627
|
-
return cn('group/nav flex w-full items-center gap-3 px-3 py-2.5 text-left
|
|
1635
|
+
return cn('group/nav nav-text flex w-full items-center gap-3 px-3 py-2.5 text-left transition-colors', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring', this.isBorderRail()
|
|
1628
1636
|
? cn('rounded-none', active ? 'text-primary' : 'text-foreground hover:text-primary')
|
|
1629
1637
|
: cn('rounded-lg', active
|
|
1630
1638
|
? 'bg-accent text-accent-foreground'
|
|
@@ -1641,7 +1649,7 @@ class NavigationEntryGridComponent {
|
|
|
1641
1649
|
return cn('text-current', item.classes?.icon);
|
|
1642
1650
|
}
|
|
1643
1651
|
entryTitleClasses(item, active) {
|
|
1644
|
-
return cn('block truncate
|
|
1652
|
+
return cn('block truncate font-medium', this.isBorderRail() ? 'text-current' : 'text-foreground', active && 'font-semibold', item.classes?.title);
|
|
1645
1653
|
}
|
|
1646
1654
|
entrySubtitleClasses(item) {
|
|
1647
1655
|
return cn('mt-0.5 block truncate text-xs text-muted-foreground', item.classes?.subtitle);
|
|
@@ -1830,7 +1838,7 @@ class NavigationEntryGridComponent {
|
|
|
1830
1838
|
<span
|
|
1831
1839
|
[class]="
|
|
1832
1840
|
badge.classes ??
|
|
1833
|
-
'inline-flex h-5 shrink-0 items-center self-center rounded-full bg-muted px-2 text-
|
|
1841
|
+
'nav-badge inline-flex h-5 shrink-0 items-center self-center rounded-full bg-muted px-2 text-muted-foreground'
|
|
1834
1842
|
"
|
|
1835
1843
|
>{{ badge.title }}</span
|
|
1836
1844
|
>
|
|
@@ -2019,7 +2027,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.3", ngImpor
|
|
|
2019
2027
|
<span
|
|
2020
2028
|
[class]="
|
|
2021
2029
|
badge.classes ??
|
|
2022
|
-
'inline-flex h-5 shrink-0 items-center self-center rounded-full bg-muted px-2 text-
|
|
2030
|
+
'nav-badge inline-flex h-5 shrink-0 items-center self-center rounded-full bg-muted px-2 text-muted-foreground'
|
|
2023
2031
|
"
|
|
2024
2032
|
>{{ badge.title }}</span
|
|
2025
2033
|
>
|
|
@@ -2253,17 +2261,17 @@ class NavigationFlyoutMenuComponent {
|
|
|
2253
2261
|
const iconOnly = this.showIconOnly();
|
|
2254
2262
|
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';
|
|
2255
2263
|
if (this.variant() === 'link') {
|
|
2256
|
-
return cn(base, 'text
|
|
2264
|
+
return cn(base, 'nav-text underline-offset-4 hover:underline',
|
|
2257
2265
|
// Icon-only tetap punya target ≥ 36px (WCAG 2.5.8) walau tanpa chrome tautan.
|
|
2258
2266
|
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());
|
|
2259
2267
|
}
|
|
2260
2268
|
if (this.variant() === 'plain') {
|
|
2261
|
-
return cn(base, 'gap-2 rounded-md text
|
|
2269
|
+
return cn(base, 'gap-2 rounded-md nav-text', iconOnly ? 'h-9 w-9 justify-center' : 'h-9 px-3 py-2', this.isOpen()
|
|
2262
2270
|
? 'bg-accent text-accent-foreground'
|
|
2263
2271
|
: 'text-foreground/80 hover:bg-accent hover:text-accent-foreground', this.itemClass());
|
|
2264
2272
|
}
|
|
2265
2273
|
// button (pil, default)
|
|
2266
|
-
return cn(base, 'h-10 gap-2 rounded-full border border-[hsl(var(--border)/var(--opacity-60))] bg-background px-4 py-2 text
|
|
2274
|
+
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()
|
|
2267
2275
|
? this.isOpen()
|
|
2268
2276
|
? 'text-primary'
|
|
2269
2277
|
: 'text-foreground/80 hover:text-primary'
|
|
@@ -2286,7 +2294,7 @@ class NavigationFlyoutMenuComponent {
|
|
|
2286
2294
|
// scrollRegionClasses) yang scroll; bar ROW 1 & kontainer panel sendiri tetap diam.
|
|
2287
2295
|
'max-h-[calc(100dvh-5rem)] overflow-hidden', this.isBorderRail()
|
|
2288
2296
|
? cn('rounded-none border-border', this.isBottom() ? 'border-t-[1.5px]' : 'border-b-[1.5px]')
|
|
2289
|
-
: 'rounded-
|
|
2297
|
+
: 'rounded-[var(--layout-frame-radius)] border border-[hsl(var(--border)/var(--opacity-70))]');
|
|
2290
2298
|
}
|
|
2291
2299
|
rowClasses() {
|
|
2292
2300
|
// Menu item = bagian tengah ROW 1: isi ruang antara Footer & Header (flex-1) lalu
|
|
@@ -2309,7 +2317,7 @@ class NavigationFlyoutMenuComponent {
|
|
|
2309
2317
|
// `-my-2 self-stretch` untuk membatalkan `py-2` row; tombol `h-full` mengisi penuh
|
|
2310
2318
|
// sehingga sisinya rata dengan border row — sudut pada sisi border dibuat siku
|
|
2311
2319
|
// agar menyambung (bawah di mode top, atas di mode bottom).
|
|
2312
|
-
'nav-trigger group/nav inline-flex h-full min-h-9 min-w-0 items-center gap-2 rounded-md px-3
|
|
2320
|
+
'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()
|
|
2313
2321
|
? this.isBranchOpen(item) || this.isItemActive(item)
|
|
2314
2322
|
? 'rounded-none text-primary'
|
|
2315
2323
|
: 'rounded-none text-foreground/80 hover:text-primary'
|
|
@@ -2761,7 +2769,7 @@ class NavigationHorizontalComponent {
|
|
|
2761
2769
|
return cn(this.groupClass(), item.classes?.container);
|
|
2762
2770
|
}
|
|
2763
2771
|
triggerClasses(item) {
|
|
2764
|
-
return cn('nav-trigger group/nav inline-flex min-w-0 items-center gap-3 rounded-md
|
|
2772
|
+
return cn('nav-trigger nav-text group/nav inline-flex min-w-0 items-center gap-3 rounded-md font-medium transition-colors', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50', 'h-9 px-3 py-2', this.compact() && 'w-10 justify-center px-0', this.isBorderRail()
|
|
2765
2773
|
? this.isPanelOpen(item) || this.isItemActive(item)
|
|
2766
2774
|
? 'rounded-none text-primary'
|
|
2767
2775
|
: 'rounded-none text-foreground/80 hover:text-primary'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ojiepermana/angular-navigation",
|
|
3
|
-
"version": "22.0.
|
|
3
|
+
"version": "22.0.43",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/edsis/angular.git"
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"@angular/common": ">=22.0.0",
|
|
14
14
|
"@angular/core": ">=22.0.0",
|
|
15
15
|
"@angular/router": ">=22.0.0",
|
|
16
|
-
"@ojiepermana/angular-component": "^22.0.
|
|
16
|
+
"@ojiepermana/angular-component": "^22.0.43",
|
|
17
17
|
"rxjs": ">=7.8.0"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
@@ -78,6 +78,8 @@ declare class NavigationService {
|
|
|
78
78
|
private readonly states;
|
|
79
79
|
private readonly openPanelKeys;
|
|
80
80
|
private readonly drawerOpenState;
|
|
81
|
+
/** Data mentah per id, dipublikasikan oleh `<Navigation>` agar surface lain (mis. apps-launcher di `Page`) bisa membaca nav by id tanpa mendaftarkan ulang id yang sama. */
|
|
82
|
+
private readonly dataById;
|
|
81
83
|
/** id navigasi → token owner instance, untuk menjaga setiap id hanya dipakai satu <Navigation> hidup. */
|
|
82
84
|
private readonly idOwners;
|
|
83
85
|
readonly openPanelKey: Signal<string | null>;
|
|
@@ -96,6 +98,12 @@ declare class NavigationService {
|
|
|
96
98
|
private releaseId;
|
|
97
99
|
state(id: string): Signal<NavigationState | null>;
|
|
98
100
|
currentState(id: string): NavigationState | null;
|
|
101
|
+
/** Data terdaftar untuk sebuah id sebagai signal; `[]` bila belum ada `<Navigation>` dengan id tersebut. */
|
|
102
|
+
data(id: string): Signal<readonly NavigationItem[]>;
|
|
103
|
+
/** Dipanggil `<Navigation>` untuk mempublikasikan datanya ke registry by id. */
|
|
104
|
+
publishData(id: string, data: readonly NavigationItem[]): void;
|
|
105
|
+
/** Dipanggil `<Navigation>` saat destroy untuk melepas datanya dari registry. */
|
|
106
|
+
clearData(id: string): void;
|
|
99
107
|
currentPanelKey(id: string): string | null;
|
|
100
108
|
update(id: string, patch: Partial<NavigationRegisterInput>): NavigationState;
|
|
101
109
|
setType(id: string, type: NavigationType): NavigationState;
|
|
@@ -178,6 +178,7 @@ declare class NavigationContainerComponent implements NavigationShellContext {
|
|
|
178
178
|
readonly openedIds: _angular_core.ModelSignal<readonly string[]>;
|
|
179
179
|
readonly itemSelected: _angular_core.OutputEmitterRef<NavigationSelection>;
|
|
180
180
|
private readonly nav;
|
|
181
|
+
private readonly destroyRef;
|
|
181
182
|
private readonly hoverPreviewExpanded;
|
|
182
183
|
/** Konfigurasi type aktif yang didaftarkan wrapper anak (sidebar/dockbar/navbar/flyout). */
|
|
183
184
|
private readonly typeConfig;
|
|
@@ -210,6 +211,7 @@ declare class NavigationContainerComponent implements NavigationShellContext {
|
|
|
210
211
|
readonly shellClasses: _angular_core.Signal<string>;
|
|
211
212
|
readonly state: _angular_core.Signal<_ojiepermana_angular_navigation.NavigationState>;
|
|
212
213
|
protected readonly hostClasses: _angular_core.Signal<string>;
|
|
214
|
+
constructor();
|
|
213
215
|
/**
|
|
214
216
|
* Dipanggil komponen type saat dibuat. Satu `<Navigation>` hanya boleh
|
|
215
217
|
* memuat satu type hidup — pendaftaran ganda dianggap salah konfigurasi.
|