@ojiepermana/angular 21.1.9 → 21.1.12

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.
@@ -5,6 +5,7 @@ import { NavigationService, DEFAULT_NAVIGATION_ID, UiNavIconComponent, TopbarCom
5
5
  import { provideMaterialTheme, withMaterialDefaults, ThemeService } from '@ojiepermana/angular/theme';
6
6
  import { cn, AvatarComponent, AvatarFallbackComponent, AvatarImageComponent, ButtonComponent, PopoverContentDirective, PopoverTriggerDirective } from '@ojiepermana/angular/component';
7
7
  import { RouterOutlet } from '@angular/router';
8
+ import { NgTemplateOutlet } from '@angular/common';
8
9
 
9
10
  const ETOS_BRAND_NAME = 'etos';
10
11
  const ETOS_THEME_CONFIG = {
@@ -13,7 +14,7 @@ const ETOS_THEME_CONFIG = {
13
14
  };
14
15
  const ETOS_LAYOUT_CONFIG = {
15
16
  mode: 'vertical',
16
- width: 'fixed',
17
+ width: 'container',
17
18
  };
18
19
 
19
20
  function provideEtosTheme(config = {}, ...features) {
@@ -52,11 +53,14 @@ const THEME_SCHEME_OPTIONS = [
52
53
  const LAYOUT_MODE_OPTIONS = [
53
54
  { value: 'horizontal', label: 'Horizontal', icon: 'view_column' },
54
55
  { value: 'vertical', label: 'Vertical', icon: 'view_sidebar' },
56
+ { value: 'empty', label: 'Empty', icon: 'crop_square' },
55
57
  ];
56
58
  const LAYOUT_WIDTH_OPTIONS = [
57
59
  { value: 'full', label: 'Full', icon: 'fit_screen' },
58
- { value: 'fixed', label: 'Fixed', icon: 'center_focus_strong' },
60
+ { value: 'container', label: 'Container', icon: 'center_focus_strong' },
61
+ { value: 'wide', label: 'Wide', icon: 'width_wide' },
59
62
  ];
63
+ const SWITCHER_PANEL_OVERLAP_OFFSET = -32;
60
64
  class EtosThemeSwitcherComponent {
61
65
  theme = inject(ThemeService);
62
66
  layout = inject(LayoutService);
@@ -70,8 +74,9 @@ class EtosThemeSwitcherComponent {
70
74
  quickActions = input.required(...(ngDevMode ? [{ debugName: "quickActions" }] : /* istanbul ignore next */ []));
71
75
  notificationShortcut = input(null, ...(ngDevMode ? [{ debugName: "notificationShortcut" }] : /* istanbul ignore next */ []));
72
76
  showNotificationShortcut = input(false, ...(ngDevMode ? [{ debugName: "showNotificationShortcut" }] : /* istanbul ignore next */ []));
73
- popoverSide = input('bottom', ...(ngDevMode ? [{ debugName: "popoverSide" }] : /* istanbul ignore next */ []));
74
- popoverAlign = input('end', ...(ngDevMode ? [{ debugName: "popoverAlign" }] : /* istanbul ignore next */ []));
77
+ popoverSide = input(null, ...(ngDevMode ? [{ debugName: "popoverSide" }] : /* istanbul ignore next */ []));
78
+ popoverAlign = input(null, ...(ngDevMode ? [{ debugName: "popoverAlign" }] : /* istanbul ignore next */ []));
79
+ popoverSideOffset = input(null, ...(ngDevMode ? [{ debugName: "popoverSideOffset" }] : /* istanbul ignore next */ []));
75
80
  actionSelected = output();
76
81
  themeMode = this.theme.mode;
77
82
  themeScheme = this.theme.scheme;
@@ -106,6 +111,9 @@ class EtosThemeSwitcherComponent {
106
111
  return this.quickActions().filter((action) => action.value !== shortcutValue);
107
112
  }, ...(ngDevMode ? [{ debugName: "actionOptions" }] : /* istanbul ignore next */ []));
108
113
  hostClasses = computed(() => cn('inline-flex shrink-0 items-center gap-2', this.class()), ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
114
+ resolvedPopoverSide = computed(() => this.popoverSide() ?? (this.layoutMode() === 'vertical' ? 'top' : 'bottom'), ...(ngDevMode ? [{ debugName: "resolvedPopoverSide" }] : /* istanbul ignore next */ []));
115
+ resolvedPopoverAlign = computed(() => this.popoverAlign() ?? (this.layoutMode() === 'vertical' ? 'start' : 'end'), ...(ngDevMode ? [{ debugName: "resolvedPopoverAlign" }] : /* istanbul ignore next */ []));
116
+ resolvedPopoverSideOffset = computed(() => this.popoverSideOffset() ?? SWITCHER_PANEL_OVERLAP_OFFSET, ...(ngDevMode ? [{ debugName: "resolvedPopoverSideOffset" }] : /* istanbul ignore next */ []));
109
117
  resolvedUserName = computed(() => this.userInfo()?.name?.trim() || this.userName(), ...(ngDevMode ? [{ debugName: "resolvedUserName" }] : /* istanbul ignore next */ []));
110
118
  resolvedUserSubtitle = computed(() => this.userInfo()?.subtitle ?? this.userSubtitle(), ...(ngDevMode ? [{ debugName: "resolvedUserSubtitle" }] : /* istanbul ignore next */ []));
111
119
  resolvedAvatarSrc = computed(() => this.userInfo()?.avatarSrc ?? this.avatarSrc(), ...(ngDevMode ? [{ debugName: "resolvedAvatarSrc" }] : /* istanbul ignore next */ []));
@@ -161,10 +169,22 @@ class EtosThemeSwitcherComponent {
161
169
  this.actionSelected.emit(shortcut.value);
162
170
  }
163
171
  labelForLayoutMode(mode) {
164
- return mode === 'horizontal' ? 'Horizontal' : 'Vertical';
172
+ if (mode === 'horizontal') {
173
+ return 'Horizontal';
174
+ }
175
+ if (mode === 'empty') {
176
+ return 'Empty';
177
+ }
178
+ return 'Vertical';
165
179
  }
166
180
  labelForLayoutWidth(width) {
167
- return width === 'full' ? 'Full' : 'Fixed';
181
+ if (width === 'container') {
182
+ return 'Container';
183
+ }
184
+ if (width === 'wide') {
185
+ return 'Wide';
186
+ }
187
+ return 'Full';
168
188
  }
169
189
  toInitials(name) {
170
190
  const segments = name.trim().split(/\s+/).filter(Boolean);
@@ -176,8 +196,8 @@ class EtosThemeSwitcherComponent {
176
196
  }
177
197
  return `${segments[0][0] ?? ''}${segments[1][0] ?? ''}`.toUpperCase();
178
198
  }
179
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: EtosThemeSwitcherComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
180
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: EtosThemeSwitcherComponent, isStandalone: true, selector: "etos-theme-switcher", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, userInfo: { classPropertyName: "userInfo", publicName: "userInfo", isSignal: true, isRequired: false, transformFunction: null }, userName: { classPropertyName: "userName", publicName: "userName", isSignal: true, isRequired: false, transformFunction: null }, userSubtitle: { classPropertyName: "userSubtitle", publicName: "userSubtitle", isSignal: true, isRequired: false, transformFunction: null }, avatarSrc: { classPropertyName: "avatarSrc", publicName: "avatarSrc", isSignal: true, isRequired: false, transformFunction: null }, avatarAlt: { classPropertyName: "avatarAlt", publicName: "avatarAlt", isSignal: true, isRequired: false, transformFunction: null }, quickActions: { classPropertyName: "quickActions", publicName: "quickActions", isSignal: true, isRequired: true, transformFunction: null }, notificationShortcut: { classPropertyName: "notificationShortcut", publicName: "notificationShortcut", isSignal: true, isRequired: false, transformFunction: null }, showNotificationShortcut: { classPropertyName: "showNotificationShortcut", publicName: "showNotificationShortcut", isSignal: true, isRequired: false, transformFunction: null }, popoverSide: { classPropertyName: "popoverSide", publicName: "popoverSide", isSignal: true, isRequired: false, transformFunction: null }, popoverAlign: { classPropertyName: "popoverAlign", publicName: "popoverAlign", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actionSelected: "actionSelected" }, host: { properties: { "class": "hostClasses()" } }, viewQueries: [{ propertyName: "popoverTrigger", first: true, predicate: ["trigger"], descendants: true, isSignal: true }], ngImport: i0, template: `
199
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EtosThemeSwitcherComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
200
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EtosThemeSwitcherComponent, isStandalone: true, selector: "etos-theme-switcher", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, userInfo: { classPropertyName: "userInfo", publicName: "userInfo", isSignal: true, isRequired: false, transformFunction: null }, userName: { classPropertyName: "userName", publicName: "userName", isSignal: true, isRequired: false, transformFunction: null }, userSubtitle: { classPropertyName: "userSubtitle", publicName: "userSubtitle", isSignal: true, isRequired: false, transformFunction: null }, avatarSrc: { classPropertyName: "avatarSrc", publicName: "avatarSrc", isSignal: true, isRequired: false, transformFunction: null }, avatarAlt: { classPropertyName: "avatarAlt", publicName: "avatarAlt", isSignal: true, isRequired: false, transformFunction: null }, quickActions: { classPropertyName: "quickActions", publicName: "quickActions", isSignal: true, isRequired: true, transformFunction: null }, notificationShortcut: { classPropertyName: "notificationShortcut", publicName: "notificationShortcut", isSignal: true, isRequired: false, transformFunction: null }, showNotificationShortcut: { classPropertyName: "showNotificationShortcut", publicName: "showNotificationShortcut", isSignal: true, isRequired: false, transformFunction: null }, popoverSide: { classPropertyName: "popoverSide", publicName: "popoverSide", isSignal: true, isRequired: false, transformFunction: null }, popoverAlign: { classPropertyName: "popoverAlign", publicName: "popoverAlign", isSignal: true, isRequired: false, transformFunction: null }, popoverSideOffset: { classPropertyName: "popoverSideOffset", publicName: "popoverSideOffset", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actionSelected: "actionSelected" }, host: { properties: { "class": "hostClasses()" } }, viewQueries: [{ propertyName: "popoverTrigger", first: true, predicate: ["trigger"], descendants: true, isSignal: true }], ngImport: i0, template: `
181
201
  @if (notificationShortcutConfig(); as shortcut) {
182
202
  <button
183
203
  type="button"
@@ -200,8 +220,9 @@ class EtosThemeSwitcherComponent {
200
220
  variant="ghost"
201
221
  size="icon"
202
222
  [uiPopoverTrigger]="preferencesPanel"
203
- [side]="popoverSide()"
204
- [align]="popoverAlign()"
223
+ [side]="resolvedPopoverSide()"
224
+ [align]="resolvedPopoverAlign()"
225
+ [sideOffset]="resolvedPopoverSideOffset()"
205
226
  [attr.aria-label]="triggerLabel()"
206
227
  [class]="triggerButtonClasses(trigger.isOpen())">
207
228
  <ui-avatar class="h-8 w-8 border border-border/60 shadow-[inset_0_1px_0_rgba(255,255,255,0.18)]">
@@ -219,7 +240,7 @@ class EtosThemeSwitcherComponent {
219
240
  data-etos-theme-switcher-panel
220
241
  role="dialog"
221
242
  aria-label="User Info"
222
- class="w-[min(21rem,calc(100vw-1.5rem))] overflow-hidden rounded-(--etos-layout-frame-radius) border border-border/70 bg-background text-foreground shadow-[0_18px_48px_rgba(15,23,42,0.12)]">
243
+ class="w-[min(21rem,calc(100vw-1.5rem))] overflow-hidden border border-border/70 bg-background text-foreground shadow-[0_18px_48px_rgba(15,23,42,0.12)]">
223
244
  <header class="p-5 pb-4">
224
245
  <div class="flex items-center gap-4">
225
246
  <ui-avatar class="h-14 w-14 border border-border/60 shadow-sm">
@@ -277,7 +298,7 @@ class EtosThemeSwitcherComponent {
277
298
  <p class="text-[0.72rem] font-semibold uppercase tracking-[0.22em] text-muted-foreground">Layout</p>
278
299
  </div>
279
300
  <div class="rounded-(--etos-layout-frame-radius) bg-muted/65 p-0.5">
280
- <div class="grid grid-cols-2 gap-1">
301
+ <div class="grid grid-cols-3 gap-1">
281
302
  @for (option of layoutModeOptions; track option.value) {
282
303
  <button
283
304
  type="button"
@@ -306,7 +327,7 @@ class EtosThemeSwitcherComponent {
306
327
  <p class="text-[0.72rem] font-semibold uppercase tracking-[0.22em] text-muted-foreground">Width</p>
307
328
  </div>
308
329
  <div class="rounded-(--etos-layout-frame-radius) bg-muted/65 p-0.5">
309
- <div class="grid grid-cols-2 gap-1">
330
+ <div class="grid grid-cols-3 gap-1">
310
331
  @for (option of layoutWidthOptions; track option.value) {
311
332
  <button
312
333
  type="button"
@@ -358,9 +379,9 @@ class EtosThemeSwitcherComponent {
358
379
  </div>
359
380
  </section>
360
381
  </ng-template>
361
- `, isInline: true, dependencies: [{ kind: "component", type: AvatarComponent, selector: "ui-avatar", inputs: ["class"] }, { kind: "component", type: AvatarFallbackComponent, selector: "ui-avatar-fallback", inputs: ["class"] }, { kind: "component", type: AvatarImageComponent, selector: "ui-avatar-image", inputs: ["src", "alt", "class"] }, { kind: "component", type: ButtonComponent, selector: "button[ui-button], a[ui-button]", inputs: ["variant", "size", "class"] }, { kind: "directive", type: PopoverContentDirective, selector: "ng-template[uiPopoverContent]", exportAs: ["uiPopoverContent"] }, { kind: "directive", type: PopoverTriggerDirective, selector: "[uiPopoverTrigger]", inputs: ["uiPopoverTrigger", "side", "align", "disabled"], outputs: ["openedChange"], exportAs: ["uiPopoverTrigger"] }, { kind: "component", type: UiNavIconComponent, selector: "ui-nav-icon", inputs: ["name", "class", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
382
+ `, isInline: true, dependencies: [{ kind: "component", type: AvatarComponent, selector: "ui-avatar", inputs: ["class"] }, { kind: "component", type: AvatarFallbackComponent, selector: "ui-avatar-fallback", inputs: ["class"] }, { kind: "component", type: AvatarImageComponent, selector: "ui-avatar-image", inputs: ["src", "alt", "class"] }, { kind: "component", type: ButtonComponent, selector: "button[ui-button], a[ui-button]", inputs: ["variant", "size", "class"] }, { kind: "directive", type: PopoverContentDirective, selector: "ng-template[uiPopoverContent]", exportAs: ["uiPopoverContent"] }, { kind: "directive", type: PopoverTriggerDirective, selector: "[uiPopoverTrigger]", inputs: ["uiPopoverTrigger", "side", "align", "sideOffset", "disabled"], outputs: ["openedChange"], exportAs: ["uiPopoverTrigger"] }, { kind: "component", type: UiNavIconComponent, selector: "ui-nav-icon", inputs: ["name", "class", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
362
383
  }
363
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: EtosThemeSwitcherComponent, decorators: [{
384
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EtosThemeSwitcherComponent, decorators: [{
364
385
  type: Component,
365
386
  args: [{
366
387
  selector: 'etos-theme-switcher',
@@ -400,8 +421,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
400
421
  variant="ghost"
401
422
  size="icon"
402
423
  [uiPopoverTrigger]="preferencesPanel"
403
- [side]="popoverSide()"
404
- [align]="popoverAlign()"
424
+ [side]="resolvedPopoverSide()"
425
+ [align]="resolvedPopoverAlign()"
426
+ [sideOffset]="resolvedPopoverSideOffset()"
405
427
  [attr.aria-label]="triggerLabel()"
406
428
  [class]="triggerButtonClasses(trigger.isOpen())">
407
429
  <ui-avatar class="h-8 w-8 border border-border/60 shadow-[inset_0_1px_0_rgba(255,255,255,0.18)]">
@@ -419,7 +441,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
419
441
  data-etos-theme-switcher-panel
420
442
  role="dialog"
421
443
  aria-label="User Info"
422
- class="w-[min(21rem,calc(100vw-1.5rem))] overflow-hidden rounded-(--etos-layout-frame-radius) border border-border/70 bg-background text-foreground shadow-[0_18px_48px_rgba(15,23,42,0.12)]">
444
+ class="w-[min(21rem,calc(100vw-1.5rem))] overflow-hidden border border-border/70 bg-background text-foreground shadow-[0_18px_48px_rgba(15,23,42,0.12)]">
423
445
  <header class="p-5 pb-4">
424
446
  <div class="flex items-center gap-4">
425
447
  <ui-avatar class="h-14 w-14 border border-border/60 shadow-sm">
@@ -477,7 +499,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
477
499
  <p class="text-[0.72rem] font-semibold uppercase tracking-[0.22em] text-muted-foreground">Layout</p>
478
500
  </div>
479
501
  <div class="rounded-(--etos-layout-frame-radius) bg-muted/65 p-0.5">
480
- <div class="grid grid-cols-2 gap-1">
502
+ <div class="grid grid-cols-3 gap-1">
481
503
  @for (option of layoutModeOptions; track option.value) {
482
504
  <button
483
505
  type="button"
@@ -506,7 +528,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
506
528
  <p class="text-[0.72rem] font-semibold uppercase tracking-[0.22em] text-muted-foreground">Width</p>
507
529
  </div>
508
530
  <div class="rounded-(--etos-layout-frame-radius) bg-muted/65 p-0.5">
509
- <div class="grid grid-cols-2 gap-1">
531
+ <div class="grid grid-cols-3 gap-1">
510
532
  @for (option of layoutWidthOptions; track option.value) {
511
533
  <button
512
534
  type="button"
@@ -560,281 +582,423 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
560
582
  </ng-template>
561
583
  `,
562
584
  }]
563
- }], propDecorators: { popoverTrigger: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], userInfo: [{ type: i0.Input, args: [{ isSignal: true, alias: "userInfo", required: false }] }], userName: [{ type: i0.Input, args: [{ isSignal: true, alias: "userName", required: false }] }], userSubtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "userSubtitle", required: false }] }], avatarSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarSrc", required: false }] }], avatarAlt: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarAlt", required: false }] }], quickActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickActions", required: true }] }], notificationShortcut: [{ type: i0.Input, args: [{ isSignal: true, alias: "notificationShortcut", required: false }] }], showNotificationShortcut: [{ type: i0.Input, args: [{ isSignal: true, alias: "showNotificationShortcut", required: false }] }], popoverSide: [{ type: i0.Input, args: [{ isSignal: true, alias: "popoverSide", required: false }] }], popoverAlign: [{ type: i0.Input, args: [{ isSignal: true, alias: "popoverAlign", required: false }] }], actionSelected: [{ type: i0.Output, args: ["actionSelected"] }] } });
585
+ }], propDecorators: { popoverTrigger: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], userInfo: [{ type: i0.Input, args: [{ isSignal: true, alias: "userInfo", required: false }] }], userName: [{ type: i0.Input, args: [{ isSignal: true, alias: "userName", required: false }] }], userSubtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "userSubtitle", required: false }] }], avatarSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarSrc", required: false }] }], avatarAlt: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarAlt", required: false }] }], quickActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickActions", required: true }] }], notificationShortcut: [{ type: i0.Input, args: [{ isSignal: true, alias: "notificationShortcut", required: false }] }], showNotificationShortcut: [{ type: i0.Input, args: [{ isSignal: true, alias: "showNotificationShortcut", required: false }] }], popoverSide: [{ type: i0.Input, args: [{ isSignal: true, alias: "popoverSide", required: false }] }], popoverAlign: [{ type: i0.Input, args: [{ isSignal: true, alias: "popoverAlign", required: false }] }], popoverSideOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "popoverSideOffset", required: false }] }], actionSelected: [{ type: i0.Output, args: ["actionSelected"] }] } });
586
+
587
+ class EmptyLayout {
588
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EmptyLayout, deps: [], target: i0.ɵɵFactoryTarget.Component });
589
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.11", type: EmptyLayout, isStandalone: true, selector: "empty", ngImport: i0, template: `
590
+ <div
591
+ class="h-dvh overflow-hidden bg-neutral-200 bg-[linear-gradient(rgba(212,212,212,0.45)_1px,transparent_1px),linear-gradient(to_right,rgba(212,212,212,0.45)_1px,transparent_1px)] bg-position-[center_center] bg-size-[2.775rem_2.775rem]">
592
+ <div class="relative isolate box-border h-full overflow-hidden py-3">
593
+ <div aria-hidden="true" class="pointer-events-none absolute inset-y-0 inset-x-0 px-3">
594
+ <div class="relative mx-auto h-full w-full">
595
+ <div class="absolute inset-y-0 left-0 w-px bg-brand"></div>
596
+ <div class="absolute inset-y-0 right-0 w-px bg-brand"></div>
597
+ </div>
598
+ </div>
564
599
 
565
- class EtosEmptyLayoutComponent {
566
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: EtosEmptyLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
567
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", type: EtosEmptyLayoutComponent, isStandalone: true, selector: "etos-empty-layout", host: { attributes: { "data-brand-layout": "etos-empty" }, classAttribute: "etos-layout-empty-host" }, ngImport: i0, template: `
568
- <main class="etos-layout-empty-main">
569
- <router-outlet />
570
- </main>
571
- `, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
600
+ <div class="h-full min-h-0 border border-brand px-3">
601
+ <main class="mx-auto w-full h-full min-h-0 overflow-y-auto bg-background/65">
602
+ <router-outlet />
603
+ </main>
604
+ </div>
605
+ </div>
606
+ </div>
607
+ `, isInline: true, styles: [""], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
572
608
  }
573
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: EtosEmptyLayoutComponent, decorators: [{
609
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EmptyLayout, decorators: [{
574
610
  type: Component,
575
- args: [{
576
- selector: 'etos-empty-layout',
577
- changeDetection: ChangeDetectionStrategy.OnPush,
578
- imports: [RouterOutlet],
579
- host: {
580
- class: 'etos-layout-empty-host',
581
- 'data-brand-layout': 'etos-empty',
582
- },
583
- template: `
584
- <main class="etos-layout-empty-main">
585
- <router-outlet />
586
- </main>
587
- `,
588
- }]
611
+ args: [{ selector: 'empty', imports: [RouterOutlet], template: `
612
+ <div
613
+ class="h-dvh overflow-hidden bg-neutral-200 bg-[linear-gradient(rgba(212,212,212,0.45)_1px,transparent_1px),linear-gradient(to_right,rgba(212,212,212,0.45)_1px,transparent_1px)] bg-position-[center_center] bg-size-[2.775rem_2.775rem]">
614
+ <div class="relative isolate box-border h-full overflow-hidden py-3">
615
+ <div aria-hidden="true" class="pointer-events-none absolute inset-y-0 inset-x-0 px-3">
616
+ <div class="relative mx-auto h-full w-full">
617
+ <div class="absolute inset-y-0 left-0 w-px bg-brand"></div>
618
+ <div class="absolute inset-y-0 right-0 w-px bg-brand"></div>
619
+ </div>
620
+ </div>
621
+
622
+ <div class="h-full min-h-0 border border-brand px-3">
623
+ <main class="mx-auto w-full h-full min-h-0 overflow-y-auto bg-background/65">
624
+ <router-outlet />
625
+ </main>
626
+ </div>
627
+ </div>
628
+ </div>
629
+ `, changeDetection: ChangeDetectionStrategy.OnPush }]
589
630
  }] });
590
631
 
591
- class EtosHorizontalLayoutComponent {
632
+ class HorizontalLayout {
592
633
  layout = inject(LayoutService);
593
- topbarAppearance = input('default', ...(ngDevMode ? [{ debugName: "topbarAppearance" }] : /* istanbul ignore next */ []));
594
- ariaLabel = input('Primary', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
595
- brandLayout = 'etos-horizontal';
634
+ brandTemplate = input(null, ...(ngDevMode ? [{ debugName: "brandTemplate" }] : /* istanbul ignore next */ []));
635
+ profileTemplate = input(null, ...(ngDevMode ? [{ debugName: "profileTemplate" }] : /* istanbul ignore next */ []));
596
636
  layoutWidth = this.layout.width;
597
- dividerBorderWidth = computed(() => 'var(--border-width)', ...(ngDevMode ? [{ debugName: "dividerBorderWidth" }] : /* istanbul ignore next */ []));
598
- hostClasses = computed(() => {
599
- const classes = ['etos-layout-host', 'etos-layout-host--horizontal'];
600
- if (this.layoutWidth() === 'fixed') {
601
- classes.push('etos-layout-host--fixed');
637
+ shellClasses = computed(() => {
638
+ switch (this.layoutWidth()) {
639
+ case 'full':
640
+ return 'relative isolate box-border h-dvh overflow-hidden py-3';
641
+ case 'wide':
642
+ return 'relative isolate box-border h-dvh overflow-hidden py-3 lg:py-10';
643
+ default:
644
+ return 'relative isolate box-border h-dvh overflow-hidden py-3 lg:py-20';
645
+ }
646
+ }, ...(ngDevMode ? [{ debugName: "shellClasses" }] : /* istanbul ignore next */ []));
647
+ railOverlayClasses = computed(() => {
648
+ const classes = ['pointer-events-none', 'absolute', 'inset-y-0', 'inset-x-0', 'z-20'];
649
+ if (this.layoutWidth() === 'full') {
650
+ classes.push('px-3');
651
+ }
652
+ else if (this.layoutWidth() === 'wide') {
653
+ classes.push('px-3', 'lg:px-10');
654
+ }
655
+ else {
656
+ classes.push('px-3', 'lg:px-10');
602
657
  }
603
658
  return classes.join(' ');
604
- }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
659
+ }, ...(ngDevMode ? [{ debugName: "railOverlayClasses" }] : /* istanbul ignore next */ []));
660
+ railGuideClasses = computed(() => this.layoutWidth() === 'container' ? 'relative mx-auto h-full w-full max-w-7xl' : 'relative mx-auto h-full w-full', ...(ngDevMode ? [{ debugName: "railGuideClasses" }] : /* istanbul ignore next */ []));
605
661
  frameClasses = computed(() => {
606
- const classes = ['etos-layout-frame', 'etos-layout-frame--horizontal'];
607
- if (this.layoutWidth() === 'fixed') {
608
- classes.push('etos-layout-frame--fixed');
662
+ const classes = ['relative', 'z-10', 'h-full', 'min-h-0', 'border', 'border-brand'];
663
+ if (this.layoutWidth() === 'full') {
664
+ classes.push('px-3');
665
+ }
666
+ else if (this.layoutWidth() === 'wide') {
667
+ classes.push('px-3', 'lg:px-10');
668
+ }
669
+ else {
670
+ classes.push('px-3', 'lg:px-10');
609
671
  }
610
672
  return classes.join(' ');
611
673
  }, ...(ngDevMode ? [{ debugName: "frameClasses" }] : /* istanbul ignore next */ []));
612
- mainClasses = computed(() => {
613
- const classes = ['etos-layout-main'];
674
+ maskClasses = computed(() => {
675
+ const classes = ['h-full', 'bg-position-[center_center]', 'bg-size-[2.775rem_2.775rem]'];
676
+ if (this.layoutWidth() === 'container') {
677
+ classes.unshift('mx-auto', 'w-full', 'max-w-7xl');
678
+ }
679
+ else {
680
+ classes.unshift('mx-auto', 'w-full');
681
+ }
682
+ return classes.join(' ');
683
+ }, ...(ngDevMode ? [{ debugName: "maskClasses" }] : /* istanbul ignore next */ []));
684
+ contentClasses = computed(() => {
685
+ const classes = [
686
+ 'relative',
687
+ 'z-20',
688
+ 'mx-auto',
689
+ 'flex',
690
+ 'h-full',
691
+ 'min-h-0',
692
+ 'flex-col',
693
+ 'overflow-hidden',
694
+ 'bg-background/65',
695
+ ];
696
+ if (this.layoutWidth() === 'container') {
697
+ classes.push('w-full', 'max-w-7xl');
698
+ }
699
+ else {
700
+ classes.push('w-full');
701
+ }
614
702
  return classes.join(' ');
615
- }, ...(ngDevMode ? [{ debugName: "mainClasses" }] : /* istanbul ignore next */ []));
616
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: EtosHorizontalLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
617
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: EtosHorizontalLayoutComponent, isStandalone: true, selector: "etos-horizontal-layout", 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-brand-layout": "brandLayout", "attr.data-layout-width": "layoutWidth()" } }, ngImport: i0, template: `
618
- <div [class]="frameClasses()">
619
- <ui-topbar
620
- class="etos-layout-topbar"
621
- [appearance]="topbarAppearance()"
622
- [ariaLabel]="ariaLabel()"
623
- [style.border-bottom-width]="dividerBorderWidth()">
624
- <div ui-topbar-start class="etos-layout-topbar-slot etos-layout-topbar-slot--start">
625
- <ng-content select="[ui-layout-brand],[ui-topbar-start]" />
703
+ }, ...(ngDevMode ? [{ debugName: "contentClasses" }] : /* istanbul ignore next */ []));
704
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: HorizontalLayout, deps: [], target: i0.ɵɵFactoryTarget.Component });
705
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: HorizontalLayout, isStandalone: true, selector: "horizontal", inputs: { brandTemplate: { classPropertyName: "brandTemplate", publicName: "brandTemplate", isSignal: true, isRequired: false, transformFunction: null }, profileTemplate: { classPropertyName: "profileTemplate", publicName: "profileTemplate", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-layout-width": "layoutWidth()" }, classAttribute: "block" }, ngImport: i0, template: `
706
+ <div
707
+ class="min-h-screen bg-neutral-200 text-neutral-600 bg-[linear-gradient(rgba(212,212,212,0.45)_1px,transparent_1px),linear-gradient(to_right,rgba(212,212,212,0.45)_1px,transparent_1px)] bg-position-[center_center] bg-size-[2.775rem_2.775rem]">
708
+ <div [class]="shellClasses()">
709
+ <div aria-hidden="true" [class]="railOverlayClasses()">
710
+ <div [class]="railGuideClasses()">
711
+ <div class="absolute inset-y-0 left-0 w-px bg-brand"></div>
712
+ <div class="absolute inset-y-0 right-0 w-px bg-brand"></div>
713
+ </div>
626
714
  </div>
627
- <div ui-topbar-end class="etos-layout-topbar-slot etos-layout-topbar-slot--end">
628
- <ng-content select="[ui-layout-profile],[ui-topbar-end]" />
715
+
716
+ <div [class]="frameClasses()">
717
+ <div aria-hidden="true" class="pointer-events-none absolute inset-0 z-0">
718
+ <div class="absolute inset-x-0 top-11 h-px bg-brand"></div>
719
+ <div class="absolute inset-x-0 bottom-11 h-px bg-brand"></div>
720
+ </div>
721
+ <div aria-hidden="true" class="pointer-events-none absolute inset-0 z-10">
722
+ <div [class]="maskClasses()"></div>
723
+ </div>
724
+ <div [class]="contentClasses()">
725
+ <nav class="shrink-0">
726
+ <topbar class="shrink-0" [showHamburger]="false">
727
+ @if (brandTemplate(); as brand) {
728
+ <div topbar-start class="min-w-0">
729
+ <ng-container [ngTemplateOutlet]="brand" />
730
+ </div>
731
+ }
732
+
733
+ @if (profileTemplate(); as profile) {
734
+ <div topbar-end class="flex min-w-0 items-center">
735
+ <ng-container [ngTemplateOutlet]="profile" />
736
+ </div>
737
+ }
738
+ </topbar>
739
+ </nav>
740
+ <main class="min-h-0 flex-1 overflow-auto">
741
+ <router-outlet />
742
+ </main>
743
+ </div>
629
744
  </div>
630
- </ui-topbar>
631
- <main [class]="mainClasses()">
632
- <router-outlet />
633
- </main>
745
+ </div>
634
746
  </div>
635
- `, 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 });
747
+ `, isInline: true, styles: [""], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { 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 });
636
748
  }
637
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: EtosHorizontalLayoutComponent, decorators: [{
749
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: HorizontalLayout, decorators: [{
638
750
  type: Component,
639
- args: [{
640
- selector: 'etos-horizontal-layout',
641
- changeDetection: ChangeDetectionStrategy.OnPush,
642
- imports: [RouterOutlet, TopbarComponent],
643
- host: {
644
- '[class]': 'hostClasses()',
645
- '[attr.data-brand-layout]': 'brandLayout',
751
+ args: [{ selector: 'horizontal', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet, RouterOutlet, TopbarComponent], host: {
752
+ class: 'block',
646
753
  '[attr.data-layout-width]': 'layoutWidth()',
647
- },
648
- template: `
649
- <div [class]="frameClasses()">
650
- <ui-topbar
651
- class="etos-layout-topbar"
652
- [appearance]="topbarAppearance()"
653
- [ariaLabel]="ariaLabel()"
654
- [style.border-bottom-width]="dividerBorderWidth()">
655
- <div ui-topbar-start class="etos-layout-topbar-slot etos-layout-topbar-slot--start">
656
- <ng-content select="[ui-layout-brand],[ui-topbar-start]" />
754
+ }, template: `
755
+ <div
756
+ class="min-h-screen bg-neutral-200 text-neutral-600 bg-[linear-gradient(rgba(212,212,212,0.45)_1px,transparent_1px),linear-gradient(to_right,rgba(212,212,212,0.45)_1px,transparent_1px)] bg-position-[center_center] bg-size-[2.775rem_2.775rem]">
757
+ <div [class]="shellClasses()">
758
+ <div aria-hidden="true" [class]="railOverlayClasses()">
759
+ <div [class]="railGuideClasses()">
760
+ <div class="absolute inset-y-0 left-0 w-px bg-brand"></div>
761
+ <div class="absolute inset-y-0 right-0 w-px bg-brand"></div>
762
+ </div>
657
763
  </div>
658
- <div ui-topbar-end class="etos-layout-topbar-slot etos-layout-topbar-slot--end">
659
- <ng-content select="[ui-layout-profile],[ui-topbar-end]" />
764
+
765
+ <div [class]="frameClasses()">
766
+ <div aria-hidden="true" class="pointer-events-none absolute inset-0 z-0">
767
+ <div class="absolute inset-x-0 top-11 h-px bg-brand"></div>
768
+ <div class="absolute inset-x-0 bottom-11 h-px bg-brand"></div>
769
+ </div>
770
+ <div aria-hidden="true" class="pointer-events-none absolute inset-0 z-10">
771
+ <div [class]="maskClasses()"></div>
772
+ </div>
773
+ <div [class]="contentClasses()">
774
+ <nav class="shrink-0">
775
+ <topbar class="shrink-0" [showHamburger]="false">
776
+ @if (brandTemplate(); as brand) {
777
+ <div topbar-start class="min-w-0">
778
+ <ng-container [ngTemplateOutlet]="brand" />
779
+ </div>
780
+ }
781
+
782
+ @if (profileTemplate(); as profile) {
783
+ <div topbar-end class="flex min-w-0 items-center">
784
+ <ng-container [ngTemplateOutlet]="profile" />
785
+ </div>
786
+ }
787
+ </topbar>
788
+ </nav>
789
+ <main class="min-h-0 flex-1 overflow-auto">
790
+ <router-outlet />
791
+ </main>
792
+ </div>
660
793
  </div>
661
- </ui-topbar>
662
- <main [class]="mainClasses()">
663
- <router-outlet />
664
- </main>
794
+ </div>
665
795
  </div>
666
- `,
667
- }]
668
- }], propDecorators: { topbarAppearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "topbarAppearance", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
796
+ ` }]
797
+ }], propDecorators: { brandTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "brandTemplate", required: false }] }], profileTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "profileTemplate", required: false }] }] } });
669
798
 
670
- class EtosVerticalLayoutComponent {
799
+ class VerticalLayout {
671
800
  layout = inject(LayoutService);
672
801
  sidebarAppearance = input('default', ...(ngDevMode ? [{ debugName: "sidebarAppearance" }] : /* istanbul ignore next */ []));
673
802
  sidebarPosition = input('left', ...(ngDevMode ? [{ debugName: "sidebarPosition" }] : /* istanbul ignore next */ []));
674
803
  ariaLabel = input('Primary', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
675
- brandLayout = 'etos-vertical';
804
+ sidebarHeaderTemplate = input(null, ...(ngDevMode ? [{ debugName: "sidebarHeaderTemplate" }] : /* istanbul ignore next */ []));
805
+ sidebarFooterTemplate = input(null, ...(ngDevMode ? [{ debugName: "sidebarFooterTemplate" }] : /* istanbul ignore next */ []));
676
806
  layoutWidth = this.layout.width;
677
- dividerBorderWidth = computed(() => 'var(--border-width)', ...(ngDevMode ? [{ debugName: "dividerBorderWidth" }] : /* istanbul ignore next */ []));
678
- hostClasses = computed(() => {
679
- const classes = ['etos-layout-host', 'etos-layout-host--vertical'];
680
- if (this.layoutWidth() === 'fixed') {
681
- classes.push('etos-layout-host--fixed');
682
- }
683
- return classes.join(' ');
684
- }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
685
- frameClasses = computed(() => {
686
- const classes = ['etos-layout-frame', 'etos-layout-frame--vertical'];
687
- if (this.layoutWidth() === 'fixed') {
688
- classes.push('etos-layout-frame--fixed', 'etos-layout-frame--vertical-fixed');
807
+ shellClasses = computed(() => {
808
+ switch (this.layoutWidth()) {
809
+ case 'full':
810
+ return 'relative isolate h-full overflow-hidden py-2';
811
+ case 'wide':
812
+ return 'relative isolate h-full overflow-hidden py-2 lg:py-10';
813
+ default:
814
+ return 'relative isolate h-full overflow-hidden py-2 lg:py-18';
689
815
  }
690
- return classes.join(' ');
691
- }, ...(ngDevMode ? [{ debugName: "frameClasses" }] : /* istanbul ignore next */ []));
692
- mainClasses = computed(() => {
693
- const classes = ['etos-layout-main'];
694
- if (this.layoutWidth() === 'fixed') {
695
- classes.push('etos-layout-main--fixed', 'etos-layout-main--vertical-fixed');
816
+ }, ...(ngDevMode ? [{ debugName: "shellClasses" }] : /* istanbul ignore next */ []));
817
+ gridClasses = computed(() => {
818
+ switch (this.layoutWidth()) {
819
+ case 'full':
820
+ return 'relative mx-auto grid h-full w-fit max-w-full grid-cols-[auto_minmax(0,100rem)] items-stretch bg-background/65';
821
+ case 'wide':
822
+ return 'relative mx-auto grid h-full w-fit max-w-full grid-cols-[auto_minmax(0,100rem)] items-stretch bg-background/65 lg:grid-cols-[auto_minmax(0,96rem)]';
823
+ default:
824
+ return 'relative mx-auto grid h-full w-fit max-w-full grid-cols-[auto_minmax(0,100rem)] items-stretch bg-background/65 lg:grid-cols-[auto_minmax(0,80rem)]';
696
825
  }
697
- return classes.join(' ');
698
- }, ...(ngDevMode ? [{ debugName: "mainClasses" }] : /* istanbul ignore next */ []));
699
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: EtosVerticalLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
700
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.9", type: EtosVerticalLayoutComponent, isStandalone: true, selector: "etos-vertical-layout", inputs: { sidebarAppearance: { classPropertyName: "sidebarAppearance", publicName: "sidebarAppearance", isSignal: true, isRequired: false, transformFunction: null }, sidebarPosition: { classPropertyName: "sidebarPosition", publicName: "sidebarPosition", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()", "attr.data-brand-layout": "brandLayout", "attr.data-layout-width": "layoutWidth()" } }, ngImport: i0, template: `
701
- <div [class]="frameClasses()">
702
- <ui-sidebar
703
- class="etos-layout-sidebar"
704
- [appearance]="sidebarAppearance()"
705
- [position]="sidebarPosition()"
706
- [ariaLabel]="ariaLabel()"
707
- [style.border-left-width]="dividerBorderWidth()"
708
- [style.border-right-width]="dividerBorderWidth()">
709
- <div ui-sidebar-header class="flex h-full w-full min-w-0 items-center">
710
- <ng-content select="[ui-layout-brand],[ui-topbar-start],[ui-sidebar-header]" />
711
- </div>
712
-
713
- <div ui-sidebar-footer class="flex h-full w-full min-w-0 items-center justify-between gap-3 px-3">
714
- <ng-content select="[ui-layout-profile],[ui-topbar-end],[ui-sidebar-footer]" />
826
+ }, ...(ngDevMode ? [{ debugName: "gridClasses" }] : /* istanbul ignore next */ []));
827
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: VerticalLayout, deps: [], target: i0.ɵɵFactoryTarget.Component });
828
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: VerticalLayout, 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 }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, sidebarHeaderTemplate: { classPropertyName: "sidebarHeaderTemplate", publicName: "sidebarHeaderTemplate", isSignal: true, isRequired: false, transformFunction: null }, sidebarFooterTemplate: { classPropertyName: "sidebarFooterTemplate", publicName: "sidebarFooterTemplate", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-layout-width": "layoutWidth()" }, classAttribute: "block h-dvh overflow-hidden" }, ngImport: i0, template: `
829
+ <!-- prettier-ignore -->
830
+ <div class="h-full overflow-hidden bg-neutral-200 bg-[linear-gradient(rgba(212,212,212,0.65)_1px,transparent_1px),linear-gradient(to_right,rgba(212,212,212,0.65)_1px,transparent_1px)] bg-position-[center_center] bg-size-[2.775rem_2.775rem]">
831
+ <div [class]="shellClasses()">
832
+ <div class="-mx-18 relative h-full border-y border-brand">
833
+ <div aria-hidden="true" class="pointer-events-none absolute inset-x-0 inset-y-8">
834
+ <div class="absolute inset-x-0 top-3.75 h-px bg-brand"></div>
835
+ <div class="absolute inset-x-0 bottom-3.75 h-px bg-brand"></div>
836
+ </div>
837
+ <div class="h-full px-20">
838
+ <div [class]="gridClasses()">
839
+ <div
840
+ aria-hidden="true"
841
+ class="pointer-events-none absolute bottom-[-100vh] left-0 top-[-100vh] z-20 w-px bg-brand"></div>
842
+ <div
843
+ aria-hidden="true"
844
+ class="pointer-events-none absolute bottom-[-100vh] right-0 top-[-100vh] z-20 w-px bg-brand"></div>
845
+ <nav class="relative h-full min-h-0 shrink-0 overflow-visible border-r border-brand">
846
+ <div
847
+ aria-hidden="true"
848
+ class="pointer-events-none absolute bottom-[-100vh] left-full top-[-100vh] -z-10 w-px bg-brand"></div>
849
+ <sidebar
850
+ class="h-full"
851
+ [appearance]="sidebarAppearance()"
852
+ [position]="sidebarPosition()"
853
+ [ariaLabel]="ariaLabel()">
854
+ @if (sidebarHeaderTemplate(); as headerTemplate) {
855
+ <div sidebar-header class="contents">
856
+ <ng-container [ngTemplateOutlet]="headerTemplate" />
857
+ </div>
858
+ }
859
+ @if (sidebarFooterTemplate(); as footerTemplate) {
860
+ <div sidebar-footer class="contents">
861
+ <ng-container [ngTemplateOutlet]="footerTemplate" />
862
+ </div>
863
+ }
864
+ </sidebar>
865
+ </nav>
866
+ <main class="relative min-w-0 overflow-y-auto">
867
+ <router-outlet />
868
+ <div class="pointer-events-none absolute right-4 top-4 z-30">
869
+ <div
870
+ class="inline-flex min-w-20 items-center justify-center rounded-full border border-brand bg-white/85 px-3 py-1 text-[0.68rem] font-semibold uppercase tracking-[0.18em] text-foreground shadow-sm backdrop-blur-sm"
871
+ aria-label="Current breakpoint identifier">
872
+ <span class="sm:hidden">mobile</span>
873
+ <span class="hidden sm:inline md:hidden">sm</span>
874
+ <span class="hidden md:inline lg:hidden">md</span>
875
+ <span class="hidden lg:inline">lg</span>
876
+ </div>
877
+ </div>
878
+ </main>
879
+ </div>
880
+ </div>
715
881
  </div>
716
- </ui-sidebar>
717
- <main [class]="mainClasses()">
718
- <router-outlet />
719
- </main>
882
+ </div>
720
883
  </div>
721
- `, 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 });
884
+ `, isInline: true, styles: [""], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { 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 });
722
885
  }
723
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: EtosVerticalLayoutComponent, decorators: [{
886
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: VerticalLayout, decorators: [{
724
887
  type: Component,
725
- args: [{
726
- selector: 'etos-vertical-layout',
727
- changeDetection: ChangeDetectionStrategy.OnPush,
728
- imports: [RouterOutlet, SidebarComponent],
729
- host: {
730
- '[class]': 'hostClasses()',
731
- '[attr.data-brand-layout]': 'brandLayout',
888
+ args: [{ selector: 'vertical', imports: [NgTemplateOutlet, RouterOutlet, SidebarComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
889
+ class: 'block h-dvh overflow-hidden',
732
890
  '[attr.data-layout-width]': 'layoutWidth()',
733
- },
734
- template: `
735
- <div [class]="frameClasses()">
736
- <ui-sidebar
737
- class="etos-layout-sidebar"
738
- [appearance]="sidebarAppearance()"
739
- [position]="sidebarPosition()"
740
- [ariaLabel]="ariaLabel()"
741
- [style.border-left-width]="dividerBorderWidth()"
742
- [style.border-right-width]="dividerBorderWidth()">
743
- <div ui-sidebar-header class="flex h-full w-full min-w-0 items-center">
744
- <ng-content select="[ui-layout-brand],[ui-topbar-start],[ui-sidebar-header]" />
745
- </div>
746
-
747
- <div ui-sidebar-footer class="flex h-full w-full min-w-0 items-center justify-between gap-3 px-3">
748
- <ng-content select="[ui-layout-profile],[ui-topbar-end],[ui-sidebar-footer]" />
891
+ }, template: `
892
+ <!-- prettier-ignore -->
893
+ <div class="h-full overflow-hidden bg-neutral-200 bg-[linear-gradient(rgba(212,212,212,0.65)_1px,transparent_1px),linear-gradient(to_right,rgba(212,212,212,0.65)_1px,transparent_1px)] bg-position-[center_center] bg-size-[2.775rem_2.775rem]">
894
+ <div [class]="shellClasses()">
895
+ <div class="-mx-18 relative h-full border-y border-brand">
896
+ <div aria-hidden="true" class="pointer-events-none absolute inset-x-0 inset-y-8">
897
+ <div class="absolute inset-x-0 top-3.75 h-px bg-brand"></div>
898
+ <div class="absolute inset-x-0 bottom-3.75 h-px bg-brand"></div>
899
+ </div>
900
+ <div class="h-full px-20">
901
+ <div [class]="gridClasses()">
902
+ <div
903
+ aria-hidden="true"
904
+ class="pointer-events-none absolute bottom-[-100vh] left-0 top-[-100vh] z-20 w-px bg-brand"></div>
905
+ <div
906
+ aria-hidden="true"
907
+ class="pointer-events-none absolute bottom-[-100vh] right-0 top-[-100vh] z-20 w-px bg-brand"></div>
908
+ <nav class="relative h-full min-h-0 shrink-0 overflow-visible border-r border-brand">
909
+ <div
910
+ aria-hidden="true"
911
+ class="pointer-events-none absolute bottom-[-100vh] left-full top-[-100vh] -z-10 w-px bg-brand"></div>
912
+ <sidebar
913
+ class="h-full"
914
+ [appearance]="sidebarAppearance()"
915
+ [position]="sidebarPosition()"
916
+ [ariaLabel]="ariaLabel()">
917
+ @if (sidebarHeaderTemplate(); as headerTemplate) {
918
+ <div sidebar-header class="contents">
919
+ <ng-container [ngTemplateOutlet]="headerTemplate" />
920
+ </div>
921
+ }
922
+ @if (sidebarFooterTemplate(); as footerTemplate) {
923
+ <div sidebar-footer class="contents">
924
+ <ng-container [ngTemplateOutlet]="footerTemplate" />
925
+ </div>
926
+ }
927
+ </sidebar>
928
+ </nav>
929
+ <main class="relative min-w-0 overflow-y-auto">
930
+ <router-outlet />
931
+ <div class="pointer-events-none absolute right-4 top-4 z-30">
932
+ <div
933
+ class="inline-flex min-w-20 items-center justify-center rounded-full border border-brand bg-white/85 px-3 py-1 text-[0.68rem] font-semibold uppercase tracking-[0.18em] text-foreground shadow-sm backdrop-blur-sm"
934
+ aria-label="Current breakpoint identifier">
935
+ <span class="sm:hidden">mobile</span>
936
+ <span class="hidden sm:inline md:hidden">sm</span>
937
+ <span class="hidden md:inline lg:hidden">md</span>
938
+ <span class="hidden lg:inline">lg</span>
939
+ </div>
940
+ </div>
941
+ </main>
942
+ </div>
943
+ </div>
749
944
  </div>
750
- </ui-sidebar>
751
- <main [class]="mainClasses()">
752
- <router-outlet />
753
- </main>
945
+ </div>
754
946
  </div>
755
- `,
756
- }]
757
- }], propDecorators: { sidebarAppearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarAppearance", required: false }] }], sidebarPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarPosition", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
947
+ ` }]
948
+ }], propDecorators: { sidebarAppearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarAppearance", required: false }] }], sidebarPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarPosition", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], sidebarHeaderTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarHeaderTemplate", required: false }] }], sidebarFooterTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarFooterTemplate", required: false }] }] } });
758
949
 
759
950
  class EtosLayoutComponent {
951
+ mode = input(null, ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
952
+ sidebarHeaderTemplate = input(null, ...(ngDevMode ? [{ debugName: "sidebarHeaderTemplate" }] : /* istanbul ignore next */ []));
953
+ sidebarFooterTemplate = input(null, ...(ngDevMode ? [{ debugName: "sidebarFooterTemplate" }] : /* istanbul ignore next */ []));
954
+ layoutBrandTemplate = input(null, ...(ngDevMode ? [{ debugName: "layoutBrandTemplate" }] : /* istanbul ignore next */ []));
955
+ layoutProfileTemplate = input(null, ...(ngDevMode ? [{ debugName: "layoutProfileTemplate" }] : /* istanbul ignore next */ []));
760
956
  layout = inject(LayoutService);
761
- ariaLabel = input('Primary', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
762
- layoutMode = this.layout.mode;
763
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: EtosLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
764
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: EtosLayoutComponent, isStandalone: true, selector: "etos-layout", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "contents" }, ngImport: i0, template: `
765
- @switch (layoutMode()) {
957
+ resolvedMode = computed(() => this.mode() ?? this.layout.mode(), ...(ngDevMode ? [{ debugName: "resolvedMode" }] : /* istanbul ignore next */ []));
958
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EtosLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
959
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.11", type: EtosLayoutComponent, isStandalone: true, selector: "etos-layout", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, sidebarHeaderTemplate: { classPropertyName: "sidebarHeaderTemplate", publicName: "sidebarHeaderTemplate", isSignal: true, isRequired: false, transformFunction: null }, sidebarFooterTemplate: { classPropertyName: "sidebarFooterTemplate", publicName: "sidebarFooterTemplate", isSignal: true, isRequired: false, transformFunction: null }, layoutBrandTemplate: { classPropertyName: "layoutBrandTemplate", publicName: "layoutBrandTemplate", isSignal: true, isRequired: false, transformFunction: null }, layoutProfileTemplate: { classPropertyName: "layoutProfileTemplate", publicName: "layoutProfileTemplate", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-layout-mode": "resolvedMode()" }, classAttribute: "contents" }, ngImport: i0, template: `
960
+ @switch (resolvedMode()) {
961
+ @case ('empty') {
962
+ <empty />
963
+ }
766
964
  @case ('horizontal') {
767
- <etos-horizontal-layout [ariaLabel]="ariaLabel()">
768
- <ng-content select="[ui-layout-brand],[ui-topbar-start]" />
769
- <ng-content select="[ui-layout-profile],[ui-topbar-end]" />
770
- </etos-horizontal-layout>
965
+ <horizontal [brandTemplate]="layoutBrandTemplate()" [profileTemplate]="layoutProfileTemplate()" />
771
966
  }
772
967
  @default {
773
- <etos-vertical-layout [ariaLabel]="ariaLabel()" />
968
+ <vertical
969
+ [sidebarHeaderTemplate]="sidebarHeaderTemplate() ?? layoutBrandTemplate()"
970
+ [sidebarFooterTemplate]="sidebarFooterTemplate() ?? layoutProfileTemplate()" />
774
971
  }
775
972
  }
776
- `, isInline: true, dependencies: [{ kind: "component", type: EtosHorizontalLayoutComponent, selector: "etos-horizontal-layout", inputs: ["topbarAppearance", "ariaLabel"] }, { kind: "component", type: EtosVerticalLayoutComponent, selector: "etos-vertical-layout", inputs: ["sidebarAppearance", "sidebarPosition", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
973
+ `, isInline: true, dependencies: [{ kind: "component", type: EmptyLayout, selector: "empty" }, { kind: "component", type: HorizontalLayout, selector: "horizontal", inputs: ["brandTemplate", "profileTemplate"] }, { kind: "component", type: VerticalLayout, selector: "vertical", inputs: ["sidebarAppearance", "sidebarPosition", "ariaLabel", "sidebarHeaderTemplate", "sidebarFooterTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
777
974
  }
778
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: EtosLayoutComponent, decorators: [{
975
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: EtosLayoutComponent, decorators: [{
779
976
  type: Component,
780
977
  args: [{
781
978
  selector: 'etos-layout',
782
979
  changeDetection: ChangeDetectionStrategy.OnPush,
783
- imports: [EtosHorizontalLayoutComponent, EtosVerticalLayoutComponent],
980
+ imports: [EmptyLayout, HorizontalLayout, VerticalLayout],
784
981
  host: {
785
982
  class: 'contents',
983
+ '[attr.data-layout-mode]': 'resolvedMode()',
786
984
  },
787
985
  template: `
788
- @switch (layoutMode()) {
986
+ @switch (resolvedMode()) {
987
+ @case ('empty') {
988
+ <empty />
989
+ }
789
990
  @case ('horizontal') {
790
- <etos-horizontal-layout [ariaLabel]="ariaLabel()">
791
- <ng-content select="[ui-layout-brand],[ui-topbar-start]" />
792
- <ng-content select="[ui-layout-profile],[ui-topbar-end]" />
793
- </etos-horizontal-layout>
991
+ <horizontal [brandTemplate]="layoutBrandTemplate()" [profileTemplate]="layoutProfileTemplate()" />
794
992
  }
795
993
  @default {
796
- <etos-vertical-layout [ariaLabel]="ariaLabel()" />
994
+ <vertical
995
+ [sidebarHeaderTemplate]="sidebarHeaderTemplate() ?? layoutBrandTemplate()"
996
+ [sidebarFooterTemplate]="sidebarFooterTemplate() ?? layoutProfileTemplate()" />
797
997
  }
798
998
  }
799
999
  `,
800
1000
  }]
801
- }], propDecorators: { ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
802
-
803
- class EtosAppShellComponent {
804
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: EtosAppShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
805
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", type: EtosAppShellComponent, isStandalone: true, selector: "etos-app-shell", host: { classAttribute: "flex h-full min-h-0 flex-col" }, ngImport: i0, template: `
806
- <header class="flex h-12 shrink-0 items-center border-b border-border bg-card px-4">
807
- <ng-content select="[etos-app-shell-header]" />
808
- </header>
809
- <main class="min-h-0 flex-1 overflow-auto">
810
- <ng-content select="[etos-app-shell-main]" />
811
- </main>
812
- <footer class="flex h-12 shrink-0 items-center border-t border-border bg-card px-4">
813
- <ng-content select="[etos-app-shell-footer]" />
814
- </footer>
815
- `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
816
- }
817
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: EtosAppShellComponent, decorators: [{
818
- type: Component,
819
- args: [{
820
- selector: 'etos-app-shell',
821
- host: {
822
- class: 'flex h-full min-h-0 flex-col',
823
- },
824
- template: `
825
- <header class="flex h-12 shrink-0 items-center border-b border-border bg-card px-4">
826
- <ng-content select="[etos-app-shell-header]" />
827
- </header>
828
- <main class="min-h-0 flex-1 overflow-auto">
829
- <ng-content select="[etos-app-shell-main]" />
830
- </main>
831
- <footer class="flex h-12 shrink-0 items-center border-t border-border bg-card px-4">
832
- <ng-content select="[etos-app-shell-footer]" />
833
- </footer>
834
- `,
835
- changeDetection: ChangeDetectionStrategy.OnPush,
836
- }]
837
- }] });
1001
+ }], propDecorators: { mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], sidebarHeaderTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarHeaderTemplate", required: false }] }], sidebarFooterTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarFooterTemplate", required: false }] }], layoutBrandTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "layoutBrandTemplate", required: false }] }], layoutProfileTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "layoutProfileTemplate", required: false }] }] } });
838
1002
 
839
1003
  /*
840
1004
  * Public API Surface of @ojiepermana/angular/etos
@@ -847,5 +1011,5 @@ const ETOS_BRAND_VERSION = '0.0.1';
847
1011
  * Generated bundle index. Do not edit.
848
1012
  */
849
1013
 
850
- export { ETOS_BRAND_NAME, ETOS_BRAND_VERSION, ETOS_LAYOUT_CONFIG, ETOS_THEME_CONFIG, EtosAppShellComponent, EtosEmptyLayoutComponent, EtosHorizontalLayoutComponent, EtosLayoutComponent, EtosThemeSwitcherComponent, EtosVerticalLayoutComponent, provideEtosBrand, provideEtosLayout, provideEtosTheme };
1014
+ export { ETOS_BRAND_NAME, ETOS_BRAND_VERSION, ETOS_LAYOUT_CONFIG, ETOS_THEME_CONFIG, EtosLayoutComponent, EtosThemeSwitcherComponent, provideEtosBrand, provideEtosLayout, provideEtosTheme };
851
1015
  //# sourceMappingURL=ojiepermana-angular-brand-etos.mjs.map