@wpmoo/ui 1.0.0-rc.6 → 1.0.0-rc.8
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 +37 -6
- package/certification.json +6 -2
- package/dist/assets/css/moo-ui.css +7799 -8113
- package/dist/assets/css/moo-ui.min.css +5 -5
- package/dist/assets/css/moo.css +707 -685
- package/dist/assets/css/moo.min.css +5 -5
- 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 +169 -52
- package/dist/js/moo-ui.min.js +3 -3
- package/dist/js/sidebar.js +122 -175
- package/dist/js/slider.js +1 -1
- package/dist/js/theme-prepaint.js +91 -0
- package/dist/release-manifest.json +24 -0
- package/package.json +12 -8
- package/scss/_components.scss +1 -4
- 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/_dialog.scss +16 -0
- package/scss/components/_dropdown.scss +12 -7
- package/scss/components/_search_trigger.scss +62 -0
- package/scss/components/_sidebar.scss +1 -2
- package/scss/components/_switch.scss +13 -5
- package/scss/components/_tabs.scss +1 -1
- package/scss/components/sidebar/_base.scss +93 -0
- package/scss/components/sidebar/_collapsed.scss +9 -90
- package/scss/foundations/_backdrop.scss +128 -0
- package/scss/foundations/_scope.scss +8 -0
- package/scss/layouts/_app.scss +77 -0
- package/scss/layouts/app/sidebar/_base.scss +117 -0
- package/scss/layouts/app/sidebar/_default.scss +26 -0
- package/scss/layouts/app/sidebar/_floating.scss +44 -0
- package/scss/layouts/app/sidebar/_inset.scss +29 -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 +20 -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/components/sidebar/_inset.scss +0 -59
- package/scss/components/sidebar/_layout.scss +0 -176
- 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
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// Bootstrap owns the overlay lifecycle for Dialog / Alert Dialog (Modal) and
|
|
2
|
+
// Sheet (Offcanvas). Moo only retunes the native backdrop appearance through a
|
|
3
|
+
// shared token primitive, so every opening surface gets the same treatment
|
|
4
|
+
// without component-specific backdrop selectors.
|
|
5
|
+
//
|
|
6
|
+
// Modal waits for the real `.modal-backdrop` transition before it starts the
|
|
7
|
+
// dialog panel. Keep that lifecycle element visually inert and animate a
|
|
8
|
+
// pseudo-element instead: the panel and visible blur/dim can then start from
|
|
9
|
+
// the same Bootstrap motion token, while the native backdrop is still retained
|
|
10
|
+
// long enough to fade the visual layer out on close. Use keyframe animation
|
|
11
|
+
// rather than a pseudo-element transition: transitionend events from a pseudo
|
|
12
|
+
// element bubble to its originating backdrop and would make Bootstrap wait for
|
|
13
|
+
// the visual layer before showing the panel.
|
|
14
|
+
@mixin moo-overlay-backdrop-appearance {
|
|
15
|
+
--#{$prefix}backdrop-opacity: var(--moo-overlay-backdrop-opacity, #{$moo-overlay-backdrop-opacity});
|
|
16
|
+
opacity: 1;
|
|
17
|
+
color: transparent;
|
|
18
|
+
background-color: transparent;
|
|
19
|
+
|
|
20
|
+
&.fade,
|
|
21
|
+
&.fade:not(.show) {
|
|
22
|
+
opacity: 1;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Bootstrap reads this duration to decide when to reveal a Modal panel.
|
|
26
|
+
// Keep entry instant; the visual transition below belongs to ::before.
|
|
27
|
+
&.show {
|
|
28
|
+
transition: none;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// On close, Bootstrap keeps the lifecycle layer in the DOM for this token
|
|
32
|
+
// duration while ::before fades out. Color has no visible effect on the
|
|
33
|
+
// empty backdrop but supplies Bootstrap's native transition lifecycle
|
|
34
|
+
// without multiplying the pseudo-element's visual fade.
|
|
35
|
+
&.fade:not(.show) {
|
|
36
|
+
color: var(--bs-body-color, currentcolor);
|
|
37
|
+
transition: color var(--moo-overlay-motion-duration, #{$moo-overlay-motion-duration}) ease-out;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
&::before {
|
|
41
|
+
position: absolute;
|
|
42
|
+
inset: 0;
|
|
43
|
+
content: "";
|
|
44
|
+
opacity: 0;
|
|
45
|
+
background-color: var(--moo-overlay-backdrop-bg, #{$moo-overlay-backdrop-bg});
|
|
46
|
+
-webkit-backdrop-filter: blur(0);
|
|
47
|
+
backdrop-filter: blur(0);
|
|
48
|
+
animation: moo-overlay-backdrop-exit var(--moo-overlay-motion-duration, #{$moo-overlay-motion-duration}) ease-out both;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@mixin moo-overlay-backdrop-shown {
|
|
53
|
+
// Bootstrap Modal routes opacity through --bs-backdrop-opacity, but
|
|
54
|
+
// Offcanvas 5.3 compiles the same state to a literal .5. Restate the shared
|
|
55
|
+
// token on both native show selectors so Dialog and Sheet dim equally.
|
|
56
|
+
&::before {
|
|
57
|
+
animation: moo-overlay-backdrop-enter var(--moo-overlay-motion-duration, #{$moo-overlay-motion-duration}) ease-out both;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@mixin moo-overlay-backdrop-reduced-motion {
|
|
62
|
+
transition: none;
|
|
63
|
+
|
|
64
|
+
&::before {
|
|
65
|
+
animation: none;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@keyframes moo-overlay-backdrop-enter {
|
|
70
|
+
from {
|
|
71
|
+
opacity: 0;
|
|
72
|
+
-webkit-backdrop-filter: blur(0);
|
|
73
|
+
backdrop-filter: blur(0);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
to {
|
|
77
|
+
opacity: var(--moo-overlay-backdrop-opacity, #{$moo-overlay-backdrop-opacity});
|
|
78
|
+
-webkit-backdrop-filter: var(--moo-overlay-backdrop-filter, #{$moo-overlay-backdrop-filter});
|
|
79
|
+
backdrop-filter: var(--moo-overlay-backdrop-filter, #{$moo-overlay-backdrop-filter});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@keyframes moo-overlay-backdrop-exit {
|
|
84
|
+
from {
|
|
85
|
+
opacity: var(--moo-overlay-backdrop-opacity, #{$moo-overlay-backdrop-opacity});
|
|
86
|
+
-webkit-backdrop-filter: var(--moo-overlay-backdrop-filter, #{$moo-overlay-backdrop-filter});
|
|
87
|
+
backdrop-filter: var(--moo-overlay-backdrop-filter, #{$moo-overlay-backdrop-filter});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
to {
|
|
91
|
+
opacity: 0;
|
|
92
|
+
-webkit-backdrop-filter: blur(0);
|
|
93
|
+
backdrop-filter: blur(0);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.modal-backdrop,
|
|
98
|
+
.offcanvas-backdrop {
|
|
99
|
+
@include moo-overlay-backdrop-appearance;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.modal-backdrop.show,
|
|
103
|
+
.offcanvas-backdrop.show {
|
|
104
|
+
@include moo-overlay-backdrop-shown;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Backdrops that are portaled into a resolved owner still need to outrank
|
|
108
|
+
// Bootstrap's scoped `.fade` and `.show` rules. Entry points include this
|
|
109
|
+
// mixin inside their single native Moo scope; the global rules above remain
|
|
110
|
+
// available for hosts that intentionally keep Bootstrap's body-level portal.
|
|
111
|
+
@mixin moo-overlay-backdrop-scoped {
|
|
112
|
+
.modal-backdrop,
|
|
113
|
+
.offcanvas-backdrop {
|
|
114
|
+
@include moo-overlay-backdrop-appearance;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.modal-backdrop.show,
|
|
118
|
+
.offcanvas-backdrop.show {
|
|
119
|
+
@include moo-overlay-backdrop-shown;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
@media (prefers-reduced-motion: reduce) {
|
|
124
|
+
.modal-backdrop,
|
|
125
|
+
.offcanvas-backdrop {
|
|
126
|
+
@include moo-overlay-backdrop-reduced-motion;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
@scope (.moo-ui) to (:where(.moo-ui[data-bs-theme="light"], .moo-ui[data-bs-theme="dark"])) {
|
|
2
|
+
@import "../components";
|
|
3
|
+
@import "../foundations/focus";
|
|
4
|
+
@import "../utilities/scroll_fade";
|
|
5
|
+
@import "../layouts/app";
|
|
6
|
+
@import "../themes/forms";
|
|
7
|
+
@include moo-overlay-backdrop-scoped;
|
|
8
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Application layout owns the shell and page geometry.
|
|
2
|
+
// It is intentionally separate from component surfaces such as Sidebar.
|
|
3
|
+
|
|
4
|
+
@import "app/sidebar/base";
|
|
5
|
+
@import "app/sidebar/default";
|
|
6
|
+
@import "app/sidebar/floating";
|
|
7
|
+
@import "app/sidebar/inset";
|
|
8
|
+
|
|
9
|
+
.wrapper[data-layout="app"] {
|
|
10
|
+
display: flex;
|
|
11
|
+
width: 100%;
|
|
12
|
+
height: 100svh;
|
|
13
|
+
min-height: 0;
|
|
14
|
+
overflow: hidden;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.wrapper[data-layout="app"][data-shell-mode="contained"] {
|
|
18
|
+
min-height: 0;
|
|
19
|
+
height: 34rem;
|
|
20
|
+
overflow: hidden;
|
|
21
|
+
border: var(--bs-border-width) solid var(--moo-border);
|
|
22
|
+
border-radius: var(--bs-border-radius-xl);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.wrapper[data-layout="app"] > [data-slot="page"] {
|
|
26
|
+
display: flex;
|
|
27
|
+
min-width: 0;
|
|
28
|
+
min-height: 0;
|
|
29
|
+
flex: 1 1 auto;
|
|
30
|
+
flex-direction: column;
|
|
31
|
+
overflow-y: auto;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.wrapper[data-layout="app"] > [data-slot="page"] > header,
|
|
35
|
+
.wrapper[data-layout="app"] > [data-slot="page"] > main,
|
|
36
|
+
.wrapper[data-layout="app"] > [data-slot="page"] > footer {
|
|
37
|
+
flex: 0 0 auto;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// The page main region owns the space between the optional header and footer.
|
|
41
|
+
// Keep the Bootstrap rail as the flex column too, so app previews and real
|
|
42
|
+
// shells can give their caller content a full-height surface without adding
|
|
43
|
+
// layout-specific height values.
|
|
44
|
+
.wrapper[data-layout="app"] > [data-slot="page"] > main {
|
|
45
|
+
display: flex;
|
|
46
|
+
min-height: 0;
|
|
47
|
+
flex: 1 1 auto;
|
|
48
|
+
flex-direction: column;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.wrapper[data-layout="app"] > [data-slot="page"] > main > :is(
|
|
52
|
+
.container,
|
|
53
|
+
.container-sm,
|
|
54
|
+
.container-md,
|
|
55
|
+
.container-lg,
|
|
56
|
+
.container-xl,
|
|
57
|
+
.container-xxl,
|
|
58
|
+
.container-fluid
|
|
59
|
+
) {
|
|
60
|
+
display: flex;
|
|
61
|
+
min-height: 0;
|
|
62
|
+
flex: 1 1 auto;
|
|
63
|
+
flex-direction: column;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@include media-breakpoint-down(lg) {
|
|
67
|
+
.wrapper[data-layout="app"][data-shell-mode="contained"] {
|
|
68
|
+
flex-direction: column;
|
|
69
|
+
height: auto;
|
|
70
|
+
min-height: 0;
|
|
71
|
+
overflow: visible;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.wrapper[data-layout="app"][data-shell-mode="contained"] > [data-slot="page"] {
|
|
75
|
+
overflow: visible;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// Shared App-owned Sidebar shell geometry. Sidebar's component partials own
|
|
2
|
+
// only the inner surface and navigation anatomy.
|
|
3
|
+
|
|
4
|
+
.sidebar {
|
|
5
|
+
--moo-sidebar-width: #{$moo-sidebar-width};
|
|
6
|
+
--moo-sidebar-width-icon: #{$moo-sidebar-width-icon};
|
|
7
|
+
--bs-offcanvas-width: var(--moo-sidebar-width);
|
|
8
|
+
flex: 0 0 var(--moo-sidebar-width);
|
|
9
|
+
width: var(--moo-sidebar-width);
|
|
10
|
+
color: var(--moo-sidebar-foreground);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Rail: a thin toggle strip straddling the Sidebar's inline-end edge.
|
|
14
|
+
.sidebar-rail {
|
|
15
|
+
position: absolute;
|
|
16
|
+
inset-block: 0;
|
|
17
|
+
inset-inline-end: 0;
|
|
18
|
+
z-index: 20;
|
|
19
|
+
width: $spacer;
|
|
20
|
+
padding: 0;
|
|
21
|
+
transform: translateX(50%);
|
|
22
|
+
border: 0;
|
|
23
|
+
background: transparent;
|
|
24
|
+
cursor: pointer;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Read the Sidebar's computed direction so this remains valid inside the
|
|
28
|
+
// resolved-owner @scope as well as under a full-document html[dir] owner.
|
|
29
|
+
.sidebar:dir(rtl) .sidebar-rail {
|
|
30
|
+
transform: translateX(-50%);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.sidebar-rail::after {
|
|
34
|
+
content: "";
|
|
35
|
+
position: absolute;
|
|
36
|
+
inset-block: 0;
|
|
37
|
+
inset-inline-start: 50%;
|
|
38
|
+
width: var(--bs-border-width);
|
|
39
|
+
background: transparent;
|
|
40
|
+
transition: background 0.15s ease;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.sidebar-rail:hover::after {
|
|
44
|
+
background: var(--moo-sidebar-border);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.wrapper[data-layout="app"][data-shell-mode="contained"] .sidebar-inner {
|
|
48
|
+
position: relative;
|
|
49
|
+
height: 100%;
|
|
50
|
+
max-height: 100%;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// The outer shell owns stacking, collapse width, and the contained-shell
|
|
54
|
+
// geometry. Inner collapsed content remains in components/sidebar/_collapsed.
|
|
55
|
+
@include media-breakpoint-up(lg) {
|
|
56
|
+
.sidebar {
|
|
57
|
+
position: relative;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// `offcanvas` is a collapsible mode, not a visual Sidebar variant. On
|
|
61
|
+
// desktop the App keeps the shell in normal flow and uses the shared App
|
|
62
|
+
// state attribute to collapse the column; below lg Bootstrap's native
|
|
63
|
+
// Offcanvas plugin continues to own the drawer transition.
|
|
64
|
+
.sidebar.offcanvas-lg[data-collapsible="offcanvas"] {
|
|
65
|
+
visibility: visible;
|
|
66
|
+
transform: none;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.wrapper[data-layout="app"][data-sidebar-state="collapsed"] > .sidebar.offcanvas-lg[data-collapsible="offcanvas"] {
|
|
70
|
+
flex-basis: 0;
|
|
71
|
+
width: 0;
|
|
72
|
+
overflow: hidden;
|
|
73
|
+
visibility: hidden;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.wrapper[data-layout="app"]:has([data-sidebar-dropdown-positioned] > .dropdown-menu.show) > .sidebar {
|
|
77
|
+
position: relative;
|
|
78
|
+
// Catalog page headers are sticky at $zindex-fixed. The Sidebar root must
|
|
79
|
+
// sit above that page-level stacking context while an identity menu is
|
|
80
|
+
// open, otherwise the workspace menu is painted underneath the header
|
|
81
|
+
// even though the menu itself is fixed and has dropdown z-index.
|
|
82
|
+
z-index: $zindex-fixed + 1;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// The sticky inner surface is its own stacking context. Elevate that
|
|
86
|
+
// context while an identity menu is open so the rail's hover indicator
|
|
87
|
+
// remains behind the fixed dropdown instead of painting across it.
|
|
88
|
+
.wrapper[data-layout="app"]:has([data-sidebar-dropdown-positioned] > .dropdown-menu.show) > .sidebar > .sidebar-inner {
|
|
89
|
+
z-index: $zindex-fixed + 1;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.wrapper[data-layout="app"][data-sidebar-state="collapsed"] .sidebar[data-collapsible="icon"] {
|
|
93
|
+
flex-basis: var(--moo-sidebar-width-icon);
|
|
94
|
+
width: var(--moo-sidebar-width-icon);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
@include media-breakpoint-down(lg) {
|
|
99
|
+
.sidebar-rail {
|
|
100
|
+
display: none;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.wrapper[data-layout="app"][data-shell-mode="contained"] .sidebar {
|
|
104
|
+
position: relative;
|
|
105
|
+
inset: auto;
|
|
106
|
+
flex: 0 0 auto;
|
|
107
|
+
width: 100%;
|
|
108
|
+
height: auto;
|
|
109
|
+
visibility: visible;
|
|
110
|
+
transform: none;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.wrapper[data-layout="app"][data-shell-mode="contained"] .sidebar-inner {
|
|
114
|
+
height: auto;
|
|
115
|
+
max-height: none;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Default App Sidebar variant: attached to the shell edge with one divider.
|
|
2
|
+
|
|
3
|
+
.sidebar[data-side="left"] .sidebar-inner {
|
|
4
|
+
// `side` is a physical placement contract. Keep the divider on the
|
|
5
|
+
// Sidebar/Page boundary when the document direction is RTL as well.
|
|
6
|
+
border-right: var(--bs-border-width) solid var(--moo-sidebar-border);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.sidebar[data-side="right"] {
|
|
10
|
+
order: 1;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// `side` is a physical placement contract. `:dir()` reads the wrapper's
|
|
14
|
+
// computed direction inside the owner scope, whether it comes from html for a
|
|
15
|
+
// document owner or from an embedded owner's own dir attribute.
|
|
16
|
+
.wrapper[data-layout="app"]:dir(rtl) > .sidebar[data-side="left"] {
|
|
17
|
+
order: 1;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.wrapper[data-layout="app"]:dir(rtl) > .sidebar[data-side="right"] {
|
|
21
|
+
order: 0;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.sidebar[data-side="right"] .sidebar-inner {
|
|
25
|
+
border-left: var(--bs-border-width) solid var(--moo-sidebar-border);
|
|
26
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Floating App Sidebar variant: the shell detaches the inner surface from
|
|
2
|
+
// the viewport edge with a margin, border, radius, and shadow.
|
|
3
|
+
|
|
4
|
+
@include media-breakpoint-up(lg) {
|
|
5
|
+
.sidebar {
|
|
6
|
+
transition: flex-basis 0.2s ease, width 0.2s ease;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.sidebar[data-variant="floating"] .sidebar-inner {
|
|
10
|
+
width: auto;
|
|
11
|
+
height: calc(100svh - #{$spacer});
|
|
12
|
+
max-height: calc(100svh - #{$spacer});
|
|
13
|
+
margin: $spacer * 0.5;
|
|
14
|
+
border: var(--bs-border-width) solid var(--moo-sidebar-border);
|
|
15
|
+
border-radius: var(--bs-border-radius-lg);
|
|
16
|
+
box-shadow: var(--bs-box-shadow-sm);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.wrapper[data-layout="app"][data-shell-mode="contained"] .sidebar[data-variant="floating"] .sidebar-inner {
|
|
20
|
+
height: calc(100% - #{$spacer});
|
|
21
|
+
max-height: calc(100% - #{$spacer});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// At icon-rail width the detached card reads as floating mostly through
|
|
25
|
+
// elevation and breathing room, since the margin/border alone are hard to
|
|
26
|
+
// read at the base icon width; step up to Bootstrap's base shadow scale
|
|
27
|
+
// (still a shared token, no new value) and widen the column by the same
|
|
28
|
+
// margin the card's sides consume, so the icon rail itself keeps its full
|
|
29
|
+
// width instead of shrinking.
|
|
30
|
+
.wrapper[data-layout="app"][data-sidebar-state="collapsed"] .sidebar[data-variant="floating"][data-collapsible="icon"] {
|
|
31
|
+
flex-basis: calc(var(--moo-sidebar-width-icon) + #{$spacer});
|
|
32
|
+
width: calc(var(--moo-sidebar-width-icon) + #{$spacer});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.wrapper[data-layout="app"][data-sidebar-state="collapsed"] .sidebar[data-variant="floating"][data-collapsible="icon"] .sidebar-inner {
|
|
36
|
+
box-shadow: var(--bs-box-shadow);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@media (prefers-reduced-motion: reduce) {
|
|
41
|
+
.sidebar {
|
|
42
|
+
transition: none;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Inset App variant: the App shell owns the background and makes the Page a
|
|
2
|
+
// sibling inset surface. Sidebar keeps only its inner navigation anatomy.
|
|
3
|
+
|
|
4
|
+
@include media-breakpoint-up(lg) {
|
|
5
|
+
.wrapper[data-layout="app"]:has(> .sidebar[data-variant="inset"]) {
|
|
6
|
+
background: var(--moo-sidebar);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.wrapper[data-layout="app"]:has(> .sidebar[data-variant="inset"]) > [data-slot="page"] {
|
|
10
|
+
margin: $spacer * 0.5;
|
|
11
|
+
margin-left: 0;
|
|
12
|
+
border-radius: var(--bs-border-radius-xl);
|
|
13
|
+
box-shadow: var(--bs-box-shadow-sm);
|
|
14
|
+
background: var(--bs-body-bg);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.wrapper[data-layout="app"][data-sidebar-state="collapsed"]:has(> .sidebar[data-variant="inset"]) > [data-slot="page"] {
|
|
18
|
+
margin-left: $spacer * 0.5;
|
|
19
|
+
}
|
|
20
|
+
|
|
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;
|
|
24
|
+
}
|
|
25
|
+
|
|
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;
|
|
28
|
+
}
|
|
29
|
+
}
|
package/scss/moo-core.scss
CHANGED
|
@@ -4,9 +4,7 @@
|
|
|
4
4
|
* Includes Bootstrap 5.3.3 component output
|
|
5
5
|
* SPDX-License-Identifier: MIT
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
|
-
$moo-spinner-animation-name: moo-spinner-rotate;
|
|
9
|
-
|
|
7
|
+
@import "settings/options";
|
|
10
8
|
@import "bootstrap/scss/functions";
|
|
11
9
|
@import "settings";
|
|
12
10
|
@import "bootstrap/scss/variables";
|
|
@@ -14,34 +12,8 @@ $moo-spinner-animation-name: moo-spinner-rotate;
|
|
|
14
12
|
@import "bootstrap/scss/maps";
|
|
15
13
|
@import "bootstrap/scss/mixins";
|
|
16
14
|
@import "bootstrap/scss/utilities";
|
|
17
|
-
@import "themes/
|
|
18
|
-
@import "foundations/
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
@include moo-core-shared;
|
|
23
|
-
@include moo-core-light;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
:where(html, body)[data-bs-theme="dark"] .moo-ui:not([data-bs-theme]) {
|
|
27
|
-
@include moo-core-dark;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
.moo-ui[data-bs-theme="light"] {
|
|
31
|
-
@include moo-core-light;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
.moo-ui[data-bs-theme="dark"] {
|
|
35
|
-
@include moo-core-dark;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
.moo-ui[dir="rtl"] {
|
|
39
|
-
direction: rtl;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
@scope (.moo-ui) {
|
|
43
|
-
@import "components";
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
@import "foundations/core_state_layer";
|
|
47
|
-
@import "foundations/overlay_backdrop";
|
|
15
|
+
@import "themes/theme";
|
|
16
|
+
@import "foundations/globals";
|
|
17
|
+
@import "foundations/backdrop";
|
|
18
|
+
@import "themes/root";
|
|
19
|
+
@import "foundations/scope";
|
package/scss/moo-ui.scss
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
@import "settings";
|
|
2
|
-
|
|
3
|
-
@import "bootstrap/scss/mixins/banner";
|
|
4
|
-
@include bsBanner("");
|
|
2
|
+
@import "mixins/banner";
|
|
5
3
|
|
|
6
4
|
// Bootstrap configuration
|
|
7
5
|
@import "bootstrap/scss/functions";
|
|
@@ -10,10 +8,12 @@
|
|
|
10
8
|
@import "bootstrap/scss/maps";
|
|
11
9
|
@import "bootstrap/scss/mixins";
|
|
12
10
|
@import "bootstrap/scss/utilities";
|
|
11
|
+
@import "themes/theme";
|
|
13
12
|
|
|
14
13
|
// Bootstrap layout and standalone-only components
|
|
15
14
|
@import "bootstrap/scss/root";
|
|
16
|
-
@import "themes/
|
|
15
|
+
@import "themes/root";
|
|
16
|
+
@import "themes/standalone";
|
|
17
17
|
@import "bootstrap/scss/reboot";
|
|
18
18
|
@import "bootstrap/scss/type";
|
|
19
19
|
@import "bootstrap/scss/images";
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
@import "bootstrap/scss/utilities/api";
|
|
47
47
|
|
|
48
48
|
@import "utilities/scroll_fade_primitives";
|
|
49
|
-
@import "
|
|
50
|
-
@import "foundations/
|
|
49
|
+
@import "foundations/backdrop";
|
|
50
|
+
@import "foundations/scope";
|
|
@@ -4,6 +4,10 @@ $btn-box-shadow: none !default;
|
|
|
4
4
|
$btn-focus-box-shadow: none !default;
|
|
5
5
|
$btn-active-box-shadow: none !default;
|
|
6
6
|
|
|
7
|
+
// Keep Bootstrap's CSS Grid utility layer available alongside the Flexbox
|
|
8
|
+
// grid so native .grid and .g-col-* markup works in Moo UI hosts.
|
|
9
|
+
$enable-cssgrid: true !default;
|
|
10
|
+
|
|
7
11
|
// Bootstrap validation icons are background images injected by the native
|
|
8
12
|
// validation mixin. Reference-style invalid fields use border/ring + error text
|
|
9
13
|
// without a trailing status glyph, so disable the Bootstrap icon branch at the
|
|
@@ -255,6 +255,20 @@ $btn-padding-y-sm: 0.3125rem !default;
|
|
|
255
255
|
$btn-padding-x-sm: 0.625rem !default;
|
|
256
256
|
$btn-padding-y-lg: 0.4375rem !default;
|
|
257
257
|
$btn-padding-x-lg: 0.625rem !default;
|
|
258
|
+
|
|
259
|
+
// Bootstrap exposes button padding, but it has no command/search-trigger
|
|
260
|
+
// composition or responsive width scale. Keep this shared control's geometry
|
|
261
|
+
// on private knobs so Catalog and Odoo consume one Core contract instead of
|
|
262
|
+
// copying chrome-specific literals into their own stylesheets.
|
|
263
|
+
$moo-search-trigger-height: 2rem !default;
|
|
264
|
+
$moo-search-trigger-width: 10rem !default;
|
|
265
|
+
$moo-search-trigger-width-lg: 13rem !default;
|
|
266
|
+
$moo-search-trigger-width-xxl: 16rem !default;
|
|
267
|
+
$moo-search-trigger-padding-y: 0.5rem !default;
|
|
268
|
+
$moo-search-trigger-padding-x: 0.75rem !default;
|
|
269
|
+
$moo-search-trigger-border-color: transparent !default;
|
|
270
|
+
$moo-search-trigger-label-gap: 0.5rem !default;
|
|
271
|
+
$moo-search-trigger-shortcut-gap: 0.25rem !default;
|
|
258
272
|
// Icon-only buttons are squares whose side equals the token-driven button
|
|
259
273
|
// height (line-height + 2*padding-y + 2*border), matching sibling text
|
|
260
274
|
// buttons. Bootstrap exposes no single icon-button size knob; the side is a
|
|
@@ -305,9 +319,14 @@ $moo-form-focus-ring-color: var(--moo-ring) !default;
|
|
|
305
319
|
// backdrops. Bootstrap exposes separate .modal-backdrop and
|
|
306
320
|
// .offcanvas-backdrop selectors; Moo keeps their visual treatment aligned via
|
|
307
321
|
// one token set instead of per-component backdrop rules.
|
|
322
|
+
// Bootstrap defaults both native panels to .3s; retain that default while
|
|
323
|
+
// exposing one runtime duration token for the panel and its backdrop.
|
|
324
|
+
$moo-overlay-motion-duration: .3s !default;
|
|
325
|
+
$modal-transition: transform var(--moo-overlay-motion-duration, #{$moo-overlay-motion-duration}) ease-out !default;
|
|
326
|
+
$offcanvas-transition-duration: var(--moo-overlay-motion-duration, #{$moo-overlay-motion-duration}) !default;
|
|
308
327
|
$moo-overlay-backdrop-opacity: 1 !default;
|
|
309
328
|
$moo-overlay-backdrop-bg: color-mix(in srgb, #0a0a0a 10%, transparent) !default;
|
|
310
|
-
$moo-overlay-backdrop-filter: blur(
|
|
329
|
+
$moo-overlay-backdrop-filter: blur(6px) !default;
|
|
311
330
|
|
|
312
331
|
// A quieter elevation scale and the extra radius step, applied UI-wide through
|
|
313
332
|
// Bootstrap's own scales so every component consumes one shared primitive.
|
|
@@ -112,7 +112,7 @@ $moo-sidebar-dark: #1c1c1f !default;
|
|
|
112
112
|
$moo-input-bg-dark: color-mix(in srgb, $moo-muted-surface-dark 50%, $moo-surface-dark) !default;
|
|
113
113
|
|
|
114
114
|
// Bootstrap root variables consumed by the scoped core build. Define them
|
|
115
|
-
// here so themes/
|
|
115
|
+
// here so themes/_theme.scss can emit Bootstrap's root contract without
|
|
116
116
|
// hardcoded consumer-side literals.
|
|
117
117
|
$body-tertiary-color: #a1a1aa !default;
|
|
118
118
|
$body-tertiary-bg: $light !default;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
:scope[data-bs-theme="light"] .form-select {
|
|
2
|
+
--#{$prefix}form-select-bg-img: #{escape-svg($form-select-indicator)};
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
:scope[data-bs-theme="dark"] .form-select {
|
|
6
|
+
--#{$prefix}form-select-bg-img: #{escape-svg($form-select-indicator-dark)};
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
:scope[data-bs-theme="light"] .form-switch .form-check-input:not(:checked):not(:focus) {
|
|
10
|
+
--#{$prefix}form-switch-bg: #{escape-svg($form-switch-bg-image)};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
:scope[data-bs-theme="dark"] .form-switch .form-check-input:not(:checked):not(:focus) {
|
|
14
|
+
--#{$prefix}form-switch-bg: #{escape-svg($form-switch-bg-image-dark)};
|
|
15
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
.moo-ui[data-bs-theme] {
|
|
2
|
+
@include moo-core-scales;
|
|
3
|
+
@include moo-core-shared;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.moo-ui[data-bs-theme="light"] {
|
|
7
|
+
@include moo-core-light;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.moo-ui[data-bs-theme="dark"] {
|
|
11
|
+
@include moo-core-dark;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.moo-ui[data-bs-theme][dir="rtl"] {
|
|
15
|
+
direction: rtl;
|
|
16
|
+
}
|
|
@@ -77,6 +77,7 @@ $moo-theme-colors-border-subtle-dark: (
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
@mixin moo-core-shared {
|
|
80
|
+
--moo-overlay-motion-duration: #{$moo-overlay-motion-duration};
|
|
80
81
|
--moo-overlay-backdrop-opacity: #{$moo-overlay-backdrop-opacity};
|
|
81
82
|
--moo-overlay-backdrop-bg: #{$moo-overlay-backdrop-bg};
|
|
82
83
|
--moo-overlay-backdrop-filter: #{$moo-overlay-backdrop-filter};
|