@wpmoo/ui 1.0.0-rc.9 → 1.1.0-dev.1
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 +38 -3
- package/certification.json +3 -1
- package/dist/assets/css/moo-ui.css +436 -25
- package/dist/assets/css/moo-ui.min.css +10 -31
- package/dist/assets/css/moo.css +428 -24
- 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 +38 -21
- package/dist/js/datepicker.js +5 -4
- package/dist/js/datepicker.min.js +4 -3
- package/dist/js/moo-ui.js +350 -15402
- package/dist/js/moo-ui.min.js +3 -23
- package/dist/js/sheet.js +46 -0
- package/dist/js/sidebar.js +3 -2
- package/dist/js/slider.js +12 -47
- package/dist/js/state.js +15 -41
- package/dist/js/table-of-contents.js +195 -0
- package/dist/release-manifest.json +4 -4
- package/package.json +5 -1
- package/scss/_components.scss +3 -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 +1 -40
- 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/_toc.scss +48 -0
- 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 +15 -0
- package/scss/layouts/_app.scss +0 -6
- package/scss/layouts/_page_grid.scss +0 -3
- package/scss/layouts/app/sidebar/_base.scss +0 -37
- package/scss/layouts/app/sidebar/_default.scss +0 -6
- package/scss/layouts/app/sidebar/_floating.scss +0 -11
- package/scss/layouts/app/sidebar/_inset.scss +0 -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 +0 -37
- package/scss/settings/_palette.scss +0 -42
- package/scss/themes/_root.scss +3 -0
- package/scss/themes/_standalone.scss +0 -2
- package/scss/themes/_theme.scss +3 -2
- package/scss/utilities/_background_color.scss +18 -0
- package/scss/utilities/_border.scss +4 -0
- package/scss/utilities/_scroll_smooth.scss +9 -0
|
@@ -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);
|
|
@@ -1,9 +1,108 @@
|
|
|
1
|
-
|
|
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).
|
|
1
|
+
/* Radio Group */
|
|
7
2
|
.radio-group legend.form-label {
|
|
8
3
|
font-size: inherit;
|
|
9
4
|
}
|
|
5
|
+
|
|
6
|
+
.form-check-card {
|
|
7
|
+
position: relative;
|
|
8
|
+
padding: 0;
|
|
9
|
+
margin-bottom: 0;
|
|
10
|
+
|
|
11
|
+
+ .form-check-card {
|
|
12
|
+
margin-block-start: $spacer * 0.5;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
> .form-check-input:not(.visually-hidden) {
|
|
16
|
+
position: absolute;
|
|
17
|
+
inset-block-start: $spacer * 0.75;
|
|
18
|
+
inset-inline-end: $spacer * 0.75;
|
|
19
|
+
float: none;
|
|
20
|
+
margin: 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
> .form-check-label {
|
|
24
|
+
display: flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
gap: $spacer * 0.75;
|
|
27
|
+
padding: $spacer * 0.75;
|
|
28
|
+
padding-inline-end: $spacer * 1.5 + $form-check-input-width;
|
|
29
|
+
border: var(--bs-border-width) solid var(--moo-border);
|
|
30
|
+
border-radius: var(--bs-border-radius);
|
|
31
|
+
color: var(--moo-foreground);
|
|
32
|
+
cursor: pointer;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
&.form-check-card--no-control > .form-check-label {
|
|
36
|
+
padding-inline-end: $spacer * 0.75;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
> .form-check-input:not(:disabled) ~ .form-check-label:hover,
|
|
40
|
+
> .form-check-input:checked ~ .form-check-label {
|
|
41
|
+
background-color: var(--moo-muted-surface);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
> .form-check-input:checked ~ .form-check-label {
|
|
45
|
+
border-color: var(--moo-foreground);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
> .form-check-input:checked ~ .form-check-label .form-check-card-media {
|
|
49
|
+
border-color: var(--moo-primary);
|
|
50
|
+
background-color: var(--moo-primary);
|
|
51
|
+
color: var(--moo-primary-foreground);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
> .form-check-input:focus-visible ~ .form-check-label {
|
|
55
|
+
border-color: var(--moo-ring);
|
|
56
|
+
box-shadow: $form-check-input-focus-box-shadow;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
> .form-check-input.is-invalid ~ .form-check-label {
|
|
60
|
+
border-color: var(--bs-form-invalid-border-color);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
> .form-check-input.is-invalid:focus-visible ~ .form-check-label {
|
|
64
|
+
box-shadow: 0 0 0 var(--bs-focus-ring-width) var(--moo-form-invalid-ring-color);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.form-check-card-content {
|
|
69
|
+
display: flex;
|
|
70
|
+
flex-direction: column;
|
|
71
|
+
gap: $spacer * 0.25;
|
|
72
|
+
min-width: 0;
|
|
73
|
+
line-height: $line-height-sm;
|
|
74
|
+
overflow-wrap: anywhere;
|
|
75
|
+
|
|
76
|
+
> .form-text {
|
|
77
|
+
margin: 0;
|
|
78
|
+
font-size: $font-size-sm;
|
|
79
|
+
line-height: inherit;
|
|
80
|
+
color: $moo-form-check-card-description-color;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.form-check-card-title {
|
|
85
|
+
font-weight: $font-weight-medium;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.form-check-card-media {
|
|
89
|
+
display: grid;
|
|
90
|
+
place-items: center;
|
|
91
|
+
flex: 0 0 auto;
|
|
92
|
+
inline-size: ($font-size-base + $font-size-sm) * $line-height-sm + $spacer * 0.25;
|
|
93
|
+
aspect-ratio: 1;
|
|
94
|
+
border: var(--bs-border-width) solid var(--moo-border);
|
|
95
|
+
border-radius: var(--bs-border-radius-sm);
|
|
96
|
+
background-color: var(--moo-muted-surface);
|
|
97
|
+
color: var(--moo-foreground);
|
|
98
|
+
|
|
99
|
+
> span {
|
|
100
|
+
font-size: $font-size-sm;
|
|
101
|
+
font-weight: $font-weight-semibold;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
> [data-icon] {
|
|
105
|
+
width: $font-size-base;
|
|
106
|
+
height: $font-size-base;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
|
|
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.
|
|
1
|
+
/* Separator */
|
|
7
2
|
hr {
|
|
8
3
|
opacity: 1;
|
|
9
4
|
border-top: var(--bs-border-width) solid var(--moo-border);
|
|
@@ -1,32 +1,16 @@
|
|
|
1
|
-
|
|
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.
|
|
1
|
+
/* Sheet */
|
|
11
2
|
.offcanvas.sheet {
|
|
12
3
|
--bs-offcanvas-width: 24rem;
|
|
13
4
|
--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
5
|
box-shadow: var(--bs-box-shadow-lg);
|
|
18
6
|
}
|
|
19
7
|
|
|
20
8
|
.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
9
|
outline: none;
|
|
24
10
|
box-shadow: var(--bs-box-shadow-lg);
|
|
25
11
|
}
|
|
26
12
|
|
|
27
13
|
.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
14
|
font-size: 1rem;
|
|
31
15
|
font-weight: $font-weight-medium;
|
|
32
16
|
}
|
|
@@ -1,17 +1,10 @@
|
|
|
1
|
+
/* Skeleton */
|
|
1
2
|
.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
3
|
color: var(--moo-border);
|
|
5
4
|
border-radius: var(--bs-border-radius);
|
|
6
5
|
overflow: hidden;
|
|
7
6
|
}
|
|
8
7
|
|
|
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
8
|
.skeleton > .placeholder {
|
|
16
9
|
display: block;
|
|
17
10
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* Slider */
|
|
1
2
|
$slider-thumb-size: $form-range-thumb-width * 0.75;
|
|
2
3
|
$slider-thumb-margin-top: ($progress-height - $slider-thumb-size) * 0.5;
|
|
3
4
|
|
|
@@ -114,8 +115,6 @@ $slider-thumb-margin-top: ($progress-height - $slider-thumb-size) * 0.5;
|
|
|
114
115
|
box-shadow: 0 0 0 #{$moo-form-focus-ring-width} color-mix(in srgb, #{$moo-form-focus-ring-color} 50%, transparent);
|
|
115
116
|
}
|
|
116
117
|
|
|
117
|
-
// Safari can keep pointer-driven range focus out of :focus-visible, while
|
|
118
|
-
// Bootstrap's native .form-range:focus thumb halo still applies.
|
|
119
118
|
.slider[data-slider-pointer-focus]:not([data-slider-dragging]) .slider-input:focus::-webkit-slider-thumb {
|
|
120
119
|
box-shadow: var(--bs-box-shadow-sm);
|
|
121
120
|
}
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
// CSS, not Bootstrap's thicker spinner-border ring — render_icon already
|
|
3
|
-
// emits the same stroke-width and line-cap Lucide markup the reference
|
|
4
|
-
// uses, so only sizing
|
|
5
|
-
// and rotation are needed here. The animation name is supplied by the active
|
|
6
|
-
// build entry: Bootstrap's spinner-border for standalone, namespaced Moo for
|
|
7
|
-
// the scoped core.
|
|
1
|
+
/* Spinner */
|
|
8
2
|
.spinner [data-icon] {
|
|
9
3
|
width: $spacer;
|
|
10
4
|
height: $spacer;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
// the shared $form-check-input-width (also used by Checkbox and Radio
|
|
3
|
-
// Group), so matching the design reference's taller track needs an
|
|
4
|
-
// explicit height here instead of a shared Bootstrap variable.
|
|
1
|
+
/* Switch */
|
|
5
2
|
.form-switch .form-check-input {
|
|
6
3
|
height: $moo-switch-height;
|
|
7
4
|
}
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
// inset, shadowed pill marking the active tab. Bootstrap's pills nav has
|
|
3
|
-
// no shared track and colors the active pill with $primary directly, so
|
|
4
|
-
// this styling is scoped to the tabs-list wrapper instead of the shared
|
|
5
|
-
// pills class — Navigation's own pills variant already owns that class
|
|
6
|
-
// and must keep its plain Bootstrap look.
|
|
1
|
+
/* Tabs */
|
|
7
2
|
.tabs-list {
|
|
8
3
|
display: inline-flex;
|
|
9
4
|
gap: $moo-tabs-list-gap;
|
|
@@ -16,17 +11,6 @@
|
|
|
16
11
|
padding: $moo-tabs-trigger-padding-y $moo-tabs-trigger-padding-x;
|
|
17
12
|
font-size: $font-size-base;
|
|
18
13
|
font-weight: 500;
|
|
19
|
-
// var(--moo-muted-foreground) on the track's own var(--moo-muted-surface)
|
|
20
|
-
// background measures 4.40:1 in light mode, under the 4.5:1 WCAG AA
|
|
21
|
-
// minimum for normal text (axe caught this in the certification fixture).
|
|
22
|
-
// var(--bs-secondary-color) is not a usable substitute here -- Moo UI's
|
|
23
|
-
// own theme sets --bs-secondary-color: var(--moo-muted-foreground)
|
|
24
|
-
// (scss/themes/_root.scss), so it resolves to the exact same
|
|
25
|
-
// failing color. var(--bs-secondary-text-emphasis) is a different,
|
|
26
|
-
// untouched Bootstrap token (Moo UI does not override it) built for
|
|
27
|
-
// accessible colored text against a tinted "subtle" surface -- the same
|
|
28
|
-
// category of fix the Kbd contrast defect used -- and measures 5.55:1
|
|
29
|
-
// light / 14.03:1 dark against this track's own background.
|
|
30
14
|
color: var(--bs-secondary-text-emphasis);
|
|
31
15
|
border-radius: var(--bs-border-radius);
|
|
32
16
|
cursor: default;
|
|
@@ -104,11 +88,6 @@
|
|
|
104
88
|
pointer-events: none;
|
|
105
89
|
}
|
|
106
90
|
|
|
107
|
-
// Bootstrap hides inactive panes with display:none, so the pane height
|
|
108
|
-
// changes the moment a shorter or taller tab becomes active — the
|
|
109
|
-
// surrounding page jumps to the new height on every switch. Stacking every
|
|
110
|
-
// pane in the same grid cell sizes the row to the tallest pane once, so
|
|
111
|
-
// switching only toggles visibility, never the container's height.
|
|
112
91
|
.tab-content {
|
|
113
92
|
display: grid;
|
|
114
93
|
width: 100%;
|
|
@@ -126,8 +105,6 @@
|
|
|
126
105
|
opacity: 0;
|
|
127
106
|
visibility: hidden;
|
|
128
107
|
pointer-events: none;
|
|
129
|
-
// Slightly longer than Bootstrap's .15s fade so the content handoff feels
|
|
130
|
-
// intentional without adding any positional movement.
|
|
131
108
|
transition: opacity 0.16s ease, visibility 0s linear 0.16s;
|
|
132
109
|
}
|
|
133
110
|
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
// autohide behavior. This partial only retunes the native surface and opts
|
|
3
|
-
// an explicitly indexed bottom-end container into the catalog deck layout.
|
|
1
|
+
/* Toast */
|
|
4
2
|
.toast {
|
|
5
3
|
--bs-toast-border-radius: var(--bs-border-radius-lg);
|
|
6
4
|
--bs-toast-border-color: var(--moo-border);
|
|
@@ -58,7 +56,6 @@
|
|
|
58
56
|
--moo-toast-stack-enter-y: #{$moo-toast-stack-enter-y};
|
|
59
57
|
}
|
|
60
58
|
|
|
61
|
-
// Without runtime indexes, the container remains readable Bootstrap flow.
|
|
62
59
|
.toast-container--stacked[data-toast-stack="deck"][data-toast-stack-active] {
|
|
63
60
|
bottom: 1rem !important;
|
|
64
61
|
inset-inline-end: 1rem !important;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/* Table of contents */
|
|
2
|
+
[data-toc] > .fw-semibold {
|
|
3
|
+
padding-inline-start: calc(#{$nav-link-padding-x} - var(--bs-border-width));
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
[data-toc]:has(> .nav) {
|
|
7
|
+
position: relative;
|
|
8
|
+
border-inline-start: calc(var(--bs-border-width) * 0.5) solid var(--bs-border-color);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
[data-toc][data-toc-marker]::after {
|
|
12
|
+
content: "";
|
|
13
|
+
position: absolute;
|
|
14
|
+
inset-block-start: 0;
|
|
15
|
+
inset-inline-start: calc(var(--bs-border-width) * -1);
|
|
16
|
+
block-size: var(--moo-toc-marker-height);
|
|
17
|
+
border-inline-start: calc(var(--bs-border-width) * 3) solid var(--moo-primary);
|
|
18
|
+
transform: translateY(var(--moo-toc-marker-offset));
|
|
19
|
+
pointer-events: none;
|
|
20
|
+
@include transition($transition-base);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
[data-toc] > .nav .nav-link {
|
|
24
|
+
display: flex;
|
|
25
|
+
position: relative;
|
|
26
|
+
margin-inline-start: calc(var(--bs-border-width) * -1);
|
|
27
|
+
color: var(--moo-muted-foreground);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
[data-toc] > .nav .nav-link::before {
|
|
31
|
+
content: "";
|
|
32
|
+
position: absolute;
|
|
33
|
+
inset-block: var(--bs-nav-link-padding-y);
|
|
34
|
+
inset-inline-start: 0;
|
|
35
|
+
border-inline-start: calc(var(--bs-border-width) * 3) solid transparent;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
[data-toc] > .nav .nav-link.active {
|
|
39
|
+
color: var(--moo-foreground);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
[data-toc] > .nav .nav-link.active::before {
|
|
43
|
+
border-inline-start-color: var(--moo-primary);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
[data-toc][data-toc-marker] > .nav .nav-link.active::before {
|
|
47
|
+
border-inline-start-color: transparent;
|
|
48
|
+
}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
// selected state should change in place instead of using the generic button
|
|
3
|
-
// press nudge.
|
|
1
|
+
/* Toggle Group */
|
|
4
2
|
.toggle-group > .btn:not(:disabled):not(.disabled):not([aria-disabled="true"]):active {
|
|
5
3
|
transform: none;
|
|
6
4
|
}
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
// text-background, px-3 py-1.5, text-xs, rounded-md, fully opaque,
|
|
3
|
-
// max-w-xs): Bootstrap's own
|
|
4
|
-
// defaults are narrower, tighter, and dimmed to 90% opacity. All four
|
|
5
|
-
// overrides route through Bootstrap's existing custom properties, so no new
|
|
6
|
-
// selectors or hardcoded colors are introduced.
|
|
1
|
+
/* Tooltip */
|
|
7
2
|
.tooltip {
|
|
8
3
|
--bs-tooltip-max-width: 20rem;
|
|
9
4
|
--bs-tooltip-padding-x: 0.75rem;
|
|
@@ -17,9 +12,6 @@
|
|
|
17
12
|
line-height: 1.333;
|
|
18
13
|
}
|
|
19
14
|
|
|
20
|
-
// Popper owns the wrapper transform for placement. Animate only the bubble
|
|
21
|
-
// surface so the tooltip opens with the reference's subtle zoom/slide without
|
|
22
|
-
// disturbing Bootstrap positioning.
|
|
23
15
|
.tooltip.fade .tooltip-inner {
|
|
24
16
|
transition: transform var(--moo-tooltip-motion-duration) var(--moo-tooltip-motion-easing);
|
|
25
17
|
transform: scale(var(--moo-tooltip-motion-scale));
|
|
@@ -59,12 +51,6 @@
|
|
|
59
51
|
}
|
|
60
52
|
}
|
|
61
53
|
|
|
62
|
-
// Bootstrap's tooltip bubble is fully token-driven already (see the vendored
|
|
63
|
-
// Bootstrap tooltip partial), so this partial only owns the plain link
|
|
64
|
-
// trigger's own text color. Unstyled, it falls through to Bootstrap's
|
|
65
|
-
// un-themed --bs-link-color, which reads too low-contrast on dark surfaces;
|
|
66
|
-
// a dotted underline also reads as "hover for more info" rather than a real
|
|
67
|
-
// navigational link.
|
|
68
54
|
.tooltip-trigger {
|
|
69
55
|
color: var(--moo-foreground);
|
|
70
56
|
text-decoration-line: underline;
|
|
@@ -73,11 +59,6 @@
|
|
|
73
59
|
text-underline-offset: 0.2em;
|
|
74
60
|
}
|
|
75
61
|
|
|
76
|
-
// Tooltip shortcut hints render the Kbd component's native <kbd> element.
|
|
77
|
-
// The catalog tooltip initializer extends Bootstrap's sanitizer allowlist
|
|
78
|
-
// with the kbd tag so it survives data-bs-html sanitization; styling comes
|
|
79
|
-
// from the shared Kbd component and Bootstrap's own reboot. A shortcut chip
|
|
80
|
-
// after trailing prose keeps a readable gap from the surrounding text.
|
|
81
62
|
.tooltip-inner kbd {
|
|
82
63
|
margin-inline-start: $kbd-padding-x;
|
|
83
64
|
}
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
// Bootstrap has no native sidebar, so this owned sidebar selector namespace
|
|
2
|
-
// provides the inner surface and anatomy. The App layout owns the outer
|
|
3
|
-
// <aside>, placement, width, visual variant, and collapse mode.
|
|
4
1
|
|
|
5
2
|
.sidebar-inner {
|
|
6
3
|
position: sticky;
|
|
@@ -84,10 +81,6 @@
|
|
|
84
81
|
font-weight: $font-weight-medium;
|
|
85
82
|
}
|
|
86
83
|
|
|
87
|
-
// Reserve room so a long label doesn't run under the absolutely positioned
|
|
88
|
-
// group action button (see .sidebar-group-action below). A descendant match
|
|
89
|
-
// covers both a group action placed directly in .sidebar-group and one
|
|
90
|
-
// nested inside .sidebar-group-content alongside the label.
|
|
91
84
|
.sidebar-group:has(.sidebar-group-action) .sidebar-group-label {
|
|
92
85
|
padding-inline-end: $spacer * 2.5;
|
|
93
86
|
}
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
// Collapsed-to-icon inner state (desktop). App owns the outer shell width,
|
|
2
|
-
// rail, stacking, and responsive placement; Sidebar owns the inner content
|
|
3
|
-
// visibility and flyout anatomy.
|
|
4
1
|
|
|
5
2
|
@include media-breakpoint-up(lg) {
|
|
6
3
|
[data-sidebar-state="collapsed"] .sidebar[data-collapsible="icon"] .sidebar-group-label,
|
|
@@ -18,9 +15,6 @@
|
|
|
18
15
|
}
|
|
19
16
|
|
|
20
17
|
[data-sidebar-state="collapsed"] .sidebar[data-collapsible="icon"]:has(.sidebar-menu-button[data-bs-toggle="dropdown"][aria-expanded="true"]) {
|
|
21
|
-
// Keep the collapsed identity trigger above sticky page chrome too. This
|
|
22
|
-
// selector is more specific than the app-root rule above and otherwise
|
|
23
|
-
// would lower the Sidebar back to the dropdown layer.
|
|
24
18
|
z-index: $zindex-fixed + 1;
|
|
25
19
|
}
|
|
26
20
|
|