@wpmoo/ui 1.0.0-rc.3 → 1.0.0-rc.4
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 +3 -1
- package/README.md +51 -123
- package/certification.json +14 -2
- package/dist/assets/css/moo-ui.css +55 -15
- package/dist/assets/css/moo-ui.min.css +3 -3
- package/dist/assets/css/moo.css +49 -15
- package/dist/assets/css/moo.min.css +3 -3
- package/dist/js/chart.js +1 -1
- package/dist/js/chart.min.js +1 -1
- package/dist/js/combobox.js +71 -18
- package/dist/js/context-menu.js +1 -1
- package/dist/js/datatable.js +1 -1
- package/dist/js/datepicker.js +1 -1
- package/dist/js/datepicker.min.js +1 -1
- package/dist/js/moo-ui.js +18950 -0
- package/dist/js/moo-ui.min.js +27 -0
- package/dist/js/sidebar.js +1 -1
- package/dist/js/slider.js +1 -1
- package/package.json +12 -4
- package/scss/_components.scss +73 -0
- package/scss/_settings.scss +8 -0
- package/scss/components/_accordion.scss +59 -0
- package/scss/components/_alert.scss +94 -0
- package/scss/components/_avatar.scss +154 -0
- package/scss/components/_badge.scss +33 -0
- package/scss/components/_breadcrumb.scss +130 -0
- package/scss/components/_button.scss +228 -0
- package/scss/components/_button_group.scss +51 -0
- package/scss/components/_card.scss +142 -0
- package/scss/components/_checkbox.scss +115 -0
- package/scss/components/_close_button.scss +59 -0
- package/scss/components/_collapsible.scss +43 -0
- package/scss/components/_combobox.scss +258 -0
- package/scss/components/_context-menu.scss +28 -0
- package/scss/components/_datatable.scss +1082 -0
- package/scss/components/_datepicker.scss +236 -0
- package/scss/components/_dialog.scss +66 -0
- package/scss/components/_dropdown.scss +202 -0
- package/scss/components/_field.scss +125 -0
- package/scss/components/_input.scss +35 -0
- package/scss/components/_input_group.scss +201 -0
- package/scss/components/_kbd.scss +10 -0
- package/scss/components/_menubar.scss +16 -0
- package/scss/components/_navigation.scss +41 -0
- package/scss/components/_pagination.scss +70 -0
- package/scss/components/_popover.scss +47 -0
- package/scss/components/_progress.scss +7 -0
- package/scss/components/_radio_group.scss +9 -0
- package/scss/components/_select.scss +7 -0
- package/scss/components/_separator.scss +15 -0
- package/scss/components/_sheet.scss +32 -0
- package/scss/components/_sidebar.scss +7 -0
- package/scss/components/_skeleton.scss +17 -0
- package/scss/components/_slider.scss +214 -0
- package/scss/components/_spinner.scss +17 -0
- package/scss/components/_switch.scss +25 -0
- package/scss/components/_table.scss +7 -0
- package/scss/components/_tabs.scss +139 -0
- package/scss/components/_textarea.scss +7 -0
- package/scss/components/_toast.scss +119 -0
- package/scss/components/_toggle_group.scss +19 -0
- package/scss/components/_tooltip.scss +83 -0
- package/scss/components/sidebar/_collapsed.scss +187 -0
- package/scss/components/sidebar/_identity.scss +72 -0
- package/scss/components/sidebar/_inset.scss +59 -0
- package/scss/components/sidebar/_layout.scss +176 -0
- package/scss/components/sidebar/_menus.scss +236 -0
- package/scss/foundations/_core_global_primitives.scss +5 -0
- package/scss/foundations/_core_state_layer.scss +25 -0
- package/scss/foundations/_focus.scss +139 -0
- package/scss/foundations/_overlay_backdrop.scss +19 -0
- package/scss/moo-core.scss +47 -0
- package/scss/moo-ui.scss +50 -0
- package/scss/settings/_bootstrap_overrides.scss +11 -0
- package/scss/settings/_component_variables.scss +479 -0
- package/scss/settings/_forms.scss +65 -0
- package/scss/settings/_palette.scss +132 -0
- package/scss/themes/_scoped_core.scss +239 -0
- package/scss/themes/_standalone_root.scss +117 -0
- package/scss/utilities/_scroll_fade.scss +193 -0
- package/scss/utilities/_scroll_fade_primitives.scss +43 -0
- package/THIRD_PARTY_NOTICES.md +0 -53
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
// Bootstrap's native input-group keeps borders/radii on each child and trims
|
|
2
|
+
// only the inner-facing seams (see the Bootstrap 5.3.3 input-group Sass
|
|
3
|
+
// source). Moo promotes the border to the parent so icon/text addons read as
|
|
4
|
+
// regions inside one compound input, but still leaves each edge child's own
|
|
5
|
+
// outer corner radius aligned with the parent instead of flattening it.
|
|
6
|
+
.input-group:not(:has(> .form-control[type="file"])) {
|
|
7
|
+
border: $input-border-width solid $input-border-color;
|
|
8
|
+
border-radius: var(--moo-input-group-border-radius);
|
|
9
|
+
background-color: var(--moo-input-bg, transparent);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Keep compound surfaces clipped, but let a directly attached menu escape so
|
|
13
|
+
// Bootstrap's positioned dropdown remains visible outside the input row.
|
|
14
|
+
.input-group:not(:has(> .form-control[type="file"])):not(:has(> .dropdown-menu)) {
|
|
15
|
+
overflow: hidden;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.input-group.rounded-pill:not(:has(> .form-control[type="file"])) {
|
|
19
|
+
--moo-input-group-border-radius: var(--bs-border-radius-pill);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// references/bootstrap/5.3.3/scss/forms/_input-group.scss:9 sets align-items:
|
|
23
|
+
// stretch on .input-group by default (this previously overrode it to center;
|
|
24
|
+
// restored here since stretch is what makes children fill the row with no
|
|
25
|
+
// centering rounding). Bootstrap's own .input-group carries no border of its
|
|
26
|
+
// own — border-height math lives entirely on each child, which is why a
|
|
27
|
+
// plain $input-height "just works" there. Moo moves that border to the
|
|
28
|
+
// parent instead, so the parent's own border needs its own extra space on
|
|
29
|
+
// top of $input-height, or children sized to a full $input-height (as
|
|
30
|
+
// .form-control and .btn both are here) overflow the parent's inner content
|
|
31
|
+
// box by exactly 2 * $input-border-width — this is what actually poked past
|
|
32
|
+
// the rounded corner, not the corner radius itself.
|
|
33
|
+
//
|
|
34
|
+
// Excludes groups with validation feedback (feedback wraps below the control)
|
|
35
|
+
// and the block-align case (a [data-align] addon wrapping to its own row
|
|
36
|
+
// below/above the control): the fixed single-row height here has higher
|
|
37
|
+
// specificity than the auto-height override further down for that case
|
|
38
|
+
// (:not(:has(...)) chains add specificity these two-class selectors don't),
|
|
39
|
+
// so without this exclusion the parent stayed pinned to one row's height
|
|
40
|
+
// and the wrapped addon rendered outside its own border box entirely.
|
|
41
|
+
.input-group:not(:has(> :is(.valid-feedback, .invalid-feedback, .valid-tooltip, .invalid-tooltip))):not(:has(textarea)):not(:has(> .form-control[type="file"])):not(:has(> [data-align])) {
|
|
42
|
+
height: calc(#{$input-height} + #{$input-border-width} * 2);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.input-group:not(:has(> :is(.valid-feedback, .invalid-feedback, .valid-tooltip, .invalid-tooltip))):not(:has(textarea)):not(:has(> .form-control[type="file"])):not(:has(> [data-align])) > .form-control {
|
|
46
|
+
min-height: 0;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.input-group > textarea.form-control {
|
|
50
|
+
resize: none;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.input-group:not(:has(> .form-control[type="file"])) > :not(:first-child):not([class~="dropdown-menu"]):not([class~="valid-tooltip"]):not([class~="valid-feedback"]):not([class~="invalid-tooltip"]):not([class~="invalid-feedback"]) {
|
|
54
|
+
margin: 0;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.input-group:not(:has(> .form-control[type="file"])) > :not(ul) {
|
|
58
|
+
border: 0;
|
|
59
|
+
border-radius: 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Restore the outer corner Bootstrap's own edge child would already carry:
|
|
63
|
+
// Bootstrap only zeros the inner-facing side of a non-edge child, never the
|
|
64
|
+
// outer side of an edge one. The trailing side also matches when a dropdown
|
|
65
|
+
// menu is the real last DOM child, since the visible trailing control sits
|
|
66
|
+
// right before it.
|
|
67
|
+
.input-group:not(:has(> .form-control[type="file"])) > :first-child:not(ul) {
|
|
68
|
+
border-start-start-radius: var(--moo-input-group-border-radius);
|
|
69
|
+
border-end-start-radius: var(--moo-input-group-border-radius);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.input-group:not(:has(> .form-control[type="file"])) > :is(:last-child, :nth-last-child(2):has(+ .dropdown-menu)):not(ul) {
|
|
73
|
+
border-start-end-radius: var(--moo-input-group-border-radius);
|
|
74
|
+
border-end-end-radius: var(--moo-input-group-border-radius);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.input-group > :is(button, a) {
|
|
78
|
+
border: var(--bs-btn-border-width) var(--bs-border-style) var(--bs-btn-border-color);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Ghost buttons inside a compound input should read as inline affordances, not
|
|
82
|
+
// standalone buttons. Keep Bootstrap's --bs-btn-* contract, but scope the
|
|
83
|
+
// hover/active surface to the small control instead of repainting the compound
|
|
84
|
+
// input edge.
|
|
85
|
+
.input-group > .btn-ghost {
|
|
86
|
+
--bs-btn-hover-bg: transparent;
|
|
87
|
+
--bs-btn-active-bg: transparent;
|
|
88
|
+
position: relative;
|
|
89
|
+
isolation: isolate;
|
|
90
|
+
border-radius: var(--moo-input-group-border-radius) !important;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Match the reference input-group affordance: the compound input stays clear,
|
|
94
|
+
// while the hovered control gets a small inset surface. The surface reuses
|
|
95
|
+
// the existing Moo muted token and Bootstrap radius instead of adding a
|
|
96
|
+
// component-specific color or geometry value.
|
|
97
|
+
.input-group > .btn-ghost::before {
|
|
98
|
+
position: absolute;
|
|
99
|
+
inset: $spacer * 0.25;
|
|
100
|
+
z-index: -1;
|
|
101
|
+
content: "";
|
|
102
|
+
border-radius: var(--moo-input-group-border-radius);
|
|
103
|
+
background-color: var(--moo-muted-surface);
|
|
104
|
+
opacity: 0;
|
|
105
|
+
transition: opacity $transition-fade;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.input-group > .btn-ghost:hover::before,
|
|
109
|
+
.input-group > .btn-ghost:is(.show, [aria-expanded="true"])::before {
|
|
110
|
+
opacity: 1;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.input-group > .btn-ghost:is(.show, [aria-expanded="true"]) {
|
|
114
|
+
color: var(--bs-btn-active-color);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.input-group > .btn-ghost[aria-pressed="true"] {
|
|
118
|
+
color: var(--bs-btn-active-color);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.input-group > .btn-ghost[aria-pressed="true"]::before {
|
|
122
|
+
opacity: 1;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.input-group > .btn:not(:disabled):not(.disabled):not([aria-disabled="true"]):active {
|
|
126
|
+
transform: none;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.input-group > :is(.btn-xs, .btn-icon-xs) {
|
|
130
|
+
--bs-btn-padding-y: #{$spacer * 0.125};
|
|
131
|
+
--bs-btn-padding-x: #{$spacer * 0.375};
|
|
132
|
+
--bs-btn-line-height: #{$spacer * 0.875};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.input-group > .input-group-text {
|
|
136
|
+
color: var(--bs-secondary-color);
|
|
137
|
+
// bg intentionally omitted — Bootstrap's addon token consumes the same
|
|
138
|
+
// --moo-input-bg surface as the parent compound input.
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.input-group > .input-group-text:first-child {
|
|
142
|
+
padding-inline-end: 0;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.input-group > .input-group-text:first-child + .form-control {
|
|
146
|
+
padding-inline-start: $input-btn-padding-y;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.input-group > .input-group-text:last-child {
|
|
150
|
+
padding-inline-start: 0;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.input-group > .form-control:has(+ .input-group-text:last-child) {
|
|
154
|
+
padding-inline-end: $input-btn-padding-y;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.input-group-text > [data-icon] {
|
|
158
|
+
width: 1rem;
|
|
159
|
+
height: 1rem;
|
|
160
|
+
flex: 0 0 auto;
|
|
161
|
+
color: var(--bs-secondary-color);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.input-group:has(> [data-align]) {
|
|
165
|
+
height: auto;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.input-group > [data-align] {
|
|
169
|
+
display: flex;
|
|
170
|
+
flex-basis: 100%;
|
|
171
|
+
align-items: center;
|
|
172
|
+
width: 100%;
|
|
173
|
+
padding: $input-btn-padding-y $input-padding-x $input-padding-y-lg;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.input-group > [data-align="block-start"] {
|
|
177
|
+
order: -1;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.input-group > [data-align] > .input-group-text {
|
|
181
|
+
padding: 0;
|
|
182
|
+
color: var(--bs-secondary-color);
|
|
183
|
+
border: 0;
|
|
184
|
+
background-color: transparent;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// The input-group's own compound focus-visible ring lives in
|
|
188
|
+
// foundations/_focus.scss, next to the other compound-control rings, instead
|
|
189
|
+
// of here -- see that file's comment for why.
|
|
190
|
+
|
|
191
|
+
// Scoped to the native form control itself, not "any focused child": the
|
|
192
|
+
// input-group already carries its own compound glow from the rule above, so
|
|
193
|
+
// only the .form-control/.form-select that would otherwise draw a second,
|
|
194
|
+
// competing glow needs its own default suppressed. A bare > :focus also
|
|
195
|
+
// matched dropdown-toggle buttons living in the same input-group (e.g. Data
|
|
196
|
+
// Table's filter-picker trigger), and its (0,4,0) specificity beat those
|
|
197
|
+
// buttons' own :focus-visible keyboard ring outright.
|
|
198
|
+
.input-group:not(:has(> .form-control[type="file"])) > :is(.form-control, .form-select):focus {
|
|
199
|
+
outline: 0;
|
|
200
|
+
box-shadow: none;
|
|
201
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
.menubar {
|
|
2
|
+
gap: $moo-menubar-gap;
|
|
3
|
+
padding: $moo-menubar-padding;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.menubar .dropdown-menu {
|
|
7
|
+
z-index: $zindex-dropdown;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.menubar [data-bs-toggle="dropdown"].show,
|
|
11
|
+
.menubar .dropdown-toggle.show {
|
|
12
|
+
--bs-btn-color: var(--moo-foreground);
|
|
13
|
+
|
|
14
|
+
color: var(--bs-btn-color);
|
|
15
|
+
font-weight: $font-weight-medium;
|
|
16
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
.nav {
|
|
2
|
+
--bs-nav-link-color: var(--moo-foreground);
|
|
3
|
+
--bs-nav-link-hover-color: var(--moo-foreground);
|
|
4
|
+
--bs-nav-link-disabled-color: var(--moo-disabled-foreground);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.nav-pills {
|
|
8
|
+
--bs-nav-pills-border-radius: var(--bs-border-radius);
|
|
9
|
+
--bs-nav-pills-link-active-color: var(--moo-foreground);
|
|
10
|
+
--bs-nav-pills-link-active-bg: var(--moo-muted-surface);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.nav-link {
|
|
14
|
+
display: inline-flex;
|
|
15
|
+
align-items: center;
|
|
16
|
+
gap: $spacer * 0.5;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.nav.flex-column .nav-link {
|
|
20
|
+
width: 100%;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.nav-pills .nav-link:not(.active, .disabled):hover {
|
|
24
|
+
background-color: var(--moo-muted-surface);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// The active pill's own background (--bs-nav-pills-link-active-bg above)
|
|
28
|
+
// is a persistent class-based state, so it stays lit even while a
|
|
29
|
+
// different pill is hovered -- two pills highlighted at once, competing
|
|
30
|
+
// for attention. Suppress it only while another pill in the same group is
|
|
31
|
+
// hovered, so exactly one pill is ever highlighted: whichever the cursor
|
|
32
|
+
// is over, or the active one when nothing is hovered.
|
|
33
|
+
.nav-pills:has(.nav-link:hover) .nav-link.active:not(:hover) {
|
|
34
|
+
background-color: transparent;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.nav-link [data-icon] {
|
|
38
|
+
width: 1rem;
|
|
39
|
+
height: 1rem;
|
|
40
|
+
flex: 0 0 auto;
|
|
41
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Bootstrap's page-link class has no icon-sizing contract; unconstrained
|
|
2
|
+
// SVGs render at an oversized default (~55px), breaking Previous/Next and
|
|
3
|
+
// the ellipsis item. Size and align icons the same way other components
|
|
4
|
+
// with inline icons already constrain their own [data-icon] children.
|
|
5
|
+
//
|
|
6
|
+
// Bootstrap's own padding is asymmetric (more horizontal than vertical), so
|
|
7
|
+
// a single digit or icon renders narrower than it is tall -- a squashed
|
|
8
|
+
// look next to the surrounding icon-only buttons. min-width/min-height (not
|
|
9
|
+
// width/height) square up short content without constraining longer labels
|
|
10
|
+
// like the optional "Previous"/"Next" text. Both are needed, not just
|
|
11
|
+
// width: the 1rem icon glyph is shorter than a text digit's own line-height,
|
|
12
|
+
// so icon-only page-links (Prev/Next/First/Last) would otherwise render a
|
|
13
|
+
// couple pixels shorter than the numbered page-links next to them.
|
|
14
|
+
.page-link {
|
|
15
|
+
$page-link-square-size: calc(
|
|
16
|
+
#{$moo-chip-height} + #{$moo-pagination-square-inset} + var(--bs-pagination-border-width) * 2
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
display: inline-flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
justify-content: center;
|
|
22
|
+
flex-shrink: 0;
|
|
23
|
+
gap: $spacer * 0.375;
|
|
24
|
+
min-width: $page-link-square-size;
|
|
25
|
+
min-height: $page-link-square-size;
|
|
26
|
+
line-height: 1.25rem;
|
|
27
|
+
font-weight: 500;
|
|
28
|
+
white-space: nowrap;
|
|
29
|
+
user-select: none;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.page-link[aria-label]:has(> span:not(.visually-hidden):not(.d-none)):has([data-icon="inline-start"]) {
|
|
33
|
+
padding-inline-start: $spacer * 0.375;
|
|
34
|
+
padding-inline-end: $spacer * 0.625;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.page-link[aria-label]:has(> span:not(.visually-hidden):not(.d-none)):has([data-icon="inline-end"]) {
|
|
38
|
+
padding-inline-start: $spacer * 0.625;
|
|
39
|
+
padding-inline-end: $spacer * 0.375;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@include media-breakpoint-up(sm) {
|
|
43
|
+
.page-link[aria-label]:has(> .d-sm-inline):has([data-icon="inline-start"]) {
|
|
44
|
+
padding-inline-start: $spacer * 0.375;
|
|
45
|
+
padding-inline-end: $spacer * 0.625;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.page-link[aria-label]:has(> .d-sm-inline):has([data-icon="inline-end"]) {
|
|
49
|
+
padding-inline-start: $spacer * 0.625;
|
|
50
|
+
padding-inline-end: $spacer * 0.375;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.page-link:has([data-icon]):not(:has(> span:not(.visually-hidden))) {
|
|
55
|
+
padding-inline: 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.page-link [data-icon] {
|
|
59
|
+
width: $spacer;
|
|
60
|
+
height: $spacer;
|
|
61
|
+
flex: 0 0 auto;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.page-item:not(.disabled) .page-link:active {
|
|
65
|
+
transform: translateY($moo-control-active-translate-y);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.page-item.disabled {
|
|
69
|
+
opacity: var(--moo-disabled-control-opacity);
|
|
70
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Bootstrap's popover is fully token-driven already (see the vendored
|
|
2
|
+
// Bootstrap popover partial), so this partial only retunes those same
|
|
3
|
+
// --bs-popover-* custom properties toward the design reference: a single
|
|
4
|
+
// borderless-feeling card (no two-tone header bar, no directional arrow,
|
|
5
|
+
// larger radius, quieter shadow, uniform padding) instead of Bootstrap's
|
|
6
|
+
// own outlined-header-plus-arrow look.
|
|
7
|
+
.popover {
|
|
8
|
+
--bs-popover-border-radius: var(--bs-border-radius-lg);
|
|
9
|
+
--bs-popover-border-color: var(--moo-border);
|
|
10
|
+
--bs-popover-header-bg: var(--bs-popover-bg);
|
|
11
|
+
--bs-popover-header-color: var(--bs-popover-body-color);
|
|
12
|
+
--bs-popover-header-padding-x: #{$spacer * 0.625};
|
|
13
|
+
--bs-popover-header-padding-y: #{$spacer * 0.625};
|
|
14
|
+
--bs-popover-body-padding-x: #{$spacer * 0.625};
|
|
15
|
+
--bs-popover-body-padding-y: #{$spacer * 0.625};
|
|
16
|
+
// The reference popover body/title both sit at text-sm (14px); Bootstrap's
|
|
17
|
+
// own $popover-font-size default is $font-size-sm, a notch smaller here.
|
|
18
|
+
--bs-popover-font-size: 0.875rem;
|
|
19
|
+
line-height: 1.43;
|
|
20
|
+
// The reference always renders a fixed 320px panel regardless of content,
|
|
21
|
+
// unlike Bootstrap's own shrink-to-fit-up-to-max-width sizing; max-width
|
|
22
|
+
// must move too, or Bootstrap's own 276px default clips the wider fixed
|
|
23
|
+
// width straight back down.
|
|
24
|
+
--bs-popover-max-width: 20rem;
|
|
25
|
+
width: 20rem;
|
|
26
|
+
// $enable-shadows is off project-wide, which turns Bootstrap's own
|
|
27
|
+
// box-shadow() mixin into a no-op, so this must be a literal property
|
|
28
|
+
// consuming a shared token directly. None of the shared tiers land
|
|
29
|
+
// exactly on the shadow-md weight the design reference uses; -lg is the
|
|
30
|
+
// closer of the two available neighbors (component styles may not
|
|
31
|
+
// hardcode raw color values, only reference existing --bs-*box-shadow*
|
|
32
|
+
// tokens, so a one-off value here is not an option).
|
|
33
|
+
box-shadow: var(--bs-box-shadow-lg);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.popover-header {
|
|
37
|
+
padding-bottom: 0;
|
|
38
|
+
border-bottom: 0;
|
|
39
|
+
font-weight: $font-weight-medium;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// The design reference's popover has no directional arrow; Bootstrap ships
|
|
43
|
+
// one by default, nested under .popover so it must be matched at the same
|
|
44
|
+
// specificity here.
|
|
45
|
+
.popover .popover-arrow {
|
|
46
|
+
display: none;
|
|
47
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Bootstrap exposes progress fill as a component CSS variable. Keep the track
|
|
2
|
+
// geometry native, but bind the fill to the same runtime primary token used by
|
|
3
|
+
// buttons, checked controls, and active selection affordances.
|
|
4
|
+
.progress {
|
|
5
|
+
--bs-progress-bar-color: var(--moo-primary-foreground);
|
|
6
|
+
--bs-progress-bar-bg: var(--moo-primary);
|
|
7
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Bootstrap's <legend> ships a heading-sized (1.5rem) default font-size
|
|
2
|
+
// that .form-label doesn't reset: form-label's own font-size is null
|
|
3
|
+
// (inherit) by default, which only works for bare <label> elements that
|
|
4
|
+
// never had a UA font-size of their own. Reset it explicitly, the same
|
|
5
|
+
// fix Bootstrap's own horizontal-form label class applies for the same
|
|
6
|
+
// reason (see vendor Bootstrap's forms/labels partial).
|
|
7
|
+
.radio-group legend.form-label {
|
|
8
|
+
font-size: inherit;
|
|
9
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Bootstrap's own hr/.vr fake a light divider with a 25%-opacity trick
|
|
2
|
+
// over an inherited/currentColor value (vendor/bootstrap/scss/_reboot.scss,
|
|
3
|
+
// helpers/_vr.scss) instead of a flat border-color fill. That renders
|
|
4
|
+
// visibly darker than --moo-border, the flat divider color already used at
|
|
5
|
+
// full opacity everywhere else a hairline border appears and the closest
|
|
6
|
+
// match to the reference's own flat border-token separator fill.
|
|
7
|
+
hr {
|
|
8
|
+
opacity: 1;
|
|
9
|
+
border-top: var(--bs-border-width) solid var(--moo-border);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.vr {
|
|
13
|
+
opacity: 1;
|
|
14
|
+
background-color: var(--moo-border);
|
|
15
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Sheet is the Moo catalog name for Bootstrap's Offcanvas component, so this
|
|
2
|
+
// partial retunes Bootstrap's own --bs-offcanvas-* custom properties toward
|
|
3
|
+
// the design reference: a narrower fixed width, a quieter border tone, and
|
|
4
|
+
// a real elevation shadow, instead of Bootstrap's own wider, shadowless
|
|
5
|
+
// panel. Scoped to .offcanvas.sheet (see the "sheet" marker class in the
|
|
6
|
+
// sheet() macro) rather than the bare .offcanvas Bootstrap ships, because
|
|
7
|
+
// the Sidebar component's own mobile drawer also carries that bare class
|
|
8
|
+
// and already sets its own --bs-offcanvas-width; a bare-class rule here
|
|
9
|
+
// would silently win or lose depending on import order instead of losing
|
|
10
|
+
// predictably to Sidebar's own more specific root selector.
|
|
11
|
+
.offcanvas.sheet {
|
|
12
|
+
--bs-offcanvas-width: 24rem;
|
|
13
|
+
--bs-offcanvas-border-color: var(--moo-border);
|
|
14
|
+
// $enable-shadows is off project-wide, which turns Bootstrap's own
|
|
15
|
+
// box-shadow() mixin into a no-op, so this must be a literal property
|
|
16
|
+
// consuming a shared token directly.
|
|
17
|
+
box-shadow: var(--bs-box-shadow-lg);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.offcanvas.sheet[tabindex]:focus-visible {
|
|
21
|
+
// Bootstrap moves focus to the open panel. Preserve its elevation instead
|
|
22
|
+
// of letting the generic tabindex focus reset flatten the panel.
|
|
23
|
+
outline: none;
|
|
24
|
+
box-shadow: var(--bs-box-shadow-lg);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.offcanvas.sheet .offcanvas-title {
|
|
28
|
+
// A literal size, not $font-size-base: this project's own base is 14px,
|
|
29
|
+
// but the reference sheet title sits at a plain, un-scaled 16px regardless.
|
|
30
|
+
font-size: 1rem;
|
|
31
|
+
font-weight: $font-weight-medium;
|
|
32
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Bootstrap has no native sidebar, so this owned selector namespace is split
|
|
2
|
+
// by responsibility while preserving one deterministic emission order.
|
|
3
|
+
@import "sidebar/layout";
|
|
4
|
+
@import "sidebar/menus";
|
|
5
|
+
@import "sidebar/identity";
|
|
6
|
+
@import "sidebar/inset";
|
|
7
|
+
@import "sidebar/collapsed";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
.skeleton {
|
|
2
|
+
// Bootstrap's placeholder utility paints via currentcolor; recolor it here
|
|
3
|
+
// (border token keeps contrast in both themes) instead of fighting bg directly.
|
|
4
|
+
color: var(--moo-border);
|
|
5
|
+
border-radius: var(--bs-border-radius);
|
|
6
|
+
overflow: hidden;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// Bootstrap's .placeholder is inline-block with vertical-align:middle, meant
|
|
10
|
+
// to sit inline within a line of real text it's replacing. Here it's the
|
|
11
|
+
// sole content of a fixed-size block wrapper instead, where that inline
|
|
12
|
+
// vertical alignment leaves a gap at the top of the wrapper and pushes the
|
|
13
|
+
// bar's own bottom edge past it, clipped by the wrapper's overflow:hidden.
|
|
14
|
+
// Block-level sizing removes the line-box alignment entirely.
|
|
15
|
+
.skeleton > .placeholder {
|
|
16
|
+
display: block;
|
|
17
|
+
}
|