@wpmoo/ui 1.0.0-rc.5 → 1.0.0-rc.7
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/ASSET_LICENSE.md +1 -1
- package/README.md +5 -6
- package/certification.json +1 -1
- package/dist/assets/css/moo-ui.css +7748 -8075
- package/dist/assets/css/moo-ui.min.css +2 -2
- package/dist/assets/css/moo.css +289 -285
- package/dist/assets/css/moo.min.css +2 -2
- package/dist/js/chart.js +57 -5
- package/dist/js/chart.min.js +3 -3
- package/dist/js/combobox.js +1 -1
- package/dist/js/context-menu.js +1 -1
- package/dist/js/datatable.js +114 -213
- package/dist/js/datepicker.js +79 -37
- package/dist/js/datepicker.min.js +2 -2
- package/dist/js/moo-ui.js +193 -51
- package/dist/js/moo-ui.min.js +3 -3
- package/dist/js/sidebar.js +145 -170
- package/dist/js/slider.js +1 -1
- package/package.json +8 -8
- package/scss/components/_alert.scss +1 -2
- package/scss/components/_card.scss +5 -5
- package/scss/components/_close_button.scss +8 -3
- package/scss/components/_datatable.scss +27 -3
- package/scss/components/_dialog.scss +16 -0
- package/scss/components/_dropdown.scss +38 -3
- package/scss/components/_switch.scss +13 -5
- package/scss/components/_table.scss +6 -0
- package/scss/components/_tabs.scss +1 -1
- package/scss/components/sidebar/_collapsed.scss +28 -19
- package/scss/components/sidebar/_inset.scss +14 -44
- package/scss/components/sidebar/_layout.scss +86 -11
- package/scss/foundations/_backdrop.scss +128 -0
- package/scss/foundations/_scope.scss +5 -0
- package/scss/mixins/_banner.scss +3 -0
- package/scss/moo-core.scss +6 -34
- package/scss/moo-ui.scss +6 -6
- package/scss/settings/_bootstrap_overrides.scss +4 -0
- package/scss/settings/_component_variables.scss +13 -1
- package/scss/settings/_options.scss +2 -0
- package/scss/settings/_palette.scss +1 -1
- package/scss/themes/_forms.scss +15 -0
- package/scss/themes/_root.scss +16 -0
- package/scss/themes/_standalone.scss +5 -0
- package/scss/themes/{_scoped_core.scss → _theme.scss} +1 -0
- package/scss/foundations/_core_state_layer.scss +0 -25
- package/scss/foundations/_overlay_backdrop.scss +0 -19
- package/scss/themes/_standalone_root.scss +0 -119
- /package/scss/foundations/{_core_global_primitives.scss → _globals.scss} +0 -0
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
border-width: var(--bs-border-width);
|
|
15
15
|
border-style: var(--bs-border-style);
|
|
16
16
|
border-color: $moo-close-button-border-color;
|
|
17
|
-
|
|
17
|
+
// Keep the square hit area visually circular in every context, including
|
|
18
|
+
// modal and offcanvas headers.
|
|
19
|
+
border-radius: var(--bs-border-radius-pill);
|
|
18
20
|
color: var(--bs-btn-close-color);
|
|
19
21
|
background-image: none;
|
|
20
22
|
transition: $btn-transition;
|
|
@@ -31,8 +33,11 @@
|
|
|
31
33
|
|
|
32
34
|
// Bootstrap's dark rule filters the whole element to recolor its background
|
|
33
35
|
// image. The glyph above uses currentColor through a mask, so filtering would
|
|
34
|
-
// incorrectly invert the token-driven hover surface as well.
|
|
35
|
-
|
|
36
|
+
// incorrectly invert the token-driven hover surface as well. Both resolved
|
|
37
|
+
// owner modes override it so an outer dark owner cannot affect an inner light
|
|
38
|
+
// owner through Bootstrap's global descendant selector.
|
|
39
|
+
:scope[data-bs-theme="light"] .btn-close,
|
|
40
|
+
:scope[data-bs-theme="dark"] .btn-close {
|
|
36
41
|
filter: none;
|
|
37
42
|
}
|
|
38
43
|
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
// visible content changed.
|
|
13
13
|
.datatable {
|
|
14
14
|
--moo-datatable-min-width: #{$moo-datatable-min-width};
|
|
15
|
+
--moo-datatable-actions-cell-bg: #{$moo-datatable-actions-cell-bg};
|
|
15
16
|
--moo-datatable-actions-cell-fade-width: #{$moo-datatable-actions-cell-fade-width};
|
|
16
17
|
--moo-datatable-card-label-width: #{$moo-datatable-card-label-width};
|
|
17
18
|
--moo-datatable-frame-header-min-height: #{$moo-datatable-frame-header-min-height};
|
|
@@ -24,6 +25,10 @@
|
|
|
24
25
|
--moo-datatable-bulk-actions-bottom: #{$moo-datatable-bulk-actions-bottom};
|
|
25
26
|
}
|
|
26
27
|
|
|
28
|
+
.card .datatable {
|
|
29
|
+
--moo-datatable-actions-cell-bg: var(--bs-card-bg);
|
|
30
|
+
}
|
|
31
|
+
|
|
27
32
|
.datatable-table {
|
|
28
33
|
table-layout: fixed;
|
|
29
34
|
}
|
|
@@ -75,7 +80,7 @@
|
|
|
75
80
|
background: linear-gradient(
|
|
76
81
|
90deg,
|
|
77
82
|
transparent 0,
|
|
78
|
-
var(--
|
|
83
|
+
var(--moo-datatable-actions-cell-bg) var(--moo-datatable-actions-cell-fade-width)
|
|
79
84
|
);
|
|
80
85
|
}
|
|
81
86
|
|
|
@@ -84,7 +89,7 @@
|
|
|
84
89
|
background: linear-gradient(
|
|
85
90
|
270deg,
|
|
86
91
|
transparent 0,
|
|
87
|
-
var(--
|
|
92
|
+
var(--moo-datatable-actions-cell-bg) var(--moo-datatable-actions-cell-fade-width)
|
|
88
93
|
);
|
|
89
94
|
}
|
|
90
95
|
|
|
@@ -172,6 +177,15 @@
|
|
|
172
177
|
width: 100%;
|
|
173
178
|
}
|
|
174
179
|
|
|
180
|
+
// A filter menu is a direct child so Bootstrap can anchor it to the trigger.
|
|
181
|
+
// Clip the joined control while the menu is closed, matching the normal
|
|
182
|
+
// input-group surface; release that clipping only while the menu is open so
|
|
183
|
+
// the positioned dropdown can escape the control without leaking focus or
|
|
184
|
+
// child paint past its rounded border.
|
|
185
|
+
.datatable-searchbar:not(:has(> .dropdown-menu.show)) {
|
|
186
|
+
overflow: hidden;
|
|
187
|
+
}
|
|
188
|
+
|
|
175
189
|
.datatable-searchbar .datatable-search {
|
|
176
190
|
flex: 1 1 auto;
|
|
177
191
|
max-width: none;
|
|
@@ -184,7 +198,9 @@
|
|
|
184
198
|
position: absolute;
|
|
185
199
|
inset-block-start: 50%;
|
|
186
200
|
inset-inline-start: 0.625rem;
|
|
187
|
-
z-index:
|
|
201
|
+
// Bootstrap raises a focused form control to z-index: 5. Keep the
|
|
202
|
+
// decorative icon above that opaque surface so focus does not hide it.
|
|
203
|
+
z-index: 6;
|
|
188
204
|
display: inline-flex;
|
|
189
205
|
align-items: center;
|
|
190
206
|
justify-content: center;
|
|
@@ -735,6 +751,14 @@
|
|
|
735
751
|
background-color: var(--moo-muted-surface);
|
|
736
752
|
}
|
|
737
753
|
|
|
754
|
+
// Sticky action cells paint a gradient instead of using the row's
|
|
755
|
+
// background-color, so selected rows need the same surface at the opaque end
|
|
756
|
+
// of that fade.
|
|
757
|
+
.datatable-row-selected > [data-datatable-column="actions"] {
|
|
758
|
+
--moo-datatable-actions-cell-bg: var(--moo-muted-surface);
|
|
759
|
+
background: var(--moo-muted-surface);
|
|
760
|
+
}
|
|
761
|
+
|
|
738
762
|
.datatable-card.datatable-row-selected {
|
|
739
763
|
border-color: var(--moo-border);
|
|
740
764
|
background-color: var(--moo-muted-surface);
|
|
@@ -34,6 +34,22 @@
|
|
|
34
34
|
gap: calc(var(--bs-modal-padding) * 0.75);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
.modal-header:has(> .btn-close) {
|
|
38
|
+
// Keep the dismiss control in a stable top/end corner, like the reference
|
|
39
|
+
// dialog surface, while reserving room so long titles cannot run beneath it.
|
|
40
|
+
position: relative;
|
|
41
|
+
padding-inline-end: calc(
|
|
42
|
+
var(--bs-modal-padding) + #{$btn-close-width} + #{$btn-close-padding-x * 2} + 0.5rem
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.modal-header:has(> .btn-close) > .btn-close {
|
|
47
|
+
position: absolute;
|
|
48
|
+
inset-block-start: 0.5rem;
|
|
49
|
+
inset-inline-end: 0.5rem;
|
|
50
|
+
margin: 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
37
53
|
.modal--alert {
|
|
38
54
|
--bs-modal-width: 24rem;
|
|
39
55
|
--bs-modal-padding: 1rem;
|
|
@@ -188,15 +188,50 @@
|
|
|
188
188
|
}
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
+
// The lg Offcanvas breakpoint still renders the sidebar as a drawer on
|
|
192
|
+
// tablets. Keep identity menus inside that drawer until the desktop fixed
|
|
193
|
+
// overlay contract becomes active.
|
|
194
|
+
@include media-breakpoint-between(sm, lg) {
|
|
195
|
+
[data-slot="sidebar-header"] .dropend > .dropdown-menu,
|
|
196
|
+
[data-slot="sidebar-footer"] .dropend > .dropdown-menu {
|
|
197
|
+
left: 0 !important;
|
|
198
|
+
right: 0 !important;
|
|
199
|
+
min-width: 100%;
|
|
200
|
+
margin: 0;
|
|
201
|
+
transform: none !important;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
[data-slot="sidebar-header"] .dropend > .dropdown-menu {
|
|
205
|
+
top: calc(100% + #{$spacer * 0.25}) !important;
|
|
206
|
+
bottom: auto !important;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
[data-slot="sidebar-footer"] .dropend > .dropdown-menu {
|
|
210
|
+
top: auto !important;
|
|
211
|
+
bottom: calc(100% + #{$spacer * 0.25}) !important;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
191
215
|
@include media-breakpoint-up(lg) {
|
|
192
|
-
[data-slot="sidebar-header"] [data-sidebar-dropdown-positioned] > .dropdown-menu
|
|
216
|
+
[data-slot="sidebar-header"] [data-sidebar-dropdown-positioned] > .dropdown-menu,
|
|
217
|
+
[data-slot="sidebar-footer"] [data-sidebar-dropdown-positioned] > .dropdown-menu {
|
|
193
218
|
position: fixed !important;
|
|
194
219
|
z-index: $zindex-dropdown;
|
|
195
|
-
|
|
196
|
-
|
|
220
|
+
left: var(--moo-sidebar-dropdown-left, auto) !important;
|
|
221
|
+
right: var(--moo-sidebar-dropdown-right, auto) !important;
|
|
197
222
|
width: var(--moo-dropdown-sidebar-min-width);
|
|
198
223
|
min-width: var(--moo-dropdown-sidebar-min-width);
|
|
199
224
|
margin: 0;
|
|
200
225
|
transform: none !important;
|
|
201
226
|
}
|
|
227
|
+
|
|
228
|
+
[data-slot="sidebar-header"] [data-sidebar-dropdown-positioned] > .dropdown-menu {
|
|
229
|
+
inset-block-start: var(--moo-sidebar-dropdown-block-start) !important;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
[data-slot="sidebar-footer"] [data-sidebar-dropdown-positioned] > .dropdown-menu {
|
|
233
|
+
inset-block-start: auto !important;
|
|
234
|
+
inset-block-end: var(--moo-sidebar-dropdown-block-end) !important;
|
|
235
|
+
}
|
|
236
|
+
|
|
202
237
|
}
|
|
@@ -6,7 +6,15 @@
|
|
|
6
6
|
height: $moo-switch-height;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
:
|
|
9
|
+
:scope[data-bs-theme="light"] .form-switch .form-check-input:checked {
|
|
10
|
+
--#{$prefix}form-switch-bg: #{escape-svg($form-switch-checked-bg-image)};
|
|
11
|
+
|
|
12
|
+
background-color: var(--moo-primary);
|
|
13
|
+
border-color: var(--moo-primary);
|
|
14
|
+
filter: none;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
:scope[data-bs-theme="dark"] .form-switch .form-check-input:checked {
|
|
10
18
|
--#{$prefix}form-switch-bg: #{escape-svg($moo-switch-checked-bg-image-dark)};
|
|
11
19
|
|
|
12
20
|
background-color: var(--moo-primary);
|
|
@@ -14,12 +22,12 @@
|
|
|
14
22
|
filter: none;
|
|
15
23
|
}
|
|
16
24
|
|
|
17
|
-
.form-switch .form-check-input:focus:active:not(:checked),
|
|
18
|
-
.form-switch .form-check-input:focus:not(:focus-visible):not(:checked) {
|
|
25
|
+
:scope[data-bs-theme="light"] .form-switch .form-check-input:focus:active:not(:checked),
|
|
26
|
+
:scope[data-bs-theme="light"] .form-switch .form-check-input:focus:not(:focus-visible):not(:checked) {
|
|
19
27
|
--#{$prefix}form-switch-bg: #{escape-svg($form-switch-bg-image)};
|
|
20
28
|
}
|
|
21
29
|
|
|
22
|
-
:
|
|
23
|
-
:
|
|
30
|
+
:scope[data-bs-theme="dark"] .form-switch .form-check-input:focus:active:not(:checked),
|
|
31
|
+
:scope[data-bs-theme="dark"] .form-switch .form-check-input:focus:not(:focus-visible):not(:checked) {
|
|
24
32
|
--#{$prefix}form-switch-bg: #{escape-svg($form-switch-bg-image-dark)};
|
|
25
33
|
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
.card .table {
|
|
2
|
+
// Keep the table surface transparent so a table composed inside a card
|
|
3
|
+
// inherits the card's light/dark surface.
|
|
4
|
+
--bs-table-bg: #{$moo-table-contained-bg};
|
|
5
|
+
}
|
|
6
|
+
|
|
1
7
|
.table-responsive:not(.scroll-fade-x):has(.table-row-actions > [aria-expanded="true"]) {
|
|
2
8
|
overflow: visible;
|
|
3
9
|
}
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
// minimum for normal text (axe caught this in the certification fixture).
|
|
22
22
|
// var(--bs-secondary-color) is not a usable substitute here -- Moo UI's
|
|
23
23
|
// own theme sets --bs-secondary-color: var(--moo-muted-foreground)
|
|
24
|
-
// (scss/themes/
|
|
24
|
+
// (scss/themes/_root.scss), so it resolves to the exact same
|
|
25
25
|
// failing color. var(--bs-secondary-text-emphasis) is a different,
|
|
26
26
|
// untouched Bootstrap token (Moo UI does not override it) built for
|
|
27
27
|
// accessible colored text against a tinted "subtle" surface -- the same
|
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
cursor: pointer;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
// Read the Sidebar's computed direction so this remains valid inside the
|
|
16
|
+
// resolved-owner @scope as well as under a full-document html[dir] owner.
|
|
17
|
+
.sidebar:dir(rtl) .sidebar-rail {
|
|
16
18
|
transform: translateX(-50%);
|
|
17
19
|
}
|
|
18
20
|
|
|
@@ -37,14 +39,25 @@
|
|
|
37
39
|
position: relative;
|
|
38
40
|
}
|
|
39
41
|
|
|
40
|
-
.
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
.wrapper[data-layout="app"]:has([data-sidebar-dropdown-positioned] > .dropdown-menu.show) > .sidebar {
|
|
43
|
+
position: relative;
|
|
44
|
+
// Catalog page headers are sticky at $zindex-fixed. The Sidebar root must
|
|
45
|
+
// sit above that page-level stacking context while an identity menu is
|
|
46
|
+
// open, otherwise the workspace menu is painted underneath the header
|
|
47
|
+
// even though the menu itself is fixed and has dropdown z-index.
|
|
48
|
+
z-index: $zindex-fixed + 1;
|
|
43
49
|
}
|
|
44
50
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
51
|
+
// The sticky inner surface is its own stacking context. Elevate that
|
|
52
|
+
// context while an identity menu is open so the rail's hover indicator
|
|
53
|
+
// remains behind the fixed dropdown instead of painting across it.
|
|
54
|
+
.wrapper[data-layout="app"]:has([data-sidebar-dropdown-positioned] > .dropdown-menu.show) > .sidebar > .sidebar-inner {
|
|
55
|
+
z-index: $zindex-fixed + 1;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.wrapper[data-layout="app"][data-sidebar-state="collapsed"] .sidebar[data-collapsible="icon"] {
|
|
59
|
+
flex-basis: var(--moo-sidebar-width-icon);
|
|
60
|
+
width: var(--moo-sidebar-width-icon);
|
|
48
61
|
}
|
|
49
62
|
|
|
50
63
|
[data-sidebar-state="collapsed"] .sidebar[data-collapsible="icon"] .sidebar-group-label,
|
|
@@ -62,14 +75,18 @@
|
|
|
62
75
|
}
|
|
63
76
|
|
|
64
77
|
[data-sidebar-state="collapsed"] .sidebar[data-collapsible="icon"]:has(.sidebar-menu-button[data-bs-toggle="dropdown"][aria-expanded="true"]) {
|
|
65
|
-
|
|
78
|
+
// Keep the collapsed identity trigger above sticky page chrome too. This
|
|
79
|
+
// selector is more specific than the app-root rule above and otherwise
|
|
80
|
+
// would lower the Sidebar back to the dropdown layer.
|
|
81
|
+
z-index: $zindex-fixed + 1;
|
|
66
82
|
}
|
|
67
83
|
|
|
68
84
|
.sidebar-menu-flyout {
|
|
69
85
|
position: fixed;
|
|
70
86
|
z-index: $zindex-dropdown;
|
|
71
87
|
inset-block-start: var(--moo-sidebar-flyout-block-start);
|
|
72
|
-
|
|
88
|
+
left: var(--moo-sidebar-flyout-left);
|
|
89
|
+
right: auto;
|
|
73
90
|
display: flex;
|
|
74
91
|
flex-direction: column;
|
|
75
92
|
min-width: $spacer * 10;
|
|
@@ -162,15 +179,7 @@
|
|
|
162
179
|
display: none;
|
|
163
180
|
}
|
|
164
181
|
|
|
165
|
-
|
|
166
|
-
.sidebar-wrapper--contained {
|
|
167
|
-
flex-direction: column;
|
|
168
|
-
height: auto;
|
|
169
|
-
min-height: 34rem;
|
|
170
|
-
overflow: visible;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
.sidebar-wrapper--contained .sidebar {
|
|
182
|
+
.wrapper[data-layout="app"][data-shell-mode="contained"] .sidebar {
|
|
174
183
|
position: relative;
|
|
175
184
|
inset: auto;
|
|
176
185
|
flex: 0 0 auto;
|
|
@@ -180,7 +189,7 @@
|
|
|
180
189
|
transform: none;
|
|
181
190
|
}
|
|
182
191
|
|
|
183
|
-
.
|
|
192
|
+
.wrapper[data-layout="app"][data-shell-mode="contained"] .sidebar-inner {
|
|
184
193
|
height: auto;
|
|
185
194
|
max-height: none;
|
|
186
195
|
}
|
|
@@ -1,59 +1,29 @@
|
|
|
1
|
-
// Inset
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
flex: 1 1 auto;
|
|
5
|
-
flex-direction: column;
|
|
6
|
-
min-width: 0;
|
|
7
|
-
background: var(--bs-body-bg);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
.sidebar-inset__header {
|
|
11
|
-
position: sticky;
|
|
12
|
-
top: 0;
|
|
13
|
-
z-index: 20;
|
|
14
|
-
display: flex;
|
|
15
|
-
align-items: center;
|
|
16
|
-
gap: $spacer * 0.5;
|
|
17
|
-
height: $spacer * 4;
|
|
18
|
-
padding-inline: $spacer;
|
|
19
|
-
border-bottom: var(--bs-border-width) solid var(--bs-border-color);
|
|
20
|
-
background: var(--bs-body-bg);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
.sidebar-inset__content {
|
|
24
|
-
flex: 1 1 auto;
|
|
25
|
-
min-width: 0;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Inset variant: the sidebar itself stays flush; the main content becomes a
|
|
29
|
-
// rounded, shadowed card with a gap around it, and the page background
|
|
30
|
-
// switches to the sidebar's own surface color so the card reads as inset.
|
|
31
|
-
// Collapsing to the icon rail restores the inline-start gap. Scoped to
|
|
32
|
-
// desktop, matching how the mobile offcanvas drawer ignores variant.
|
|
1
|
+
// Inset Sidebar variant --------------------------------------------------
|
|
2
|
+
// The Sidebar owns the navigation surface; the App root owns the sibling
|
|
3
|
+
// page geometry. This variant only supplies the page-side visual treatment.
|
|
33
4
|
@include media-breakpoint-up(lg) {
|
|
34
|
-
.
|
|
5
|
+
.wrapper[data-layout="app"]:has(> .sidebar[data-variant="inset"]) {
|
|
35
6
|
background: var(--moo-sidebar);
|
|
36
7
|
}
|
|
37
8
|
|
|
38
|
-
.
|
|
9
|
+
.wrapper[data-layout="app"]:has(> .sidebar[data-variant="inset"]) > [data-slot="page"] {
|
|
39
10
|
margin: $spacer * 0.5;
|
|
40
|
-
margin-
|
|
11
|
+
margin-left: 0;
|
|
41
12
|
border-radius: var(--bs-border-radius-xl);
|
|
42
13
|
box-shadow: var(--bs-box-shadow-sm);
|
|
14
|
+
background: var(--bs-body-bg);
|
|
43
15
|
}
|
|
44
16
|
|
|
45
|
-
.
|
|
46
|
-
margin-
|
|
17
|
+
.wrapper[data-layout="app"][data-sidebar-state="collapsed"]:has(> .sidebar[data-variant="inset"]) > [data-slot="page"] {
|
|
18
|
+
margin-left: $spacer * 0.5;
|
|
47
19
|
}
|
|
48
20
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
margin-inline-start: $spacer * 0.5;
|
|
53
|
-
margin-inline-end: 0;
|
|
21
|
+
.wrapper[data-layout="app"]:has(> .sidebar[data-variant="inset"][data-side="right"]) > [data-slot="page"] {
|
|
22
|
+
margin-left: $spacer * 0.5;
|
|
23
|
+
margin-right: 0;
|
|
54
24
|
}
|
|
55
25
|
|
|
56
|
-
.
|
|
57
|
-
margin-
|
|
26
|
+
.wrapper[data-layout="app"][data-sidebar-state="collapsed"]:has(> .sidebar[data-variant="inset"][data-side="right"]) > [data-slot="page"] {
|
|
27
|
+
margin-right: $spacer * 0.5;
|
|
58
28
|
}
|
|
59
29
|
}
|
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
// Geometry rides the $moo-sidebar-* Sass knobs; every color consumes a
|
|
4
4
|
// runtime --moo-* token.
|
|
5
5
|
|
|
6
|
-
.
|
|
7
|
-
--moo-sidebar-width: #{$moo-sidebar-width};
|
|
8
|
-
--moo-sidebar-width-icon: #{$moo-sidebar-width-icon};
|
|
6
|
+
.wrapper[data-layout="app"] {
|
|
9
7
|
display: flex;
|
|
10
8
|
width: 100%;
|
|
11
|
-
|
|
9
|
+
height: 100svh;
|
|
10
|
+
min-height: 0;
|
|
11
|
+
overflow: hidden;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
.
|
|
14
|
+
.wrapper[data-layout="app"][data-shell-mode="contained"] {
|
|
15
15
|
min-height: 0;
|
|
16
16
|
height: 34rem;
|
|
17
17
|
overflow: hidden;
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
|
|
22
22
|
// Sidebar column ---------------------------------------------------------
|
|
23
23
|
.sidebar {
|
|
24
|
+
--moo-sidebar-width: #{$moo-sidebar-width};
|
|
25
|
+
--moo-sidebar-width-icon: #{$moo-sidebar-width-icon};
|
|
24
26
|
--bs-offcanvas-width: var(--moo-sidebar-width);
|
|
25
27
|
flex: 0 0 var(--moo-sidebar-width);
|
|
26
28
|
width: var(--moo-sidebar-width);
|
|
@@ -28,15 +30,28 @@
|
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
.sidebar[data-side="left"] .sidebar-inner {
|
|
31
|
-
|
|
33
|
+
// `side` is a physical placement contract. Keep the divider on the
|
|
34
|
+
// Sidebar/Page boundary when the document direction is RTL as well.
|
|
35
|
+
border-right: var(--bs-border-width) solid var(--moo-sidebar-border);
|
|
32
36
|
}
|
|
33
37
|
|
|
34
38
|
.sidebar[data-side="right"] {
|
|
35
39
|
order: 1;
|
|
36
40
|
}
|
|
37
41
|
|
|
42
|
+
// `side` is a physical placement contract. `:dir()` reads the wrapper's
|
|
43
|
+
// computed direction inside the owner scope, whether it comes from html for a
|
|
44
|
+
// document owner or from an embedded owner's own dir attribute.
|
|
45
|
+
.wrapper[data-layout="app"]:dir(rtl) > .sidebar[data-side="left"] {
|
|
46
|
+
order: 1;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.wrapper[data-layout="app"]:dir(rtl) > .sidebar[data-side="right"] {
|
|
50
|
+
order: 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
38
53
|
.sidebar[data-side="right"] .sidebar-inner {
|
|
39
|
-
border-
|
|
54
|
+
border-left: var(--bs-border-width) solid var(--moo-sidebar-border);
|
|
40
55
|
}
|
|
41
56
|
|
|
42
57
|
// Floating variant: the surface detaches from the viewport edge with a
|
|
@@ -58,7 +73,7 @@
|
|
|
58
73
|
box-shadow: var(--bs-box-shadow-sm);
|
|
59
74
|
}
|
|
60
75
|
|
|
61
|
-
.
|
|
76
|
+
.wrapper[data-layout="app"][data-shell-mode="contained"] .sidebar[data-variant="floating"] .sidebar-inner {
|
|
62
77
|
height: calc(100% - #{$spacer});
|
|
63
78
|
max-height: calc(100% - #{$spacer});
|
|
64
79
|
}
|
|
@@ -69,16 +84,22 @@
|
|
|
69
84
|
// (still a shared token, no new value) and widen the column by the same
|
|
70
85
|
// margin the card's sides consume, so the icon rail itself keeps its full
|
|
71
86
|
// width instead of shrinking.
|
|
72
|
-
.
|
|
87
|
+
.wrapper[data-layout="app"][data-sidebar-state="collapsed"] .sidebar[data-variant="floating"][data-collapsible="icon"] {
|
|
73
88
|
flex-basis: calc(var(--moo-sidebar-width-icon) + #{$spacer});
|
|
74
89
|
width: calc(var(--moo-sidebar-width-icon) + #{$spacer});
|
|
75
90
|
}
|
|
76
91
|
|
|
77
|
-
.
|
|
92
|
+
.wrapper[data-layout="app"][data-sidebar-state="collapsed"] .sidebar[data-variant="floating"][data-collapsible="icon"] .sidebar-inner {
|
|
78
93
|
box-shadow: var(--bs-box-shadow);
|
|
79
94
|
}
|
|
80
95
|
}
|
|
81
96
|
|
|
97
|
+
@media (prefers-reduced-motion: reduce) {
|
|
98
|
+
.sidebar {
|
|
99
|
+
transition: none;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
82
103
|
.sidebar-inner {
|
|
83
104
|
position: sticky;
|
|
84
105
|
top: 0;
|
|
@@ -90,12 +111,66 @@
|
|
|
90
111
|
background: var(--moo-sidebar);
|
|
91
112
|
}
|
|
92
113
|
|
|
93
|
-
.
|
|
114
|
+
.wrapper[data-layout="app"][data-shell-mode="contained"] .sidebar-inner {
|
|
94
115
|
position: relative;
|
|
95
116
|
height: 100%;
|
|
96
117
|
max-height: 100%;
|
|
97
118
|
}
|
|
98
119
|
|
|
120
|
+
.wrapper[data-layout="app"] > [data-slot="page"] {
|
|
121
|
+
display: flex;
|
|
122
|
+
min-width: 0;
|
|
123
|
+
min-height: 0;
|
|
124
|
+
flex: 1 1 auto;
|
|
125
|
+
flex-direction: column;
|
|
126
|
+
overflow-y: auto;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.wrapper[data-layout="app"] > [data-slot="page"] > header,
|
|
130
|
+
.wrapper[data-layout="app"] > [data-slot="page"] > main,
|
|
131
|
+
.wrapper[data-layout="app"] > [data-slot="page"] > footer {
|
|
132
|
+
flex: 0 0 auto;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// The page main region owns the space between the optional header and footer.
|
|
136
|
+
// Keep the Bootstrap rail as the flex column too, so app previews and real
|
|
137
|
+
// shells can give their caller content a full-height surface without adding
|
|
138
|
+
// layout-specific height values.
|
|
139
|
+
.wrapper[data-layout="app"] > [data-slot="page"] > main {
|
|
140
|
+
display: flex;
|
|
141
|
+
min-height: 0;
|
|
142
|
+
flex: 1 1 auto;
|
|
143
|
+
flex-direction: column;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.wrapper[data-layout="app"] > [data-slot="page"] > main > :is(
|
|
147
|
+
.container,
|
|
148
|
+
.container-sm,
|
|
149
|
+
.container-md,
|
|
150
|
+
.container-lg,
|
|
151
|
+
.container-xl,
|
|
152
|
+
.container-xxl,
|
|
153
|
+
.container-fluid
|
|
154
|
+
) {
|
|
155
|
+
display: flex;
|
|
156
|
+
min-height: 0;
|
|
157
|
+
flex: 1 1 auto;
|
|
158
|
+
flex-direction: column;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
@include media-breakpoint-down(lg) {
|
|
162
|
+
.wrapper[data-layout="app"][data-shell-mode="contained"] {
|
|
163
|
+
flex-direction: column;
|
|
164
|
+
height: auto;
|
|
165
|
+
min-height: 0;
|
|
166
|
+
overflow: visible;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.wrapper[data-layout="app"][data-shell-mode="contained"] > [data-slot="page"] {
|
|
170
|
+
overflow: visible;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
99
174
|
.sidebar-header,
|
|
100
175
|
.sidebar-footer {
|
|
101
176
|
display: flex;
|