@flusys/ng-layout 6.3.0 → 6.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +150 -11
- package/assets/layout/base/_brand.scss +44 -0
- package/assets/layout/{_core.scss → base/_core.scss} +8 -1
- package/assets/layout/{_footer.scss → base/_footer.scss} +1 -1
- package/assets/layout/{_forms.scss → base/_forms.scss} +3 -3
- package/assets/layout/base/_menu.scss +52 -0
- package/assets/layout/base/_rtl.scss +230 -0
- package/assets/layout/base/_topbar.scss +132 -0
- package/assets/layout/base/variables/_common.scss +62 -0
- package/assets/layout/classic/_main.scss +14 -0
- package/assets/layout/classic/_menu.scss +77 -0
- package/assets/layout/classic/_responsive.scss +101 -0
- package/assets/layout/classic/_rtl.scss +26 -0
- package/assets/layout/classic/_topbar.scss +46 -0
- package/assets/layout/{_topbar_nav.scss → classic/_topbar_nav.scss} +31 -15
- package/assets/layout/classic/classic.scss +6 -0
- package/assets/layout/layout.scss +18 -16
- package/assets/layout/modern/_menu.scss +98 -0
- package/assets/layout/modern/_responsive.scss +93 -0
- package/assets/layout/modern/_rtl.scss +24 -0
- package/assets/layout/modern/_shell.scss +59 -0
- package/assets/layout/modern/_sidebar.scss +101 -0
- package/assets/layout/modern/_topbar.scss +37 -0
- package/assets/layout/modern/_variables.scss +114 -0
- package/assets/layout/modern/modern.scss +7 -0
- package/fesm2022/flusys-ng-layout.mjs +1315 -939
- package/fesm2022/flusys-ng-layout.mjs.map +1 -1
- package/package.json +4 -4
- package/types/flusys-ng-layout.d.ts +171 -64
- package/assets/layout/_main.scss +0 -13
- package/assets/layout/_menu.scss +0 -188
- package/assets/layout/_responsive.scss +0 -128
- package/assets/layout/_rtl.scss +0 -482
- package/assets/layout/_topbar.scss +0 -215
- package/assets/layout/variables/_common.scss +0 -20
- /package/assets/layout/{_mixins.scss → base/_mixins.scss} +0 -0
- /package/assets/layout/{_preloading.scss → base/_preloading.scss} +0 -0
- /package/assets/layout/{_typography.scss → base/_typography.scss} +0 -0
- /package/assets/layout/{_utils.scss → base/_utils.scss} +0 -0
- /package/assets/layout/{variables → base/variables}/_dark.scss +0 -0
- /package/assets/layout/{variables → base/variables}/_light.scss +0 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
@use 'mixins' as *;
|
|
2
|
+
|
|
3
|
+
// Shared topbar chrome. Each skin positions and paints its own bar; everything the
|
|
4
|
+
// bars render from the same components — the action rail, the round action buttons
|
|
5
|
+
// and the widget menu — is styled once here and tuned through the topbar tokens in
|
|
6
|
+
// base/variables/_common.scss. A new skin joins the selector list instead of
|
|
7
|
+
// restating the block.
|
|
8
|
+
.layout-topbar,
|
|
9
|
+
.layout-modern-topbar {
|
|
10
|
+
.layout-topbar-actions {
|
|
11
|
+
margin-inline-start: auto;
|
|
12
|
+
display: flex;
|
|
13
|
+
align-items: center;
|
|
14
|
+
gap: var(--layout-topbar-actions-gap);
|
|
15
|
+
flex-shrink: 0;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.layout-config-menu,
|
|
19
|
+
.layout-topbar-menu-content {
|
|
20
|
+
display: flex;
|
|
21
|
+
align-items: center;
|
|
22
|
+
gap: var(--layout-topbar-group-gap);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.layout-topbar-action {
|
|
26
|
+
display: inline-flex;
|
|
27
|
+
justify-content: center;
|
|
28
|
+
align-items: center;
|
|
29
|
+
width: var(--layout-topbar-action-size);
|
|
30
|
+
height: var(--layout-topbar-action-size);
|
|
31
|
+
flex-shrink: 0;
|
|
32
|
+
border-radius: var(--layout-topbar-action-radius, 50%);
|
|
33
|
+
background: transparent;
|
|
34
|
+
color: var(--text-color);
|
|
35
|
+
cursor: pointer;
|
|
36
|
+
transition: background-color var(--element-transition-duration);
|
|
37
|
+
|
|
38
|
+
&:hover {
|
|
39
|
+
background-color: var(--surface-hover);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
&:focus-visible {
|
|
43
|
+
@include focused();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
ui-icon {
|
|
47
|
+
font-size: var(--layout-topbar-action-icon-size);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Revealed only inside the compact widget menu below, where the actions become
|
|
51
|
+
// labelled rows instead of icon buttons.
|
|
52
|
+
span {
|
|
53
|
+
font-size: 1rem;
|
|
54
|
+
display: none;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
&.layout-topbar-action-highlight {
|
|
58
|
+
background-color: var(--primary-color);
|
|
59
|
+
color: var(--primary-contrast-color);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Declared after `.layout-topbar-action` — same specificity, so the later rule
|
|
64
|
+
// wins and the overflow button stays hidden until the compact breakpoint reveals it.
|
|
65
|
+
.layout-topbar-menu-button {
|
|
66
|
+
display: none;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Compact topbar — matches the `lg:` breakpoint the markup uses to reveal the menu,
|
|
71
|
+
// so the overflow button and the menu it toggles are never both hidden.
|
|
72
|
+
@media (max-width: 1023.98px) {
|
|
73
|
+
.layout-topbar,
|
|
74
|
+
.layout-modern-topbar {
|
|
75
|
+
.layout-topbar-menu-button {
|
|
76
|
+
display: inline-flex;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.layout-topbar-menu {
|
|
80
|
+
// Local to the bar's stacking context — only needs to clear its siblings.
|
|
81
|
+
position: absolute;
|
|
82
|
+
z-index: 1;
|
|
83
|
+
top: var(--layout-topbar-height);
|
|
84
|
+
inset-inline-end: var(--layout-topbar-inline-padding);
|
|
85
|
+
min-width: 15rem;
|
|
86
|
+
padding: 1rem;
|
|
87
|
+
background-color: var(--surface-overlay);
|
|
88
|
+
border: var(--f-border-width, 1px) solid var(--surface-border);
|
|
89
|
+
border-radius: var(--content-border-radius);
|
|
90
|
+
box-shadow: var(--f-shadow-xl);
|
|
91
|
+
transform-origin: top;
|
|
92
|
+
|
|
93
|
+
.layout-topbar-menu-content {
|
|
94
|
+
flex-direction: column;
|
|
95
|
+
align-items: stretch;
|
|
96
|
+
gap: 0.5rem;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.layout-topbar-action {
|
|
100
|
+
width: 100%;
|
|
101
|
+
height: auto;
|
|
102
|
+
justify-content: flex-start;
|
|
103
|
+
gap: 0.5rem;
|
|
104
|
+
padding: 0.5rem 1rem;
|
|
105
|
+
border-radius: var(--content-border-radius);
|
|
106
|
+
|
|
107
|
+
ui-icon {
|
|
108
|
+
font-size: 1rem;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
span {
|
|
112
|
+
display: block;
|
|
113
|
+
font-weight: 500;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Compact bar. The tokens are re-declared on the bar itself rather than on :root so
|
|
121
|
+
// they also win over a skin's own values, which sit on an ancestor shell class.
|
|
122
|
+
@media (max-width: 639px) {
|
|
123
|
+
.layout-topbar,
|
|
124
|
+
.layout-modern-topbar {
|
|
125
|
+
--layout-topbar-inline-padding: 0.75rem;
|
|
126
|
+
--layout-topbar-actions-gap: 0.25rem;
|
|
127
|
+
--layout-topbar-group-gap: 0.25rem;
|
|
128
|
+
--layout-topbar-action-size: 2.25rem;
|
|
129
|
+
|
|
130
|
+
gap: 0.5rem;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--primary-color: var(--f-primary-color);
|
|
3
|
+
--primary-contrast-color: var(--f-primary-contrast-color);
|
|
4
|
+
--text-color: var(--f-text-color);
|
|
5
|
+
--text-color-secondary: var(--f-text-muted-color);
|
|
6
|
+
--surface-border: var(--f-content-border-color);
|
|
7
|
+
--surface-card: var(--f-content-background);
|
|
8
|
+
--surface-hover: var(--f-content-hover-background);
|
|
9
|
+
--surface-overlay: var(--f-overlay-popover-background);
|
|
10
|
+
--transition-duration: var(--f-transition-duration);
|
|
11
|
+
--maskbg: var(--f-mask-background);
|
|
12
|
+
--content-border-radius: var(--f-content-border-radius);
|
|
13
|
+
--layout-section-transition-duration: 0.2s;
|
|
14
|
+
--element-transition-duration: var(--f-transition-duration);
|
|
15
|
+
--focus-ring-width: var(--f-focus-ring-width);
|
|
16
|
+
--focus-ring-style: var(--f-focus-ring-style);
|
|
17
|
+
--focus-ring-color: var(--f-focus-ring-color);
|
|
18
|
+
--focus-ring-offset: var(--f-focus-ring-offset);
|
|
19
|
+
--focus-ring-shadow: var(--f-focus-ring-shadow);
|
|
20
|
+
|
|
21
|
+
--layout-viewport-height: 100dvh;
|
|
22
|
+
--layout-sidebar-width: 19rem;
|
|
23
|
+
--layout-content-padding: 2rem;
|
|
24
|
+
|
|
25
|
+
/* Topbar geometry. A skin overrides these on its own shell class; the shared
|
|
26
|
+
topbar chrome in base/_topbar.scss reads them rather than hard-coding sizes. */
|
|
27
|
+
--layout-topbar-height: 4rem;
|
|
28
|
+
--layout-topbar-inline-padding: var(--layout-content-padding);
|
|
29
|
+
/* Gap between the rail's top-level groups, and inside each group. */
|
|
30
|
+
--layout-topbar-actions-gap: 1rem;
|
|
31
|
+
--layout-topbar-group-gap: 1rem;
|
|
32
|
+
--layout-topbar-action-size: 2.5rem;
|
|
33
|
+
--layout-topbar-action-radius: 50%;
|
|
34
|
+
--layout-topbar-action-icon-size: 1.25rem;
|
|
35
|
+
|
|
36
|
+
/* Distance from the top of the viewport to the bottom of the shell's topbar.
|
|
37
|
+
Shared topbar widgets that pin a full-width overlay (the mobile search sheet)
|
|
38
|
+
measure from this, so a skin that insets its topbar only overrides the token. */
|
|
39
|
+
--layout-shell-topbar-bottom: var(--layout-topbar-height);
|
|
40
|
+
/* The space left under the shell's topbar. Anything pinned below the topbar and
|
|
41
|
+
bounded by the viewport bottom (the classic sidebar) sizes from this, so a skin
|
|
42
|
+
that insets its topbar only has to override --layout-shell-topbar-bottom. */
|
|
43
|
+
--layout-content-viewport-height: calc(
|
|
44
|
+
var(--layout-viewport-height) - var(--layout-shell-topbar-bottom)
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
/* Stacking order: topbar < mask < sidebar */
|
|
48
|
+
--layout-topbar-z: 997;
|
|
49
|
+
--layout-mask-z: 998;
|
|
50
|
+
--layout-sidebar-z: 999;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* ── Preset-scoped shell overrides ─────────────────────────────────────────────
|
|
54
|
+
`data-f-preset` is published on <html> by the theme applier. It exists for the
|
|
55
|
+
handful of shell rules that express a preset's design language as a whole
|
|
56
|
+
rather than as one token — a rule that has to know it is being asked for a
|
|
57
|
+
square, motionless look, not just a smaller radius. */
|
|
58
|
+
:root[data-f-preset='Nora'] {
|
|
59
|
+
/* A brutalist preset squares its chrome as well: a circular topbar button next
|
|
60
|
+
to a square field and a square card reads as an oversight, not a choice. */
|
|
61
|
+
--layout-topbar-action-radius: 0px;
|
|
62
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
.layout-main-container {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
min-height: var(--layout-viewport-height);
|
|
5
|
+
justify-content: space-between;
|
|
6
|
+
padding: calc(var(--layout-topbar-height) + var(--layout-content-padding))
|
|
7
|
+
var(--layout-content-padding) 0;
|
|
8
|
+
transition: margin-inline-start var(--layout-section-transition-duration);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.layout-main {
|
|
12
|
+
flex: 1 1 auto;
|
|
13
|
+
padding-bottom: var(--layout-content-padding);
|
|
14
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
.layout-sidebar {
|
|
2
|
+
position: fixed;
|
|
3
|
+
inset-inline-start: 0;
|
|
4
|
+
top: var(--layout-topbar-height);
|
|
5
|
+
width: var(--layout-sidebar-width);
|
|
6
|
+
// Fills exactly the space left under the topbar — never taller than the viewport,
|
|
7
|
+
// so the last menu item stays reachable.
|
|
8
|
+
height: var(--layout-content-viewport-height);
|
|
9
|
+
z-index: var(--layout-sidebar-z);
|
|
10
|
+
overflow-y: auto;
|
|
11
|
+
overscroll-behavior: contain;
|
|
12
|
+
user-select: none;
|
|
13
|
+
transition:
|
|
14
|
+
transform var(--layout-section-transition-duration),
|
|
15
|
+
inset-inline-start var(--layout-section-transition-duration);
|
|
16
|
+
background-color: var(--surface-overlay);
|
|
17
|
+
padding: 1rem 1.5rem;
|
|
18
|
+
border-inline-end: var(--f-sidebar-border-width) solid
|
|
19
|
+
var(--f-content-border-color);
|
|
20
|
+
border-end-end-radius: var(--f-sidebar-radius);
|
|
21
|
+
box-shadow: var(--f-sidebar-shadow);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Classic look for the shared menu structure (see base/_menu.scss). Scoped to the
|
|
25
|
+
// sidebar so the horizontal nav in topbar mode — which styles the same markup from
|
|
26
|
+
// scratch in classic/_topbar_nav.scss — is left alone.
|
|
27
|
+
.layout-sidebar .layout-menu {
|
|
28
|
+
li {
|
|
29
|
+
margin-top: 5px;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
li.active-menuitem > a {
|
|
33
|
+
background-color: var(--f-highlight-background);
|
|
34
|
+
color: var(--f-highlight-color) !important;
|
|
35
|
+
border-radius: var(--f-menuitem-active-radius);
|
|
36
|
+
border-inline-start: var(--f-menuitem-active-border-width) solid
|
|
37
|
+
var(--f-primary-color);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
ul {
|
|
41
|
+
a {
|
|
42
|
+
padding: 0.5rem 1rem;
|
|
43
|
+
border-radius: var(--content-border-radius);
|
|
44
|
+
|
|
45
|
+
&.active-route {
|
|
46
|
+
font-weight: 600;
|
|
47
|
+
background-color: var(--f-highlight-background);
|
|
48
|
+
color: var(--f-highlight-color);
|
|
49
|
+
border-radius: var(--f-menuitem-active-radius);
|
|
50
|
+
border-inline-start: var(--f-menuitem-active-border-width) solid
|
|
51
|
+
var(--f-primary-color);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&:not(.active-route):hover {
|
|
55
|
+
color: var(--f-primary-color);
|
|
56
|
+
font-weight: 600;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Each nesting level steps the row further in. Generated rather than hand-written
|
|
61
|
+
// so the ladder stays consistent, and inline-start so RTL mirrors for free.
|
|
62
|
+
ul {
|
|
63
|
+
overflow: hidden;
|
|
64
|
+
border-radius: var(--content-border-radius);
|
|
65
|
+
|
|
66
|
+
$indents: 1rem, 2rem, 2.5rem, 3rem, 3.5rem, 4rem, 4.5rem, 5rem, 5.5rem;
|
|
67
|
+
$selector: '& > li';
|
|
68
|
+
|
|
69
|
+
@each $indent in $indents {
|
|
70
|
+
#{$selector} > a {
|
|
71
|
+
margin-inline-start: $indent;
|
|
72
|
+
}
|
|
73
|
+
$selector: '#{$selector} > ul > li';
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// Written with logical properties, so RTL only needs the drawer transform mirrored
|
|
2
|
+
// (see classic/_rtl.scss) rather than a second copy of these rules.
|
|
3
|
+
$sidebar-drawer-easing: 0.4s cubic-bezier(0.05, 0.74, 0.2, 0.99);
|
|
4
|
+
$sidebar-drawer-shadow:
|
|
5
|
+
0px 3px 5px rgba(0, 0, 0, 0.02),
|
|
6
|
+
0px 0px 2px rgba(0, 0, 0, 0.05),
|
|
7
|
+
0px 1px 4px rgba(0, 0, 0, 0.08);
|
|
8
|
+
|
|
9
|
+
// The sidebar leaves its column and floats over the content as a full-height drawer.
|
|
10
|
+
@mixin sidebar-drawer {
|
|
11
|
+
transform: translateX(-100%);
|
|
12
|
+
top: 0;
|
|
13
|
+
height: var(--layout-viewport-height);
|
|
14
|
+
transition:
|
|
15
|
+
transform $sidebar-drawer-easing,
|
|
16
|
+
inset-inline-start $sidebar-drawer-easing;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@media screen and (min-width: 1960px) {
|
|
20
|
+
.layout-main {
|
|
21
|
+
width: 1504px;
|
|
22
|
+
margin-inline: auto !important;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@media (min-width: 992px) {
|
|
27
|
+
.layout-wrapper {
|
|
28
|
+
&.layout-overlay {
|
|
29
|
+
.layout-sidebar {
|
|
30
|
+
@include sidebar-drawer;
|
|
31
|
+
box-shadow: $sidebar-drawer-shadow;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
&.layout-overlay-active .layout-sidebar {
|
|
35
|
+
transform: translateX(0);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
&.layout-static {
|
|
40
|
+
.layout-main-container {
|
|
41
|
+
margin-inline-start: var(--layout-sidebar-width);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
&.layout-static-inactive {
|
|
45
|
+
.layout-sidebar {
|
|
46
|
+
transform: translateX(-100%);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.layout-main-container {
|
|
50
|
+
margin-inline-start: 0;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
&.layout-topbar-mode {
|
|
56
|
+
.layout-sidebar {
|
|
57
|
+
display: none;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// The horizontal nav adds a second row under the topbar; when it is toggled
|
|
61
|
+
// off the content moves back up under the bar alone.
|
|
62
|
+
&.layout-topbar-nav-hidden .layout-main-container {
|
|
63
|
+
padding-top: var(--layout-topbar-height);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.layout-mask {
|
|
68
|
+
display: none;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@media (max-width: 991px) {
|
|
74
|
+
.layout-wrapper {
|
|
75
|
+
.layout-main-container {
|
|
76
|
+
margin-inline-start: 0;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.layout-sidebar {
|
|
80
|
+
@include sidebar-drawer;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.layout-mask {
|
|
84
|
+
display: none;
|
|
85
|
+
position: fixed;
|
|
86
|
+
inset: 0;
|
|
87
|
+
z-index: var(--layout-mask-z);
|
|
88
|
+
background-color: var(--maskbg);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
&.layout-mobile-active {
|
|
92
|
+
.layout-sidebar {
|
|
93
|
+
transform: translateX(0);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.layout-mask {
|
|
97
|
+
display: block;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// The classic shell is built on logical properties, so only the drawer transform —
|
|
2
|
+
// which has no logical equivalent — needs mirroring.
|
|
3
|
+
@media (min-width: 992px) {
|
|
4
|
+
html[dir='rtl'] .layout-wrapper {
|
|
5
|
+
&.layout-overlay .layout-sidebar,
|
|
6
|
+
&.layout-static.layout-static-inactive .layout-sidebar {
|
|
7
|
+
transform: translateX(100%);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
&.layout-overlay.layout-overlay-active .layout-sidebar {
|
|
11
|
+
transform: translateX(0);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@media (max-width: 991px) {
|
|
17
|
+
html[dir='rtl'] .layout-wrapper {
|
|
18
|
+
.layout-sidebar {
|
|
19
|
+
transform: translateX(100%);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
&.layout-mobile-active .layout-sidebar {
|
|
23
|
+
transform: translateX(0);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Bar itself and the brand block on its leading edge. Everything on the trailing
|
|
2
|
+
// edge — the action rail, the round buttons, the compact widget menu — is shared
|
|
3
|
+
// with the other skins and lives in base/_topbar.scss.
|
|
4
|
+
.layout-topbar {
|
|
5
|
+
position: fixed;
|
|
6
|
+
height: var(--layout-topbar-height);
|
|
7
|
+
z-index: var(--layout-topbar-z);
|
|
8
|
+
inset-inline-start: 0;
|
|
9
|
+
top: 0;
|
|
10
|
+
width: 100%;
|
|
11
|
+
padding: 0 var(--layout-topbar-inline-padding);
|
|
12
|
+
background-color: var(--surface-card);
|
|
13
|
+
transition: inset-inline-start var(--layout-section-transition-duration);
|
|
14
|
+
display: flex;
|
|
15
|
+
align-items: center;
|
|
16
|
+
gap: 1rem;
|
|
17
|
+
border-bottom: var(--f-topbar-border-width) solid
|
|
18
|
+
var(--f-content-border-color);
|
|
19
|
+
box-shadow: var(--f-topbar-shadow);
|
|
20
|
+
|
|
21
|
+
.layout-topbar-logo-container {
|
|
22
|
+
width: calc(var(--layout-sidebar-width) - 2rem);
|
|
23
|
+
display: flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
flex-shrink: 0;
|
|
26
|
+
|
|
27
|
+
&.layout-topbar-logo-container-desktop {
|
|
28
|
+
justify-content: space-between;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.layout-topbar-action-right {
|
|
33
|
+
margin-inline-start: auto !important;
|
|
34
|
+
margin-inline-end: -0.9rem !important;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.layout-menu-button {
|
|
38
|
+
margin-inline-end: 0.5rem;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@media (max-width: 991px) {
|
|
43
|
+
.layout-topbar .layout-topbar-logo-container {
|
|
44
|
+
width: auto;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
@use "mixins" as *;
|
|
1
|
+
@use "../base/mixins" as *;
|
|
2
2
|
|
|
3
3
|
// Define common values as variables
|
|
4
4
|
$submenu-box-shadow:
|
|
@@ -19,7 +19,7 @@ $submenu-icon-margin: 0.5rem;
|
|
|
19
19
|
pointer-events: none;
|
|
20
20
|
position: $position;
|
|
21
21
|
background-color: var(--surface-overlay);
|
|
22
|
-
border: 1px solid var(--surface-border);
|
|
22
|
+
border: var(--f-border-width, 1px) solid var(--surface-border);
|
|
23
23
|
border-radius: var(--content-border-radius);
|
|
24
24
|
box-shadow: $submenu-box-shadow;
|
|
25
25
|
flex-direction: column;
|
|
@@ -58,7 +58,7 @@ $submenu-icon-margin: 0.5rem;
|
|
|
58
58
|
transition: background-color var(--element-transition-duration);
|
|
59
59
|
|
|
60
60
|
.layout-menuitem-icon {
|
|
61
|
-
margin-
|
|
61
|
+
margin-inline-end: $submenu-icon-margin;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
.layout-menuitem-text {
|
|
@@ -70,7 +70,8 @@ $submenu-icon-margin: 0.5rem;
|
|
|
70
70
|
background-color: var(--f-highlight-background);
|
|
71
71
|
color: var(--f-highlight-color);
|
|
72
72
|
border-radius: var(--f-menuitem-active-radius);
|
|
73
|
-
border-inline-start: var(--f-menuitem-active-border-width) solid
|
|
73
|
+
border-inline-start: var(--f-menuitem-active-border-width) solid
|
|
74
|
+
var(--f-primary-color);
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
77
|
|
|
@@ -214,14 +215,32 @@ $submenu-icon-margin: 0.5rem;
|
|
|
214
215
|
flex-direction: row;
|
|
215
216
|
align-items: center;
|
|
216
217
|
flex: 1 1 auto;
|
|
218
|
+
|
|
219
|
+
align-self: stretch;
|
|
217
220
|
padding: 0 1rem;
|
|
218
221
|
overflow-x: auto;
|
|
219
222
|
overflow-y: hidden;
|
|
223
|
+
overscroll-behavior-x: contain;
|
|
220
224
|
-webkit-overflow-scrolling: touch;
|
|
221
|
-
scrollbar-width:
|
|
225
|
+
scrollbar-width: thin;
|
|
226
|
+
scrollbar-color: color-mix(in srgb, var(--text-color) 35%, transparent)
|
|
227
|
+
transparent;
|
|
222
228
|
|
|
223
229
|
&::-webkit-scrollbar {
|
|
224
|
-
|
|
230
|
+
height: 0.25rem;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
&::-webkit-scrollbar-track {
|
|
234
|
+
background: transparent;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
&::-webkit-scrollbar-thumb {
|
|
238
|
+
background-color: color-mix(in srgb, var(--text-color) 35%, transparent);
|
|
239
|
+
border-radius: 999px;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
&::-webkit-scrollbar-thumb:hover {
|
|
243
|
+
background-color: color-mix(in srgb, var(--text-color) 55%, transparent);
|
|
225
244
|
}
|
|
226
245
|
|
|
227
246
|
&.layout-topbar-nav-hidden {
|
|
@@ -237,11 +256,6 @@ $submenu-icon-margin: 0.5rem;
|
|
|
237
256
|
gap: 0.25rem;
|
|
238
257
|
flex-shrink: 0;
|
|
239
258
|
|
|
240
|
-
// Reset sidebar menu nested margins in topbar mode
|
|
241
|
-
a {
|
|
242
|
-
margin-left: 0 !important;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
259
|
> ul {
|
|
246
260
|
display: flex;
|
|
247
261
|
flex-direction: row;
|
|
@@ -285,12 +299,12 @@ $submenu-icon-margin: 0.5rem;
|
|
|
285
299
|
transition: background-color var(--element-transition-duration);
|
|
286
300
|
|
|
287
301
|
.layout-menuitem-icon {
|
|
288
|
-
margin-
|
|
302
|
+
margin-inline-end: 0.5rem;
|
|
289
303
|
}
|
|
290
304
|
|
|
291
305
|
.layout-submenu-toggler {
|
|
292
306
|
display: inline;
|
|
293
|
-
margin-
|
|
307
|
+
margin-inline-start: 0.5rem;
|
|
294
308
|
font-size: 0.75rem;
|
|
295
309
|
}
|
|
296
310
|
|
|
@@ -302,7 +316,8 @@ $submenu-icon-margin: 0.5rem;
|
|
|
302
316
|
background-color: var(--f-highlight-background);
|
|
303
317
|
color: var(--f-highlight-color);
|
|
304
318
|
border-radius: var(--f-menuitem-active-radius);
|
|
305
|
-
border-inline-start: var(--f-menuitem-active-border-width) solid
|
|
319
|
+
border-inline-start: var(--f-menuitem-active-border-width) solid
|
|
320
|
+
var(--f-primary-color);
|
|
306
321
|
}
|
|
307
322
|
}
|
|
308
323
|
|
|
@@ -344,7 +359,8 @@ $submenu-icon-margin: 0.5rem;
|
|
|
344
359
|
background-color: var(--f-highlight-background);
|
|
345
360
|
color: var(--f-highlight-color);
|
|
346
361
|
border-radius: var(--f-menuitem-active-radius);
|
|
347
|
-
border-inline-start: var(--f-menuitem-active-border-width) solid
|
|
362
|
+
border-inline-start: var(--f-menuitem-active-border-width) solid
|
|
363
|
+
var(--f-primary-color);
|
|
348
364
|
}
|
|
349
365
|
}
|
|
350
366
|
}
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
@use './variables/
|
|
3
|
-
@use './variables/
|
|
4
|
-
@use './
|
|
5
|
-
@use './
|
|
6
|
-
@use './
|
|
7
|
-
@use './
|
|
8
|
-
@use
|
|
9
|
-
@use
|
|
10
|
-
@use './
|
|
11
|
-
@use './
|
|
12
|
-
@use './
|
|
13
|
-
@use './
|
|
14
|
-
@use './
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
// Shared foundation — applies to every layout skin
|
|
2
|
+
@use './base/variables/common';
|
|
3
|
+
@use './base/variables/light';
|
|
4
|
+
@use './base/variables/dark';
|
|
5
|
+
@use './base/preloading';
|
|
6
|
+
@use './base/core';
|
|
7
|
+
@use './base/typography';
|
|
8
|
+
@use './base/forms';
|
|
9
|
+
@use './base/brand';
|
|
10
|
+
@use './base/topbar';
|
|
11
|
+
@use './base/menu';
|
|
12
|
+
@use './base/footer';
|
|
13
|
+
@use './base/utils';
|
|
14
|
+
@use './base/rtl';
|
|
15
|
+
|
|
16
|
+
// Layout skins — selected at runtime via LayoutConfig.layoutTheme
|
|
17
|
+
@use './classic/classic';
|
|
18
|
+
@use './modern/modern';
|