@flusys/ng-layout 6.3.0 → 6.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +152 -11
  2. package/assets/layout/base/_brand.scss +44 -0
  3. package/assets/layout/{_core.scss → base/_core.scss} +8 -1
  4. package/assets/layout/{_footer.scss → base/_footer.scss} +1 -1
  5. package/assets/layout/{_forms.scss → base/_forms.scss} +3 -3
  6. package/assets/layout/base/_menu.scss +52 -0
  7. package/assets/layout/base/_rtl.scss +230 -0
  8. package/assets/layout/base/_topbar.scss +132 -0
  9. package/assets/layout/base/variables/_common.scss +62 -0
  10. package/assets/layout/classic/_main.scss +14 -0
  11. package/assets/layout/classic/_menu.scss +77 -0
  12. package/assets/layout/classic/_responsive.scss +95 -0
  13. package/assets/layout/classic/_rtl.scss +26 -0
  14. package/assets/layout/classic/_topbar.scss +53 -0
  15. package/assets/layout/{_topbar_nav.scss → classic/_topbar_nav.scss} +45 -17
  16. package/assets/layout/classic/classic.scss +6 -0
  17. package/assets/layout/layout.scss +18 -16
  18. package/assets/layout/modern/_menu.scss +98 -0
  19. package/assets/layout/modern/_responsive.scss +93 -0
  20. package/assets/layout/modern/_rtl.scss +24 -0
  21. package/assets/layout/modern/_shell.scss +59 -0
  22. package/assets/layout/modern/_sidebar.scss +101 -0
  23. package/assets/layout/modern/_topbar.scss +37 -0
  24. package/assets/layout/modern/_variables.scss +114 -0
  25. package/assets/layout/modern/modern.scss +7 -0
  26. package/fesm2022/flusys-ng-layout.mjs +1353 -954
  27. package/fesm2022/flusys-ng-layout.mjs.map +1 -1
  28. package/package.json +4 -4
  29. package/types/flusys-ng-layout.d.ts +175 -65
  30. package/assets/layout/_main.scss +0 -13
  31. package/assets/layout/_menu.scss +0 -188
  32. package/assets/layout/_responsive.scss +0 -128
  33. package/assets/layout/_rtl.scss +0 -482
  34. package/assets/layout/_topbar.scss +0 -215
  35. package/assets/layout/variables/_common.scss +0 -20
  36. /package/assets/layout/{_mixins.scss → base/_mixins.scss} +0 -0
  37. /package/assets/layout/{_preloading.scss → base/_preloading.scss} +0 -0
  38. /package/assets/layout/{_typography.scss → base/_typography.scss} +0 -0
  39. /package/assets/layout/{_utils.scss → base/_utils.scss} +0 -0
  40. /package/assets/layout/{variables → base/variables}/_dark.scss +0 -0
  41. /package/assets/layout/{variables → base/variables}/_light.scss +0 -0
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@flusys/ng-layout",
3
- "version": "6.3.0",
3
+ "version": "6.4.1",
4
4
  "description": "Layout components for FLUSYS Angular applications",
5
5
  "license": "MIT",
6
6
  "peerDependencies": {
7
7
  "@angular/common": ">=22.0.0",
8
8
  "@angular/core": ">=22.0.0",
9
9
  "@angular/router": ">=22.0.0",
10
- "@flusys/ng-core": ">=6.3.0",
11
- "@flusys/ng-shared": ">=6.3.0",
12
- "@flusys/ng-ui": ">=6.3.0",
10
+ "@flusys/ng-core": ">=6.4.1",
11
+ "@flusys/ng-shared": ">=6.4.1",
12
+ "@flusys/ng-ui": ">=6.4.1",
13
13
  "tailwindcss": ">=4.0.0",
14
14
  "rxjs": "^7.8.0"
15
15
  },
@@ -1,24 +1,13 @@
1
+ import * as rxjs from 'rxjs';
2
+ import { Observable } from 'rxjs';
1
3
  import * as _angular_core from '@angular/core';
2
4
  import { Signal, InjectionToken, Type } from '@angular/core';
5
+ import { LayoutConfig, LayoutTheme } from '@flusys/ng-core';
6
+ import { ILogicNode, IconTypeEnum } from '@flusys/ng-shared';
3
7
  import { PresetName, ApplyThemeOptions } from '@flusys/ng-ui';
4
8
  export { ApplyThemeOptions, applyTheme, buildBootstrapPreset } from '@flusys/ng-ui';
5
- import * as rxjs from 'rxjs';
6
- import { Observable } from 'rxjs';
7
- import { LayoutConfig } from '@flusys/ng-core';
8
- import { ILogicNode, IconTypeEnum } from '@flusys/ng-shared';
9
9
  import * as _flusys_ng_layout from '@flusys/ng-layout';
10
10
 
11
- declare class AppFooter {
12
- private readonly layoutService;
13
- readonly appName: string;
14
- readonly displayLogo: string;
15
- readonly isLogoSvg: boolean;
16
- readonly authorName: string;
17
- readonly authorUrl: string;
18
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<AppFooter, never>;
19
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AppFooter, "app-footer", never, {}, {}, never, never, true, never>;
20
- }
21
-
22
11
  interface ILauncherApp {
23
12
  id: string;
24
13
  /** Display name (use nameKey for localization instead) */
@@ -107,7 +96,6 @@ interface LayoutState {
107
96
  configSidebarVisible?: boolean;
108
97
  staticMenuMobileActive?: boolean;
109
98
  menuHoverActive?: boolean;
110
- topbarMenuVisible?: boolean;
111
99
  }
112
100
  interface MenuChangeEvent {
113
101
  key: string;
@@ -162,6 +150,10 @@ declare class LayoutService {
162
150
  readonly isMobile: _angular_core.Signal<boolean>;
163
151
  readonly isDarkTheme: _angular_core.Signal<boolean | undefined>;
164
152
  readonly isOverlay: _angular_core.Signal<boolean>;
153
+ readonly layoutTheme: _angular_core.Signal<LayoutTheme>;
154
+ readonly isModernLayout: _angular_core.Signal<boolean>;
155
+ readonly isClassicLayout: _angular_core.Signal<boolean>;
156
+ /** The modern skin has no horizontal nav, so topbar mode only applies to the classic skin. */
165
157
  readonly isTopbar: _angular_core.Signal<boolean>;
166
158
  readonly userName: _angular_core.Signal<string>;
167
159
  readonly userEmail: _angular_core.Signal<string>;
@@ -178,6 +170,7 @@ declare class LayoutService {
178
170
  readonly resetSource$: rxjs.Observable<boolean>;
179
171
  readonly overlayOpen$: rxjs.Observable<void>;
180
172
  private initialized;
173
+ private appliedDarkTheme;
181
174
  constructor();
182
175
  toggleDarkMode(config?: LayoutConfig): void;
183
176
  private handleDarkModeTransition;
@@ -200,16 +193,42 @@ declare class LayoutService {
200
193
  declare class LayoutPersistenceService {
201
194
  private readonly platformId;
202
195
  private readonly isBrowser;
203
- private readonly validPresets;
204
- private readonly validMenuModes;
205
196
  load(): LayoutConfig | null;
206
197
  save(config: LayoutConfig): void;
207
198
  clear(): void;
199
+ /**
200
+ * Coerces a stored value only when it is present and unrecognised. A field the
201
+ * user never changed stays absent so the app's own default still wins when this
202
+ * result is merged over it.
203
+ */
208
204
  private validateConfig;
209
205
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<LayoutPersistenceService, never>;
210
206
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<LayoutPersistenceService>;
211
207
  }
212
208
 
209
+ /**
210
+ * Layout shell entry point.
211
+ * Renders the skin selected by `LayoutConfig.layoutTheme` — every skin shares
212
+ * the same services, menu and topbar components, only the markup and styling differ.
213
+ */
214
+ declare class AppLayout {
215
+ readonly layoutService: LayoutService;
216
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<AppLayout, never>;
217
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AppLayout, "app-layout", never, {}, {}, never, never, true, never>;
218
+ }
219
+
220
+ /**
221
+ * Home link showing the active company logo and name.
222
+ * Every skin renders this same markup; sizing and colour come from the bar it sits in.
223
+ */
224
+ declare class AppBrandLogo {
225
+ readonly layoutService: LayoutService;
226
+ readonly companyName: _angular_core.Signal<string>;
227
+ readonly displayLogo: _angular_core.Signal<string>;
228
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<AppBrandLogo, never>;
229
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AppBrandLogo, "app-brand-logo", never, {}, {}, never, never, true, never>;
230
+ }
231
+
213
232
  declare type SurfacesType = {
214
233
  name?: string;
215
234
  palette?: {
@@ -238,6 +257,10 @@ declare class AppConfigurator {
238
257
  label: string;
239
258
  value: "static" | "overlay" | "topbar";
240
259
  }[]>;
260
+ readonly layoutThemeOptions: _angular_core.Signal<{
261
+ label: string;
262
+ value: LayoutTheme;
263
+ }[]>;
241
264
  constructor();
242
265
  readonly surfaces: SurfacesType[];
243
266
  readonly selectedPrimaryColor: _angular_core.Signal<string | undefined>;
@@ -245,11 +268,13 @@ declare class AppConfigurator {
245
268
  isSurfaceSelected(surfaceName: string | undefined): boolean;
246
269
  readonly selectedPreset: _angular_core.Signal<string | undefined>;
247
270
  readonly menuMode: _angular_core.Signal<"static" | "overlay" | "topbar" | undefined>;
271
+ readonly layoutTheme: _angular_core.Signal<LayoutTheme>;
248
272
  readonly primaryColors: _angular_core.Signal<SurfacesType[]>;
249
273
  updateColors(event: MouseEvent, type: string, color: SurfacesType): void;
250
274
  private _applyColorChange;
251
275
  onPresetChange(event: string): void;
252
276
  onMenuModeChange(event: 'static' | 'overlay' | 'topbar'): void;
277
+ onLayoutThemeChange(event: LayoutTheme): void;
253
278
  private translate;
254
279
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AppConfigurator, never>;
255
280
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<AppConfigurator, "app-configurator", never, {}, {}, never, never, true, never>;
@@ -264,27 +289,15 @@ declare class AppFloatingConfigurator {
264
289
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<AppFloatingConfigurator, "app-floating-configurator", never, {}, {}, never, never, true, never>;
265
290
  }
266
291
 
267
- declare class AppLayout {
268
- private readonly destroyRef;
269
- private readonly document;
270
- readonly layoutService: LayoutService;
271
- private readonly renderer;
272
- private readonly router;
273
- private menuOutsideClickListener;
274
- constructor();
275
- isOutsideClicked(event: MouseEvent): boolean;
276
- hideMenu(): void;
277
- blockBodyScroll(): void;
278
- unblockBodyScroll(): void;
279
- readonly isOverlay: _angular_core.Signal<boolean>;
280
- readonly isStatic: _angular_core.Signal<boolean>;
281
- readonly isTopbarMode: _angular_core.Signal<boolean>;
282
- readonly isStaticInactive: _angular_core.Signal<boolean | undefined>;
283
- readonly isOverlayActive: _angular_core.Signal<boolean | undefined>;
284
- readonly isMobileActive: _angular_core.Signal<boolean | undefined>;
285
- readonly isTopbarNavHidden: _angular_core.Signal<boolean>;
286
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<AppLayout, never>;
287
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AppLayout, "app-layout", never, {}, {}, never, never, true, never>;
292
+ declare class AppFooter {
293
+ private readonly layoutService;
294
+ readonly appName: string;
295
+ readonly displayLogo: string;
296
+ readonly isLogoSvg: boolean;
297
+ readonly authorName: string;
298
+ readonly authorUrl: string;
299
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<AppFooter, never>;
300
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AppFooter, "app-footer", never, {}, {}, never, never, true, never>;
288
301
  }
289
302
 
290
303
  /**
@@ -353,34 +366,37 @@ declare class AppMenuitem {
353
366
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<AppMenuitem, "[app-menuitem]", never, { "item": { "alias": "item"; "required": true; "isSignal": true; }; "index": { "alias": "index"; "required": true; "isSignal": true; }; "parentKey": { "alias": "parentKey"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
354
367
  }
355
368
 
356
- declare class AppSidebar {
357
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<AppSidebar, never>;
358
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AppSidebar, "app-sidebar", never, {}, {}, never, never, true, never>;
359
- }
360
-
361
- type ActivePanel = 'config' | null;
362
- declare class AppTopbar {
363
- private readonly appConfig;
364
- private readonly document;
369
+ /**
370
+ * Shared shell behaviour for every layout skin.
371
+ * Holds the menu open/close lifecycle so a skin only owns markup and styling.
372
+ */
373
+ declare abstract class LayoutShellBase {
365
374
  private readonly destroyRef;
375
+ private readonly document;
376
+ private readonly renderer;
377
+ private readonly router;
366
378
  readonly layoutService: LayoutService;
367
- readonly notificationBellComponent: _angular_core.Type<unknown> | null;
368
- readonly languageSelectorComponent: _angular_core.Type<unknown> | null;
369
- private readonly searchAdapter;
370
- readonly hasSearchAdapter: _angular_core.Signal<boolean>;
371
- private readonly configContainer;
372
- private readonly navContainer;
373
- readonly activePanel: _angular_core.WritableSignal<ActivePanel>;
379
+ private menuOutsideClickListener;
380
+ /** Elements that must not close the menu when clicked. */
381
+ protected abstract outsideClickSelectors(): string[];
382
+ /** Extra work a skin needs on every completed navigation. */
383
+ protected onNavigated(): void;
374
384
  constructor();
375
- readonly companyName: _angular_core.Signal<string>;
376
- readonly displayLogo: _angular_core.Signal<string>;
377
- readonly enableCompanyFeature: boolean;
378
- toggleDarkMode(): void;
379
- togglePanel(panel: ActivePanel): void;
380
- private handleOutsideClick;
381
- private recalculateHoveredSubmenu;
382
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<AppTopbar, never>;
383
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<AppTopbar, "app-topbar", never, {}, {}, never, never, true, never>;
385
+ isOutsideClicked(event: MouseEvent): boolean;
386
+ hideMenu(): void;
387
+ blockBodyScroll(): void;
388
+ unblockBodyScroll(): void;
389
+ readonly isOverlay: _angular_core.Signal<boolean>;
390
+ /** Delegated so a skin that has no horizontal nav is never treated as being in it. */
391
+ readonly isTopbarMode: _angular_core.Signal<boolean>;
392
+ readonly isOverlayActive: _angular_core.Signal<boolean | undefined>;
393
+ readonly isMobileActive: _angular_core.Signal<boolean | undefined>;
394
+ /**
395
+ * The desktop sidebar is collapsed in place. Only meaningful for the modes that
396
+ * keep the sidebar in the layout flow — an overlay drawer and the horizontal nav
397
+ * have nothing to collapse.
398
+ */
399
+ readonly isDesktopCollapsed: _angular_core.Signal<boolean>;
384
400
  }
385
401
 
386
402
  /** Company/branch switcher displayed in top bar */
@@ -489,6 +505,100 @@ declare class AppSearchbar {
489
505
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<AppSearchbar, "app-searchbar", never, {}, {}, never, never, true, never>;
490
506
  }
491
507
 
508
+ /**
509
+ * Trailing action rail of the topbar — search, theme controls and the widget menu.
510
+ * Skins own the bar around it; the rail itself is identical in every skin, and
511
+ * `display: contents` on the host keeps it a direct flex child of the bar.
512
+ */
513
+ declare class AppTopbarActions {
514
+ private readonly appConfig;
515
+ private readonly document;
516
+ private readonly destroyRef;
517
+ readonly layoutService: LayoutService;
518
+ readonly notificationBellComponent: _angular_core.Type<unknown> | null;
519
+ readonly languageSelectorComponent: _angular_core.Type<unknown> | null;
520
+ private readonly searchAdapter;
521
+ private readonly configContainer;
522
+ private readonly _configPanelOpen;
523
+ readonly configPanelOpen: _angular_core.Signal<boolean>;
524
+ readonly hasSearchAdapter: _angular_core.Signal<boolean>;
525
+ readonly enableCompanyFeature: boolean;
526
+ constructor();
527
+ toggleDarkMode(): void;
528
+ toggleConfigPanel(): void;
529
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<AppTopbarActions, never>;
530
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AppTopbarActions, "app-topbar-actions", never, {}, {}, never, never, true, never>;
531
+ }
532
+
533
+ declare class AppClassicLayout extends LayoutShellBase {
534
+ readonly isStatic: _angular_core.Signal<boolean>;
535
+ protected outsideClickSelectors(): string[];
536
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<AppClassicLayout, never>;
537
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AppClassicLayout, "app-classic-layout", never, {}, {}, never, never, true, never>;
538
+ }
539
+
540
+ declare class AppSidebar {
541
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<AppSidebar, never>;
542
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AppSidebar, "app-sidebar", never, {}, {}, never, never, true, never>;
543
+ }
544
+
545
+ declare class AppTopbar {
546
+ readonly layoutService: LayoutService;
547
+ private readonly navContainer;
548
+ private readonly _scrollThumb;
549
+ readonly scrollThumb: _angular_core.Signal<{
550
+ width: number;
551
+ offset: number;
552
+ }>;
553
+ constructor();
554
+ syncScrollThumb(): void;
555
+ /**
556
+ * Horizontal-nav submenus are `position: fixed`, so scrolling the nav strip leaves
557
+ * an open submenu behind — re-anchor it to the item it belongs to.
558
+ */
559
+ private recalculateHoveredSubmenu;
560
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<AppTopbar, never>;
561
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AppTopbar, "app-topbar", never, {}, {}, never, never, true, never>;
562
+ }
563
+
564
+ declare class AppModernLayout extends LayoutShellBase {
565
+ private readonly content;
566
+ protected outsideClickSelectors(): string[];
567
+ /**
568
+ * The page scrolls inside the content card rather than the window, so the router's
569
+ * scroll restoration never reaches it — reset it here instead.
570
+ */
571
+ protected onNavigated(): void;
572
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<AppModernLayout, never>;
573
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AppModernLayout, "app-modern-layout", never, {}, {}, never, never, true, never>;
574
+ }
575
+
576
+ declare class AppModernSidebar {
577
+ readonly layoutService: LayoutService;
578
+ /**
579
+ * Only the in-flow column can be collapsed from here. As an overlay or mobile
580
+ * drawer the sidebar is opened by the topbar button and dismissed by the mask,
581
+ * so a second toggle inside it would be dead weight next to the brand.
582
+ */
583
+ readonly showMenuButton: _angular_core.Signal<boolean>;
584
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<AppModernSidebar, never>;
585
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AppModernSidebar, "app-modern-sidebar", never, {}, {}, never, never, true, never>;
586
+ }
587
+
588
+ declare class AppModernTopbar {
589
+ private readonly destroyRef;
590
+ private readonly router;
591
+ readonly layoutService: LayoutService;
592
+ private readonly _pageTitle;
593
+ readonly pageTitle: _angular_core.Signal<string>;
594
+ /** The sidebar is a drawer (not a column) in these modes, so the topbar owns the brand. */
595
+ readonly showBrand: _angular_core.Signal<boolean>;
596
+ constructor();
597
+ private resolvePageTitle;
598
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<AppModernTopbar, never>;
599
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<AppModernTopbar, "app-modern-topbar", never, {}, {}, never, never, true, never>;
600
+ }
601
+
492
602
  /** Filter launcher apps based on user permission codes */
493
603
  declare function filterAppsByPermissions(apps: ILauncherApp[], permissionCodes: string[]): ILauncherApp[];
494
604
 
@@ -518,5 +628,5 @@ declare const GreenTheme: ApplyThemeOptions;
518
628
 
519
629
  declare const LAYOUT_MESSAGES: Record<string, string>;
520
630
 
521
- export { AppCompanyBranchSelector, AppConfigurator, AppFloatingConfigurator, AppFooter, AppLauncher, AppLayout, AppMenu, AppMenuitem, AppProfile, AppSearchbar, AppSidebar, AppTopbar, GreenTheme, LAYOUT_AUTH_API, LAYOUT_AUTH_STATE, LAYOUT_IS_RTL, LAYOUT_LANGUAGE_SELECTOR, LAYOUT_LANGUAGE_SELECTOR_PANEL, LAYOUT_MESSAGES, LAYOUT_NOTIFICATION_BELL, LAYOUT_SEARCHBAR, LAYOUT_SEARCH_ADAPTER, LayoutPersistenceService, LayoutService, NavyBlueTheme, buildPreset, filterAppsByPermissions, filterMenuByPermissions };
631
+ export { AppBrandLogo, AppClassicLayout, AppCompanyBranchSelector, AppConfigurator, AppFloatingConfigurator, AppFooter, AppLauncher, AppLayout, AppMenu, AppMenuitem, AppModernLayout, AppModernSidebar, AppModernTopbar, AppProfile, AppSearchbar, AppSidebar, AppTopbar, AppTopbarActions, GreenTheme, LAYOUT_AUTH_API, LAYOUT_AUTH_STATE, LAYOUT_IS_RTL, LAYOUT_LANGUAGE_SELECTOR, LAYOUT_LANGUAGE_SELECTOR_PANEL, LAYOUT_MESSAGES, LAYOUT_NOTIFICATION_BELL, LAYOUT_SEARCHBAR, LAYOUT_SEARCH_ADAPTER, LayoutPersistenceService, LayoutService, LayoutShellBase, NavyBlueTheme, buildPreset, filterAppsByPermissions, filterMenuByPermissions };
522
632
  export type { CompanyProfile, DocumentWithViewTransition, IBranchInfo, ICompanyInfo, ILauncherApp, ILayoutAuthApi, ILayoutAuthState, IMenuItem, ISearchAdapter, ISearchSuggestion, IUserInfo, LayoutState, MenuChangeEvent, UserProfile, ViewTransition };
@@ -1,13 +0,0 @@
1
- .layout-main-container {
2
- display: flex;
3
- flex-direction: column;
4
- min-height: 100vh;
5
- justify-content: space-between;
6
- padding: 6rem 2rem 0 2rem;
7
- transition: margin-left var(--layout-section-transition-duration);
8
- }
9
-
10
- .layout-main {
11
- flex: 1 1 auto;
12
- padding-bottom: 2rem;
13
- }
@@ -1,188 +0,0 @@
1
- @use 'mixins' as *;
2
-
3
- .layout-sidebar {
4
- position: fixed;
5
- width: 22rem;
6
- height: 100vh;
7
- z-index: 999;
8
- overflow-y: auto;
9
- user-select: none;
10
- top: 4rem;
11
- transition:
12
- transform var(--layout-section-transition-duration),
13
- left var(--layout-section-transition-duration);
14
- background-color: var(--surface-overlay);
15
- padding: 1rem 1.5rem;
16
- border-inline-end: var(--f-sidebar-border-width) solid var(--f-content-border-color);
17
- border-end-end-radius: var(--f-sidebar-radius);
18
- box-shadow: var(--f-sidebar-shadow);
19
- }
20
-
21
- .layout-menu {
22
- margin: 0;
23
- padding: 0;
24
- list-style-type: none;
25
-
26
- .layout-root-menuitem {
27
- >.layout-menuitem-root-text {
28
- font-size: 0.857rem;
29
- text-transform: uppercase;
30
- font-weight: 700;
31
- color: var(--text-color);
32
- margin: 0.75rem 0;
33
- }
34
-
35
- >a {
36
- display: none;
37
- }
38
- }
39
-
40
- a {
41
- user-select: none;
42
-
43
- &.active-menuitem {
44
- >.layout-submenu-toggler {
45
- transform: rotate(-180deg);
46
- }
47
- }
48
- }
49
-
50
- li {
51
- margin-top: 5px;
52
- }
53
-
54
- li.active-menuitem {
55
- >a {
56
- background-color: var(--f-highlight-background);
57
- color: var(--f-highlight-color) !important;
58
- border-radius: var(--f-menuitem-active-radius);
59
- border-inline-start: var(--f-menuitem-active-border-width) solid var(--f-primary-color);
60
-
61
- .layout-submenu-toggler {
62
- transform: rotate(-180deg);
63
- }
64
- }
65
- }
66
-
67
- ul {
68
- margin: 0;
69
- padding: 0;
70
- list-style-type: none;
71
-
72
- a {
73
- display: flex;
74
- align-items: center;
75
- position: relative;
76
- outline: 0 none;
77
- color: var(--text-color);
78
- cursor: pointer;
79
- padding: 0.50rem 1rem;
80
- border-radius: var(--content-border-radius);
81
- transition:
82
- background-color var(--element-transition-duration),
83
- box-shadow var(--element-transition-duration);
84
-
85
- .layout-menuitem-icon {
86
- margin-right: 0.5rem;
87
- }
88
-
89
- .layout-submenu-toggler {
90
- font-size: 75%;
91
- margin-left: auto;
92
- transition: transform var(--element-transition-duration);
93
- }
94
-
95
- &.active-route {
96
- font-weight: 600;
97
- background-color: var(--f-highlight-background);
98
- color: var(--f-highlight-color);
99
- border-radius: var(--f-menuitem-active-radius);
100
- border-inline-start: var(--f-menuitem-active-border-width) solid var(--f-primary-color);
101
- }
102
-
103
- &:not(.active-route):hover {
104
- color: var(--f-primary-color);
105
- font-weight: 600;
106
- }
107
- }
108
-
109
- ul {
110
- overflow: hidden;
111
- border-radius: var(--content-border-radius);
112
-
113
- li {
114
- a {
115
- margin-left: 1rem;
116
- }
117
-
118
- li {
119
- a {
120
- margin-left: 2rem;
121
- }
122
-
123
- li {
124
- a {
125
- margin-left: 2.5rem;
126
- }
127
-
128
- li {
129
- a {
130
- margin-left: 3rem;
131
- }
132
-
133
- li {
134
- a {
135
- margin-left: 3.5rem;
136
- }
137
-
138
- li {
139
- a {
140
- margin-left: 4rem;
141
- }
142
-
143
- li {
144
- a {
145
- margin-left: 4.5rem;
146
- }
147
-
148
- li {
149
- a {
150
- margin-left: 5rem;
151
- }
152
-
153
- li {
154
- a {
155
- margin-left: 5.5rem;
156
- }
157
- }
158
- }
159
- }
160
- }
161
- }
162
- }
163
- }
164
- }
165
- }
166
- }
167
- }
168
- }
169
-
170
- .layout-submenu-enter-from,
171
- .layout-submenu-leave-to {
172
- max-height: 0;
173
- }
174
-
175
- .layout-submenu-enter-to,
176
- .layout-submenu-leave-from {
177
- max-height: 1000px;
178
- }
179
-
180
- .layout-submenu-leave-active {
181
- overflow: hidden;
182
- transition: max-height 0.45s cubic-bezier(0, 1, 0, 1);
183
- }
184
-
185
- .layout-submenu-enter-active {
186
- overflow: hidden;
187
- transition: max-height 1s ease-in-out;
188
- }
@@ -1,128 +0,0 @@
1
- @media screen and (min-width: 1960px) {
2
- .layout-main,
3
- .landing-wrapper {
4
- width: 1504px;
5
- margin-left: auto !important;
6
- margin-right: auto !important;
7
- }
8
- }
9
-
10
- @media (min-width: 992px) {
11
- .layout-wrapper {
12
- &.layout-overlay {
13
- .layout-main-container {
14
- margin-left: 0;
15
- padding-left: 2rem;
16
- }
17
-
18
- .layout-sidebar {
19
- transform: translateX(-100%);
20
- left: 0;
21
- top: 0;
22
- height: 100vh;
23
- border-top-left-radius: 0;
24
- border-bottom-left-radius: 0;
25
- border-right: 1px solid var(--surface-border);
26
- transition:
27
- transform 0.4s cubic-bezier(0.05, 0.74, 0.2, 0.99),
28
- left 0.4s cubic-bezier(0.05, 0.74, 0.2, 0.99);
29
- box-shadow:
30
- 0px 3px 5px rgba(0, 0, 0, 0.02),
31
- 0px 0px 2px rgba(0, 0, 0, 0.05),
32
- 0px 1px 4px rgba(0, 0, 0, 0.08);
33
- }
34
-
35
- &.layout-overlay-active {
36
- .layout-sidebar {
37
- transform: translateX(0);
38
- }
39
- }
40
- }
41
-
42
- &.layout-static {
43
- .layout-main-container {
44
- margin-left: 22rem;
45
- }
46
-
47
- &.layout-static-inactive {
48
- .layout-sidebar {
49
- transform: translateX(-100%);
50
- left: 0;
51
- }
52
-
53
- .layout-main-container {
54
- margin-left: 0;
55
- padding-left: 2rem;
56
- }
57
- }
58
- }
59
-
60
- &.layout-topbar-mode {
61
- .layout-sidebar {
62
- display: none;
63
- }
64
-
65
- .layout-main-container {
66
- margin-left: 0;
67
- padding-left: 2rem;
68
- padding-top: 6rem;
69
- }
70
-
71
- &.layout-topbar-nav-hidden {
72
- .layout-main-container {
73
- padding-top: 4rem;
74
- }
75
- }
76
- }
77
-
78
- .layout-mask {
79
- display: none;
80
- }
81
- }
82
- }
83
-
84
- @media (max-width: 991px) {
85
- .blocked-scroll {
86
- overflow: hidden;
87
- }
88
-
89
- .layout-wrapper {
90
- .layout-main-container {
91
- margin-left: 0;
92
- padding-left: 2rem;
93
- }
94
-
95
- .layout-sidebar {
96
- transform: translateX(-100%);
97
- left: 0;
98
- top: 0;
99
- height: 100vh;
100
- border-top-left-radius: 0;
101
- border-bottom-left-radius: 0;
102
- transition:
103
- transform 0.4s cubic-bezier(0.05, 0.74, 0.2, 0.99),
104
- left 0.4s cubic-bezier(0.05, 0.74, 0.2, 0.99);
105
- }
106
-
107
- .layout-mask {
108
- display: none;
109
- position: fixed;
110
- top: 0;
111
- left: 0;
112
- z-index: 998;
113
- width: 100%;
114
- height: 100%;
115
- background-color: var(--maskbg);
116
- }
117
-
118
- &.layout-mobile-active {
119
- .layout-sidebar {
120
- transform: translateX(0);
121
- }
122
-
123
- .layout-mask {
124
- display: block;
125
- }
126
- }
127
- }
128
- }