@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 text-xs font-medium', this.active() ? 'bg-background text-foreground' : 'bg-muted text-muted-foreground'), /* @ts-ignore */
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 text-sm 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());
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 text-sm 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());
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-xs font-medium uppercase tracking-wide text-muted-foreground', this.item().classes?.title);
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', this.position() === 'right'
1182
- ? 'right-16 border-r border-[hsl(var(--border)/var(--opacity-70))]'
1183
- : 'left-16 border-l border-[hsl(var(--border)/var(--opacity-70))]', this.isDrawerMode() &&
1184
- cn('z-50 shadow-xl', this.position() === 'right'
1185
- ? 'border-l border-l-[hsl(var(--border)/var(--opacity-70))]'
1186
- : 'border-r border-r-[hsl(var(--border)/var(--opacity-70))]')), /* @ts-ignore */
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 text-sm 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)
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 text-sm transition-colors', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring', this.isBorderRail()
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 text-sm font-medium', this.isBorderRail() ? 'text-current' : 'text-foreground', active && 'font-semibold', item.classes?.title);
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-xs font-medium text-muted-foreground'
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-xs font-medium text-muted-foreground'
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-sm underline-offset-4 hover:underline',
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-sm', iconOnly ? 'h-9 w-9 justify-center' : 'h-9 px-3 py-2', this.isOpen()
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-sm shadow-sm', iconOnly && 'w-10 justify-center gap-0 px-0', this.isBorderRail()
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-xl border border-[hsl(var(--border)/var(--opacity-70))]');
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 text-sm 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()
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 text-sm 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()
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.36",
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.36",
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.