@wpmoo/ui 1.0.0-rc.8 → 1.0.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/ASSET_LICENSE.md +1 -1
- package/LICENSE +28 -0
- package/README.md +34 -6
- package/certification.json +3 -2
- package/dist/assets/css/moo-ui.css +634 -33
- package/dist/assets/css/moo-ui.min.css +10 -31
- package/dist/assets/css/moo.css +624 -30
- package/dist/assets/css/moo.min.css +10 -32
- package/dist/js/chart.js +23 -21
- package/dist/js/chart.min.js +5 -5
- package/dist/js/combobox.js +18 -65
- package/dist/js/context-menu.js +16 -68
- package/dist/js/datatable.js +39 -22
- package/dist/js/datepicker.js +4 -3
- package/dist/js/datepicker.min.js +4 -3
- package/dist/js/moo-ui.js +160 -15402
- package/dist/js/moo-ui.min.js +3 -23
- package/dist/js/sheet.js +46 -0
- package/dist/js/sidebar.js +5 -4
- package/dist/js/slider.js +12 -47
- package/dist/js/state.js +76 -0
- package/dist/release-manifest.json +6 -6
- package/package.json +5 -3
- package/scss/_components.scss +2 -2
- package/scss/_config.scss +15 -21
- package/scss/_settings.scss +0 -3
- package/scss/components/_accordion.scss +1 -12
- package/scss/components/_alert.scss +1 -12
- package/scss/components/_avatar.scss +1 -16
- package/scss/components/_badge.scss +1 -0
- package/scss/components/_breadcrumb.scss +1 -12
- package/scss/components/_button.scss +1 -29
- package/scss/components/_button_group.scss +1 -25
- package/scss/components/_card.scss +1 -29
- package/scss/components/_checkbox.scss +1 -38
- package/scss/components/_close_button.scss +1 -9
- package/scss/components/_collapsible.scss +1 -0
- package/scss/components/_combobox.scss +1 -6
- package/scss/components/_context-menu.scss +1 -11
- package/scss/components/_datatable.scss +46 -85
- package/scss/components/_datepicker.scss +1 -0
- package/scss/components/_dialog.scss +1 -14
- package/scss/components/_dropdown.scss +5 -51
- package/scss/components/_field.scss +6 -37
- package/scss/components/_input.scss +1 -5
- package/scss/components/_input_group.scss +1 -51
- package/scss/components/_kbd.scss +1 -0
- package/scss/components/_menubar.scss +1 -0
- package/scss/components/_navigation.scss +76 -6
- package/scss/components/_pagination.scss +1 -13
- package/scss/components/_popover.scss +1 -22
- package/scss/components/_progress.scss +1 -3
- package/scss/components/_radio_group.scss +105 -6
- package/scss/components/_search_trigger.scss +1 -2
- package/scss/components/_select.scss +1 -0
- package/scss/components/_separator.scss +1 -6
- package/scss/components/_sheet.scss +1 -17
- package/scss/components/_sidebar.scss +1 -2
- package/scss/components/_skeleton.scss +1 -8
- package/scss/components/_slider.scss +1 -2
- package/scss/components/_spinner.scss +1 -7
- package/scss/components/_switch.scss +1 -4
- package/scss/components/_table.scss +1 -2
- package/scss/components/_tabs.scss +1 -24
- package/scss/components/_textarea.scss +1 -0
- package/scss/components/_toast.scss +1 -4
- package/scss/components/_toggle_group.scss +1 -3
- package/scss/components/_tooltip.scss +1 -20
- package/scss/components/sidebar/_base.scss +0 -7
- package/scss/components/sidebar/_collapsed.scss +0 -6
- package/scss/components/sidebar/_identity.scss +0 -1
- package/scss/components/sidebar/_menus.scss +0 -17
- package/scss/foundations/_backdrop.scss +0 -26
- package/scss/foundations/_focus.scss +0 -56
- package/scss/foundations/_scope.scss +19 -0
- package/scss/layouts/_app.scss +5 -7
- package/scss/layouts/_page_grid.scss +27 -0
- package/scss/layouts/app/sidebar/_base.scss +0 -33
- package/scss/layouts/app/sidebar/_default.scss +2 -8
- package/scss/layouts/app/sidebar/_floating.scss +1 -9
- package/scss/layouts/app/sidebar/_inset.scss +5 -2
- package/scss/mixins/_banner.scss +9 -3
- package/scss/moo-core.scss +3 -6
- package/scss/moo-ui.scss +9 -5
- package/scss/settings/_bootstrap_overrides.scss +0 -8
- package/scss/settings/_component_variables.scss +4 -266
- package/scss/settings/_forms.scss +1 -38
- package/scss/settings/_palette.scss +0 -42
- package/scss/themes/_root.scss +4 -0
- package/scss/themes/_standalone.scss +1 -3
- package/scss/themes/_theme.scss +4 -0
- package/scss/utilities/_background_color.scss +18 -0
- package/scss/utilities/_border.scss +4 -0
- package/dist/js/theme-prepaint.js +0 -91
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
// partial retunes Bootstrap's own --bs-modal-* custom properties toward the
|
|
3
|
-
// design reference: a larger radius, a quieter border tone, a borderless
|
|
4
|
-
// header, one shared surface, and a lighter-weight tightly-set title, instead
|
|
5
|
-
// of Bootstrap's own sharper-cornered, divided, heavier-titled look.
|
|
1
|
+
/* Dialog */
|
|
6
2
|
.modal {
|
|
7
3
|
--bs-modal-border-radius: var(--bs-border-radius-xl);
|
|
8
4
|
--bs-modal-border-color: var(--moo-border);
|
|
@@ -13,9 +9,6 @@
|
|
|
13
9
|
}
|
|
14
10
|
|
|
15
11
|
.modal[tabindex]:focus-visible {
|
|
16
|
-
// Bootstrap focuses the modal root when it opens. The shared focus rule
|
|
17
|
-
// intentionally covers generic tabindex controls, so reset that container
|
|
18
|
-
// ring here without weakening focus treatment for actual controls.
|
|
19
12
|
outline: none;
|
|
20
13
|
}
|
|
21
14
|
|
|
@@ -24,8 +17,6 @@
|
|
|
24
17
|
}
|
|
25
18
|
|
|
26
19
|
.modal-title {
|
|
27
|
-
// A literal size, not $font-size-base: this project's own base is 14px,
|
|
28
|
-
// but the reference dialog title sits at a plain, un-scaled 16px regardless.
|
|
29
20
|
font-size: 1rem;
|
|
30
21
|
font-weight: $font-weight-medium;
|
|
31
22
|
}
|
|
@@ -35,8 +26,6 @@
|
|
|
35
26
|
}
|
|
36
27
|
|
|
37
28
|
.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
29
|
position: relative;
|
|
41
30
|
padding-inline-end: calc(
|
|
42
31
|
var(--bs-modal-padding) + #{$btn-close-width} + #{$btn-close-padding-x * 2} + 0.5rem
|
|
@@ -76,7 +65,5 @@
|
|
|
76
65
|
}
|
|
77
66
|
|
|
78
67
|
.modal-footer {
|
|
79
|
-
// Bootstrap derives this from --bs-modal-padding minus half the button
|
|
80
|
-
// gap (12px here); the reference footer keeps the full 16px card padding.
|
|
81
68
|
padding: $spacer;
|
|
82
69
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
// the native menu the reference's surface without a private Moo token layer.
|
|
1
|
+
/* Dropdown */
|
|
3
2
|
.dropdown-menu {
|
|
4
3
|
--bs-dropdown-bg: var(--moo-surface);
|
|
5
4
|
--bs-dropdown-border-color: var(--moo-border);
|
|
@@ -13,8 +12,6 @@
|
|
|
13
12
|
--bs-dropdown-link-disabled-color: var(--moo-disabled-foreground);
|
|
14
13
|
--bs-dropdown-header-color: var(--moo-muted-foreground);
|
|
15
14
|
|
|
16
|
-
// Bootstrap gates dropdown shadow behind $enable-shadows, so apply the
|
|
17
|
-
// shared elevation token directly after bridging it to --bs-dropdown-box-shadow.
|
|
18
15
|
box-shadow: var(--bs-dropdown-box-shadow);
|
|
19
16
|
}
|
|
20
17
|
|
|
@@ -26,29 +23,21 @@
|
|
|
26
23
|
gap: $spacer * 0.5;
|
|
27
24
|
}
|
|
28
25
|
|
|
29
|
-
// Bootstrap's own .dropdown-item bundles :hover and :focus into the same
|
|
30
|
-
// highlight (vendor/bootstrap/scss/_dropdown.scss), so an item that still
|
|
31
|
-
// holds DOM focus from a prior mouse click (clicking a button leaves it
|
|
32
|
-
// focused) keeps its highlight after the mouse moves to hover a different
|
|
33
|
-
// item -- two rows lit up at once. Resetting the stale, non-keyboard focus
|
|
34
|
-
// back to resting style (only when the item isn't also genuinely hovered,
|
|
35
|
-
// so real hover still wins) leaves exactly one item highlighted at a time;
|
|
36
|
-
// real keyboard :focus-visible navigation is untouched, since it's a subset
|
|
37
|
-
// of :focus and this selector explicitly excludes it.
|
|
38
26
|
.dropdown-item:focus:not(:focus-visible):not(:hover) {
|
|
39
27
|
color: var(--bs-dropdown-link-color);
|
|
40
28
|
background-color: transparent;
|
|
41
29
|
}
|
|
42
30
|
|
|
31
|
+
.dropdown-menu:has(.dropdown-item:hover) .dropdown-item.active:not(:hover) {
|
|
32
|
+
background-color: transparent;
|
|
33
|
+
}
|
|
34
|
+
|
|
43
35
|
.dropdown-item > [data-icon] {
|
|
44
36
|
width: 1rem;
|
|
45
37
|
height: 1rem;
|
|
46
38
|
flex: 0 0 auto;
|
|
47
39
|
}
|
|
48
40
|
|
|
49
|
-
// Destructive dropdown items use the shared --moo-destructive token so the
|
|
50
|
-
// red stays in sync with every other destructive control. Matches the
|
|
51
|
-
// reference pattern: red text at rest, destructive-tinted bg on hover.
|
|
52
41
|
.dropdown-item[data-variant="destructive"] {
|
|
53
42
|
color: var(--moo-destructive) !important;
|
|
54
43
|
}
|
|
@@ -79,14 +68,6 @@
|
|
|
79
68
|
background-color: var(--bs-dropdown-link-hover-bg);
|
|
80
69
|
}
|
|
81
70
|
|
|
82
|
-
// A checkbox-style menu item can't nest a real <input type="checkbox"> inside
|
|
83
|
-
// its <button> (invalid, inaccessible markup), so this indicator stands in
|
|
84
|
-
// for one. Sized off Bootstrap's own $form-check-input-* tokens and always
|
|
85
|
-
// showing its box (not opacity-toggled to nothing) so it reads as the same
|
|
86
|
-
// checkable control as Checkbox itself, wherever a menu uses it -- Menubar,
|
|
87
|
-
// Context Menu, and Data Table's column-visibility, page-size, and faceted
|
|
88
|
-
// filter menus all compose this one indicator rather than each inventing
|
|
89
|
-
// their own checkbox-adjacent look.
|
|
90
71
|
.dropdown-item-check__indicator {
|
|
91
72
|
--moo-dropdown-item-check-border-radius: #{$moo-dropdown-item-check-border-radius};
|
|
92
73
|
|
|
@@ -101,9 +82,6 @@
|
|
|
101
82
|
color: transparent;
|
|
102
83
|
}
|
|
103
84
|
|
|
104
|
-
// Matches Checkbox's own checked fill (scss/components/_checkbox.scss:
|
|
105
|
-
// $form-check-input-checked-bg-color, resolved to --moo-foreground) so a
|
|
106
|
-
// checked menu item and a checked Checkbox read as the same control.
|
|
107
85
|
.dropdown-item-check.active .dropdown-item-check__indicator {
|
|
108
86
|
background-color: var(--moo-foreground);
|
|
109
87
|
border-color: var(--moo-foreground);
|
|
@@ -115,12 +93,6 @@
|
|
|
115
93
|
height: 0.75rem;
|
|
116
94
|
}
|
|
117
95
|
|
|
118
|
-
// Single-choice ("radio") menu items reuse the same indicator markup as the
|
|
119
|
-
// checkbox variant above but read as a plain checkmark-on-select instead: no
|
|
120
|
-
// boxed square, since a box implies each item has its own independent on/off
|
|
121
|
-
// state, which is wrong when only one item in the group can ever be active
|
|
122
|
-
// (e.g. Data Table's page-size menu). The icon stays hidden until the item
|
|
123
|
-
// is active, matching how the reference and native menus mark single-choice items.
|
|
124
96
|
.dropdown-item-check--radio .dropdown-item-check__indicator {
|
|
125
97
|
border-color: transparent;
|
|
126
98
|
background-color: transparent;
|
|
@@ -150,28 +122,13 @@
|
|
|
150
122
|
height: 0.875rem;
|
|
151
123
|
}
|
|
152
124
|
|
|
153
|
-
// The Sidebar header/footer triggers (team switcher, account menu) span
|
|
154
|
-
// the sidebar's full width, and the design reference matches its menu
|
|
155
|
-
// width to that trigger so it extends past the sidebar edge into the content
|
|
156
|
-
// column. Bootstrap's own dropdown-menu only sizes to its own content, so
|
|
157
|
-
// match the trigger via the shared positioned dropdown ancestor's width
|
|
158
|
-
// instead. Scoped by data-slot attribute, not a sidebar class selector, so
|
|
159
|
-
// this stays inside the dropdown component's own selector ownership.
|
|
160
125
|
[data-slot="sidebar-header"] .dropdown-menu,
|
|
161
126
|
[data-slot="sidebar-footer"] .dropdown-menu {
|
|
162
127
|
--moo-dropdown-sidebar-min-width: #{$moo-dropdown-sidebar-min-width};
|
|
163
128
|
|
|
164
|
-
// unquote(): libsass resolves max() as its own Sass function and rejects
|
|
165
|
-
// var() as a non-numeric argument, so escape it through to plain CSS
|
|
166
|
-
// (same technique already used for clamp() in the catalog stylesheet).
|
|
167
129
|
min-width: #{unquote("max(100%, var(--moo-dropdown-sidebar-min-width))")};
|
|
168
130
|
}
|
|
169
131
|
|
|
170
|
-
// Header identity menus reuse the Sidebar account-menu body. Keep the same
|
|
171
|
-
// comfortable width when the shared body is hosted by the global navbar
|
|
172
|
-
// instead of a Sidebar slot; ordinary Header dropdowns remain content-sized.
|
|
173
|
-
// The trigger marker is the integration contract, so Dropdown does not reach
|
|
174
|
-
// into Sidebar's private class namespace to identify the menu body.
|
|
175
132
|
[data-identity-trigger="1"] + .dropdown-menu {
|
|
176
133
|
--moo-dropdown-sidebar-min-width: #{$moo-dropdown-sidebar-min-width};
|
|
177
134
|
min-width: var(--moo-dropdown-sidebar-min-width);
|
|
@@ -198,9 +155,6 @@
|
|
|
198
155
|
}
|
|
199
156
|
}
|
|
200
157
|
|
|
201
|
-
// The lg Offcanvas breakpoint still renders the sidebar as a drawer on
|
|
202
|
-
// tablets. Keep identity menus inside that drawer until the desktop fixed
|
|
203
|
-
// overlay contract becomes active.
|
|
204
158
|
@include media-breakpoint-between(sm, lg) {
|
|
205
159
|
[data-slot="sidebar-header"] .dropend > .dropdown-menu,
|
|
206
160
|
[data-slot="sidebar-footer"] .dropend > .dropdown-menu {
|
|
@@ -1,22 +1,14 @@
|
|
|
1
|
+
/* Field */
|
|
1
2
|
.field {
|
|
2
3
|
display: flex;
|
|
3
4
|
flex-direction: column;
|
|
4
5
|
gap: $moo-field-gap;
|
|
5
6
|
|
|
6
|
-
// Bootstrap's own .form-label carries a margin-bottom of its own
|
|
7
|
-
// (form-label-margin-bottom), which would stack on top of this flex gap
|
|
8
|
-
// and roughly double the real spacing the design reference's flat
|
|
9
|
-
// gap-only model produces.
|
|
10
7
|
> .form-label {
|
|
11
8
|
margin-bottom: 0;
|
|
12
|
-
// $form-label-font-weight is unset (inherits normal body weight); the
|
|
13
|
-
// reference's own field label sits at a medium weight instead.
|
|
14
9
|
font-weight: $font-weight-medium;
|
|
15
10
|
}
|
|
16
11
|
|
|
17
|
-
// Bootstrap owns the control and .invalid-feedback state. Field mirrors
|
|
18
|
-
// the reference's wrapper-level invalid state with data-invalid, so labels
|
|
19
|
-
// inherit the destructive color only when the field itself opts into that state.
|
|
20
12
|
&[data-invalid="true"] {
|
|
21
13
|
color: var(--bs-form-invalid-color);
|
|
22
14
|
}
|
|
@@ -48,18 +40,9 @@
|
|
|
48
40
|
pointer-events: none;
|
|
49
41
|
}
|
|
50
42
|
|
|
51
|
-
// field_description()/field_error() keep Bootstrap's own .form-text /
|
|
52
|
-
// .invalid-feedback class alongside these (the latter is load-bearing:
|
|
53
|
-
// Bootstrap's own validity sibling-selector CSS targets that exact class
|
|
54
|
-
// name to show/hide it), so every default here is a token override on top
|
|
55
|
-
// of Bootstrap's own rule rather than a full replacement of it.
|
|
56
43
|
.field-description,
|
|
57
44
|
.field-error {
|
|
58
45
|
margin-top: 0;
|
|
59
|
-
// .form-text/.invalid-feedback both default to Bootstrap's smaller
|
|
60
|
-
// $font-size-sm scale; the reference's own description/error text sit
|
|
61
|
-
// at the same size as the label itself, which this project's own
|
|
62
|
-
// $font-size-base already matches exactly (0.875rem).
|
|
63
46
|
font-size: $font-size-base;
|
|
64
47
|
}
|
|
65
48
|
|
|
@@ -68,12 +51,14 @@
|
|
|
68
51
|
flex-direction: column;
|
|
69
52
|
gap: $moo-field-group-gap;
|
|
70
53
|
|
|
71
|
-
// Inside a gap-managed group a separator adds no spacing of its own;
|
|
72
|
-
// Bootstrap's default block margins on <hr> would otherwise stack on
|
|
73
|
-
// top of the group gap and double the visual distance.
|
|
74
54
|
> hr {
|
|
75
55
|
margin-block: 0;
|
|
76
56
|
}
|
|
57
|
+
|
|
58
|
+
&.row {
|
|
59
|
+
flex-direction: row;
|
|
60
|
+
gap: 0;
|
|
61
|
+
}
|
|
77
62
|
}
|
|
78
63
|
|
|
79
64
|
.field-form {
|
|
@@ -82,29 +67,16 @@
|
|
|
82
67
|
gap: $moo-field-form-gap;
|
|
83
68
|
}
|
|
84
69
|
|
|
85
|
-
// Bootstrap's own <legend> reboot rule (float/width/padding/line-height)
|
|
86
|
-
// still applies here; this only retunes its type scale. A dedicated class
|
|
87
|
-
// rather than reusing .form-label, since Field owns this legend's styling
|
|
88
|
-
// independently of Radio Group's own separate <legend class="form-label">
|
|
89
|
-
// choice.
|
|
90
70
|
.field-legend {
|
|
91
71
|
font-size: $moo-field-legend-font-size;
|
|
92
72
|
font-weight: $font-weight-medium;
|
|
93
73
|
margin-bottom: $moo-field-legend-margin-bottom;
|
|
94
74
|
}
|
|
95
75
|
|
|
96
|
-
// One standard, token-based gap between a fieldset's direct building
|
|
97
|
-
// blocks (the legend/description header, field groups, lone fields).
|
|
98
|
-
// Sibling margins rather than flex gap: Bootstrap's reboot floats
|
|
99
|
-
// <legend> to give it native block flow, and turning the fieldset into a
|
|
100
|
-
// flex container would silently opt out of that contract.
|
|
101
76
|
.field-fieldset > * + * {
|
|
102
77
|
margin-top: $moo-field-fieldset-gap;
|
|
103
78
|
}
|
|
104
79
|
|
|
105
|
-
// The optional description directly under the legend is part of the
|
|
106
|
-
// header unit: it sits on the legend's own tight margin instead of the
|
|
107
|
-
// standard section gap.
|
|
108
80
|
.field-fieldset > .field-legend + .field-description {
|
|
109
81
|
margin-top: 0;
|
|
110
82
|
}
|
|
@@ -117,9 +89,6 @@
|
|
|
117
89
|
margin-top: 0;
|
|
118
90
|
}
|
|
119
91
|
|
|
120
|
-
// A separator() placed between two fieldsets (or field-group sections) is
|
|
121
|
-
// a much quieter division in the design reference than Bootstrap's own
|
|
122
|
-
// default <hr> opacity renders.
|
|
123
92
|
.field-fieldset + hr {
|
|
124
93
|
opacity: $moo-field-separator-opacity;
|
|
125
94
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
+
/* Input */
|
|
1
2
|
.form-control {
|
|
2
3
|
min-height: $input-height;
|
|
3
4
|
}
|
|
4
5
|
|
|
5
|
-
// Text inputs should visually match the outer box of an Input Group, whose
|
|
6
|
-
// border is promoted to the parent wrapper.
|
|
7
6
|
.form-control:not(textarea):not([type="file"]):not(.form-control-sm, .form-control-lg) {
|
|
8
7
|
min-height: calc(#{$input-height} + #{$input-border-width} * 2);
|
|
9
8
|
}
|
|
@@ -17,9 +16,6 @@
|
|
|
17
16
|
position: relative;
|
|
18
17
|
}
|
|
19
18
|
|
|
20
|
-
// Chromium's clock icon is the primary pointer trigger for the native time
|
|
21
|
-
// picker. Keep the indicator covering the whole control but visually hidden so
|
|
22
|
-
// pointer users retain picker access without the icon showing.
|
|
23
19
|
.form-control[type="time"]::-webkit-calendar-picker-indicator {
|
|
24
20
|
position: absolute;
|
|
25
21
|
inset: 0;
|
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
|
|
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.
|
|
1
|
+
/* Input Group */
|
|
6
2
|
.input-group:not(:has(> .form-control[type="file"])) {
|
|
7
3
|
border: $input-border-width solid $input-border-color;
|
|
8
4
|
border-radius: var(--moo-input-group-border-radius);
|
|
9
5
|
background-color: var(--moo-input-bg, transparent);
|
|
10
6
|
}
|
|
11
7
|
|
|
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
8
|
.input-group:not(:has(> .form-control[type="file"])):not(:has(> .dropdown-menu)) {
|
|
15
9
|
overflow: hidden;
|
|
16
10
|
}
|
|
@@ -19,25 +13,6 @@
|
|
|
19
13
|
--moo-input-group-border-radius: var(--bs-border-radius-pill);
|
|
20
14
|
}
|
|
21
15
|
|
|
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
16
|
.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
17
|
height: calc(#{$input-height} + #{$input-border-width} * 2);
|
|
43
18
|
}
|
|
@@ -59,11 +34,6 @@
|
|
|
59
34
|
border-radius: 0;
|
|
60
35
|
}
|
|
61
36
|
|
|
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
37
|
.input-group:not(:has(> .form-control[type="file"])) > :first-child:not(ul) {
|
|
68
38
|
border-start-start-radius: var(--moo-input-group-border-radius);
|
|
69
39
|
border-end-start-radius: var(--moo-input-group-border-radius);
|
|
@@ -78,10 +48,6 @@
|
|
|
78
48
|
border: var(--bs-btn-border-width) var(--bs-border-style) var(--bs-btn-border-color);
|
|
79
49
|
}
|
|
80
50
|
|
|
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
51
|
.input-group > .btn-ghost {
|
|
86
52
|
--bs-btn-hover-bg: transparent;
|
|
87
53
|
--bs-btn-active-bg: transparent;
|
|
@@ -90,10 +56,6 @@
|
|
|
90
56
|
border-radius: var(--moo-input-group-border-radius) !important;
|
|
91
57
|
}
|
|
92
58
|
|
|
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
59
|
.input-group > .btn-ghost::before {
|
|
98
60
|
position: absolute;
|
|
99
61
|
inset: $spacer * 0.25;
|
|
@@ -134,8 +96,6 @@
|
|
|
134
96
|
|
|
135
97
|
.input-group > .input-group-text {
|
|
136
98
|
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
99
|
}
|
|
140
100
|
|
|
141
101
|
.input-group > .input-group-text:first-child {
|
|
@@ -184,17 +144,7 @@
|
|
|
184
144
|
background-color: transparent;
|
|
185
145
|
}
|
|
186
146
|
|
|
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
147
|
|
|
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
148
|
.input-group:not(:has(> .form-control[type="file"])) > :is(.form-control, .form-select):focus {
|
|
199
149
|
outline: 0;
|
|
200
150
|
box-shadow: none;
|
|
@@ -1,7 +1,23 @@
|
|
|
1
|
+
/* Navigation */
|
|
2
|
+
$nav-step-icon-size: $spacer * 2 !default;
|
|
3
|
+
$nav-step-gap: $spacer * 0.25 !default;
|
|
4
|
+
$nav-step-border-color: var(--bs-border-color) !default;
|
|
5
|
+
$nav-step-completed-border-color: var(--moo-primary) !default;
|
|
6
|
+
$nav-link-description-color: color-mix(in srgb, var(--moo-muted-foreground) 95%, var(--moo-foreground)) !default;
|
|
7
|
+
|
|
1
8
|
.nav {
|
|
2
9
|
--bs-nav-link-color: var(--moo-foreground);
|
|
3
10
|
--bs-nav-link-hover-color: var(--moo-foreground);
|
|
4
11
|
--bs-nav-link-disabled-color: var(--moo-disabled-foreground);
|
|
12
|
+
--bs-nav-link-description-color: #{$nav-link-description-color};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.nav-link-description {
|
|
16
|
+
color: var(--bs-nav-link-description-color);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.nav-link.disabled .nav-link-description {
|
|
20
|
+
color: var(--bs-nav-link-disabled-color);
|
|
5
21
|
}
|
|
6
22
|
|
|
7
23
|
.nav-pills {
|
|
@@ -24,12 +40,6 @@
|
|
|
24
40
|
background-color: var(--moo-muted-surface);
|
|
25
41
|
}
|
|
26
42
|
|
|
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
43
|
.nav-pills:has(.nav-link:hover) .nav-link.active:not(:hover) {
|
|
34
44
|
background-color: transparent;
|
|
35
45
|
}
|
|
@@ -39,3 +49,63 @@
|
|
|
39
49
|
height: 1rem;
|
|
40
50
|
flex: 0 0 auto;
|
|
41
51
|
}
|
|
52
|
+
|
|
53
|
+
.nav-link-icon {
|
|
54
|
+
display: inline-flex;
|
|
55
|
+
align-items: center;
|
|
56
|
+
flex: 0 0 auto;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.nav-steps {
|
|
60
|
+
--bs-nav-step-icon-size: #{$nav-step-icon-size};
|
|
61
|
+
--bs-nav-step-gap: #{$nav-step-gap};
|
|
62
|
+
|
|
63
|
+
gap: var(--bs-nav-step-gap);
|
|
64
|
+
|
|
65
|
+
.nav-item {
|
|
66
|
+
position: relative;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.nav-item:not(:only-child)::before {
|
|
70
|
+
position: absolute;
|
|
71
|
+
z-index: 1;
|
|
72
|
+
inset-inline-start: calc(var(--bs-nav-link-padding-x) + var(--bs-nav-step-icon-size) / 2);
|
|
73
|
+
inset-block: calc(var(--bs-nav-step-gap) / -2);
|
|
74
|
+
border-inline-start: var(--bs-border-width) solid $nav-step-border-color;
|
|
75
|
+
content: "";
|
|
76
|
+
pointer-events: none;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.nav-item:first-child::before {
|
|
80
|
+
inset-block-start: 50%;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.nav-item:last-child::before {
|
|
84
|
+
inset-block-end: 50%;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.nav-link-icon {
|
|
88
|
+
position: relative;
|
|
89
|
+
z-index: 2;
|
|
90
|
+
display: inline-flex;
|
|
91
|
+
align-items: center;
|
|
92
|
+
justify-content: center;
|
|
93
|
+
flex: 0 0 var(--bs-nav-step-icon-size);
|
|
94
|
+
inline-size: var(--bs-nav-step-icon-size);
|
|
95
|
+
block-size: var(--bs-nav-step-icon-size);
|
|
96
|
+
color: var(--moo-foreground);
|
|
97
|
+
background-color: var(--moo-muted-surface);
|
|
98
|
+
border: var(--bs-border-width) solid $nav-step-border-color;
|
|
99
|
+
border-radius: var(--bs-border-radius);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.nav-link.disabled .nav-link-icon {
|
|
103
|
+
color: var(--moo-disabled-foreground);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.nav-item[data-nav-completed="true"] .nav-link-icon {
|
|
107
|
+
color: var(--moo-primary-foreground);
|
|
108
|
+
background-color: var(--moo-primary);
|
|
109
|
+
border-color: $nav-step-completed-border-color;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -1,16 +1,4 @@
|
|
|
1
|
-
|
|
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.
|
|
1
|
+
/* Pagination */
|
|
14
2
|
.page-link {
|
|
15
3
|
$page-link-square-size: calc(
|
|
16
4
|
#{$moo-chip-height} + #{$moo-pagination-square-inset} + var(--bs-pagination-border-width) * 2
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
|
|
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.
|
|
1
|
+
/* Popover */
|
|
7
2
|
.popover {
|
|
8
3
|
--bs-popover-border-radius: var(--bs-border-radius-lg);
|
|
9
4
|
--bs-popover-border-color: var(--moo-border);
|
|
@@ -13,23 +8,10 @@
|
|
|
13
8
|
--bs-popover-header-padding-y: #{$spacer * 0.625};
|
|
14
9
|
--bs-popover-body-padding-x: #{$spacer * 0.625};
|
|
15
10
|
--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
11
|
--bs-popover-font-size: 0.875rem;
|
|
19
12
|
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
13
|
--bs-popover-max-width: 20rem;
|
|
25
14
|
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
15
|
box-shadow: var(--bs-box-shadow-lg);
|
|
34
16
|
}
|
|
35
17
|
|
|
@@ -39,9 +21,6 @@
|
|
|
39
21
|
font-weight: $font-weight-medium;
|
|
40
22
|
}
|
|
41
23
|
|
|
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
24
|
.popover .popover-arrow {
|
|
46
25
|
display: none;
|
|
47
26
|
}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
// geometry native, but bind the fill to the same runtime primary token used by
|
|
3
|
-
// buttons, checked controls, and active selection affordances.
|
|
1
|
+
/* Progress */
|
|
4
2
|
.progress {
|
|
5
3
|
--bs-progress-bar-color: var(--moo-primary-foreground);
|
|
6
4
|
--bs-progress-bar-bg: var(--moo-primary);
|