@ojiepermana/angular-navigation 22.0.27

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 ADDED
@@ -0,0 +1,231 @@
1
+ # Navigation
2
+
3
+ `@ojiepermana/angular-navigation` renders input-driven navigation with configurable types and instance-aware state.
4
+
5
+ ```ts
6
+ import {
7
+ NavigationContainerComponent,
8
+ NavigationSidebarComponent, // type: NavigationDockbar/Navbar/FlyoutComponent
9
+ NavigationHeaderComponent,
10
+ NavigationContentComponent,
11
+ NavigationFooterComponent,
12
+ type NavigationItem,
13
+ } from '@ojiepermana/angular-navigation';
14
+ import { NavigationService } from '@ojiepermana/angular-navigation/service';
15
+
16
+ const items: NavigationItem[] = [
17
+ { id: 'dashboard', title: 'Dashboard', link: '/dashboard', icon: 'dashboard' },
18
+ {
19
+ id: 'reports',
20
+ title: 'Reports',
21
+ type: 'collapsible',
22
+ children: [{ id: 'monthly', title: 'Monthly', link: '/reports/monthly' }],
23
+ },
24
+ ];
25
+ ```
26
+
27
+ ```html
28
+ <Navigation id="erp-sidebar" [data]="items" class="h-full">
29
+ <NavigationSidebar>
30
+ <NavigationHeader class="px-1" [toggle]="true">
31
+ <div class="text-sm font-semibold">Workspace</div>
32
+ </NavigationHeader>
33
+
34
+ <NavigationContent />
35
+
36
+ <NavigationFooter class="p-3">
37
+ <button type="button">Sign out</button>
38
+ </NavigationFooter>
39
+ </NavigationSidebar>
40
+ </Navigation>
41
+
42
+ <Navigation id="erp-topbar" [data]="items">
43
+ <NavigationNavbar />
44
+ </Navigation>
45
+ ```
46
+
47
+ Type dipilih lewat komponen anak deklaratif — `NavigationSidebar`, `NavigationDockbar`, `NavigationNavbar`, atau `NavigationFlyout` — satu type hidup per `<Navigation>`. Di dalam type, `NavigationHeader` dan `NavigationFooter` opsional, sedangkan `NavigationContent` selalu dirender (otomatis dibuat bila tidak diproyeksikan).
48
+
49
+ ## API Notes
50
+
51
+ - `data` is the preferred source of navigation data.
52
+ - `items` is still accepted as a compatibility alias while consumers migrate.
53
+ - Type is declared by the child component: `NavigationSidebar`/`NavigationDockbar` (vertical), `NavigationNavbar`/`NavigationFlyout` (horizontal). Orientation is implied by the type child.
54
+ - `id` identifies a navigation instance so multiple navs can keep distinct service state.
55
+ - `position` on `NavigationSidebar`/`NavigationDockbar` accepts `left` or `right` (vertical).
56
+ - `collapsed` on `NavigationSidebar` controls the icon-only sidebar state.
57
+ - `mode` on `NavigationDockbar` accepts `sticky` or `drawer`.
58
+ - `ariaLabel` overrides the host navigation label and defaults to `Primary navigation`.
59
+ - `label` on `NavigationFlyout` sets the single trigger label and defaults to `Menu`.
60
+ - `icon` on `NavigationFlyout` renders a Material Symbols icon on the trigger; `icon-position` (`start`/`end`) sets its placement and `icon-only` hides the label visually while keeping it as the accessible name (compact mode is always icon-only and falls back to the `menu` icon).
61
+ - `nav-position` on `NavigationNavbar`/`NavigationFlyout` accepts `top` (default) or `bottom`. With `bottom`, the navbar grid panel opens upward with squared bottom corners, and the flyout panel anchors to the container's bottom edge with the tab row docked at the bottom — seamless for bars placed below the content.
62
+ - `nav-type-style` on `NavigationNavbar`/`NavigationFlyout` accepts `default` or `border-rail`. `border-rail` squares the panel (no rounding), frames entry icons with dimmed blueprint-style rail lines plus dashed center cross lines (instead of rounded boxes), renders the nested-collapse rail dashed, and replaces hover/active backgrounds with primary-colored text. `default` keeps the current visuals.
63
+ - The `navbar` type renders root items inline immediately; clicking a group (hover does not open it) opens a full-width grid panel below the bar with the same flyout-style entries, responsive columns, and nested collapse.
64
+ - The `flyout` type renders one trigger button that opens a floating panel overlaying the parent container exactly (same top position and width, covering the trigger with no visible gap; `display: contents` wrappers are skipped when measuring the container). Root items with children become the horizontal navigation inside the panel (their `icon` renders in the row), their children render as title/subtitle entries in a responsive grid (1 column on mobile, 2 from `sm`, 3 from `md`, 4 from `lg` and up; `columns` caps the maximum at 1–4), and deeper children render as a vertical collapse below their entry — expanded by default every time the panel opens, collapsible per entry via the chevron, with the child icons aligned on the same vertical line as the parent entry icon. The panel closes on `Escape`, outside clicks, the close button, or leaf selection.
65
+ - Items with children render a `chevron_right` icon pinned at the right edge and vertically centered: it points right by default and rotates down (in place, no layout shift) only while open — hover does not move it. This applies to flyout tabs and entries, navbar branch triggers, and collapsible items.
66
+ - Angular Router is supported for internal links through `link`, `queryParams`, `fragment`, `exactMatch`, and `isActiveMatchOptions`.
67
+ - External links can use `href` or `link` with `externalLink: true`.
68
+ - `activeIds` lets consumers force active state by nav id or normalized key.
69
+ - `activeUrl` lets consumers drive active matching without relying on the current router URL.
70
+ - `openedIds` owns collapsible state and supports two-way binding.
71
+ - `previewExpanded` on `NavigationSidebar` forces a collapsed sidebar instance to render in expanded-preview mode.
72
+ - `itemSelected` emits for action, router, and external items.
73
+ - `class` applies classes to the host `nav` element.
74
+ - `itemClass` applies shared classes to rendered items.
75
+ - `nav-group-class` (`groupClass`) applies Tailwind classes to the container of each horizontal group — the flyout tab `<li>` and the navbar group `<li>` — so consumers can tune height, padding, or borders of the group container. Per-group control is also available via `item.classes.container`.
76
+ - `compact` is still supported as a compatibility alias for collapsed vertical sidebars.
77
+ - `nav-sidebar-collapse` on `NavigationSidebar` enables hover-preview behavior for collapsed vertical sidebars.
78
+ - `collapse-tree` accepts `stairs` or `straight` for nested collapsible connector styling.
79
+ - `NavigationHeader` is optional, accepts Tailwind classes through `class`, and can render a built-in collapse toggle with `[toggle]="true"`.
80
+ - `NavigationFooter` is optional and accepts Tailwind classes through `class`.
81
+ - `NavigationContent` wraps the active navigation renderer and owns the scrollable region between the optional header and footer slots. It is rendered automatically by the type component when not projected, and accepts `class` when used explicitly.
82
+
83
+ ## Nav Inputs And Outputs
84
+
85
+ Inputs pada `<Navigation>` (container):
86
+
87
+ | API | Type | Notes |
88
+ | ----------------- | -------------------------------------------------- | ------------------------------------------------------------------------------- |
89
+ | `id` | `string` | Navigation instance id. `main` is the only id persisted to `localStorage`. |
90
+ | `data` | `readonly NavigationItem[]` | Preferred source of items. |
91
+ | `items` | `readonly NavigationItem[]` | Compatibility alias for `data`. |
92
+ | `ariaLabel` | `string` | Accessible label on the host navigation landmark. |
93
+ | `compact` | `boolean` | Compatibility alias for collapsed-rail item layout. |
94
+ | `collapse-tree` | `stairs \| straight` | Controls nested connector styling for collapsible items. |
95
+ | `class` | `string` | Extra classes for the host `nav`. |
96
+ | `itemClass` | `string` | Shared classes applied to rendered nav items. |
97
+ | `nav-group-class` | `string` | Classes for each horizontal group container (flyout tab / navbar group `<li>`). |
98
+ | `activeIds` | `ReadonlySet<string> \| readonly string[] \| null` | Explicit active state override by item id or normalized key. |
99
+ | `activeUrl` | `string \| null` | Explicit URL used during active matching. |
100
+ | `openedIds` | `readonly string[]` | Two-way bound open state for collapsible items. |
101
+ | `itemSelected` | `NavigationSelection` | Emits when a leaf item is selected. |
102
+
103
+ Inputs pada komponen type:
104
+
105
+ | Component | API | Type | Notes |
106
+ | ------------------- | ---------------------- | -------------------------- | ----------------------------------------------------------------------------- |
107
+ | `NavigationSidebar` | `position` | `left \| right \| null` | Side the rail docks to. |
108
+ | `NavigationSidebar` | `collapsed` | `boolean \| null` | Controls collapsed vertical sidebar state. |
109
+ | `NavigationSidebar` | `nav-sidebar-collapse` | `boolean` | Enables hover-driven preview expansion on collapsed sidebars. |
110
+ | `NavigationSidebar` | `previewExpanded` | `boolean` | Forces a collapsed sidebar to render expanded for preview. |
111
+ | `NavigationDockbar` | `mode` | `sticky \| drawer \| null` | Docked aside beside the rail, or overlay drawer. |
112
+ | `NavigationDockbar` | `position` | `left \| right \| null` | Side the rail docks to. |
113
+ | `NavigationNavbar` | `nav-type-style` | `default \| border-rail` | Style variant. `border-rail` = squared panel, dashed icon rails, no hover bg. |
114
+ | `NavigationFlyout` | `label` | `string` | Trigger label. Defaults to `Menu`. |
115
+ | `NavigationFlyout` | `nav-type-style` | `default \| border-rail` | Style variant. `border-rail` = squared panel, dashed icon rails, no hover bg. |
116
+
117
+ Semua type juga menerima `class` untuk kelas tambahan pada elemen shell-nya.
118
+
119
+ ## NavigationItem
120
+
121
+ `NavigationItem` supports deeper trees, mixed item kinds, and both router and external navigation.
122
+
123
+ | Field | Type | Notes |
124
+ | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
125
+ | `id` | `string` | Stable item id. Reused for active/open state when present. |
126
+ | `type` | `item \| basic \| aside \| group \| collapsible \| collapsable \| mega \| divider \| spacer` | `collapsable` is accepted as a compatibility alias of `collapsible`. |
127
+ | `title`, `subtitle`, `tooltip` | `string` | Primary labels and optional compact tooltip. |
128
+ | `active`, `disabled` | `boolean` | Explicit active and disabled flags. |
129
+ | `icon` | `string` | Rendered through the default icon slot unless overridden. |
130
+ | `badge` | `{ title?: string; classes?: string }` | Small label rendered beside the item title. |
131
+ | `classes` | `{ wrapper?, container?, icon?, title?, subtitle? }` | Per-item class overrides. `container` targets the horizontal group `<li>` wrapper. |
132
+ | `meta` | `Record<string, unknown>` | Consumer-owned metadata bag. |
133
+ | `isHidden` | `(item) => boolean` | Filters items at normalization time. |
134
+ | `link` | `string \| readonly unknown[] \| UrlTree` | Angular Router link target. |
135
+ | `href` | `string` | Direct external URL. |
136
+ | `queryParams`, `queryParamsHandling`, `fragment`, `preserveFragment` | Router options | Extra Angular Router navigation options. |
137
+ | `externalLink`, `target`, `rel` | link options | External navigation behavior and rel handling. |
138
+ | `exactMatch`, `isActiveMatchOptions` | Router match options | Control how router activity is resolved. |
139
+ | `action` | `(item) => void` | Callback for action-driven leaf items. |
140
+ | `columns` | `number` | Column count for `mega` style items. |
141
+ | `children` | `readonly NavigationItem[]` | Nested items. Trees can be deeper than one level. |
142
+
143
+ ## Public Shell APIs
144
+
145
+ - `NavigationHeader` exposes `[toggle]` and `class`.
146
+ - `NavigationFooter` exposes `class`.
147
+ - `NavigationContent` exposes `class` and renders the active type menu; declare it explicitly to control slot order, or omit it for the automatic default.
148
+ - `[NavigationCollapseRoot]` adjusts layout for collapsible shell content when the sidebar rail is collapsed.
149
+ - `[NavigationCollapseExpanded]` only renders its template while the vertical shell is not in collapsed display mode.
150
+
151
+ ```html
152
+ <div NavigationCollapseRoot class="flex items-center gap-3 px-3">
153
+ <Icon name="work" />
154
+
155
+ <span *NavigationCollapseExpanded>Workspace</span>
156
+ </div>
157
+ ```
158
+
159
+ ## Nav Service
160
+
161
+ `@ojiepermana/angular-navigation/service` exposes `NavigationService` as a singleton registry for navigation type and overlay state.
162
+
163
+ ```ts
164
+ import { NavigationService } from '@ojiepermana/angular-navigation/service';
165
+
166
+ const nav = inject(NavigationService);
167
+
168
+ nav.setType('erp-sidebar', 'dockbar');
169
+ nav.setCollapsed('erp-sidebar', true);
170
+ nav.toggleCollapsed('erp-sidebar');
171
+ nav.setPosition('erp-sidebar', 'right');
172
+ nav.setDockbarMode('erp-sidebar', 'drawer');
173
+ nav.openDrawer('erp-sidebar');
174
+ nav.closeDrawer('erp-sidebar');
175
+ ```
176
+
177
+ Available service helpers include:
178
+
179
+ - `register`, `unregister`, `state`, `currentState`, and `update` for instance lifecycle and state access.
180
+ - `setType`, `setPosition`, `setCollapsed`, `toggleCollapsed`, and `setDockbarMode` for instance configuration.
181
+ - `currentPanelKey`, `isPanelOpen`, `openPanel`, `togglePanel`, and `closePanel` for flyout or mega-panel state.
182
+ - `isDrawerOpen`, `openDrawer`, `toggleDrawer`, and `closeDrawer` for drawer dockbar mode.
183
+ - `exactMatchOptions` and `subsetMatchOptions` for router matching defaults.
184
+
185
+ Only the primary sidebar navigation (`id="main"`) persists preferences in `localStorage` under:
186
+
187
+ - `nav-orientation`
188
+ - `nav-type`
189
+ - `nav-position`
190
+ - `nav-type-mode`
191
+
192
+ `nav-type-mode` depends on the active vertical type:
193
+
194
+ - sidebar: `default` or `collapsed`
195
+ - dockbar: `sticky` or `drawer`
196
+
197
+ Any other navigation id, such as `erp-navbar`, only keeps its state in memory for the active instance. Consumers should provide those values explicitly at usage time or rely on the built-in defaults.
198
+
199
+ ## Icons
200
+
201
+ Saat `item.icon` tersedia, `nav` akan merender Material Symbols secara default melalui `@ojiepermana/angular-component/icon`. Jalankan `provideUiTheme()` untuk preload global, atau biarkan `IconComponent` melakukan lazy-load saat icon pertama dipakai.
202
+
203
+ ```html
204
+ <Navigation [items]="items">
205
+ <NavigationSidebar />
206
+ </Navigation>
207
+ ```
208
+
209
+ Gunakan template `NavigationIcon` hanya bila consumer ingin override renderer bawaan.
210
+
211
+ ```html
212
+ <Navigation [items]="items">
213
+ <NavigationSidebar />
214
+
215
+ <ng-template NavigationIcon let-icon let-item="item" let-active="active" let-level="level">
216
+ <Icon [name]="icon" class="text-primary" />
217
+ </ng-template>
218
+ </Navigation>
219
+ ```
220
+
221
+ `NavigationIcon` template context exposes:
222
+
223
+ - `$implicit` and `icon`: resolved icon name.
224
+ - `item`: source `NavigationItem`.
225
+ - `active`: current active state.
226
+ - `orientation`: current nav orientation.
227
+ - `level`: current nesting depth.
228
+
229
+ ## Boundaries
230
+
231
+ Entry point ini tetap extensible di layer consumer. Type defaults, instance registration, overlay state, dan affordance icon bawaan dikelola di library, sementara consumer masih bisa mengganti renderer icon dan komposisi layout sesuai kebutuhan.