@ojiepermana/angular 0.1.0 → 21.0.0

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 (91) hide show
  1. package/README.md +41 -246
  2. package/chart/README.md +0 -0
  3. package/fesm2022/ojiepermana-angular-chart.mjs +3714 -0
  4. package/fesm2022/ojiepermana-angular-chart.mjs.map +1 -0
  5. package/fesm2022/ojiepermana-angular-component.mjs +3463 -0
  6. package/fesm2022/ojiepermana-angular-component.mjs.map +1 -0
  7. package/fesm2022/ojiepermana-angular-layout.mjs +272 -401
  8. package/fesm2022/ojiepermana-angular-layout.mjs.map +1 -1
  9. package/fesm2022/ojiepermana-angular-navigation.mjs +2225 -135
  10. package/fesm2022/ojiepermana-angular-navigation.mjs.map +1 -1
  11. package/fesm2022/ojiepermana-angular-theme.mjs +381 -1
  12. package/fesm2022/ojiepermana-angular-theme.mjs.map +1 -1
  13. package/fesm2022/ojiepermana-angular.mjs +15 -1
  14. package/fesm2022/ojiepermana-angular.mjs.map +1 -1
  15. package/package.json +49 -36
  16. package/theme/styles/etos.css +38 -0
  17. package/theme/styles/index.css +32 -8
  18. package/theme/styles/themes/brand/etos/color.css +21 -0
  19. package/theme/styles/themes/brand/etos/style.css +50 -0
  20. package/theme/styles/themes/library/_components.css +63 -0
  21. package/theme/styles/themes/library/_layers.css +15 -0
  22. package/theme/styles/themes/library/_material-overrides.css +254 -0
  23. package/theme/styles/themes/library/_tokens.css +54 -0
  24. package/theme/styles/themes/library/color/amber.css +18 -0
  25. package/theme/styles/themes/library/color/blue.css +23 -0
  26. package/theme/styles/themes/library/color/green.css +18 -0
  27. package/theme/styles/themes/library/color/index.css +9 -0
  28. package/theme/styles/themes/library/color/purple.css +18 -0
  29. package/theme/styles/themes/library/color/red.css +18 -0
  30. package/theme/styles/themes/library/style/brutal.css +47 -0
  31. package/theme/styles/themes/library/style/default.css +51 -0
  32. package/theme/styles/themes/library/style/index.css +8 -0
  33. package/theme/styles/themes/library/style/sharp.css +47 -0
  34. package/theme/styles/themes/library/style/soft.css +47 -0
  35. package/theme/styles/themes/mode/dark.css +20 -0
  36. package/theme/styles/themes/mode/index.css +6 -0
  37. package/theme/styles/themes/mode/light.css +24 -0
  38. package/theme/styles/themes/taildwind.css +109 -0
  39. package/types/ojiepermana-angular-chart.d.ts +1094 -0
  40. package/types/ojiepermana-angular-component.d.ts +1174 -0
  41. package/types/ojiepermana-angular-layout.d.ts +123 -76
  42. package/types/ojiepermana-angular-navigation.d.ts +257 -71
  43. package/types/ojiepermana-angular-theme.d.ts +170 -1
  44. package/types/ojiepermana-angular.d.ts +2 -1
  45. package/fesm2022/ojiepermana-angular-internal.mjs +0 -473
  46. package/fesm2022/ojiepermana-angular-internal.mjs.map +0 -1
  47. package/fesm2022/ojiepermana-angular-navigation-horizontal.mjs +0 -785
  48. package/fesm2022/ojiepermana-angular-navigation-horizontal.mjs.map +0 -1
  49. package/fesm2022/ojiepermana-angular-navigation-vertical.mjs +0 -1568
  50. package/fesm2022/ojiepermana-angular-navigation-vertical.mjs.map +0 -1
  51. package/fesm2022/ojiepermana-angular-shell.mjs +0 -14
  52. package/fesm2022/ojiepermana-angular-shell.mjs.map +0 -1
  53. package/fesm2022/ojiepermana-angular-theme-component.mjs +0 -235
  54. package/fesm2022/ojiepermana-angular-theme-component.mjs.map +0 -1
  55. package/fesm2022/ojiepermana-angular-theme-directive.mjs +0 -29
  56. package/fesm2022/ojiepermana-angular-theme-directive.mjs.map +0 -1
  57. package/fesm2022/ojiepermana-angular-theme-service.mjs +0 -241
  58. package/fesm2022/ojiepermana-angular-theme-service.mjs.map +0 -1
  59. package/layout/README.md +0 -144
  60. package/navigation/README.md +0 -215
  61. package/shell/README.md +0 -37
  62. package/styles/index.css +0 -2
  63. package/styles/resets.css +0 -22
  64. package/theme/README.md +0 -379
  65. package/theme/styles/adapters/material-ui/index.css +0 -205
  66. package/theme/styles/layout/horizontal.css +0 -109
  67. package/theme/styles/layout/index.css +0 -19
  68. package/theme/styles/layout/vertical.css +0 -75
  69. package/theme/styles/modes/dark.css +0 -84
  70. package/theme/styles/presets/colors/blue.css +0 -45
  71. package/theme/styles/presets/colors/brand.css +0 -52
  72. package/theme/styles/presets/colors/cyan.css +0 -45
  73. package/theme/styles/presets/colors/green.css +0 -45
  74. package/theme/styles/presets/colors/index.css +0 -7
  75. package/theme/styles/presets/colors/orange.css +0 -45
  76. package/theme/styles/presets/colors/purple.css +0 -45
  77. package/theme/styles/presets/colors/red.css +0 -45
  78. package/theme/styles/presets/styles/flat.css +0 -61
  79. package/theme/styles/presets/styles/glass.css +0 -28
  80. package/theme/styles/presets/styles/index.css +0 -2
  81. package/theme/styles/roles/index.css +0 -67
  82. package/theme/styles/tokens/foundation.css +0 -136
  83. package/theme/styles/tokens/semantic.css +0 -87
  84. package/theme/styles/utilities/index.css +0 -88
  85. package/types/ojiepermana-angular-internal.d.ts +0 -89
  86. package/types/ojiepermana-angular-navigation-horizontal.d.ts +0 -77
  87. package/types/ojiepermana-angular-navigation-vertical.d.ts +0 -260
  88. package/types/ojiepermana-angular-shell.d.ts +0 -12
  89. package/types/ojiepermana-angular-theme-component.d.ts +0 -46
  90. package/types/ojiepermana-angular-theme-directive.d.ts +0 -10
  91. package/types/ojiepermana-angular-theme-service.d.ts +0 -68
@@ -1,461 +1,332 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, PLATFORM_ID, signal, effect, Injectable, Directive, ChangeDetectionStrategy, Component, computed, isDevMode, makeEnvironmentProviders } from '@angular/core';
3
- import { DOCUMENT, isPlatformBrowser } from '@angular/common';
4
- import { LocalStorageStateAdapter, libraryLucideConfigProvider } from '@ojiepermana/angular/internal';
2
+ import { InjectionToken, inject, signal, effect, Injectable, input, computed, ChangeDetectionStrategy, Component, makeEnvironmentProviders, provideEnvironmentInitializer } from '@angular/core';
5
3
  import { RouterOutlet } from '@angular/router';
6
- import { MatIconButton } from '@angular/material/button';
7
- import { MatTooltip } from '@angular/material/tooltip';
8
- import { LucideExpand, LucideShrink, LucidePanelLeft, LucidePanelTop, LucideAppWindow } from '@lucide/angular';
9
- import { MatMenu, MatMenuItem, MatMenuTrigger } from '@angular/material/menu';
4
+ import { SidebarComponent, TopbarComponent } from '@ojiepermana/angular/navigation';
5
+ import { ThemeService } from '@ojiepermana/angular/theme';
6
+ import { DOCUMENT } from '@angular/common';
10
7
 
11
- const DEFAULT_NG_LAYOUT_CONFIG = {
8
+ const LAYOUT_MODES = ['vertical', 'horizontal'];
9
+ const LAYOUT_WIDTHS = ['full', 'fixed'];
10
+ const MATERIAL_LAYOUT_CONFIG = new InjectionToken('MATERIAL_LAYOUT_CONFIG');
11
+ const DEFAULT_MATERIAL_LAYOUT_CONFIG = {
12
12
  defaultMode: 'vertical',
13
- defaultContainer: 'full',
13
+ defaultWidth: 'fixed',
14
+ storageKey: 'layout-mode',
15
+ widthStorageKey: 'layout-width',
14
16
  };
15
- const NG_LAYOUT_CONFIG = new InjectionToken('NG_LAYOUT_CONFIG', {
16
- providedIn: 'root',
17
- factory: () => ({ ...DEFAULT_NG_LAYOUT_CONFIG }),
18
- });
19
-
20
- const LAYOUT_MODES = ['vertical', 'horizontal', 'empty'];
21
- const LAYOUT_CONTAINERS = ['full', 'boxed'];
22
- const LAYOUT_MODE_SET = new Set(LAYOUT_MODES);
23
- const LAYOUT_CONTAINER_SET = new Set(LAYOUT_CONTAINERS);
24
17
  function isLayoutMode(value) {
25
- return typeof value === 'string' && LAYOUT_MODE_SET.has(value);
18
+ return LAYOUT_MODES.some((mode) => mode === value);
26
19
  }
27
- function isLayoutContainer(value) {
28
- return typeof value === 'string' && LAYOUT_CONTAINER_SET.has(value);
20
+ function isLayoutWidth(value) {
21
+ return LAYOUT_WIDTHS.some((width) => width === value);
29
22
  }
30
23
 
31
- const STORAGE_KEYS = {
32
- 'layout-mode': 'layout-mode',
33
- 'layout-container': 'layout-container',
34
- };
35
- const LEGACY_STORAGE_PREFIX = 'ng-theme:v2';
36
24
  class LayoutService {
37
- config = inject(NG_LAYOUT_CONFIG);
38
25
  document = inject(DOCUMENT);
39
- isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
40
- storage = new LocalStorageStateAdapter({
41
- isBrowser: this.isBrowser,
42
- storage: this.document.defaultView?.localStorage ?? null,
43
- keys: STORAGE_KEYS,
44
- legacyPrefix: LEGACY_STORAGE_PREFIX,
45
- });
46
- mode = signal(this.storage.read('layout-mode', this.config.defaultMode, isLayoutMode), ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
47
- container = signal(this.storage.read('layout-container', this.config.defaultContainer, isLayoutContainer), ...(ngDevMode ? [{ debugName: "container" }] : /* istanbul ignore next */ []));
26
+ config = this.resolveConfig();
27
+ _mode = signal(this.readPersistedMode() ?? this.config.defaultMode, ...(ngDevMode ? [{ debugName: "_mode" }] : /* istanbul ignore next */ []));
28
+ _width = signal(this.readPersistedWidth() ?? this.config.defaultWidth, ...(ngDevMode ? [{ debugName: "_width" }] : /* istanbul ignore next */ []));
29
+ mode = this._mode.asReadonly();
30
+ width = this._width.asReadonly();
48
31
  constructor() {
49
32
  effect(() => {
50
- if (this.isBrowser) {
51
- this.applyToDOM();
52
- }
33
+ this.persistMode(this._mode());
34
+ });
35
+ effect(() => {
36
+ this.persistWidth(this._width());
53
37
  });
54
38
  }
55
- /**
56
- * Updates the active shell mode and persists the value for future sessions.
57
- */
58
- setMode(value) {
59
- this.storage.persist('layout-mode', value);
60
- this.mode.set(value);
39
+ setMode(mode) {
40
+ this._mode.set(mode);
41
+ }
42
+ toggleMode() {
43
+ this._mode.update((mode) => (mode === 'vertical' ? 'horizontal' : 'vertical'));
44
+ }
45
+ setWidth(width) {
46
+ this._width.set(width);
61
47
  }
62
- /**
63
- * Updates the active container width mode and persists the value for future sessions.
64
- */
65
- setContainer(value) {
66
- this.storage.persist('layout-container', value);
67
- this.container.set(value);
48
+ toggleWidth() {
49
+ this._width.update((width) => (width === 'fixed' ? 'full' : 'fixed'));
50
+ }
51
+ resolveConfig() {
52
+ const config = inject(MATERIAL_LAYOUT_CONFIG, { optional: true }) ?? {};
53
+ const configuredMode = config.mode ?? config.defaultMode;
54
+ const configuredWidth = config.width;
55
+ return {
56
+ defaultMode: isLayoutMode(configuredMode) ? configuredMode : DEFAULT_MATERIAL_LAYOUT_CONFIG.defaultMode,
57
+ defaultWidth: isLayoutWidth(configuredWidth) ? configuredWidth : DEFAULT_MATERIAL_LAYOUT_CONFIG.defaultWidth,
58
+ storageKey: config.storageKey ?? DEFAULT_MATERIAL_LAYOUT_CONFIG.storageKey,
59
+ widthStorageKey: config.widthStorageKey ?? DEFAULT_MATERIAL_LAYOUT_CONFIG.widthStorageKey,
60
+ };
61
+ }
62
+ readPersistedMode() {
63
+ const key = this.config.storageKey;
64
+ if (!key)
65
+ return null;
66
+ try {
67
+ const value = this.document.defaultView?.localStorage?.getItem(key);
68
+ return isLayoutMode(value) ? value : null;
69
+ }
70
+ catch {
71
+ return null;
72
+ }
73
+ }
74
+ readPersistedWidth() {
75
+ const key = this.config.widthStorageKey;
76
+ if (!key)
77
+ return null;
78
+ try {
79
+ const value = this.document.defaultView?.localStorage?.getItem(key);
80
+ return isLayoutWidth(value) ? value : null;
81
+ }
82
+ catch {
83
+ return null;
84
+ }
68
85
  }
69
- /**
70
- * Clears persisted layout state and restores the configured defaults for mode and container.
71
- */
72
- reset() {
73
- this.storage.clear('layout-mode');
74
- this.storage.clear('layout-container');
75
- this.mode.set(this.config.defaultMode);
76
- this.container.set(this.config.defaultContainer);
86
+ persistMode(mode) {
87
+ const key = this.config.storageKey;
88
+ if (!key)
89
+ return;
90
+ try {
91
+ this.document.defaultView?.localStorage?.setItem(key, mode);
92
+ }
93
+ catch {
94
+ /* ignore */
95
+ }
77
96
  }
78
- applyToDOM() {
79
- const element = this.document.documentElement;
80
- element.dataset['layoutMode'] = this.mode();
81
- element.dataset['layoutContainer'] = this.container();
97
+ persistWidth(width) {
98
+ const key = this.config.widthStorageKey;
99
+ if (!key)
100
+ return;
101
+ try {
102
+ this.document.defaultView?.localStorage?.setItem(key, width);
103
+ }
104
+ catch {
105
+ /* ignore */
106
+ }
82
107
  }
83
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: LayoutService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
84
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: LayoutService, providedIn: 'root' });
108
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LayoutService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
109
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LayoutService, providedIn: 'root' });
85
110
  }
86
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: LayoutService, decorators: [{
111
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LayoutService, decorators: [{
87
112
  type: Injectable,
88
113
  args: [{ providedIn: 'root' }]
89
114
  }], ctorParameters: () => [] });
90
115
 
91
- class LayoutHostDirective {
116
+ /**
117
+ * Vertical layout — sidebar + main (scrollable).
118
+ *
119
+ * Data navigasi diambil dari `NavigationService` (register via
120
+ * `NavigationService.registerItems()` di bootstrap). Main memegang
121
+ * `<router-outlet>` dan scroll jika konten panjang.
122
+ *
123
+ * Markup:
124
+ * ```html
125
+ * <vertical>
126
+ * <!-- sidebar + router-outlet dirender oleh komponen -->
127
+ * </vertical>
128
+ * ```
129
+ */
130
+ class VerticalLayoutComponent {
92
131
  layout = inject(LayoutService);
93
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: LayoutHostDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
94
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.8", type: LayoutHostDirective, isStandalone: true, selector: "[ngtLayoutHost]", host: { properties: { "attr.data-layout-mode": "layout.mode()", "attr.data-layout-container": "layout.container()" } }, ngImport: i0 });
95
- }
96
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: LayoutHostDirective, decorators: [{
97
- type: Directive,
98
- args: [{
99
- selector: '[ngtLayoutHost]',
100
- host: {
101
- '[attr.data-layout-mode]': 'layout.mode()',
102
- '[attr.data-layout-container]': 'layout.container()',
103
- },
104
- }]
105
- }] });
106
-
107
- class LayoutElementDirective {
108
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: LayoutElementDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
109
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.8", type: LayoutElementDirective, isStandalone: true, selector: "layout", ngImport: i0 });
110
- }
111
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: LayoutElementDirective, decorators: [{
112
- type: Directive,
113
- args: [{
114
- selector: 'layout',
115
- }]
116
- }] });
117
- class ContentElementDirective {
118
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ContentElementDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
119
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.8", type: ContentElementDirective, isStandalone: true, selector: "content,shell-content", ngImport: i0 });
120
- }
121
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: ContentElementDirective, decorators: [{
122
- type: Directive,
123
- args: [{
124
- selector: 'content,shell-content',
125
- }]
126
- }] });
127
- class BrandElementDirective {
128
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BrandElementDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
129
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.8", type: BrandElementDirective, isStandalone: true, selector: "brand", ngImport: i0 });
130
- }
131
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: BrandElementDirective, decorators: [{
132
- type: Directive,
133
- args: [{
134
- selector: 'brand',
135
- }]
136
- }] });
137
- class PanelElementDirective {
138
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: PanelElementDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
139
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.8", type: PanelElementDirective, isStandalone: true, selector: "panel", ngImport: i0 });
140
- }
141
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: PanelElementDirective, decorators: [{
142
- type: Directive,
143
- args: [{
144
- selector: 'panel',
145
- }]
146
- }] });
147
-
148
- class LayoutHorizontalComponent {
149
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: LayoutHorizontalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
150
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.8", type: LayoutHorizontalComponent, isStandalone: true, selector: "horizontal", host: { properties: { "attr.data-layout-mode": "\"horizontal\"" } }, ngImport: i0, template: `
151
- <layout>
152
- <shell-content>
153
- <header>
154
- <brand>
155
- <ng-content select="[headerBrand]"></ng-content>
156
- </brand>
157
-
158
- <nav>
159
- <ng-content select="[headerNavigation]"></ng-content>
160
- </nav>
161
-
162
- <panel>
163
- <ng-content select="[headerActions]"></ng-content>
164
- </panel>
165
- </header>
166
-
167
- <main>
168
- <router-outlet />
169
- </main>
170
- </shell-content>
171
- </layout>
172
- `, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: LayoutElementDirective, selector: "layout" }, { kind: "directive", type: ContentElementDirective, selector: "content,shell-content" }, { kind: "directive", type: BrandElementDirective, selector: "brand" }, { kind: "directive", type: PanelElementDirective, selector: "panel" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
173
- }
174
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: LayoutHorizontalComponent, decorators: [{
175
- type: Component,
176
- args: [{
177
- selector: 'horizontal',
178
- imports: [
179
- RouterOutlet,
180
- LayoutElementDirective,
181
- ContentElementDirective,
182
- BrandElementDirective,
183
- PanelElementDirective,
184
- ],
185
- host: {
186
- '[attr.data-layout-mode]': '"horizontal"',
187
- },
188
- template: `
189
- <layout>
190
- <shell-content>
191
- <header>
192
- <brand>
193
- <ng-content select="[headerBrand]"></ng-content>
194
- </brand>
195
-
196
- <nav>
197
- <ng-content select="[headerNavigation]"></ng-content>
198
- </nav>
199
-
200
- <panel>
201
- <ng-content select="[headerActions]"></ng-content>
202
- </panel>
203
- </header>
204
-
205
- <main>
206
- <router-outlet />
207
- </main>
208
- </shell-content>
209
- </layout>
210
- `,
211
- changeDetection: ChangeDetectionStrategy.OnPush,
212
- }]
213
- }] });
214
-
215
- class LayoutVerticalComponent {
216
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: LayoutVerticalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
217
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.8", type: LayoutVerticalComponent, isStandalone: true, selector: "vertical", host: { properties: { "attr.data-layout-mode": "\"vertical\"" } }, ngImport: i0, template: `
218
- <layout>
219
- <shell-content>
220
- <aside>
221
- <ng-content select="[navigation]"></ng-content>
222
- </aside>
223
- <main>
224
- <router-outlet />
225
- </main>
226
- </shell-content>
227
- </layout>
228
- `, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: LayoutElementDirective, selector: "layout" }, { kind: "directive", type: ContentElementDirective, selector: "content,shell-content" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
132
+ theme = inject(ThemeService);
133
+ sidebarAppearance = input('default', ...(ngDevMode ? [{ debugName: "sidebarAppearance" }] : /* istanbul ignore next */ []));
134
+ sidebarPosition = input('left', ...(ngDevMode ? [{ debugName: "sidebarPosition" }] : /* istanbul ignore next */ []));
135
+ sidebarMode = input('side', ...(ngDevMode ? [{ debugName: "sidebarMode" }] : /* istanbul ignore next */ []));
136
+ ariaLabel = input('Primary', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
137
+ layoutWidth = this.layout.width;
138
+ themeStyle = this.theme.style;
139
+ shellBorderWidth = computed(() => (this.layoutWidth() === 'fixed' ? 'var(--border-width)' : null), ...(ngDevMode ? [{ debugName: "shellBorderWidth" }] : /* istanbul ignore next */ []));
140
+ dividerBorderWidth = computed(() => 'var(--border-width)', ...(ngDevMode ? [{ debugName: "dividerBorderWidth" }] : /* istanbul ignore next */ []));
141
+ hostClasses = computed(() => {
142
+ const classes = ['flex', 'h-dvh', 'w-full', 'overflow-hidden', 'bg-background', 'text-foreground'];
143
+ if (this.layoutWidth() === 'fixed') {
144
+ classes.push('lg:mx-auto', 'lg:my-8', 'lg:h-[calc(100dvh-4rem)]', 'lg:w-[calc(100%-4rem)]', 'lg:border', 'lg:border-border', 'lg:rounded-lg', 'lg:shadow-sm');
145
+ }
146
+ return classes.join(' ');
147
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
148
+ mainClasses = computed(() => {
149
+ const classes = ['flex-1', 'overflow-auto'];
150
+ if (this.layoutWidth() === 'fixed')
151
+ classes.push('lg:mx-auto', 'lg:max-w-7xl');
152
+ return classes.join(' ');
153
+ }, ...(ngDevMode ? [{ debugName: "mainClasses" }] : /* istanbul ignore next */ []));
154
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: VerticalLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
155
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: VerticalLayoutComponent, isStandalone: true, selector: "vertical", inputs: { sidebarAppearance: { classPropertyName: "sidebarAppearance", publicName: "sidebarAppearance", isSignal: true, isRequired: false, transformFunction: null }, sidebarPosition: { classPropertyName: "sidebarPosition", publicName: "sidebarPosition", isSignal: true, isRequired: false, transformFunction: null }, sidebarMode: { classPropertyName: "sidebarMode", publicName: "sidebarMode", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()", "attr.data-layout-width": "layoutWidth()", "attr.data-style": "themeStyle()", "style.border-width": "shellBorderWidth()" } }, ngImport: i0, template: `
156
+ <ui-sidebar
157
+ [appearance]="sidebarAppearance()"
158
+ [position]="sidebarPosition()"
159
+ [ariaLabel]="ariaLabel()"
160
+ [style.border-left-width]="dividerBorderWidth()"
161
+ [style.border-right-width]="dividerBorderWidth()" />
162
+ <main [class]="mainClasses()">
163
+ <router-outlet />
164
+ </main>
165
+ `, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: SidebarComponent, selector: "ui-sidebar", inputs: ["items", "navigationId", "appearance", "position", "ariaLabel", "header", "class", "autoMobile", "autoRegister"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
229
166
  }
230
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: LayoutVerticalComponent, decorators: [{
167
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: VerticalLayoutComponent, decorators: [{
231
168
  type: Component,
232
169
  args: [{
233
170
  selector: 'vertical',
234
- imports: [RouterOutlet, LayoutElementDirective, ContentElementDirective],
171
+ changeDetection: ChangeDetectionStrategy.OnPush,
172
+ imports: [RouterOutlet, SidebarComponent],
235
173
  host: {
236
- '[attr.data-layout-mode]': '"vertical"',
174
+ '[class]': 'hostClasses()',
175
+ '[attr.data-layout-width]': 'layoutWidth()',
176
+ '[attr.data-style]': 'themeStyle()',
177
+ '[style.border-width]': 'shellBorderWidth()',
237
178
  },
238
179
  template: `
239
- <layout>
240
- <shell-content>
241
- <aside>
242
- <ng-content select="[navigation]"></ng-content>
243
- </aside>
244
- <main>
245
- <router-outlet />
246
- </main>
247
- </shell-content>
248
- </layout>
180
+ <ui-sidebar
181
+ [appearance]="sidebarAppearance()"
182
+ [position]="sidebarPosition()"
183
+ [ariaLabel]="ariaLabel()"
184
+ [style.border-left-width]="dividerBorderWidth()"
185
+ [style.border-right-width]="dividerBorderWidth()" />
186
+ <main [class]="mainClasses()">
187
+ <router-outlet />
188
+ </main>
249
189
  `,
250
- changeDetection: ChangeDetectionStrategy.OnPush,
251
190
  }]
252
- }] });
191
+ }], propDecorators: { sidebarAppearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarAppearance", required: false }] }], sidebarPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarPosition", required: false }] }], sidebarMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarMode", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
253
192
 
254
- class LayoutContainerSwitcherComponent {
193
+ /**
194
+ * Horizontal layout — topbar (h-12) + main (scrollable).
195
+ *
196
+ * Data navigasi diambil dari `NavigationService`.
197
+ * Consumer app dapat memproyeksikan brand kiri dan profile kanan.
198
+ *
199
+ * Markup:
200
+ * ```html
201
+ * <horizontal>
202
+ * <a ui-layout-brand>Brand</a>
203
+ * <button ui-layout-profile type="button">Profile</button>
204
+ * </horizontal>
205
+ * ```
206
+ */
207
+ class HorizontalLayoutComponent {
255
208
  layout = inject(LayoutService);
256
- label = computed(() => this.layout.container() === 'boxed' ? 'Boxed layout container enabled' : 'Boxed layout container disabled', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
257
- toggle() {
258
- this.layout.setContainer(this.layout.container() === 'full' ? 'boxed' : 'full');
259
- }
260
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: LayoutContainerSwitcherComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
261
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: LayoutContainerSwitcherComponent, isStandalone: true, selector: "layout-container-switcher", providers: [libraryLucideConfigProvider], ngImport: i0, template: `
262
- <button
263
- class="ngt-icon-button"
264
- type="button"
265
- mat-icon-button
266
- aria-label="Boxed layout container"
267
- [attr.aria-pressed]="layout.container() === 'boxed'"
268
- [matTooltip]="label()"
269
- (click)="toggle()">
270
- @if (layout.container() === 'full') {
271
- <svg lucideExpand aria-hidden="true"></svg>
272
- } @else {
273
- <svg lucideShrink aria-hidden="true"></svg>
274
- }
275
- </button>
276
- `, isInline: true, dependencies: [{ kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: LucideExpand, selector: "svg[lucideExpand]" }, { kind: "component", type: LucideShrink, selector: "svg[lucideShrink]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
209
+ theme = inject(ThemeService);
210
+ topbarAppearance = input('default', ...(ngDevMode ? [{ debugName: "topbarAppearance" }] : /* istanbul ignore next */ []));
211
+ ariaLabel = input('Primary', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
212
+ layoutWidth = this.layout.width;
213
+ themeStyle = this.theme.style;
214
+ shellBorderWidth = computed(() => (this.layoutWidth() === 'fixed' ? 'var(--border-width)' : null), ...(ngDevMode ? [{ debugName: "shellBorderWidth" }] : /* istanbul ignore next */ []));
215
+ dividerBorderWidth = computed(() => 'var(--border-width)', ...(ngDevMode ? [{ debugName: "dividerBorderWidth" }] : /* istanbul ignore next */ []));
216
+ hostClasses = computed(() => {
217
+ const classes = ['flex', 'h-dvh', 'w-full', 'flex-col', 'overflow-hidden', 'bg-background', 'text-foreground'];
218
+ if (this.layoutWidth() === 'fixed') {
219
+ classes.push('lg:mx-auto', 'lg:my-8', 'lg:max-w-7xl', 'lg:h-[calc(100dvh-4rem)]', 'lg:w-[calc(100%-4rem)]', 'lg:border', 'lg:border-border', 'lg:rounded-lg', 'lg:shadow-sm');
220
+ }
221
+ return classes.join(' ');
222
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
223
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: HorizontalLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
224
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: HorizontalLayoutComponent, isStandalone: true, selector: "horizontal", inputs: { topbarAppearance: { classPropertyName: "topbarAppearance", publicName: "topbarAppearance", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()", "attr.data-layout-width": "layoutWidth()", "attr.data-style": "themeStyle()", "style.border-width": "shellBorderWidth()" } }, ngImport: i0, template: `
225
+ <ui-topbar
226
+ class="h-12 w-full shrink-0 border-b border-border"
227
+ [style.border-bottom-width]="dividerBorderWidth()"
228
+ [appearance]="topbarAppearance()"
229
+ [ariaLabel]="ariaLabel()">
230
+ <div ui-topbar-start class="flex min-w-0 items-center">
231
+ <ng-content select="[ui-layout-brand],[ui-topbar-start]" />
232
+ </div>
233
+ <div ui-topbar-end class="flex min-w-0 items-center">
234
+ <ng-content select="[ui-layout-profile],[ui-topbar-end]" />
235
+ </div>
236
+ </ui-topbar>
237
+ <main class="flex-1 overflow-auto">
238
+ <router-outlet />
239
+ </main>
240
+ `, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: TopbarComponent, selector: "ui-topbar", inputs: ["items", "navigationId", "appearance", "ariaLabel", "class", "autoRegister", "showHamburger", "hamburgerLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
277
241
  }
278
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: LayoutContainerSwitcherComponent, decorators: [{
242
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: HorizontalLayoutComponent, decorators: [{
279
243
  type: Component,
280
244
  args: [{
281
- selector: 'layout-container-switcher',
282
- imports: [MatIconButton, MatTooltip, LucideExpand, LucideShrink],
283
- providers: [libraryLucideConfigProvider],
245
+ selector: 'horizontal',
284
246
  changeDetection: ChangeDetectionStrategy.OnPush,
247
+ imports: [RouterOutlet, TopbarComponent],
248
+ host: {
249
+ '[class]': 'hostClasses()',
250
+ '[attr.data-layout-width]': 'layoutWidth()',
251
+ '[attr.data-style]': 'themeStyle()',
252
+ '[style.border-width]': 'shellBorderWidth()',
253
+ },
285
254
  template: `
286
- <button
287
- class="ngt-icon-button"
288
- type="button"
289
- mat-icon-button
290
- aria-label="Boxed layout container"
291
- [attr.aria-pressed]="layout.container() === 'boxed'"
292
- [matTooltip]="label()"
293
- (click)="toggle()">
294
- @if (layout.container() === 'full') {
295
- <svg lucideExpand aria-hidden="true"></svg>
296
- } @else {
297
- <svg lucideShrink aria-hidden="true"></svg>
298
- }
299
- </button>
255
+ <ui-topbar
256
+ class="h-12 w-full shrink-0 border-b border-border"
257
+ [style.border-bottom-width]="dividerBorderWidth()"
258
+ [appearance]="topbarAppearance()"
259
+ [ariaLabel]="ariaLabel()">
260
+ <div ui-topbar-start class="flex min-w-0 items-center">
261
+ <ng-content select="[ui-layout-brand],[ui-topbar-start]" />
262
+ </div>
263
+ <div ui-topbar-end class="flex min-w-0 items-center">
264
+ <ng-content select="[ui-layout-profile],[ui-topbar-end]" />
265
+ </div>
266
+ </ui-topbar>
267
+ <main class="flex-1 overflow-auto">
268
+ <router-outlet />
269
+ </main>
300
270
  `,
301
271
  }]
302
- }] });
303
-
304
- class LayoutModeSwitcherComponent {
305
- layout = inject(LayoutService);
306
- // Empty mode remains programmatic so the UI only exposes the two navigational shell variants.
307
- options = [
308
- { value: 'vertical', label: 'Vertical Sidebar' },
309
- { value: 'horizontal', label: 'Horizontal Navbar' },
310
- ];
311
- currentOption = computed(() => this.options.find((option) => option.value === this.layout.mode()) ?? {
312
- value: 'empty',
313
- label: 'Content Only',
314
- }, ...(ngDevMode ? [{ debugName: "currentOption" }] : /* istanbul ignore next */ []));
315
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: LayoutModeSwitcherComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
316
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: LayoutModeSwitcherComponent, isStandalone: true, selector: "layout-mode-switcher", providers: [libraryLucideConfigProvider], ngImport: i0, template: `
317
- <button
318
- class="ngt-icon-button"
319
- type="button"
320
- mat-icon-button
321
- [attr.aria-label]="'Layout mode: ' + currentOption().label"
322
- [matTooltip]="'Layout mode: ' + currentOption().label"
323
- [matMenuTriggerFor]="menu">
324
- @switch (layout.mode()) {
325
- @case ('vertical') {
326
- <svg lucidePanelLeft aria-hidden="true"></svg>
327
- }
328
- @case ('horizontal') {
329
- <svg lucidePanelTop aria-hidden="true"></svg>
330
- }
331
- @default {
332
- <svg lucideAppWindow aria-hidden="true"></svg>
333
- }
334
- }
335
- </button>
272
+ }], propDecorators: { topbarAppearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "topbarAppearance", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
336
273
 
337
- <mat-menu #menu="matMenu">
338
- @for (option of options; track option.value) {
339
- <button
340
- type="button"
341
- mat-menu-item
342
- role="menuitemradio"
343
- [attr.aria-checked]="layout.mode() === option.value"
344
- (click)="layout.setMode(option.value)">
345
- @switch (option.value) {
346
- @case ('vertical') {
347
- <svg lucidePanelLeft aria-hidden="true"></svg>
348
- }
349
- @case ('horizontal') {
350
- <svg lucidePanelTop aria-hidden="true"></svg>
351
- }
352
- @default {
353
- <svg lucideAppWindow aria-hidden="true"></svg>
354
- }
355
- }
356
- <span>{{ option.label }}</span>
357
- </button>
358
- }
359
- </mat-menu>
360
- `, isInline: true, dependencies: [{ kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: LucidePanelLeft, selector: "svg[lucidePanelLeft], svg[lucideSidebar]" }, { kind: "component", type: LucidePanelTop, selector: "svg[lucidePanelTop]" }, { kind: "component", type: LucideAppWindow, selector: "svg[lucideAppWindow]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
274
+ /**
275
+ * Empty layout full-viewport, flex-centered main.
276
+ *
277
+ * Cocok untuk halaman login / error / onboarding (pola shadcn `login-05`).
278
+ * Konten dirender lewat `<router-outlet>`; consumer men-style card / form
279
+ * milik halaman route sendiri.
280
+ *
281
+ * Markup:
282
+ * ```html
283
+ * <empty>
284
+ * <!-- router-outlet dirender oleh komponen -->
285
+ * </empty>
286
+ * ```
287
+ */
288
+ class EmptyLayoutComponent {
289
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: EmptyLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
290
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", type: EmptyLayoutComponent, isStandalone: true, selector: "empty", host: { classAttribute: "flex min-h-dvh w-full items-center justify-center bg-background p-6 text-foreground" }, ngImport: i0, template: `
291
+ <main class="w-full max-w-sm">
292
+ <router-outlet />
293
+ </main>
294
+ `, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
361
295
  }
362
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: LayoutModeSwitcherComponent, decorators: [{
296
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: EmptyLayoutComponent, decorators: [{
363
297
  type: Component,
364
298
  args: [{
365
- selector: 'layout-mode-switcher',
366
- imports: [
367
- MatIconButton,
368
- MatTooltip,
369
- MatMenu,
370
- MatMenuItem,
371
- MatMenuTrigger,
372
- LucidePanelLeft,
373
- LucidePanelTop,
374
- LucideAppWindow,
375
- ],
376
- providers: [libraryLucideConfigProvider],
299
+ selector: 'empty',
377
300
  changeDetection: ChangeDetectionStrategy.OnPush,
301
+ imports: [RouterOutlet],
302
+ host: {
303
+ class: 'flex min-h-dvh w-full items-center justify-center bg-background p-6 text-foreground',
304
+ },
378
305
  template: `
379
- <button
380
- class="ngt-icon-button"
381
- type="button"
382
- mat-icon-button
383
- [attr.aria-label]="'Layout mode: ' + currentOption().label"
384
- [matTooltip]="'Layout mode: ' + currentOption().label"
385
- [matMenuTriggerFor]="menu">
386
- @switch (layout.mode()) {
387
- @case ('vertical') {
388
- <svg lucidePanelLeft aria-hidden="true"></svg>
389
- }
390
- @case ('horizontal') {
391
- <svg lucidePanelTop aria-hidden="true"></svg>
392
- }
393
- @default {
394
- <svg lucideAppWindow aria-hidden="true"></svg>
395
- }
396
- }
397
- </button>
398
-
399
- <mat-menu #menu="matMenu">
400
- @for (option of options; track option.value) {
401
- <button
402
- type="button"
403
- mat-menu-item
404
- role="menuitemradio"
405
- [attr.aria-checked]="layout.mode() === option.value"
406
- (click)="layout.setMode(option.value)">
407
- @switch (option.value) {
408
- @case ('vertical') {
409
- <svg lucidePanelLeft aria-hidden="true"></svg>
410
- }
411
- @case ('horizontal') {
412
- <svg lucidePanelTop aria-hidden="true"></svg>
413
- }
414
- @default {
415
- <svg lucideAppWindow aria-hidden="true"></svg>
416
- }
417
- }
418
- <span>{{ option.label }}</span>
419
- </button>
420
- }
421
- </mat-menu>
306
+ <main class="w-full max-w-sm">
307
+ <router-outlet />
308
+ </main>
422
309
  `,
423
310
  }]
424
311
  }] });
425
312
 
426
- function warnInvalidLayoutConfig(message) {
427
- if (isDevMode()) {
428
- console.warn(`[provideNgLayout] ${message}`);
429
- }
430
- }
431
- function normalizeLayoutMode(value) {
432
- if (typeof value === 'undefined' || isLayoutMode(value)) {
433
- return value ?? DEFAULT_NG_LAYOUT_CONFIG.defaultMode;
434
- }
435
- warnInvalidLayoutConfig(`Ignoring invalid defaultMode ${JSON.stringify(value)}. Falling back to ${JSON.stringify(DEFAULT_NG_LAYOUT_CONFIG.defaultMode)}.`);
436
- return DEFAULT_NG_LAYOUT_CONFIG.defaultMode;
437
- }
438
- function normalizeLayoutContainer(value) {
439
- if (typeof value === 'undefined' || isLayoutContainer(value)) {
440
- return value ?? DEFAULT_NG_LAYOUT_CONFIG.defaultContainer;
441
- }
442
- warnInvalidLayoutConfig(`Ignoring invalid defaultContainer ${JSON.stringify(value)}. Falling back to ${JSON.stringify(DEFAULT_NG_LAYOUT_CONFIG.defaultContainer)}.`);
443
- return DEFAULT_NG_LAYOUT_CONFIG.defaultContainer;
444
- }
445
- function normalizeLayoutConfig(config) {
446
- return {
447
- ...DEFAULT_NG_LAYOUT_CONFIG,
448
- defaultMode: normalizeLayoutMode(config.defaultMode),
449
- defaultContainer: normalizeLayoutContainer(config.defaultContainer),
450
- };
451
- }
452
- function provideNgLayout(config = {}) {
453
- return makeEnvironmentProviders([{ provide: NG_LAYOUT_CONFIG, useValue: normalizeLayoutConfig(config) }]);
313
+ function provideMaterialLayout(config = {}) {
314
+ return makeEnvironmentProviders([
315
+ { provide: MATERIAL_LAYOUT_CONFIG, useValue: config },
316
+ provideEnvironmentInitializer(() => {
317
+ inject(LayoutService);
318
+ }),
319
+ ]);
454
320
  }
455
321
 
322
+ /*
323
+ * Public API Surface of @ojiepermana/angular/layout
324
+ */
325
+ const LAYOUT_VERSION = '0.0.1';
326
+
456
327
  /**
457
328
  * Generated bundle index. Do not edit.
458
329
  */
459
330
 
460
- export { LayoutContainerSwitcherComponent, LayoutHorizontalComponent, LayoutHostDirective, LayoutModeSwitcherComponent, LayoutService, LayoutVerticalComponent, NG_LAYOUT_CONFIG, provideNgLayout };
331
+ export { DEFAULT_MATERIAL_LAYOUT_CONFIG, EmptyLayoutComponent, HorizontalLayoutComponent, LAYOUT_MODES, LAYOUT_VERSION, LAYOUT_WIDTHS, LayoutService, MATERIAL_LAYOUT_CONFIG, VerticalLayoutComponent, isLayoutMode, isLayoutWidth, provideMaterialLayout };
461
332
  //# sourceMappingURL=ojiepermana-angular-layout.mjs.map