@ojiepermana/angular 21.1.20 → 21.1.23

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.
@@ -125,10 +125,10 @@ class LayoutService {
125
125
  /* ignore */
126
126
  }
127
127
  }
128
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: LayoutService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
129
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: LayoutService, providedIn: 'root' });
128
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: LayoutService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
129
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: LayoutService, providedIn: 'root' });
130
130
  }
131
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: LayoutService, decorators: [{
131
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: LayoutService, decorators: [{
132
132
  type: Injectable,
133
133
  args: [{ providedIn: 'root' }]
134
134
  }], ctorParameters: () => [] });
@@ -143,7 +143,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
143
143
  * Markup:
144
144
  * ```html
145
145
  * <vertical>
146
- * <!-- sidebar + router-outlet dirender oleh komponen -->
146
+ * <a ui-layout-brand>Brand</a>
147
+ * <button ui-layout-profile type="button">Profile</button>
147
148
  * </vertical>
148
149
  * ```
149
150
  */
@@ -160,16 +161,19 @@ class VerticalLayoutComponent {
160
161
  isWideWidth = computed(() => this.layoutWidth() === 'wide', ...(ngDevMode ? [{ debugName: "isWideWidth" }] : /* istanbul ignore next */ []));
161
162
  shellBorderWidth = computed(() => (this.isConstrainedWidth() ? 'var(--border-width)' : null), ...(ngDevMode ? [{ debugName: "shellBorderWidth" }] : /* istanbul ignore next */ []));
162
163
  hostClasses = computed(() => {
163
- const classes = ['block', 'h-dvh', 'w-full', 'overflow-hidden', 'bg-background', 'text-foreground'];
164
+ const classes = ['block', 'h-dvh', 'w-full', 'overflow-hidden', 'text-foreground'];
164
165
  if (this.isConstrainedWidth()) {
165
- classes.push('box-border', 'lg:p-8');
166
+ classes.push('bg-primary/10', 'box-border', 'lg:p-8');
167
+ }
168
+ else {
169
+ classes.push('bg-background');
166
170
  }
167
171
  return classes.join(' ');
168
172
  }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
169
173
  frameClasses = computed(() => {
170
- const classes = ['flex', 'h-full', 'w-full', 'overflow-hidden'];
174
+ const classes = ['flex', 'h-full', 'w-full', 'overflow-hidden', 'bg-background'];
171
175
  if (this.isConstrainedWidth()) {
172
- classes.push('lg:mx-auto', this.isWideWidth() ? 'lg:max-w-[calc(17.5rem+96rem)]' : 'lg:max-w-[calc(17.5rem+80rem)]', 'lg:border', 'lg:border-border', 'lg:rounded-lg', 'lg:shadow-sm');
176
+ classes.push('lg:mx-auto', this.isWideWidth() ? 'lg:max-w-[calc(17.5rem+96rem)]' : 'lg:max-w-[calc(17.5rem+80rem)]', 'lg:border', 'lg:border-primary/30', 'lg:rounded-lg', 'lg:shadow-sm');
173
177
  }
174
178
  return classes.join(' ');
175
179
  }, ...(ngDevMode ? [{ debugName: "frameClasses" }] : /* istanbul ignore next */ []));
@@ -183,17 +187,24 @@ class VerticalLayoutComponent {
183
187
  }
184
188
  return classes.join(' ');
185
189
  }, ...(ngDevMode ? [{ debugName: "mainClasses" }] : /* istanbul ignore next */ []));
186
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: VerticalLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
187
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.12", 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()" } }, ngImport: i0, template: `
190
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: VerticalLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
191
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.13", 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()" } }, ngImport: i0, template: `
188
192
  <div [class]="frameClasses()" [style.border-width]="shellBorderWidth()">
189
- <sidebar [appearance]="sidebarAppearance()" [position]="sidebarPosition()" [ariaLabel]="ariaLabel()" />
193
+ <sidebar [appearance]="sidebarAppearance()" [position]="sidebarPosition()" [ariaLabel]="ariaLabel()">
194
+ <div sidebar-header class="contents">
195
+ <ng-content select="[ui-layout-brand],[sidebar-header]" />
196
+ </div>
197
+ <div sidebar-footer class="contents">
198
+ <ng-content select="[ui-layout-profile],[sidebar-footer]" />
199
+ </div>
200
+ </sidebar>
190
201
  <main [class]="mainClasses()">
191
202
  <router-outlet />
192
203
  </main>
193
204
  </div>
194
- `, 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: "sidebar", inputs: ["items", "navigationId", "appearance", "position", "ariaLabel", "header", "class", "autoMobile", "autoRegister"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
205
+ `, 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: "sidebar", inputs: ["items", "navigationId", "appearance", "borderSource", "position", "ariaLabel", "header", "class", "autoMobile", "autoRegister"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
195
206
  }
196
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: VerticalLayoutComponent, decorators: [{
207
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: VerticalLayoutComponent, decorators: [{
197
208
  type: Component,
198
209
  args: [{
199
210
  selector: 'vertical',
@@ -206,7 +217,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
206
217
  },
207
218
  template: `
208
219
  <div [class]="frameClasses()" [style.border-width]="shellBorderWidth()">
209
- <sidebar [appearance]="sidebarAppearance()" [position]="sidebarPosition()" [ariaLabel]="ariaLabel()" />
220
+ <sidebar [appearance]="sidebarAppearance()" [position]="sidebarPosition()" [ariaLabel]="ariaLabel()">
221
+ <div sidebar-header class="contents">
222
+ <ng-content select="[ui-layout-brand],[sidebar-header]" />
223
+ </div>
224
+ <div sidebar-footer class="contents">
225
+ <ng-content select="[ui-layout-profile],[sidebar-footer]" />
226
+ </div>
227
+ </sidebar>
210
228
  <main [class]="mainClasses()">
211
229
  <router-outlet />
212
230
  </main>
@@ -241,16 +259,19 @@ class HorizontalLayoutComponent {
241
259
  shellBorderWidth = computed(() => (this.isConstrainedWidth() ? 'var(--border-width)' : null), ...(ngDevMode ? [{ debugName: "shellBorderWidth" }] : /* istanbul ignore next */ []));
242
260
  dividerBorderWidth = computed(() => 'var(--border-width)', ...(ngDevMode ? [{ debugName: "dividerBorderWidth" }] : /* istanbul ignore next */ []));
243
261
  hostClasses = computed(() => {
244
- const classes = ['block', 'h-dvh', 'w-full', 'overflow-hidden', 'bg-background', 'text-foreground'];
262
+ const classes = ['block', 'h-dvh', 'w-full', 'overflow-hidden', 'text-foreground'];
245
263
  if (this.isConstrainedWidth()) {
246
- classes.push('box-border', 'lg:p-8');
264
+ classes.push('bg-primary/10', 'box-border', 'lg:p-8');
265
+ }
266
+ else {
267
+ classes.push('bg-background');
247
268
  }
248
269
  return classes.join(' ');
249
270
  }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
250
271
  frameClasses = computed(() => {
251
- const classes = ['flex', 'h-full', 'w-full', 'flex-col', 'overflow-hidden'];
272
+ const classes = ['flex', 'h-full', 'w-full', 'flex-col', 'overflow-hidden', 'bg-background'];
252
273
  if (this.isConstrainedWidth()) {
253
- classes.push('lg:border', 'lg:border-border', 'lg:rounded-lg', 'lg:shadow-sm');
274
+ classes.push('lg:border', 'lg:border-primary/30', 'lg:rounded-lg', 'lg:shadow-sm');
254
275
  }
255
276
  return classes.join(' ');
256
277
  }, ...(ngDevMode ? [{ debugName: "frameClasses" }] : /* istanbul ignore next */ []));
@@ -264,8 +285,8 @@ class HorizontalLayoutComponent {
264
285
  }
265
286
  return classes.join(' ');
266
287
  }, ...(ngDevMode ? [{ debugName: "mainClasses" }] : /* istanbul ignore next */ []));
267
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: HorizontalLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
268
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.12", 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()" } }, ngImport: i0, template: `
288
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: HorizontalLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
289
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.13", 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()" } }, ngImport: i0, template: `
269
290
  <div [class]="frameClasses()" [style.border-width]="shellBorderWidth()">
270
291
  <topbar
271
292
  class="w-full shrink-0 border-b border-border"
@@ -285,7 +306,7 @@ class HorizontalLayoutComponent {
285
306
  </div>
286
307
  `, 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: "topbar", inputs: ["items", "navigationId", "appearance", "ariaLabel", "class", "autoRegister", "showHamburger", "hamburgerLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
287
308
  }
288
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: HorizontalLayoutComponent, decorators: [{
309
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: HorizontalLayoutComponent, decorators: [{
289
310
  type: Component,
290
311
  args: [{
291
312
  selector: 'horizontal',
@@ -333,14 +354,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
333
354
  * ```
334
355
  */
335
356
  class EmptyLayoutComponent {
336
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: EmptyLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
337
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.12", 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: `
357
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: EmptyLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
358
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.13", 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: `
338
359
  <main class="w-full max-w-sm">
339
360
  <router-outlet />
340
361
  </main>
341
362
  `, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
342
363
  }
343
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: EmptyLayoutComponent, decorators: [{
364
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: EmptyLayoutComponent, decorators: [{
344
365
  type: Component,
345
366
  args: [{
346
367
  selector: 'empty',
@@ -1 +1 @@
1
- {"version":3,"file":"ojiepermana-angular-layout.mjs","sources":["../../../projects/angular/layout/src/lib/core/layout.tokens.ts","../../../projects/angular/layout/src/lib/core/layout.service.ts","../../../projects/angular/layout/src/lib/vertical/vertical.component.ts","../../../projects/angular/layout/src/lib/horizontal/horizontal.component.ts","../../../projects/angular/layout/src/lib/empty/empty.component.ts","../../../projects/angular/layout/src/lib/core/layout.provider.ts","../../../projects/angular/layout/public-api.ts","../../../projects/angular/layout/ojiepermana-angular-layout.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\nexport const LAYOUT_MODES = ['vertical', 'horizontal', 'empty'] as const;\n\nexport type LayoutMode = (typeof LAYOUT_MODES)[number];\n\nexport const LAYOUT_WIDTHS = ['full', 'container', 'wide'] as const;\n\nexport type LayoutWidth = (typeof LAYOUT_WIDTHS)[number];\n\n/** @deprecated Use `container` instead. */\nexport type LegacyLayoutWidth = 'fixed';\n\nexport type ConfiguredLayoutWidth = LayoutWidth | LegacyLayoutWidth;\n\nexport interface MaterialLayoutConfig {\n /** Initial layout mode. */\n readonly mode?: LayoutMode;\n /** Initial layout width. */\n readonly width?: ConfiguredLayoutWidth;\n /** @deprecated Use `mode` instead. */\n /** Initial layout mode. Defaults to `vertical`. */\n readonly defaultMode?: LayoutMode;\n /** localStorage key used to persist the layout mode. Set to `null` to disable persistence. */\n readonly storageKey?: string | null;\n /** localStorage key used to persist the layout width. Set to `null` to disable persistence. */\n readonly widthStorageKey?: string | null;\n}\n\nexport interface ResolvedMaterialLayoutConfig {\n readonly defaultMode: LayoutMode;\n readonly defaultWidth: LayoutWidth;\n readonly storageKey: string | null;\n readonly widthStorageKey: string | null;\n}\n\nexport const MATERIAL_LAYOUT_CONFIG = new InjectionToken<MaterialLayoutConfig>('MATERIAL_LAYOUT_CONFIG');\n\nexport const DEFAULT_MATERIAL_LAYOUT_CONFIG: ResolvedMaterialLayoutConfig = {\n defaultMode: 'vertical',\n defaultWidth: 'wide',\n storageKey: 'layout-mode',\n widthStorageKey: 'layout-width',\n};\n\nexport function isLayoutMode(value: string | null | undefined): value is LayoutMode {\n return LAYOUT_MODES.some((mode) => mode === value);\n}\n\nexport function isLayoutWidth(value: string | null | undefined): value is LayoutWidth {\n return LAYOUT_WIDTHS.some((width) => width === value);\n}\n\nexport function normalizeLayoutWidth(value: string | null | undefined): LayoutWidth | null {\n if (isLayoutWidth(value)) {\n return value;\n }\n\n if (value === 'fixed') {\n return 'container';\n }\n\n return null;\n}\n","import { DOCUMENT } from '@angular/common';\nimport { Injectable, effect, inject, signal } from '@angular/core';\nimport {\n DEFAULT_MATERIAL_LAYOUT_CONFIG,\n LAYOUT_WIDTHS,\n MATERIAL_LAYOUT_CONFIG,\n isLayoutMode,\n normalizeLayoutWidth,\n type LayoutMode,\n type LayoutWidth,\n type ResolvedMaterialLayoutConfig,\n} from './layout.tokens';\n\n@Injectable({ providedIn: 'root' })\nexport class LayoutService {\n private readonly document = inject(DOCUMENT);\n private readonly config = this.resolveConfig();\n\n private readonly _mode = signal<LayoutMode>(this.readPersistedMode() ?? this.config.defaultMode);\n private readonly _width = signal<LayoutWidth>(this.readPersistedWidth() ?? this.config.defaultWidth);\n\n readonly mode = this._mode.asReadonly();\n readonly width = this._width.asReadonly();\n\n constructor() {\n effect(() => {\n this.persistMode(this._mode());\n });\n\n effect(() => {\n this.persistWidth(this._width());\n });\n }\n\n setMode(mode: LayoutMode): void {\n this._mode.set(mode);\n }\n\n toggleMode(): void {\n this._mode.update((mode) => {\n if (mode === 'vertical') {\n return 'horizontal';\n }\n\n if (mode === 'horizontal') {\n return 'vertical';\n }\n\n return 'vertical';\n });\n }\n\n setWidth(width: LayoutWidth): void {\n this._width.set(width);\n }\n\n toggleWidth(): void {\n this._width.update((width) => {\n const currentIndex = LAYOUT_WIDTHS.indexOf(width);\n return LAYOUT_WIDTHS[(currentIndex + 1) % LAYOUT_WIDTHS.length] ?? LAYOUT_WIDTHS[0];\n });\n }\n\n private resolveConfig(): ResolvedMaterialLayoutConfig {\n const config = inject(MATERIAL_LAYOUT_CONFIG, { optional: true }) ?? {};\n const configuredMode = config.mode ?? config.defaultMode;\n const configuredWidth = config.width;\n\n return {\n defaultMode: isLayoutMode(configuredMode) ? configuredMode : DEFAULT_MATERIAL_LAYOUT_CONFIG.defaultMode,\n defaultWidth: normalizeLayoutWidth(configuredWidth) ?? DEFAULT_MATERIAL_LAYOUT_CONFIG.defaultWidth,\n storageKey: config.storageKey ?? DEFAULT_MATERIAL_LAYOUT_CONFIG.storageKey,\n widthStorageKey: config.widthStorageKey ?? DEFAULT_MATERIAL_LAYOUT_CONFIG.widthStorageKey,\n };\n }\n\n private readPersistedMode(): LayoutMode | null {\n const key = this.config.storageKey;\n if (!key) return null;\n try {\n const value = this.document.defaultView?.localStorage?.getItem(key);\n return isLayoutMode(value) ? value : null;\n } catch {\n return null;\n }\n }\n\n private readPersistedWidth(): LayoutWidth | null {\n const key = this.config.widthStorageKey;\n if (!key) return null;\n try {\n const value = this.document.defaultView?.localStorage?.getItem(key);\n return normalizeLayoutWidth(value);\n } catch {\n return null;\n }\n }\n\n private persistMode(mode: LayoutMode): void {\n const key = this.config.storageKey;\n if (!key) return;\n try {\n this.document.defaultView?.localStorage?.setItem(key, mode);\n } catch {\n /* ignore */\n }\n }\n\n private persistWidth(width: LayoutWidth): void {\n const key = this.config.widthStorageKey;\n if (!key) return;\n try {\n this.document.defaultView?.localStorage?.setItem(key, width);\n } catch {\n /* ignore */\n }\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\nimport {\n SidebarComponent,\n type SidebarAppearance,\n type SidebarMode,\n type SidebarPosition,\n} from '@ojiepermana/angular/navigation';\nimport { ThemeService } from '@ojiepermana/angular/theme';\nimport { LayoutService } from '../core/layout.service';\n\n/**\n * Vertical layout — sidebar + main (scrollable).\n *\n * Data navigasi diambil dari `NavigationService` (register via\n * `NavigationService.registerItems()` di bootstrap). Main memegang\n * `<router-outlet>` dan scroll jika konten panjang.\n *\n * Markup:\n * ```html\n * <vertical>\n * <!-- sidebar + router-outlet dirender oleh komponen -->\n * </vertical>\n * ```\n */\n@Component({\n selector: 'vertical',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [RouterOutlet, SidebarComponent],\n host: {\n '[class]': 'hostClasses()',\n '[attr.data-layout-width]': 'layoutWidth()',\n '[attr.data-style]': 'themeStyle()',\n },\n template: `\n <div [class]=\"frameClasses()\" [style.border-width]=\"shellBorderWidth()\">\n <sidebar [appearance]=\"sidebarAppearance()\" [position]=\"sidebarPosition()\" [ariaLabel]=\"ariaLabel()\" />\n <main [class]=\"mainClasses()\">\n <router-outlet />\n </main>\n </div>\n `,\n})\nexport class VerticalLayoutComponent {\n private readonly layout = inject(LayoutService);\n private readonly theme = inject(ThemeService);\n\n readonly sidebarAppearance = input<SidebarAppearance>('default');\n readonly sidebarPosition = input<SidebarPosition>('left');\n readonly sidebarMode = input<SidebarMode>('side');\n readonly ariaLabel = input<string>('Primary');\n\n protected readonly layoutWidth = this.layout.width;\n protected readonly themeStyle = this.theme.style;\n protected readonly isConstrainedWidth = computed(() => this.layoutWidth() !== 'full');\n protected readonly isWideWidth = computed(() => this.layoutWidth() === 'wide');\n protected readonly shellBorderWidth = computed(() => (this.isConstrainedWidth() ? 'var(--border-width)' : null));\n\n protected readonly hostClasses = computed(() => {\n const classes = ['block', 'h-dvh', 'w-full', 'overflow-hidden', 'bg-background', 'text-foreground'];\n if (this.isConstrainedWidth()) {\n classes.push('box-border', 'lg:p-8');\n }\n return classes.join(' ');\n });\n\n protected readonly frameClasses = computed(() => {\n const classes = ['flex', 'h-full', 'w-full', 'overflow-hidden'];\n if (this.isConstrainedWidth()) {\n classes.push(\n 'lg:mx-auto',\n this.isWideWidth() ? 'lg:max-w-[calc(17.5rem+96rem)]' : 'lg:max-w-[calc(17.5rem+80rem)]',\n 'lg:border',\n 'lg:border-border',\n 'lg:rounded-lg',\n 'lg:shadow-sm',\n );\n }\n return classes.join(' ');\n });\n\n protected readonly mainClasses = computed(() => {\n const classes = ['min-w-0', 'flex-1', 'overflow-auto'];\n if (this.layoutWidth() === 'container') {\n classes.push('w-full', 'max-w-7xl');\n } else if (this.isWideWidth()) {\n classes.push('w-full', 'max-w-screen-2xl');\n }\n return classes.join(' ');\n });\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\nimport { TopbarComponent, type TopbarAppearance } from '@ojiepermana/angular/navigation';\nimport { ThemeService } from '@ojiepermana/angular/theme';\nimport { LayoutService } from '../core/layout.service';\n\n/**\n * Horizontal layout — themed topbar + main (scrollable).\n *\n * Data navigasi diambil dari `NavigationService`.\n * Consumer app dapat memproyeksikan brand kiri dan profile kanan.\n *\n * Markup:\n * ```html\n * <horizontal>\n * <a ui-layout-brand>Brand</a>\n * <button ui-layout-profile type=\"button\">Profile</button>\n * </horizontal>\n * ```\n */\n@Component({\n selector: 'horizontal',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [RouterOutlet, TopbarComponent],\n host: {\n '[class]': 'hostClasses()',\n '[attr.data-layout-width]': 'layoutWidth()',\n '[attr.data-style]': 'themeStyle()',\n },\n template: `\n <div [class]=\"frameClasses()\" [style.border-width]=\"shellBorderWidth()\">\n <topbar\n class=\"w-full shrink-0 border-b border-border\"\n [style.border-bottom-width]=\"dividerBorderWidth()\"\n [appearance]=\"topbarAppearance()\"\n [ariaLabel]=\"ariaLabel()\">\n <div topbar-start class=\"flex min-w-0 items-center\">\n <ng-content select=\"[ui-layout-brand],[topbar-start]\" />\n </div>\n <div topbar-end class=\"flex min-w-0 items-center\">\n <ng-content select=\"[ui-layout-profile],[topbar-end]\" />\n </div>\n </topbar>\n <main [class]=\"mainClasses()\">\n <router-outlet />\n </main>\n </div>\n `,\n})\nexport class HorizontalLayoutComponent {\n private readonly layout = inject(LayoutService);\n private readonly theme = inject(ThemeService);\n\n readonly topbarAppearance = input<TopbarAppearance>('default');\n readonly ariaLabel = input<string>('Primary');\n\n protected readonly layoutWidth = this.layout.width;\n protected readonly themeStyle = this.theme.style;\n protected readonly isConstrainedWidth = computed(() => this.layoutWidth() !== 'full');\n protected readonly isWideWidth = computed(() => this.layoutWidth() === 'wide');\n protected readonly shellBorderWidth = computed(() => (this.isConstrainedWidth() ? 'var(--border-width)' : null));\n protected readonly dividerBorderWidth = computed(() => 'var(--border-width)');\n\n protected readonly hostClasses = computed(() => {\n const classes = ['block', 'h-dvh', 'w-full', 'overflow-hidden', 'bg-background', 'text-foreground'];\n if (this.isConstrainedWidth()) {\n classes.push('box-border', 'lg:p-8');\n }\n return classes.join(' ');\n });\n\n protected readonly frameClasses = computed(() => {\n const classes = ['flex', 'h-full', 'w-full', 'flex-col', 'overflow-hidden'];\n if (this.isConstrainedWidth()) {\n classes.push('lg:border', 'lg:border-border', 'lg:rounded-lg', 'lg:shadow-sm');\n }\n return classes.join(' ');\n });\n\n protected readonly mainClasses = computed(() => {\n const classes = ['min-w-0', 'flex-1', 'overflow-auto'];\n if (this.layoutWidth() === 'container') {\n classes.push('mx-auto', 'w-full', 'max-w-7xl');\n } else if (this.isWideWidth()) {\n classes.push('mx-auto', 'w-full', 'max-w-screen-2xl');\n }\n return classes.join(' ');\n });\n}\n","import { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\n\n/**\n * Empty layout — full-viewport, flex-centered main.\n *\n * Cocok untuk halaman login / error / onboarding (pola shadcn `login-05`).\n * Konten dirender lewat `<router-outlet>`; consumer men-style card / form\n * milik halaman route sendiri.\n *\n * Markup:\n * ```html\n * <empty>\n * <!-- router-outlet dirender oleh komponen -->\n * </empty>\n * ```\n */\n@Component({\n selector: 'empty',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [RouterOutlet],\n host: {\n class: 'flex min-h-dvh w-full items-center justify-center bg-background p-6 text-foreground',\n },\n template: `\n <main class=\"w-full max-w-sm\">\n <router-outlet />\n </main>\n `,\n})\nexport class EmptyLayoutComponent {}\n","import {\n inject,\n type EnvironmentProviders,\n makeEnvironmentProviders,\n provideEnvironmentInitializer,\n} from '@angular/core';\nimport { LayoutService } from './layout.service';\nimport { MATERIAL_LAYOUT_CONFIG, type MaterialLayoutConfig } from './layout.tokens';\n\nexport function provideMaterialLayout(config: MaterialLayoutConfig = {}): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: MATERIAL_LAYOUT_CONFIG, useValue: config },\n provideEnvironmentInitializer(() => {\n inject(LayoutService);\n }),\n ]);\n}\n","/*\n * Public API Surface of @ojiepermana/angular/layout\n */\n\nexport * from './src/lib/vertical/vertical.component';\nexport * from './src/lib/horizontal/horizontal.component';\nexport * from './src/lib/empty/empty.component';\nexport * from './src/lib/core/layout.tokens';\nexport * from './src/lib/core/layout.service';\nexport * from './src/lib/core/layout.provider';\n\nexport const LAYOUT_VERSION = '0.0.1';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ojiepermana-angular-layout.mjs","sources":["../../../projects/angular/layout/src/lib/core/layout.tokens.ts","../../../projects/angular/layout/src/lib/core/layout.service.ts","../../../projects/angular/layout/src/lib/vertical/vertical.component.ts","../../../projects/angular/layout/src/lib/horizontal/horizontal.component.ts","../../../projects/angular/layout/src/lib/empty/empty.component.ts","../../../projects/angular/layout/src/lib/core/layout.provider.ts","../../../projects/angular/layout/public-api.ts","../../../projects/angular/layout/ojiepermana-angular-layout.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\nexport const LAYOUT_MODES = ['vertical', 'horizontal', 'empty'] as const;\n\nexport type LayoutMode = (typeof LAYOUT_MODES)[number];\n\nexport const LAYOUT_WIDTHS = ['full', 'container', 'wide'] as const;\n\nexport type LayoutWidth = (typeof LAYOUT_WIDTHS)[number];\n\n/** @deprecated Use `container` instead. */\nexport type LegacyLayoutWidth = 'fixed';\n\nexport type ConfiguredLayoutWidth = LayoutWidth | LegacyLayoutWidth;\n\nexport interface MaterialLayoutConfig {\n /** Initial layout mode. */\n readonly mode?: LayoutMode;\n /** Initial layout width. */\n readonly width?: ConfiguredLayoutWidth;\n /** @deprecated Use `mode` instead. */\n /** Initial layout mode. Defaults to `vertical`. */\n readonly defaultMode?: LayoutMode;\n /** localStorage key used to persist the layout mode. Set to `null` to disable persistence. */\n readonly storageKey?: string | null;\n /** localStorage key used to persist the layout width. Set to `null` to disable persistence. */\n readonly widthStorageKey?: string | null;\n}\n\nexport interface ResolvedMaterialLayoutConfig {\n readonly defaultMode: LayoutMode;\n readonly defaultWidth: LayoutWidth;\n readonly storageKey: string | null;\n readonly widthStorageKey: string | null;\n}\n\nexport const MATERIAL_LAYOUT_CONFIG = new InjectionToken<MaterialLayoutConfig>('MATERIAL_LAYOUT_CONFIG');\n\nexport const DEFAULT_MATERIAL_LAYOUT_CONFIG: ResolvedMaterialLayoutConfig = {\n defaultMode: 'vertical',\n defaultWidth: 'wide',\n storageKey: 'layout-mode',\n widthStorageKey: 'layout-width',\n};\n\nexport function isLayoutMode(value: string | null | undefined): value is LayoutMode {\n return LAYOUT_MODES.some((mode) => mode === value);\n}\n\nexport function isLayoutWidth(value: string | null | undefined): value is LayoutWidth {\n return LAYOUT_WIDTHS.some((width) => width === value);\n}\n\nexport function normalizeLayoutWidth(value: string | null | undefined): LayoutWidth | null {\n if (isLayoutWidth(value)) {\n return value;\n }\n\n if (value === 'fixed') {\n return 'container';\n }\n\n return null;\n}\n","import { DOCUMENT } from '@angular/common';\nimport { Injectable, effect, inject, signal } from '@angular/core';\nimport {\n DEFAULT_MATERIAL_LAYOUT_CONFIG,\n LAYOUT_WIDTHS,\n MATERIAL_LAYOUT_CONFIG,\n isLayoutMode,\n normalizeLayoutWidth,\n type LayoutMode,\n type LayoutWidth,\n type ResolvedMaterialLayoutConfig,\n} from './layout.tokens';\n\n@Injectable({ providedIn: 'root' })\nexport class LayoutService {\n private readonly document = inject(DOCUMENT);\n private readonly config = this.resolveConfig();\n\n private readonly _mode = signal<LayoutMode>(this.readPersistedMode() ?? this.config.defaultMode);\n private readonly _width = signal<LayoutWidth>(this.readPersistedWidth() ?? this.config.defaultWidth);\n\n readonly mode = this._mode.asReadonly();\n readonly width = this._width.asReadonly();\n\n constructor() {\n effect(() => {\n this.persistMode(this._mode());\n });\n\n effect(() => {\n this.persistWidth(this._width());\n });\n }\n\n setMode(mode: LayoutMode): void {\n this._mode.set(mode);\n }\n\n toggleMode(): void {\n this._mode.update((mode) => {\n if (mode === 'vertical') {\n return 'horizontal';\n }\n\n if (mode === 'horizontal') {\n return 'vertical';\n }\n\n return 'vertical';\n });\n }\n\n setWidth(width: LayoutWidth): void {\n this._width.set(width);\n }\n\n toggleWidth(): void {\n this._width.update((width) => {\n const currentIndex = LAYOUT_WIDTHS.indexOf(width);\n return LAYOUT_WIDTHS[(currentIndex + 1) % LAYOUT_WIDTHS.length] ?? LAYOUT_WIDTHS[0];\n });\n }\n\n private resolveConfig(): ResolvedMaterialLayoutConfig {\n const config = inject(MATERIAL_LAYOUT_CONFIG, { optional: true }) ?? {};\n const configuredMode = config.mode ?? config.defaultMode;\n const configuredWidth = config.width;\n\n return {\n defaultMode: isLayoutMode(configuredMode) ? configuredMode : DEFAULT_MATERIAL_LAYOUT_CONFIG.defaultMode,\n defaultWidth: normalizeLayoutWidth(configuredWidth) ?? DEFAULT_MATERIAL_LAYOUT_CONFIG.defaultWidth,\n storageKey: config.storageKey ?? DEFAULT_MATERIAL_LAYOUT_CONFIG.storageKey,\n widthStorageKey: config.widthStorageKey ?? DEFAULT_MATERIAL_LAYOUT_CONFIG.widthStorageKey,\n };\n }\n\n private readPersistedMode(): LayoutMode | null {\n const key = this.config.storageKey;\n if (!key) return null;\n try {\n const value = this.document.defaultView?.localStorage?.getItem(key);\n return isLayoutMode(value) ? value : null;\n } catch {\n return null;\n }\n }\n\n private readPersistedWidth(): LayoutWidth | null {\n const key = this.config.widthStorageKey;\n if (!key) return null;\n try {\n const value = this.document.defaultView?.localStorage?.getItem(key);\n return normalizeLayoutWidth(value);\n } catch {\n return null;\n }\n }\n\n private persistMode(mode: LayoutMode): void {\n const key = this.config.storageKey;\n if (!key) return;\n try {\n this.document.defaultView?.localStorage?.setItem(key, mode);\n } catch {\n /* ignore */\n }\n }\n\n private persistWidth(width: LayoutWidth): void {\n const key = this.config.widthStorageKey;\n if (!key) return;\n try {\n this.document.defaultView?.localStorage?.setItem(key, width);\n } catch {\n /* ignore */\n }\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\nimport {\n SidebarComponent,\n type SidebarAppearance,\n type SidebarMode,\n type SidebarPosition,\n} from '@ojiepermana/angular/navigation';\nimport { ThemeService } from '@ojiepermana/angular/theme';\nimport { LayoutService } from '../core/layout.service';\n\n/**\n * Vertical layout — sidebar + main (scrollable).\n *\n * Data navigasi diambil dari `NavigationService` (register via\n * `NavigationService.registerItems()` di bootstrap). Main memegang\n * `<router-outlet>` dan scroll jika konten panjang.\n *\n * Markup:\n * ```html\n * <vertical>\n * <a ui-layout-brand>Brand</a>\n * <button ui-layout-profile type=\"button\">Profile</button>\n * </vertical>\n * ```\n */\n@Component({\n selector: 'vertical',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [RouterOutlet, SidebarComponent],\n host: {\n '[class]': 'hostClasses()',\n '[attr.data-layout-width]': 'layoutWidth()',\n '[attr.data-style]': 'themeStyle()',\n },\n template: `\n <div [class]=\"frameClasses()\" [style.border-width]=\"shellBorderWidth()\">\n <sidebar [appearance]=\"sidebarAppearance()\" [position]=\"sidebarPosition()\" [ariaLabel]=\"ariaLabel()\">\n <div sidebar-header class=\"contents\">\n <ng-content select=\"[ui-layout-brand],[sidebar-header]\" />\n </div>\n <div sidebar-footer class=\"contents\">\n <ng-content select=\"[ui-layout-profile],[sidebar-footer]\" />\n </div>\n </sidebar>\n <main [class]=\"mainClasses()\">\n <router-outlet />\n </main>\n </div>\n `,\n})\nexport class VerticalLayoutComponent {\n private readonly layout = inject(LayoutService);\n private readonly theme = inject(ThemeService);\n\n readonly sidebarAppearance = input<SidebarAppearance>('default');\n readonly sidebarPosition = input<SidebarPosition>('left');\n readonly sidebarMode = input<SidebarMode>('side');\n readonly ariaLabel = input<string>('Primary');\n\n protected readonly layoutWidth = this.layout.width;\n protected readonly themeStyle = this.theme.style;\n protected readonly isConstrainedWidth = computed(() => this.layoutWidth() !== 'full');\n protected readonly isWideWidth = computed(() => this.layoutWidth() === 'wide');\n protected readonly shellBorderWidth = computed(() => (this.isConstrainedWidth() ? 'var(--border-width)' : null));\n\n protected readonly hostClasses = computed(() => {\n const classes = ['block', 'h-dvh', 'w-full', 'overflow-hidden', 'text-foreground'];\n if (this.isConstrainedWidth()) {\n classes.push('bg-primary/10', 'box-border', 'lg:p-8');\n } else {\n classes.push('bg-background');\n }\n return classes.join(' ');\n });\n\n protected readonly frameClasses = computed(() => {\n const classes = ['flex', 'h-full', 'w-full', 'overflow-hidden', 'bg-background'];\n if (this.isConstrainedWidth()) {\n classes.push(\n 'lg:mx-auto',\n this.isWideWidth() ? 'lg:max-w-[calc(17.5rem+96rem)]' : 'lg:max-w-[calc(17.5rem+80rem)]',\n 'lg:border',\n 'lg:border-primary/30',\n 'lg:rounded-lg',\n 'lg:shadow-sm',\n );\n }\n return classes.join(' ');\n });\n\n protected readonly mainClasses = computed(() => {\n const classes = ['min-w-0', 'flex-1', 'overflow-auto'];\n if (this.layoutWidth() === 'container') {\n classes.push('w-full', 'max-w-7xl');\n } else if (this.isWideWidth()) {\n classes.push('w-full', 'max-w-screen-2xl');\n }\n return classes.join(' ');\n });\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\nimport { TopbarComponent, type TopbarAppearance } from '@ojiepermana/angular/navigation';\nimport { ThemeService } from '@ojiepermana/angular/theme';\nimport { LayoutService } from '../core/layout.service';\n\n/**\n * Horizontal layout — themed topbar + main (scrollable).\n *\n * Data navigasi diambil dari `NavigationService`.\n * Consumer app dapat memproyeksikan brand kiri dan profile kanan.\n *\n * Markup:\n * ```html\n * <horizontal>\n * <a ui-layout-brand>Brand</a>\n * <button ui-layout-profile type=\"button\">Profile</button>\n * </horizontal>\n * ```\n */\n@Component({\n selector: 'horizontal',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [RouterOutlet, TopbarComponent],\n host: {\n '[class]': 'hostClasses()',\n '[attr.data-layout-width]': 'layoutWidth()',\n '[attr.data-style]': 'themeStyle()',\n },\n template: `\n <div [class]=\"frameClasses()\" [style.border-width]=\"shellBorderWidth()\">\n <topbar\n class=\"w-full shrink-0 border-b border-border\"\n [style.border-bottom-width]=\"dividerBorderWidth()\"\n [appearance]=\"topbarAppearance()\"\n [ariaLabel]=\"ariaLabel()\">\n <div topbar-start class=\"flex min-w-0 items-center\">\n <ng-content select=\"[ui-layout-brand],[topbar-start]\" />\n </div>\n <div topbar-end class=\"flex min-w-0 items-center\">\n <ng-content select=\"[ui-layout-profile],[topbar-end]\" />\n </div>\n </topbar>\n <main [class]=\"mainClasses()\">\n <router-outlet />\n </main>\n </div>\n `,\n})\nexport class HorizontalLayoutComponent {\n private readonly layout = inject(LayoutService);\n private readonly theme = inject(ThemeService);\n\n readonly topbarAppearance = input<TopbarAppearance>('default');\n readonly ariaLabel = input<string>('Primary');\n\n protected readonly layoutWidth = this.layout.width;\n protected readonly themeStyle = this.theme.style;\n protected readonly isConstrainedWidth = computed(() => this.layoutWidth() !== 'full');\n protected readonly isWideWidth = computed(() => this.layoutWidth() === 'wide');\n protected readonly shellBorderWidth = computed(() => (this.isConstrainedWidth() ? 'var(--border-width)' : null));\n protected readonly dividerBorderWidth = computed(() => 'var(--border-width)');\n\n protected readonly hostClasses = computed(() => {\n const classes = ['block', 'h-dvh', 'w-full', 'overflow-hidden', 'text-foreground'];\n if (this.isConstrainedWidth()) {\n classes.push('bg-primary/10', 'box-border', 'lg:p-8');\n } else {\n classes.push('bg-background');\n }\n return classes.join(' ');\n });\n\n protected readonly frameClasses = computed(() => {\n const classes = ['flex', 'h-full', 'w-full', 'flex-col', 'overflow-hidden', 'bg-background'];\n if (this.isConstrainedWidth()) {\n classes.push('lg:border', 'lg:border-primary/30', 'lg:rounded-lg', 'lg:shadow-sm');\n }\n return classes.join(' ');\n });\n\n protected readonly mainClasses = computed(() => {\n const classes = ['min-w-0', 'flex-1', 'overflow-auto'];\n if (this.layoutWidth() === 'container') {\n classes.push('mx-auto', 'w-full', 'max-w-7xl');\n } else if (this.isWideWidth()) {\n classes.push('mx-auto', 'w-full', 'max-w-screen-2xl');\n }\n return classes.join(' ');\n });\n}\n","import { ChangeDetectionStrategy, Component } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\n\n/**\n * Empty layout — full-viewport, flex-centered main.\n *\n * Cocok untuk halaman login / error / onboarding (pola shadcn `login-05`).\n * Konten dirender lewat `<router-outlet>`; consumer men-style card / form\n * milik halaman route sendiri.\n *\n * Markup:\n * ```html\n * <empty>\n * <!-- router-outlet dirender oleh komponen -->\n * </empty>\n * ```\n */\n@Component({\n selector: 'empty',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [RouterOutlet],\n host: {\n class: 'flex min-h-dvh w-full items-center justify-center bg-background p-6 text-foreground',\n },\n template: `\n <main class=\"w-full max-w-sm\">\n <router-outlet />\n </main>\n `,\n})\nexport class EmptyLayoutComponent {}\n","import {\n inject,\n type EnvironmentProviders,\n makeEnvironmentProviders,\n provideEnvironmentInitializer,\n} from '@angular/core';\nimport { LayoutService } from './layout.service';\nimport { MATERIAL_LAYOUT_CONFIG, type MaterialLayoutConfig } from './layout.tokens';\n\nexport function provideMaterialLayout(config: MaterialLayoutConfig = {}): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: MATERIAL_LAYOUT_CONFIG, useValue: config },\n provideEnvironmentInitializer(() => {\n inject(LayoutService);\n }),\n ]);\n}\n","/*\n * Public API Surface of @ojiepermana/angular/layout\n */\n\nexport * from './src/lib/vertical/vertical.component';\nexport * from './src/lib/horizontal/horizontal.component';\nexport * from './src/lib/empty/empty.component';\nexport * from './src/lib/core/layout.tokens';\nexport * from './src/lib/core/layout.service';\nexport * from './src/lib/core/layout.provider';\n\nexport const LAYOUT_VERSION = '0.0.1';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -197,10 +197,10 @@ class NavigationService {
197
197
  /* ignore */
198
198
  }
199
199
  }
200
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: NavigationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
201
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: NavigationService, providedIn: 'root' });
200
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: NavigationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
201
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: NavigationService, providedIn: 'root' });
202
202
  }
203
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: NavigationService, decorators: [{
203
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: NavigationService, decorators: [{
204
204
  type: Injectable,
205
205
  args: [{ providedIn: 'root' }]
206
206
  }], ctorParameters: () => [] });
@@ -240,10 +240,10 @@ class UiNavIconComponent {
240
240
  link.setAttribute(MATERIAL_SYMBOLS_FONT_ATTR, MATERIAL_SYMBOLS_FONT_ID);
241
241
  this.doc.head.appendChild(link);
242
242
  }
243
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UiNavIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
244
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.12", type: UiNavIconComponent, isStandalone: true, selector: "ui-nav-icon", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "aria-hidden": "true", "translate": "no" }, properties: { "class": "classes()", "style.font-size.px": "size()", "style.font-variation-settings": "fontVariationSettings" } }, ngImport: i0, template: `{{ name() }}`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
243
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: UiNavIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
244
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.13", type: UiNavIconComponent, isStandalone: true, selector: "ui-nav-icon", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "aria-hidden": "true", "translate": "no" }, properties: { "class": "classes()", "style.font-size.px": "size()", "style.font-variation-settings": "fontVariationSettings" } }, ngImport: i0, template: `{{ name() }}`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
245
245
  }
246
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UiNavIconComponent, decorators: [{
246
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: UiNavIconComponent, decorators: [{
247
247
  type: Component,
248
248
  args: [{
249
249
  selector: 'ui-nav-icon',
@@ -323,8 +323,8 @@ class UiNavItemComponent {
323
323
  item.action(item);
324
324
  }
325
325
  }
326
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UiNavItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
327
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: UiNavItemComponent, isStandalone: true, selector: "ui-nav-item", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, level: { classPropertyName: "level", publicName: "level", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
326
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: UiNavItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
327
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: UiNavItemComponent, isStandalone: true, selector: "ui-nav-item", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, level: { classPropertyName: "level", publicName: "level", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
328
328
  @switch (type()) {
329
329
  @case ('divider') {
330
330
  <hr class="my-2 border-t border-border" role="separator" />
@@ -527,7 +527,7 @@ class UiNavItemComponent {
527
527
  }
528
528
  `, isInline: true, dependencies: [{ kind: "component", type: UiNavItemComponent, selector: "ui-nav-item", inputs: ["item", "level", "compact"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: UiNavIconComponent, selector: "ui-nav-icon", inputs: ["name", "class", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
529
529
  }
530
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UiNavItemComponent, decorators: [{
530
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: UiNavItemComponent, decorators: [{
531
531
  type: Component,
532
532
  args: [{
533
533
  selector: 'ui-nav-item',
@@ -761,6 +761,8 @@ class SidebarComponent {
761
761
  /** Registry key di `NavigationService`. Default `'main'`. */
762
762
  navigationId = input(DEFAULT_NAVIGATION_ID, ...(ngDevMode ? [{ debugName: "navigationId" }] : /* istanbul ignore next */ []));
763
763
  appearance = input('default', ...(ngDevMode ? [{ debugName: "appearance" }] : /* istanbul ignore next */ []));
764
+ /** Desktop border can be owned by the sidebar or by the surrounding layout shell. */
765
+ borderSource = input('component', ...(ngDevMode ? [{ debugName: "borderSource" }] : /* istanbul ignore next */ []));
764
766
  position = input('left', ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
765
767
  ariaLabel = input('Primary', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
766
768
  header = input(true, ...(ngDevMode ? [{ debugName: "header" }] : /* istanbul ignore next */ []));
@@ -822,21 +824,28 @@ class SidebarComponent {
822
824
  base.push('w-16');
823
825
  else
824
826
  base.push('[width:17.5rem]');
825
- if (this.position() === 'right')
826
- base.push('border-l', 'border-brand');
827
+ if (this.borderSource() === 'component') {
828
+ if (this.position() === 'right')
829
+ base.push('border-l', 'border-primary/30');
830
+ else
831
+ base.push('border-r', 'border-primary/30');
832
+ }
827
833
  return [...base, this.class()].join(' ');
828
834
  }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
829
835
  headerClasses = computed(() => {
830
- const base = ['flex h-12 items-center gap-2 border-b border-brand'];
836
+ const base = ['flex items-center gap-1 border-b border-primary/30'];
831
837
  if (this.isCompact()) {
832
- base.push('justify-center px-2');
838
+ base.push('h-12', 'justify-center', 'px-2');
839
+ }
840
+ else {
841
+ base.push('h-12', 'pr-2');
833
842
  }
834
843
  return base.join(' ');
835
844
  }, ...(ngDevMode ? [{ debugName: "headerClasses" }] : /* istanbul ignore next */ []));
836
845
  headerSlotClasses = computed(() => {
837
846
  const base = ['min-w-0'];
838
847
  if (this.isCompact()) {
839
- base.push('flex flex-1 items-center justify-center overflow-hidden', '[&>[sidebar-header]>*]:mx-auto', '[&>[sidebar-header]>*]:max-w-full', '[&>[sidebar-header]>*]:shrink-0');
848
+ base.push('flex flex-1 items-center justify-center overflow-hidden', '[&>[sidebar-header]>*]:mx-auto', '[&>[sidebar-header]>*]:w-auto', '[&>[sidebar-header]>*]:max-w-full', '[&>[sidebar-header]>*]:justify-center', '[&>[sidebar-header]>*]:gap-0', '[&>[sidebar-header]>*]:px-0', '[&>[sidebar-header]>*]:shrink-0', '[&>[sidebar-header]>*>*:first-child]:mx-auto', '[&>[sidebar-header]>*>*:nth-child(n+2)]:hidden');
840
849
  }
841
850
  else {
842
851
  base.push('flex min-w-0 flex-1 items-center');
@@ -844,14 +853,15 @@ class SidebarComponent {
844
853
  return base.join(' ');
845
854
  }, ...(ngDevMode ? [{ debugName: "headerSlotClasses" }] : /* istanbul ignore next */ []));
846
855
  navClasses = computed(() => {
847
- const base = ['min-h-full overflow-x-hidden'];
856
+ const base = ['min-h-full'];
848
857
  if (this.isCompact()) {
849
858
  base.push('px-2', '[&_.ui-nav-text]:mx-auto', '[&_.ui-nav-text]:w-10', '[&_.ui-nav-text]:justify-center', '[&_.ui-nav-text]:px-0');
850
859
  }
851
860
  return base.join(' ');
852
861
  }, ...(ngDevMode ? [{ debugName: "navClasses" }] : /* istanbul ignore next */ []));
862
+ scrollViewportClasses = computed(() => 'overflow-y-auto overflow-x-hidden scrollbar-thin scrollbar-thumb-primary scrollbar-track-primary/10', ...(ngDevMode ? [{ debugName: "scrollViewportClasses" }] : /* istanbul ignore next */ []));
853
863
  footerClasses = computed(() => {
854
- const base = ['h-12 border-t border-brand'];
864
+ const base = ['h-12 border-t border-primary/30'];
855
865
  if (this.isCompact()) {
856
866
  base.push('flex items-center justify-center px-2');
857
867
  }
@@ -874,7 +884,7 @@ class SidebarComponent {
874
884
  base.push('bg-background');
875
885
  }
876
886
  if (overlayActive) {
877
- base.push('absolute inset-y-0 z-30 shadow-xl [width:17.5rem]', this.position() === 'right' ? 'right-0 border-l border-brand' : 'left-0 border-r border-brand');
887
+ base.push('absolute inset-y-0 z-30 shadow-xl [width:17.5rem]', this.position() === 'right' ? 'right-0 border-l border-primary/30' : 'left-0 border-r border-primary/30');
878
888
  }
879
889
  else {
880
890
  base.push('w-full');
@@ -953,8 +963,8 @@ class SidebarComponent {
953
963
  this.previouslyFocused?.focus?.();
954
964
  this.previouslyFocused = null;
955
965
  }
956
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: SidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
957
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: SidebarComponent, isStandalone: true, selector: "sidebar", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, navigationId: { classPropertyName: "navigationId", publicName: "navigationId", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, autoMobile: { classPropertyName: "autoMobile", publicName: "autoMobile", isSignal: true, isRequired: false, transformFunction: null }, autoRegister: { classPropertyName: "autoRegister", publicName: "autoRegister", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "navigation" }, listeners: { "mouseenter": "onHoverEnter()", "mouseleave": "onHoverLeave()", "focusin": "onHoverEnter()", "click": "onHostClick($event)" }, properties: { "attr.aria-label": "ariaLabel()", "class": "hostClasses()", "attr.data-appearance": "resolvedAppearance()", "attr.data-position": "position()", "attr.data-expanded": "isExpanded()", "hidden": "isMobile()" } }, viewQueries: [{ propertyName: "drawerTpl", first: true, predicate: ["drawerTpl"], descendants: true, isSignal: true }], ngImport: i0, template: `
966
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: SidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
967
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: SidebarComponent, isStandalone: true, selector: "sidebar", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, navigationId: { classPropertyName: "navigationId", publicName: "navigationId", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, borderSource: { classPropertyName: "borderSource", publicName: "borderSource", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, autoMobile: { classPropertyName: "autoMobile", publicName: "autoMobile", isSignal: true, isRequired: false, transformFunction: null }, autoRegister: { classPropertyName: "autoRegister", publicName: "autoRegister", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "navigation" }, listeners: { "mouseenter": "onHoverEnter()", "mouseleave": "onHoverLeave()", "focusin": "onHoverEnter()", "click": "onHostClick($event)" }, properties: { "attr.aria-label": "ariaLabel()", "class": "hostClasses()", "attr.data-appearance": "resolvedAppearance()", "attr.data-position": "position()", "attr.data-expanded": "isExpanded()", "hidden": "isMobile()" } }, viewQueries: [{ propertyName: "drawerTpl", first: true, predicate: ["drawerTpl"], descendants: true, isSignal: true }], ngImport: i0, template: `
958
968
  <div [class]="innerClasses()">
959
969
  <ng-container [ngTemplateOutlet]="body" />
960
970
  </div>
@@ -969,7 +979,7 @@ class SidebarComponent {
969
979
  <button
970
980
  type="button"
971
981
  data-sidebar-toggle
972
- class="ml-auto mr-2 inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background"
982
+ class="inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background"
973
983
  [attr.aria-label]="toggleButtonLabel()"
974
984
  [attr.title]="toggleButtonLabel()"
975
985
  [attr.aria-pressed]="resolvedAppearance() === 'thin'"
@@ -979,7 +989,7 @@ class SidebarComponent {
979
989
  }
980
990
  </div>
981
991
  }
982
- <ui-scroll-area class="min-h-0 flex-1">
992
+ <ui-scroll-area class="min-h-0 flex-1" [viewportClass]="scrollViewportClasses()">
983
993
  <nav [class]="navClasses()">
984
994
  @for (item of resolvedItems(); track item.id) {
985
995
  <ui-nav-item [item]="item" [compact]="isCompact()" />
@@ -998,15 +1008,16 @@ class SidebarComponent {
998
1008
  role="dialog"
999
1009
  aria-modal="true"
1000
1010
  [attr.aria-label]="ariaLabel()"
1001
- class="flex h-full w-72 max-w-[85vw] flex-col text-foreground shadow-xl"
1011
+ class="flex h-full w-72 max-w-[85vw] flex-col border-primary/30 text-foreground shadow-xl"
1012
+ [class.border-r]="position() === 'left'"
1002
1013
  [class.border-l]="position() === 'right'"
1003
- [class.border-brand]="position() === 'right'">
1014
+ [class.border-primary/30]="position() === 'left' || position() === 'right'">
1004
1015
  <ng-container [ngTemplateOutlet]="body" />
1005
1016
  </div>
1006
1017
  </ng-template>
1007
- `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ScrollAreaComponent, selector: "ui-scroll-area", inputs: ["class"] }, { kind: "component", type: UiNavIconComponent, selector: "ui-nav-icon", inputs: ["name", "class", "size"] }, { kind: "component", type: UiNavItemComponent, selector: "ui-nav-item", inputs: ["item", "level", "compact"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1018
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ScrollAreaComponent, selector: "ui-scroll-area", inputs: ["class", "viewportClass"] }, { kind: "component", type: UiNavIconComponent, selector: "ui-nav-icon", inputs: ["name", "class", "size"] }, { kind: "component", type: UiNavItemComponent, selector: "ui-nav-item", inputs: ["item", "level", "compact"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1008
1019
  }
1009
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: SidebarComponent, decorators: [{
1020
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: SidebarComponent, decorators: [{
1010
1021
  type: Component,
1011
1022
  args: [{
1012
1023
  selector: 'sidebar',
@@ -1040,7 +1051,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
1040
1051
  <button
1041
1052
  type="button"
1042
1053
  data-sidebar-toggle
1043
- class="ml-auto mr-2 inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background"
1054
+ class="inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background"
1044
1055
  [attr.aria-label]="toggleButtonLabel()"
1045
1056
  [attr.title]="toggleButtonLabel()"
1046
1057
  [attr.aria-pressed]="resolvedAppearance() === 'thin'"
@@ -1050,7 +1061,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
1050
1061
  }
1051
1062
  </div>
1052
1063
  }
1053
- <ui-scroll-area class="min-h-0 flex-1">
1064
+ <ui-scroll-area class="min-h-0 flex-1" [viewportClass]="scrollViewportClasses()">
1054
1065
  <nav [class]="navClasses()">
1055
1066
  @for (item of resolvedItems(); track item.id) {
1056
1067
  <ui-nav-item [item]="item" [compact]="isCompact()" />
@@ -1069,15 +1080,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
1069
1080
  role="dialog"
1070
1081
  aria-modal="true"
1071
1082
  [attr.aria-label]="ariaLabel()"
1072
- class="flex h-full w-72 max-w-[85vw] flex-col text-foreground shadow-xl"
1083
+ class="flex h-full w-72 max-w-[85vw] flex-col border-primary/30 text-foreground shadow-xl"
1084
+ [class.border-r]="position() === 'left'"
1073
1085
  [class.border-l]="position() === 'right'"
1074
- [class.border-brand]="position() === 'right'">
1086
+ [class.border-primary/30]="position() === 'left' || position() === 'right'">
1075
1087
  <ng-container [ngTemplateOutlet]="body" />
1076
1088
  </div>
1077
1089
  </ng-template>
1078
1090
  `,
1079
1091
  }]
1080
- }], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], navigationId: [{ type: i0.Input, args: [{ isSignal: true, alias: "navigationId", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], header: [{ type: i0.Input, args: [{ isSignal: true, alias: "header", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], autoMobile: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoMobile", required: false }] }], autoRegister: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoRegister", required: false }] }], drawerTpl: [{ type: i0.ViewChild, args: ['drawerTpl', { isSignal: true }] }] } });
1092
+ }], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], navigationId: [{ type: i0.Input, args: [{ isSignal: true, alias: "navigationId", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], borderSource: [{ type: i0.Input, args: [{ isSignal: true, alias: "borderSource", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], header: [{ type: i0.Input, args: [{ isSignal: true, alias: "header", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], autoMobile: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoMobile", required: false }] }], autoRegister: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoRegister", required: false }] }], drawerTpl: [{ type: i0.ViewChild, args: ['drawerTpl', { isSignal: true }] }] } });
1081
1093
 
1082
1094
  /**
1083
1095
  * Horizontal navigation (topbar) — shadcn-styled.
@@ -1265,8 +1277,8 @@ class TopbarComponent {
1265
1277
  const items = this.collectPanelFocusables(panel);
1266
1278
  items[0]?.focus();
1267
1279
  }
1268
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TopbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1269
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: TopbarComponent, isStandalone: true, selector: "topbar", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, navigationId: { classPropertyName: "navigationId", publicName: "navigationId", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, autoRegister: { classPropertyName: "autoRegister", publicName: "autoRegister", isSignal: true, isRequired: false, transformFunction: null }, showHamburger: { classPropertyName: "showHamburger", publicName: "showHamburger", isSignal: true, isRequired: false, transformFunction: null }, hamburgerLabel: { classPropertyName: "hamburgerLabel", publicName: "hamburgerLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "navigation" }, properties: { "attr.aria-label": "ariaLabel()", "class": "hostClasses()", "attr.data-appearance": "appearance()" } }, viewQueries: [{ propertyName: "dropdownTpl", first: true, predicate: ["dropdownTpl"], descendants: true, isSignal: true }], ngImport: i0, template: `
1280
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: TopbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1281
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: TopbarComponent, isStandalone: true, selector: "topbar", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, navigationId: { classPropertyName: "navigationId", publicName: "navigationId", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, autoRegister: { classPropertyName: "autoRegister", publicName: "autoRegister", isSignal: true, isRequired: false, transformFunction: null }, showHamburger: { classPropertyName: "showHamburger", publicName: "showHamburger", isSignal: true, isRequired: false, transformFunction: null }, hamburgerLabel: { classPropertyName: "hamburgerLabel", publicName: "hamburgerLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "navigation" }, properties: { "attr.aria-label": "ariaLabel()", "class": "hostClasses()", "attr.data-appearance": "appearance()" } }, viewQueries: [{ propertyName: "dropdownTpl", first: true, predicate: ["dropdownTpl"], descendants: true, isSignal: true }], ngImport: i0, template: `
1270
1282
  <div class="flex h-full w-full items-center gap-3 px-1">
1271
1283
  <div data-topbar-slot="start" class="flex shrink-0 items-center gap-2">
1272
1284
  @if (showHamburger()) {
@@ -1371,7 +1383,7 @@ class TopbarComponent {
1371
1383
  </ng-template>
1372
1384
  `, isInline: true, dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "component", type: UiNavIconComponent, selector: "ui-nav-icon", inputs: ["name", "class", "size"] }, { kind: "component", type: UiNavItemComponent, selector: "ui-nav-item", inputs: ["item", "level", "compact"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1373
1385
  }
1374
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: TopbarComponent, decorators: [{
1386
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: TopbarComponent, decorators: [{
1375
1387
  type: Component,
1376
1388
  args: [{
1377
1389
  selector: 'topbar',