@ojiepermana/angular 0.1.0 → 0.1.1

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.
Files changed (30) hide show
  1. package/README.md +8 -5
  2. package/fesm2022/ojiepermana-angular-internal.mjs +16 -0
  3. package/fesm2022/ojiepermana-angular-internal.mjs.map +1 -1
  4. package/fesm2022/ojiepermana-angular-layout.mjs +44 -41
  5. package/fesm2022/ojiepermana-angular-layout.mjs.map +1 -1
  6. package/fesm2022/ojiepermana-angular-navigation-horizontal.mjs +198 -262
  7. package/fesm2022/ojiepermana-angular-navigation-horizontal.mjs.map +1 -1
  8. package/fesm2022/ojiepermana-angular-navigation-vertical.mjs +123 -44
  9. package/fesm2022/ojiepermana-angular-navigation-vertical.mjs.map +1 -1
  10. package/fesm2022/ojiepermana-angular-navigation.mjs +326 -30
  11. package/fesm2022/ojiepermana-angular-navigation.mjs.map +1 -1
  12. package/fesm2022/ojiepermana-angular-shell.mjs +6 -1
  13. package/fesm2022/ojiepermana-angular-shell.mjs.map +1 -1
  14. package/layout/README.md +3 -3
  15. package/{theme/styles/layout → layout/src/component/horizontal}/horizontal.css +38 -17
  16. package/{theme/styles/layout → layout/src/component/vertical}/vertical.css +7 -7
  17. package/{theme/styles/layout/index.css → layout/src/layout.css} +0 -3
  18. package/navigation/README.md +91 -5
  19. package/navigation/horizontal/README.md +49 -0
  20. package/navigation/vertical/README.md +0 -0
  21. package/package.json +1 -1
  22. package/shell/README.md +5 -1
  23. package/styles/index.css +1 -1
  24. package/theme/README.md +2 -2
  25. package/types/ojiepermana-angular-internal.d.ts +1 -0
  26. package/types/ojiepermana-angular-layout.d.ts +1 -1
  27. package/types/ojiepermana-angular-navigation-horizontal.d.ts +26 -22
  28. package/types/ojiepermana-angular-navigation-vertical.d.ts +24 -22
  29. package/types/ojiepermana-angular-navigation.d.ts +55 -9
  30. package/types/ojiepermana-angular-shell.d.ts +2 -0
@@ -1,5 +1,51 @@
1
1
  import * as i0 from '@angular/core';
2
- import { signal, computed, Injectable } from '@angular/core';
2
+ import { InjectionToken, isDevMode, makeEnvironmentProviders, inject, PLATFORM_ID, signal, Injectable, computed } from '@angular/core';
3
+ import { DOCUMENT, isPlatformBrowser } from '@angular/common';
4
+
5
+ const DEFAULT_NG_NAVIGATION_CONFIG = {
6
+ defaultHorizontalVariant: 'default',
7
+ defaultVerticalVariant: 'default',
8
+ };
9
+ const NG_NAVIGATION_CONFIG = new InjectionToken('NG_NAVIGATION_CONFIG', {
10
+ providedIn: 'root',
11
+ factory: () => ({ ...DEFAULT_NG_NAVIGATION_CONFIG }),
12
+ });
13
+
14
+ function warnInvalidNavigationConfig(message) {
15
+ if (isDevMode()) {
16
+ console.warn(`[provideNgNavigation] ${message}`);
17
+ }
18
+ }
19
+ function isHorizontalNavigationVariant$1(value) {
20
+ return value === 'default' || value === 'mega';
21
+ }
22
+ function isVerticalNavigationAppearance$1(value) {
23
+ return value === 'default' || value === 'collapsible';
24
+ }
25
+ function normalizeHorizontalVariant(value) {
26
+ if (typeof value === 'undefined' || isHorizontalNavigationVariant$1(value)) {
27
+ return value ?? DEFAULT_NG_NAVIGATION_CONFIG.defaultHorizontalVariant;
28
+ }
29
+ warnInvalidNavigationConfig(`Ignoring invalid defaultHorizontalVariant ${JSON.stringify(value)}. Falling back to ${JSON.stringify(DEFAULT_NG_NAVIGATION_CONFIG.defaultHorizontalVariant)}.`);
30
+ return DEFAULT_NG_NAVIGATION_CONFIG.defaultHorizontalVariant;
31
+ }
32
+ function normalizeVerticalVariant(value) {
33
+ if (typeof value === 'undefined' || isVerticalNavigationAppearance$1(value)) {
34
+ return value ?? DEFAULT_NG_NAVIGATION_CONFIG.defaultVerticalVariant;
35
+ }
36
+ warnInvalidNavigationConfig(`Ignoring invalid defaultVerticalVariant ${JSON.stringify(value)}. Falling back to ${JSON.stringify(DEFAULT_NG_NAVIGATION_CONFIG.defaultVerticalVariant)}.`);
37
+ return DEFAULT_NG_NAVIGATION_CONFIG.defaultVerticalVariant;
38
+ }
39
+ function normalizeNavigationConfig(config) {
40
+ return {
41
+ ...DEFAULT_NG_NAVIGATION_CONFIG,
42
+ defaultHorizontalVariant: normalizeHorizontalVariant(config.defaultHorizontalVariant),
43
+ defaultVerticalVariant: normalizeVerticalVariant(config.defaultVerticalVariant),
44
+ };
45
+ }
46
+ function provideNgNavigation(config = {}) {
47
+ return makeEnvironmentProviders([{ provide: NG_NAVIGATION_CONFIG, useValue: normalizeNavigationConfig(config) }]);
48
+ }
3
49
 
4
50
  function getNavigationItemAction(item) {
5
51
  return isNavigationRoutableItem(item) ? item.action : undefined;
@@ -23,6 +69,271 @@ function isNavigationRoutableItem(item) {
23
69
  return item.type === 'basic' || item.type === 'aside' || item.type === 'collapsable';
24
70
  }
25
71
 
72
+ class NavigationStorageAdapter {
73
+ config;
74
+ constructor(config) {
75
+ this.config = config;
76
+ }
77
+ clear(axis) {
78
+ if (!this.config.isBrowser || !this.config.storage) {
79
+ return;
80
+ }
81
+ this.config.storage.removeItem(this.key(axis));
82
+ this.config.storage.removeItem(this.legacyKey(axis));
83
+ }
84
+ persist(axis, value) {
85
+ if (!this.config.isBrowser || !this.config.storage) {
86
+ return;
87
+ }
88
+ this.config.storage.setItem(this.key(axis), value);
89
+ this.config.storage.removeItem(this.legacyKey(axis));
90
+ }
91
+ read(axis, fallback, isValid) {
92
+ if (!this.config.isBrowser || !this.config.storage) {
93
+ return fallback;
94
+ }
95
+ const storedValue = this.config.storage.getItem(this.key(axis));
96
+ if (storedValue && isValid(storedValue)) {
97
+ return storedValue;
98
+ }
99
+ const legacyValue = this.config.storage.getItem(this.legacyKey(axis));
100
+ if (legacyValue && isValid(legacyValue)) {
101
+ this.config.storage.setItem(this.key(axis), legacyValue);
102
+ this.config.storage.removeItem(this.legacyKey(axis));
103
+ return legacyValue;
104
+ }
105
+ return fallback;
106
+ }
107
+ readValue(axis) {
108
+ if (!this.config.isBrowser || !this.config.storage) {
109
+ return null;
110
+ }
111
+ const storedValue = this.config.storage.getItem(this.key(axis));
112
+ if (storedValue !== null) {
113
+ return storedValue;
114
+ }
115
+ const legacyValue = this.config.storage.getItem(this.legacyKey(axis));
116
+ if (legacyValue !== null) {
117
+ this.config.storage.setItem(this.key(axis), legacyValue);
118
+ this.config.storage.removeItem(this.legacyKey(axis));
119
+ return legacyValue;
120
+ }
121
+ return null;
122
+ }
123
+ key(axis) {
124
+ return this.config.keys[axis];
125
+ }
126
+ legacyKey(axis) {
127
+ return `${this.config.legacyPrefix}:${axis}`;
128
+ }
129
+ }
130
+ const STORAGE_KEYS = {
131
+ 'horizontal-variant': 'navigation-horizontal-variant',
132
+ 'vertical-appearance': 'navigation-vertical-appearance',
133
+ 'active-item': 'navigation-active-item',
134
+ 'expanded-items': 'navigation-expanded-items',
135
+ };
136
+ const LEGACY_STORAGE_PREFIX = 'ng-navigation:v1';
137
+ function isHorizontalNavigationVariant(value) {
138
+ return value === 'default' || value === 'mega';
139
+ }
140
+ function isVerticalNavigationAppearance(value) {
141
+ return value === 'default' || value === 'collapsible';
142
+ }
143
+ function normalizeVerticalNavigationAppearance(value) {
144
+ if (value === null) {
145
+ return null;
146
+ }
147
+ if (isVerticalNavigationAppearance(value)) {
148
+ return value;
149
+ }
150
+ if (value === 'compact' || value === 'dense' || value === 'thin') {
151
+ return 'collapsible';
152
+ }
153
+ return null;
154
+ }
155
+ function normalizeExpandedItemIds(ids) {
156
+ return Array.from(new Set(ids.map((id) => id.trim()).filter((id) => id.length > 0)));
157
+ }
158
+ function parseExpandedItemIds(value) {
159
+ if (value === null) {
160
+ return [];
161
+ }
162
+ try {
163
+ const parsed = JSON.parse(value);
164
+ if (!Array.isArray(parsed) || parsed.some((item) => typeof item !== 'string')) {
165
+ return null;
166
+ }
167
+ return normalizeExpandedItemIds(parsed);
168
+ }
169
+ catch {
170
+ return null;
171
+ }
172
+ }
173
+ function collectNavigationMetadata(navigation) {
174
+ const allIds = new Set();
175
+ const expandableIds = new Set();
176
+ const visit = (items) => {
177
+ for (const item of items) {
178
+ if (item.id) {
179
+ allIds.add(item.id);
180
+ if (hasNavigationChildren(item)) {
181
+ expandableIds.add(item.id);
182
+ }
183
+ }
184
+ if (Array.isArray(item.children) && item.children.length > 0) {
185
+ visit(item.children);
186
+ }
187
+ }
188
+ };
189
+ visit(navigation);
190
+ return { allIds, expandableIds };
191
+ }
192
+ class NavigationPreferencesService {
193
+ config = inject(NG_NAVIGATION_CONFIG);
194
+ document = inject(DOCUMENT);
195
+ isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
196
+ storage = new NavigationStorageAdapter({
197
+ isBrowser: this.isBrowser,
198
+ storage: this.document.defaultView?.localStorage ?? null,
199
+ keys: STORAGE_KEYS,
200
+ legacyPrefix: LEGACY_STORAGE_PREFIX,
201
+ });
202
+ _horizontalVariant = signal(this.readHorizontalVariant(), ...(ngDevMode ? [{ debugName: "_horizontalVariant" }] : /* istanbul ignore next */ []));
203
+ _verticalAppearance = signal(this.readVerticalAppearance(), ...(ngDevMode ? [{ debugName: "_verticalAppearance" }] : /* istanbul ignore next */ []));
204
+ _activeItemId = signal(this.readActiveItemId(), ...(ngDevMode ? [{ debugName: "_activeItemId" }] : /* istanbul ignore next */ []));
205
+ _expandedItemIds = signal(this.readExpandedItemIds(), ...(ngDevMode ? [{ debugName: "_expandedItemIds" }] : /* istanbul ignore next */ []));
206
+ horizontalVariant = this._horizontalVariant.asReadonly();
207
+ verticalAppearance = this._verticalAppearance.asReadonly();
208
+ activeItemId = this._activeItemId.asReadonly();
209
+ expandedItemIds = this._expandedItemIds.asReadonly();
210
+ setHorizontalVariant(value) {
211
+ this.storage.persist('horizontal-variant', value);
212
+ this._horizontalVariant.set(value);
213
+ }
214
+ setVerticalAppearance(value) {
215
+ this.storage.persist('vertical-appearance', value);
216
+ this._verticalAppearance.set(value);
217
+ }
218
+ setActiveItem(id) {
219
+ const normalizedId = id?.trim() ?? null;
220
+ if (!normalizedId) {
221
+ this.clearActiveItem();
222
+ return;
223
+ }
224
+ this.storage.persist('active-item', normalizedId);
225
+ this._activeItemId.set(normalizedId);
226
+ }
227
+ clearActiveItem() {
228
+ this.storage.clear('active-item');
229
+ this._activeItemId.set(null);
230
+ }
231
+ setExpandedItemIds(ids) {
232
+ const normalizedIds = normalizeExpandedItemIds(ids);
233
+ if (normalizedIds.length === 0) {
234
+ this.clearExpandedItems();
235
+ return;
236
+ }
237
+ this.storage.persist('expanded-items', JSON.stringify(normalizedIds));
238
+ this._expandedItemIds.set(normalizedIds);
239
+ }
240
+ expandItem(id) {
241
+ const normalizedId = id.trim();
242
+ if (!normalizedId || this._expandedItemIds().includes(normalizedId)) {
243
+ return;
244
+ }
245
+ this.setExpandedItemIds([...this._expandedItemIds(), normalizedId]);
246
+ }
247
+ collapseItem(id) {
248
+ const normalizedId = id.trim();
249
+ if (!normalizedId || !this._expandedItemIds().includes(normalizedId)) {
250
+ return;
251
+ }
252
+ this.setExpandedItemIds(this._expandedItemIds().filter((expandedId) => expandedId !== normalizedId));
253
+ }
254
+ toggleExpandedItem(id) {
255
+ const normalizedId = id.trim();
256
+ if (!normalizedId) {
257
+ return;
258
+ }
259
+ if (this._expandedItemIds().includes(normalizedId)) {
260
+ this.collapseItem(normalizedId);
261
+ return;
262
+ }
263
+ this.expandItem(normalizedId);
264
+ }
265
+ clearExpandedItems() {
266
+ this.storage.clear('expanded-items');
267
+ this._expandedItemIds.set([]);
268
+ }
269
+ reset() {
270
+ this.storage.clear('horizontal-variant');
271
+ this._horizontalVariant.set(this.config.defaultHorizontalVariant);
272
+ this.storage.clear('vertical-appearance');
273
+ this._verticalAppearance.set(this.config.defaultVerticalVariant);
274
+ this.clearActiveItem();
275
+ this.clearExpandedItems();
276
+ }
277
+ syncWithNavigation(navigation) {
278
+ const { allIds, expandableIds } = collectNavigationMetadata(navigation);
279
+ const activeItemId = this._activeItemId();
280
+ if (activeItemId && !allIds.has(activeItemId)) {
281
+ this.clearActiveItem();
282
+ }
283
+ const filteredExpandedIds = this._expandedItemIds().filter((id) => expandableIds.has(id));
284
+ if (filteredExpandedIds.length !== this._expandedItemIds().length) {
285
+ this.setExpandedItemIds(filteredExpandedIds);
286
+ }
287
+ }
288
+ readActiveItemId() {
289
+ const storedValue = this.storage.readValue('active-item')?.trim();
290
+ if (!storedValue) {
291
+ this.storage.clear('active-item');
292
+ return null;
293
+ }
294
+ return storedValue;
295
+ }
296
+ readExpandedItemIds() {
297
+ const storedValue = this.storage.readValue('expanded-items');
298
+ const parsedValue = parseExpandedItemIds(storedValue);
299
+ if (parsedValue === null) {
300
+ this.storage.clear('expanded-items');
301
+ return [];
302
+ }
303
+ return parsedValue;
304
+ }
305
+ readHorizontalVariant() {
306
+ const storedValue = this.storage.readValue('horizontal-variant');
307
+ if (storedValue && isHorizontalNavigationVariant(storedValue)) {
308
+ return storedValue;
309
+ }
310
+ if (storedValue !== null) {
311
+ this.storage.clear('horizontal-variant');
312
+ }
313
+ return this.config.defaultHorizontalVariant;
314
+ }
315
+ readVerticalAppearance() {
316
+ const storedValue = this.storage.readValue('vertical-appearance');
317
+ const normalizedValue = normalizeVerticalNavigationAppearance(storedValue);
318
+ if (normalizedValue) {
319
+ if (storedValue !== normalizedValue) {
320
+ this.storage.persist('vertical-appearance', normalizedValue);
321
+ }
322
+ return normalizedValue;
323
+ }
324
+ if (storedValue !== null) {
325
+ this.storage.clear('vertical-appearance');
326
+ }
327
+ return this.config.defaultVerticalVariant;
328
+ }
329
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NavigationPreferencesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
330
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NavigationPreferencesService, providedIn: 'root' });
331
+ }
332
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NavigationPreferencesService, decorators: [{
333
+ type: Injectable,
334
+ args: [{ providedIn: 'root' }]
335
+ }] });
336
+
26
337
  /**
27
338
  * Navigation Service
28
339
  *
@@ -32,19 +343,19 @@ function isNavigationRoutableItem(item) {
32
343
  * 3. Utility functions untuk navigation operations
33
344
  */
34
345
  class NavigationService {
346
+ preferences = inject(NavigationPreferencesService);
35
347
  _navigation = signal([], ...(ngDevMode ? [{ debugName: "_navigation" }] : /* istanbul ignore next */ []));
36
- _activeItemId = signal(null, ...(ngDevMode ? [{ debugName: "_activeItemId" }] : /* istanbul ignore next */ []));
37
- _expandedItemIds = signal(new Set(), ...(ngDevMode ? [{ debugName: "_expandedItemIds" }] : /* istanbul ignore next */ []));
38
348
  navigationItems = this._navigation.asReadonly();
39
- activeItemId = this._activeItemId.asReadonly();
349
+ activeItemId = this.preferences.activeItemId;
40
350
  flatNavigation = computed(() => this.getFlatNavigation(this._navigation()), ...(ngDevMode ? [{ debugName: "flatNavigation" }] : /* istanbul ignore next */ []));
41
- expandedItemIds = computed(() => Array.from(this._expandedItemIds()), ...(ngDevMode ? [{ debugName: "expandedItemIds" }] : /* istanbul ignore next */ []));
351
+ expandedItemIds = this.preferences.expandedItemIds;
42
352
  /**
43
353
  * Store navigation data
44
354
  * Biasanya dipanggil saat app initialization
45
355
  */
46
356
  storeNavigation(navigation) {
47
357
  this._navigation.set(navigation);
358
+ this.preferences.syncWithNavigation(navigation);
48
359
  }
49
360
  /**
50
361
  * Get navigation data dari storage
@@ -56,7 +367,7 @@ class NavigationService {
56
367
  * Delete navigation data dari storage
57
368
  */
58
369
  deleteNavigation() {
59
- if (!this._navigation().length) {
370
+ if (!this._navigation().length && this.activeItemId() === null && this.expandedItemIds().length === 0) {
60
371
  return;
61
372
  }
62
373
  this._navigation.set([]);
@@ -64,47 +375,32 @@ class NavigationService {
64
375
  this.clearExpandedItems();
65
376
  }
66
377
  setActiveItem(id) {
67
- this._activeItemId.set(id);
378
+ this.preferences.setActiveItem(id);
68
379
  }
69
380
  clearActiveItem() {
70
- this._activeItemId.set(null);
381
+ this.preferences.clearActiveItem();
71
382
  }
72
383
  getActiveItem(navigation = this._navigation()) {
73
- const activeItemId = this._activeItemId();
384
+ const activeItemId = this.activeItemId();
74
385
  if (!activeItemId) {
75
386
  return null;
76
387
  }
77
388
  return this.getItem(activeItemId, navigation);
78
389
  }
79
390
  expandItem(id) {
80
- this._expandedItemIds.update((expandedItemIds) => {
81
- const nextExpandedItemIds = new Set(expandedItemIds);
82
- nextExpandedItemIds.add(id);
83
- return nextExpandedItemIds;
84
- });
391
+ this.preferences.expandItem(id);
85
392
  }
86
393
  collapseItem(id) {
87
- this._expandedItemIds.update((expandedItemIds) => {
88
- if (!expandedItemIds.has(id)) {
89
- return expandedItemIds;
90
- }
91
- const nextExpandedItemIds = new Set(expandedItemIds);
92
- nextExpandedItemIds.delete(id);
93
- return nextExpandedItemIds;
94
- });
394
+ this.preferences.collapseItem(id);
95
395
  }
96
396
  toggleItemExpanded(id) {
97
- if (this.isItemExpanded(id)) {
98
- this.collapseItem(id);
99
- return;
100
- }
101
- this.expandItem(id);
397
+ this.preferences.toggleExpandedItem(id);
102
398
  }
103
399
  isItemExpanded(id) {
104
- return this._expandedItemIds().has(id);
400
+ return this.expandedItemIds().includes(id);
105
401
  }
106
402
  clearExpandedItems() {
107
- this._expandedItemIds.set(new Set());
403
+ this.preferences.clearExpandedItems();
108
404
  }
109
405
  /**
110
406
  * Flatten navigation array
@@ -172,5 +468,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
172
468
  * Generated bundle index. Do not edit.
173
469
  */
174
470
 
175
- export { NavigationService, getNavigationChildren, getNavigationItemAction, getNavigationItemVisibilityHandler, hasNavigationChildren, isNavigationItemHidden, isNavigationRoutableItem, shouldRenderNavigationItem };
471
+ export { DEFAULT_NG_NAVIGATION_CONFIG, NG_NAVIGATION_CONFIG, NavigationPreferencesService, NavigationService, getNavigationChildren, getNavigationItemAction, getNavigationItemVisibilityHandler, hasNavigationChildren, isNavigationItemHidden, isNavigationRoutableItem, provideNgNavigation, shouldRenderNavigationItem };
176
472
  //# sourceMappingURL=ojiepermana-angular-navigation.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ojiepermana-angular-navigation.mjs","sources":["../../../projects/library/navigation/navigation.utils.ts","../../../projects/library/navigation/navigation.service.ts","../../../projects/library/navigation/index.ts","../../../projects/library/navigation/ojiepermana-angular-navigation.ts"],"sourcesContent":["import {\n NavigationActionHandler,\n NavigationBranchItem,\n NavigationItem,\n NavigationRoutableItemBase,\n NavigationVisibilityHandler,\n} from './navigation.type';\n\nexport function getNavigationItemAction(item: NavigationItem): NavigationActionHandler | undefined {\n return isNavigationRoutableItem(item) ? item.action : undefined;\n}\n\nexport function getNavigationItemVisibilityHandler(item: NavigationItem): NavigationVisibilityHandler | undefined {\n return item.isHidden;\n}\n\nexport function isNavigationItemHidden(item: NavigationItem): boolean {\n return !!getNavigationItemVisibilityHandler(item)?.(item);\n}\n\nexport function shouldRenderNavigationItem(item: NavigationItem): boolean {\n return !isNavigationItemHidden(item);\n}\n\nexport function hasNavigationChildren(item: NavigationItem): item is NavigationBranchItem {\n return Array.isArray(item.children) && item.children.length > 0;\n}\n\nexport function getNavigationChildren(item: NavigationItem): NavigationItem[] {\n return Array.isArray(item.children) ? item.children : [];\n}\n\nexport function isNavigationRoutableItem(item: NavigationItem): item is NavigationItem & NavigationRoutableItemBase {\n return item.type === 'basic' || item.type === 'aside' || item.type === 'collapsable';\n}\n","import { computed, Injectable, signal } from '@angular/core';\nimport { NavigationItem } from './navigation.type';\nimport { getNavigationChildren, hasNavigationChildren } from './navigation.utils';\n\n/**\n * Navigation Service\n *\n * Service ini bertanggung jawab untuk:\n * 1. Store dan retrieve navigation data\n * 2. Menyediakan state aktif dan expanded item\n * 3. Utility functions untuk navigation operations\n */\n@Injectable({ providedIn: 'root' })\nexport class NavigationService {\n private _navigation = signal<NavigationItem[]>([]);\n private _activeItemId = signal<string | null>(null);\n private _expandedItemIds = signal<Set<string>>(new Set());\n\n readonly navigationItems = this._navigation.asReadonly();\n readonly activeItemId = this._activeItemId.asReadonly();\n readonly flatNavigation = computed(() => this.getFlatNavigation(this._navigation()));\n\n readonly expandedItemIds = computed(() => Array.from(this._expandedItemIds()));\n\n /**\n * Store navigation data\n * Biasanya dipanggil saat app initialization\n */\n storeNavigation(navigation: NavigationItem[]): void {\n this._navigation.set(navigation);\n }\n\n /**\n * Get navigation data dari storage\n */\n getNavigation(): NavigationItem[] {\n return this._navigation();\n }\n\n /**\n * Delete navigation data dari storage\n */\n deleteNavigation(): void {\n if (!this._navigation().length) {\n return;\n }\n this._navigation.set([]);\n this.clearActiveItem();\n this.clearExpandedItems();\n }\n\n setActiveItem(id: string | null): void {\n this._activeItemId.set(id);\n }\n\n clearActiveItem(): void {\n this._activeItemId.set(null);\n }\n\n getActiveItem(navigation: NavigationItem[] = this._navigation()): NavigationItem | null {\n const activeItemId = this._activeItemId();\n if (!activeItemId) {\n return null;\n }\n\n return this.getItem(activeItemId, navigation);\n }\n\n expandItem(id: string): void {\n this._expandedItemIds.update((expandedItemIds) => {\n const nextExpandedItemIds = new Set(expandedItemIds);\n nextExpandedItemIds.add(id);\n return nextExpandedItemIds;\n });\n }\n\n collapseItem(id: string): void {\n this._expandedItemIds.update((expandedItemIds) => {\n if (!expandedItemIds.has(id)) {\n return expandedItemIds;\n }\n\n const nextExpandedItemIds = new Set(expandedItemIds);\n nextExpandedItemIds.delete(id);\n return nextExpandedItemIds;\n });\n }\n\n toggleItemExpanded(id: string): void {\n if (this.isItemExpanded(id)) {\n this.collapseItem(id);\n return;\n }\n\n this.expandItem(id);\n }\n\n isItemExpanded(id: string): boolean {\n return this._expandedItemIds().has(id);\n }\n\n clearExpandedItems(): void {\n this._expandedItemIds.set(new Set());\n }\n\n /**\n * Flatten navigation array\n * Convert nested structure menjadi flat array (hanya basic items)\n * Berguna untuk search, analytics, atau operations lainnya\n */\n getFlatNavigation(navigation: NavigationItem[], flatNavigation: NavigationItem[] = []): NavigationItem[] {\n for (const item of navigation) {\n if (item.type === 'basic') {\n flatNavigation.push(item);\n }\n\n if (hasNavigationChildren(item)) {\n this.getFlatNavigation(getNavigationChildren(item), flatNavigation);\n }\n }\n\n return flatNavigation;\n }\n\n /**\n * Get item by ID dari navigation tree\n * Recursive search untuk find item dengan id tertentu\n */\n getItem(id: string, navigation: NavigationItem[]): NavigationItem | null {\n for (const item of navigation) {\n if (item.id === id) {\n return item;\n }\n\n if (hasNavigationChildren(item)) {\n const childItem = this.getItem(id, getNavigationChildren(item));\n if (childItem) {\n return childItem;\n }\n }\n }\n\n return null;\n }\n\n /**\n * Get parent dari item dengan id tertentu\n * Berguna untuk breadcrumb atau navigation path\n */\n getItemParent(\n id: string,\n navigation: NavigationItem[],\n parent: NavigationItem[] | NavigationItem,\n ): NavigationItem[] | NavigationItem | null {\n for (const item of navigation) {\n if (item.id === id) {\n return parent;\n }\n\n if (hasNavigationChildren(item)) {\n const result = this.getItemParent(id, getNavigationChildren(item), item);\n if (result) {\n return result;\n }\n }\n }\n\n return null;\n }\n}\n","/* Navigation state and utility exports. */\n\nexport * from './navigation.type';\nexport * from './navigation.utils';\nexport * from './navigation.service';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ojiepermana-angular-navigation.mjs","sources":["../../../projects/library/navigation/state/navigation.token.ts","../../../projects/library/navigation/state/navigation.provider.ts","../../../projects/library/navigation/state/navigation.utils.ts","../../../projects/library/navigation/state/navigation-preferences.service.ts","../../../projects/library/navigation/state/navigation.service.ts","../../../projects/library/navigation/index.ts","../../../projects/library/navigation/ojiepermana-angular-navigation.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport { NgNavigationConfig } from './navigation.types';\n\nexport const DEFAULT_NG_NAVIGATION_CONFIG: NgNavigationConfig = {\n defaultHorizontalVariant: 'default',\n defaultVerticalVariant: 'default',\n};\n\nexport const NG_NAVIGATION_CONFIG = new InjectionToken<NgNavigationConfig>('NG_NAVIGATION_CONFIG', {\n providedIn: 'root',\n factory: () => ({ ...DEFAULT_NG_NAVIGATION_CONFIG }),\n});\n","import { EnvironmentProviders, isDevMode, makeEnvironmentProviders } from '@angular/core';\nimport { DEFAULT_NG_NAVIGATION_CONFIG, NG_NAVIGATION_CONFIG } from './navigation.token';\nimport { HorizontalNavigationVariant, VerticalNavigationAppearance } from './navigation.type';\nimport { NgNavigationConfig } from './navigation.types';\n\nfunction warnInvalidNavigationConfig(message: string): void {\n if (isDevMode()) {\n console.warn(`[provideNgNavigation] ${message}`);\n }\n}\n\nfunction isHorizontalNavigationVariant(value: unknown): value is HorizontalNavigationVariant {\n return value === 'default' || value === 'mega';\n}\n\nfunction isVerticalNavigationAppearance(value: unknown): value is VerticalNavigationAppearance {\n return value === 'default' || value === 'collapsible';\n}\n\nfunction normalizeHorizontalVariant(value: unknown): HorizontalNavigationVariant {\n if (typeof value === 'undefined' || isHorizontalNavigationVariant(value)) {\n return value ?? DEFAULT_NG_NAVIGATION_CONFIG.defaultHorizontalVariant;\n }\n\n warnInvalidNavigationConfig(\n `Ignoring invalid defaultHorizontalVariant ${JSON.stringify(value)}. Falling back to ${JSON.stringify(DEFAULT_NG_NAVIGATION_CONFIG.defaultHorizontalVariant)}.`,\n );\n\n return DEFAULT_NG_NAVIGATION_CONFIG.defaultHorizontalVariant;\n}\n\nfunction normalizeVerticalVariant(value: unknown): VerticalNavigationAppearance {\n if (typeof value === 'undefined' || isVerticalNavigationAppearance(value)) {\n return value ?? DEFAULT_NG_NAVIGATION_CONFIG.defaultVerticalVariant;\n }\n\n warnInvalidNavigationConfig(\n `Ignoring invalid defaultVerticalVariant ${JSON.stringify(value)}. Falling back to ${JSON.stringify(DEFAULT_NG_NAVIGATION_CONFIG.defaultVerticalVariant)}.`,\n );\n\n return DEFAULT_NG_NAVIGATION_CONFIG.defaultVerticalVariant;\n}\n\nfunction normalizeNavigationConfig(config: Partial<NgNavigationConfig>): NgNavigationConfig {\n return {\n ...DEFAULT_NG_NAVIGATION_CONFIG,\n defaultHorizontalVariant: normalizeHorizontalVariant(config.defaultHorizontalVariant),\n defaultVerticalVariant: normalizeVerticalVariant(config.defaultVerticalVariant),\n };\n}\n\nexport function provideNgNavigation(config: Partial<NgNavigationConfig> = {}): EnvironmentProviders {\n return makeEnvironmentProviders([{ provide: NG_NAVIGATION_CONFIG, useValue: normalizeNavigationConfig(config) }]);\n}\n","import {\n NavigationActionHandler,\n NavigationBranchItem,\n NavigationItem,\n NavigationRoutableItemBase,\n NavigationVisibilityHandler,\n} from './navigation.type';\n\nexport function getNavigationItemAction(item: NavigationItem): NavigationActionHandler | undefined {\n return isNavigationRoutableItem(item) ? item.action : undefined;\n}\n\nexport function getNavigationItemVisibilityHandler(item: NavigationItem): NavigationVisibilityHandler | undefined {\n return item.isHidden;\n}\n\nexport function isNavigationItemHidden(item: NavigationItem): boolean {\n return !!getNavigationItemVisibilityHandler(item)?.(item);\n}\n\nexport function shouldRenderNavigationItem(item: NavigationItem): boolean {\n return !isNavigationItemHidden(item);\n}\n\nexport function hasNavigationChildren(item: NavigationItem): item is NavigationBranchItem {\n return Array.isArray(item.children) && item.children.length > 0;\n}\n\nexport function getNavigationChildren(item: NavigationItem): NavigationItem[] {\n return Array.isArray(item.children) ? item.children : [];\n}\n\nexport function isNavigationRoutableItem(item: NavigationItem): item is NavigationItem & NavigationRoutableItemBase {\n return item.type === 'basic' || item.type === 'aside' || item.type === 'collapsable';\n}\n","import { DOCUMENT, isPlatformBrowser } from '@angular/common';\nimport { Injectable, PLATFORM_ID, inject, signal } from '@angular/core';\nimport { NG_NAVIGATION_CONFIG } from './navigation.token';\nimport { HorizontalNavigationVariant, NavigationItem, VerticalNavigationAppearance } from './navigation.type';\nimport { hasNavigationChildren } from './navigation.utils';\n\ninterface StorageLike {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n removeItem(key: string): void;\n}\n\ninterface NavigationStorageAdapterConfig<Axis extends string> {\n readonly isBrowser: boolean;\n readonly storage: StorageLike | null;\n readonly keys: Record<Axis, string>;\n readonly legacyPrefix: string;\n}\n\nclass NavigationStorageAdapter<Axis extends string> {\n constructor(private readonly config: NavigationStorageAdapterConfig<Axis>) {}\n\n clear(axis: Axis): void {\n if (!this.config.isBrowser || !this.config.storage) {\n return;\n }\n\n this.config.storage.removeItem(this.key(axis));\n this.config.storage.removeItem(this.legacyKey(axis));\n }\n\n persist(axis: Axis, value: string): void {\n if (!this.config.isBrowser || !this.config.storage) {\n return;\n }\n\n this.config.storage.setItem(this.key(axis), value);\n this.config.storage.removeItem(this.legacyKey(axis));\n }\n\n read<T extends string>(axis: Axis, fallback: T, isValid: (value: string) => value is T): T {\n if (!this.config.isBrowser || !this.config.storage) {\n return fallback;\n }\n\n const storedValue = this.config.storage.getItem(this.key(axis));\n\n if (storedValue && isValid(storedValue)) {\n return storedValue;\n }\n\n const legacyValue = this.config.storage.getItem(this.legacyKey(axis));\n\n if (legacyValue && isValid(legacyValue)) {\n this.config.storage.setItem(this.key(axis), legacyValue);\n this.config.storage.removeItem(this.legacyKey(axis));\n return legacyValue;\n }\n\n return fallback;\n }\n\n readValue(axis: Axis): string | null {\n if (!this.config.isBrowser || !this.config.storage) {\n return null;\n }\n\n const storedValue = this.config.storage.getItem(this.key(axis));\n\n if (storedValue !== null) {\n return storedValue;\n }\n\n const legacyValue = this.config.storage.getItem(this.legacyKey(axis));\n\n if (legacyValue !== null) {\n this.config.storage.setItem(this.key(axis), legacyValue);\n this.config.storage.removeItem(this.legacyKey(axis));\n return legacyValue;\n }\n\n return null;\n }\n\n private key(axis: Axis): string {\n return this.config.keys[axis];\n }\n\n private legacyKey(axis: Axis): string {\n return `${this.config.legacyPrefix}:${axis}`;\n }\n}\n\nconst STORAGE_KEYS = {\n 'horizontal-variant': 'navigation-horizontal-variant',\n 'vertical-appearance': 'navigation-vertical-appearance',\n 'active-item': 'navigation-active-item',\n 'expanded-items': 'navigation-expanded-items',\n} as const;\n\ntype NavigationPreferenceAxis = keyof typeof STORAGE_KEYS;\n\nconst LEGACY_STORAGE_PREFIX = 'ng-navigation:v1';\n\nfunction isHorizontalNavigationVariant(value: string): value is HorizontalNavigationVariant {\n return value === 'default' || value === 'mega';\n}\n\nfunction isVerticalNavigationAppearance(value: string): value is VerticalNavigationAppearance {\n return value === 'default' || value === 'collapsible';\n}\n\nfunction normalizeVerticalNavigationAppearance(value: string | null): VerticalNavigationAppearance | null {\n if (value === null) {\n return null;\n }\n\n if (isVerticalNavigationAppearance(value)) {\n return value;\n }\n\n if (value === 'compact' || value === 'dense' || value === 'thin') {\n return 'collapsible';\n }\n\n return null;\n}\n\nfunction normalizeExpandedItemIds(ids: readonly string[]): string[] {\n return Array.from(new Set(ids.map((id) => id.trim()).filter((id): id is string => id.length > 0)));\n}\n\nfunction parseExpandedItemIds(value: string | null): string[] | null {\n if (value === null) {\n return [];\n }\n\n try {\n const parsed = JSON.parse(value);\n\n if (!Array.isArray(parsed) || parsed.some((item) => typeof item !== 'string')) {\n return null;\n }\n\n return normalizeExpandedItemIds(parsed);\n } catch {\n return null;\n }\n}\n\nfunction collectNavigationMetadata(navigation: readonly NavigationItem[]): {\n readonly allIds: Set<string>;\n readonly expandableIds: Set<string>;\n} {\n const allIds = new Set<string>();\n const expandableIds = new Set<string>();\n\n const visit = (items: readonly NavigationItem[]): void => {\n for (const item of items) {\n if (item.id) {\n allIds.add(item.id);\n\n if (hasNavigationChildren(item)) {\n expandableIds.add(item.id);\n }\n }\n\n if (Array.isArray(item.children) && item.children.length > 0) {\n visit(item.children);\n }\n }\n };\n\n visit(navigation);\n\n return { allIds, expandableIds };\n}\n\n@Injectable({ providedIn: 'root' })\nexport class NavigationPreferencesService {\n private readonly config = inject(NG_NAVIGATION_CONFIG);\n private readonly document = inject(DOCUMENT);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly storage = new NavigationStorageAdapter<NavigationPreferenceAxis>({\n isBrowser: this.isBrowser,\n storage: this.document.defaultView?.localStorage ?? null,\n keys: STORAGE_KEYS,\n legacyPrefix: LEGACY_STORAGE_PREFIX,\n });\n\n private readonly _horizontalVariant = signal<HorizontalNavigationVariant>(this.readHorizontalVariant());\n private readonly _verticalAppearance = signal<VerticalNavigationAppearance>(this.readVerticalAppearance());\n private readonly _activeItemId = signal<string | null>(this.readActiveItemId());\n private readonly _expandedItemIds = signal<string[]>(this.readExpandedItemIds());\n\n readonly horizontalVariant = this._horizontalVariant.asReadonly();\n readonly verticalAppearance = this._verticalAppearance.asReadonly();\n readonly activeItemId = this._activeItemId.asReadonly();\n readonly expandedItemIds = this._expandedItemIds.asReadonly();\n\n setHorizontalVariant(value: HorizontalNavigationVariant): void {\n this.storage.persist('horizontal-variant', value);\n this._horizontalVariant.set(value);\n }\n\n setVerticalAppearance(value: VerticalNavigationAppearance): void {\n this.storage.persist('vertical-appearance', value);\n this._verticalAppearance.set(value);\n }\n\n setActiveItem(id: string | null): void {\n const normalizedId = id?.trim() ?? null;\n\n if (!normalizedId) {\n this.clearActiveItem();\n return;\n }\n\n this.storage.persist('active-item', normalizedId);\n this._activeItemId.set(normalizedId);\n }\n\n clearActiveItem(): void {\n this.storage.clear('active-item');\n this._activeItemId.set(null);\n }\n\n setExpandedItemIds(ids: readonly string[]): void {\n const normalizedIds = normalizeExpandedItemIds(ids);\n\n if (normalizedIds.length === 0) {\n this.clearExpandedItems();\n return;\n }\n\n this.storage.persist('expanded-items', JSON.stringify(normalizedIds));\n this._expandedItemIds.set(normalizedIds);\n }\n\n expandItem(id: string): void {\n const normalizedId = id.trim();\n\n if (!normalizedId || this._expandedItemIds().includes(normalizedId)) {\n return;\n }\n\n this.setExpandedItemIds([...this._expandedItemIds(), normalizedId]);\n }\n\n collapseItem(id: string): void {\n const normalizedId = id.trim();\n\n if (!normalizedId || !this._expandedItemIds().includes(normalizedId)) {\n return;\n }\n\n this.setExpandedItemIds(this._expandedItemIds().filter((expandedId) => expandedId !== normalizedId));\n }\n\n toggleExpandedItem(id: string): void {\n const normalizedId = id.trim();\n\n if (!normalizedId) {\n return;\n }\n\n if (this._expandedItemIds().includes(normalizedId)) {\n this.collapseItem(normalizedId);\n return;\n }\n\n this.expandItem(normalizedId);\n }\n\n clearExpandedItems(): void {\n this.storage.clear('expanded-items');\n this._expandedItemIds.set([]);\n }\n\n reset(): void {\n this.storage.clear('horizontal-variant');\n this._horizontalVariant.set(this.config.defaultHorizontalVariant);\n this.storage.clear('vertical-appearance');\n this._verticalAppearance.set(this.config.defaultVerticalVariant);\n this.clearActiveItem();\n this.clearExpandedItems();\n }\n\n syncWithNavigation(navigation: readonly NavigationItem[]): void {\n const { allIds, expandableIds } = collectNavigationMetadata(navigation);\n const activeItemId = this._activeItemId();\n\n if (activeItemId && !allIds.has(activeItemId)) {\n this.clearActiveItem();\n }\n\n const filteredExpandedIds = this._expandedItemIds().filter((id) => expandableIds.has(id));\n\n if (filteredExpandedIds.length !== this._expandedItemIds().length) {\n this.setExpandedItemIds(filteredExpandedIds);\n }\n }\n\n private readActiveItemId(): string | null {\n const storedValue = this.storage.readValue('active-item')?.trim();\n\n if (!storedValue) {\n this.storage.clear('active-item');\n return null;\n }\n\n return storedValue;\n }\n\n private readExpandedItemIds(): string[] {\n const storedValue = this.storage.readValue('expanded-items');\n const parsedValue = parseExpandedItemIds(storedValue);\n\n if (parsedValue === null) {\n this.storage.clear('expanded-items');\n return [];\n }\n\n return parsedValue;\n }\n\n private readHorizontalVariant(): HorizontalNavigationVariant {\n const storedValue = this.storage.readValue('horizontal-variant');\n\n if (storedValue && isHorizontalNavigationVariant(storedValue)) {\n return storedValue;\n }\n\n if (storedValue !== null) {\n this.storage.clear('horizontal-variant');\n }\n\n return this.config.defaultHorizontalVariant;\n }\n\n private readVerticalAppearance(): VerticalNavigationAppearance {\n const storedValue = this.storage.readValue('vertical-appearance');\n const normalizedValue = normalizeVerticalNavigationAppearance(storedValue);\n\n if (normalizedValue) {\n if (storedValue !== normalizedValue) {\n this.storage.persist('vertical-appearance', normalizedValue);\n }\n\n return normalizedValue;\n }\n\n if (storedValue !== null) {\n this.storage.clear('vertical-appearance');\n }\n\n return this.config.defaultVerticalVariant;\n }\n}\n","import { Injectable, signal, inject, computed } from '@angular/core';\nimport { NavigationItem } from './navigation.type';\nimport { getNavigationChildren, hasNavigationChildren } from './navigation.utils';\nimport { NavigationPreferencesService } from './navigation-preferences.service';\n\n/**\n * Navigation Service\n *\n * Service ini bertanggung jawab untuk:\n * 1. Store dan retrieve navigation data\n * 2. Menyediakan state aktif dan expanded item\n * 3. Utility functions untuk navigation operations\n */\n@Injectable({ providedIn: 'root' })\nexport class NavigationService {\n private readonly preferences = inject(NavigationPreferencesService);\n private _navigation = signal<NavigationItem[]>([]);\n\n readonly navigationItems = this._navigation.asReadonly();\n readonly activeItemId = this.preferences.activeItemId;\n readonly flatNavigation = computed(() => this.getFlatNavigation(this._navigation()));\n readonly expandedItemIds = this.preferences.expandedItemIds;\n\n /**\n * Store navigation data\n * Biasanya dipanggil saat app initialization\n */\n storeNavigation(navigation: NavigationItem[]): void {\n this._navigation.set(navigation);\n this.preferences.syncWithNavigation(navigation);\n }\n\n /**\n * Get navigation data dari storage\n */\n getNavigation(): NavigationItem[] {\n return this._navigation();\n }\n\n /**\n * Delete navigation data dari storage\n */\n deleteNavigation(): void {\n if (!this._navigation().length && this.activeItemId() === null && this.expandedItemIds().length === 0) {\n return;\n }\n\n this._navigation.set([]);\n this.clearActiveItem();\n this.clearExpandedItems();\n }\n\n setActiveItem(id: string | null): void {\n this.preferences.setActiveItem(id);\n }\n\n clearActiveItem(): void {\n this.preferences.clearActiveItem();\n }\n\n getActiveItem(navigation: NavigationItem[] = this._navigation()): NavigationItem | null {\n const activeItemId = this.activeItemId();\n if (!activeItemId) {\n return null;\n }\n\n return this.getItem(activeItemId, navigation);\n }\n\n expandItem(id: string): void {\n this.preferences.expandItem(id);\n }\n\n collapseItem(id: string): void {\n this.preferences.collapseItem(id);\n }\n\n toggleItemExpanded(id: string): void {\n this.preferences.toggleExpandedItem(id);\n }\n\n isItemExpanded(id: string): boolean {\n return this.expandedItemIds().includes(id);\n }\n\n clearExpandedItems(): void {\n this.preferences.clearExpandedItems();\n }\n\n /**\n * Flatten navigation array\n * Convert nested structure menjadi flat array (hanya basic items)\n * Berguna untuk search, analytics, atau operations lainnya\n */\n getFlatNavigation(navigation: NavigationItem[], flatNavigation: NavigationItem[] = []): NavigationItem[] {\n for (const item of navigation) {\n if (item.type === 'basic') {\n flatNavigation.push(item);\n }\n\n if (hasNavigationChildren(item)) {\n this.getFlatNavigation(getNavigationChildren(item), flatNavigation);\n }\n }\n\n return flatNavigation;\n }\n\n /**\n * Get item by ID dari navigation tree\n * Recursive search untuk find item dengan id tertentu\n */\n getItem(id: string, navigation: NavigationItem[]): NavigationItem | null {\n for (const item of navigation) {\n if (item.id === id) {\n return item;\n }\n\n if (hasNavigationChildren(item)) {\n const childItem = this.getItem(id, getNavigationChildren(item));\n if (childItem) {\n return childItem;\n }\n }\n }\n\n return null;\n }\n\n /**\n * Get parent dari item dengan id tertentu\n * Berguna untuk breadcrumb atau navigation path\n */\n getItemParent(\n id: string,\n navigation: NavigationItem[],\n parent: NavigationItem[] | NavigationItem,\n ): NavigationItem[] | NavigationItem | null {\n for (const item of navigation) {\n if (item.id === id) {\n return parent;\n }\n\n if (hasNavigationChildren(item)) {\n const result = this.getItemParent(id, getNavigationChildren(item), item);\n if (result) {\n return result;\n }\n }\n }\n\n return null;\n }\n}\n","/* Navigation state and utility exports. */\n\nexport * from './state/navigation.provider';\nexport * from './state/navigation-preferences.service';\nexport * from './state/navigation.token';\nexport * from './state/navigation.type';\nexport * from './state/navigation.types';\nexport * from './state/navigation.utils';\nexport * from './state/navigation.service';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["isHorizontalNavigationVariant","isVerticalNavigationAppearance"],"mappings":"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"}
@@ -1,9 +1,14 @@
1
1
  import { makeEnvironmentProviders } from '@angular/core';
2
2
  import { provideNgLayout } from '@ojiepermana/angular/layout';
3
+ import { provideNgNavigation } from '@ojiepermana/angular/navigation';
3
4
  import { provideNgTheme } from '@ojiepermana/angular/theme/service';
4
5
 
5
6
  function provideNgShell(config = {}) {
6
- return makeEnvironmentProviders([provideNgTheme(config.theme), provideNgLayout(config.layout)]);
7
+ return makeEnvironmentProviders([
8
+ provideNgTheme(config.theme),
9
+ provideNgLayout(config.layout),
10
+ provideNgNavigation(config.navigation),
11
+ ]);
7
12
  }
8
13
 
9
14
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ojiepermana-angular-shell.mjs","sources":["../../../projects/library/shell/src/shell.provider.ts","../../../projects/library/shell/ojiepermana-angular-shell.ts"],"sourcesContent":["import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { provideNgLayout } from '@ojiepermana/angular/layout';\nimport type { NgLayoutConfig } from '@ojiepermana/angular/layout';\nimport { provideNgTheme } from '@ojiepermana/angular/theme/service';\nimport type { NgThemeConfig } from '@ojiepermana/angular/theme/service';\n\nexport interface NgShellConfig {\n readonly theme?: Partial<NgThemeConfig>;\n readonly layout?: Partial<NgLayoutConfig>;\n}\n\nexport function provideNgShell(config: NgShellConfig = {}): EnvironmentProviders {\n return makeEnvironmentProviders([provideNgTheme(config.theme), provideNgLayout(config.layout)]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;AAWM,SAAU,cAAc,CAAC,MAAA,GAAwB,EAAE,EAAA;AACvD,IAAA,OAAO,wBAAwB,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;AACjG;;ACbA;;AAEG;;;;"}
1
+ {"version":3,"file":"ojiepermana-angular-shell.mjs","sources":["../../../projects/library/shell/src/shell.provider.ts","../../../projects/library/shell/ojiepermana-angular-shell.ts"],"sourcesContent":["import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { provideNgLayout } from '@ojiepermana/angular/layout';\nimport type { NgLayoutConfig } from '@ojiepermana/angular/layout';\nimport { provideNgNavigation } from '@ojiepermana/angular/navigation';\nimport type { NgNavigationConfig } from '@ojiepermana/angular/navigation';\nimport { provideNgTheme } from '@ojiepermana/angular/theme/service';\nimport type { NgThemeConfig } from '@ojiepermana/angular/theme/service';\n\nexport interface NgShellConfig {\n readonly theme?: Partial<NgThemeConfig>;\n readonly layout?: Partial<NgLayoutConfig>;\n readonly navigation?: Partial<NgNavigationConfig>;\n}\n\nexport function provideNgShell(config: NgShellConfig = {}): EnvironmentProviders {\n return makeEnvironmentProviders([\n provideNgTheme(config.theme),\n provideNgLayout(config.layout),\n provideNgNavigation(config.navigation),\n ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;AAcM,SAAU,cAAc,CAAC,MAAA,GAAwB,EAAE,EAAA;AACvD,IAAA,OAAO,wBAAwB,CAAC;AAC9B,QAAA,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC;AAC5B,QAAA,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC;AAC9B,QAAA,mBAAmB,CAAC,MAAM,CAAC,UAAU,CAAC;AACvC,KAAA,CAAC;AACJ;;ACpBA;;AAEG;;;;"}
package/layout/README.md CHANGED
@@ -65,10 +65,10 @@ Persistence keys are fixed by the runtime. Deprecated config fields such as `sto
65
65
 
66
66
  ## Styles
67
67
 
68
- The layout stylesheet source is `projects/library/layout/styles/index.css` inside this workspace.
68
+ The layout-wide stylesheet source is `projects/library/layout/src/layout.css` inside this workspace.
69
69
 
70
- It owns the `data-layout-*` selectors and imports the mode-scoped shell styles.
71
- Layout-wide axis selectors such as `data-layout-container` and `data-layout-mode='empty'` stay in `projects/library/layout/styles/index.css`, while the flat shell rules now live in `projects/library/layout/styles/horizontal/flat.css` and `projects/library/layout/styles/vertical/flat.css`.
70
+ It owns the `data-layout-*` selectors that are global to the runtime.
71
+ The horizontal shell rules now live beside `src/component/horizontal/horizontal.ts`, and the vertical shell rules live beside `src/component/vertical/vertical.ts` through component-level CSS metadata.
72
72
 
73
73
  Layout styles consume theme tokens. For application usage, prefer the aggregate stylesheet entry at `projects/library/styles/index.css` in this workspace or `@ojiepermana/angular/styles/index.css` from the published package.
74
74
  The shared bundle now includes reduced-motion-aware transitions for shell chrome colors, shadows, and radii while keeping structural mode changes immediate to avoid layout jank.