redo buttons

This commit is contained in:
Mark Otto 2025-09-23 22:34:34 -07:00
parent aaf730a893
commit 3c4beecd0c
3 changed files with 192 additions and 12 deletions

View File

@ -1,6 +1,10 @@
@use "sass:color";
@use "sass:list";
@use "sass:map";
@use "sass:meta";
@use "../colors" as *;
@use "../config" as *;
@use "../theme" as *;
@use "../variables" as *;
@use "../theme" as *;
@use "../functions" as *;
@ -12,12 +16,102 @@
@use "../mixins/transition" as *;
@use "button-variables" as *;
// Button variants
//
// Easily pump out default styles, as well as :hover, :focus, :active,
// and disabled options for all buttons
// scss-docs-start btn-variants
$button-variants: (
"solid": (
"base": (
"bg": "bg",
"color": "contrast",
"border-color": "bg"
),
"hover": (
"bg": "bg",
"border-color": "bg",
"color": "contrast"
),
"active": (
"bg": "bg",
"border-color": "bg",
"color": "contrast"
)
),
"outline": (
"base": (
"bg": "transparent",
"color": "text",
"border-color": "border"
),
"hover": (
"bg": "bg",
"color": "contrast",
"border-color": "bg"
),
"active": (
"bg": "bg",
"color": "contrast",
"border-color": "bg"
)
),
"subtle": (
"base": (
"bg": "bg-subtle",
"color": "text",
"border-color": "transparent"
),
"hover": (
"bg": ("bg-muted", "bg-subtle"),
"color": "text"
),
"active": (
"bg": "bg-subtle",
"color": "text"
)
),
"text": (
"base": (
"color": "text",
"bg": "transparent",
"border-color": "transparent"
),
"hover": (
"color": "text",
"bg": "bg-subtle"
),
"active": (
"color": "text",
"bg": "bg-subtle"
)
)
) !default;
// scss-docs-end btn-variants
// Helper function to get nested map values using dot notation
@function get-nested-value($map, $keys) {
$value: $map;
@each $key in $keys {
@if type-of($value) == "map" {
$value: map-get($value, $key);
} @else {
@return null;
}
}
@return $value;
}
// Helper function to split dot notation string into list
@function split-keys($key) {
$keys: ();
$parts: str-slice($key, 1);
@each $part in $parts {
$keys: append($keys, $part);
}
@return $keys;
}
// Main button style generator mixin
// scss-docs-start btn-variant-mixin
<<<<<<< HEAD
// @mixin button-variant(
// $background,
// $border,
@ -73,6 +167,67 @@
// --#{$prefix}gradient: none;
// }
// scss-docs-end btn-outline-variant-mixin
=======
@mixin button-variant($color, $variant) {
$variant-styles: map.get($button-variants, $variant);
@if $variant-styles {
// Base properties
@each $property, $value in map.get($variant-styles, "base") {
@if $value == "transparent" {
--#{$prefix}btn-#{$property}: transparent;
} @else {
--#{$prefix}btn-#{$property}: var(--#{$prefix}#{$color}-#{$value});
}
}
// Hover state
&:hover {
@each $property, $value in map.get($variant-styles, "hover") {
@if $value == "transparent" {
--#{$prefix}btn-hover-#{$property}: transparent;
} @else if meta.type-of($value) == "list" {
$first-value: list.nth($value, 1);
$second-value: list.nth($value, 2);
--#{$prefix}btn-hover-#{$property}: color-mix(in oklch, var(--#{$prefix}#{$color}-#{$first-value}) 50%, var(--#{$prefix}#{$color}-#{$second-value}));
} @else if $value == "bg-subtle" {
--#{$prefix}btn-hover-#{$property}: var(--#{$prefix}#{$color}-#{$value});
} @else {
--#{$prefix}btn-hover-#{$property}: oklch(from var(--#{$prefix}#{$color}-#{$value}) calc(l * .95) calc(c * 1.1) h);
}
}
}
&:focus-visible {
outline-color: var(--#{$prefix}#{$color}-focus-ring);
}
// Active state
&:active,
&.active {
@each $property, $value in map.get($variant-styles, "active") {
@if $value == "transparent" {
--#{$prefix}btn-active-#{$property}: transparent;
} @else if $value == "bg-subtle" {
--#{$prefix}btn-active-#{$property}: var(--#{$prefix}#{$color}-#{$value});
} @else {
--#{$prefix}btn-active-#{$property}: oklch(from var(--#{$prefix}#{$color}-#{$value}) calc(l * .9) calc(c * 1.15) h);
}
}
}
}
}
// scss-docs-end btn-variant-mixin
// Generate all button variants
@each $color, $_ in $new-theme-colors {
@each $variant, $_ in $button-variants {
.btn-#{$color}-#{$variant} {
@include button-variant($color, $variant);
}
}
}
>>>>>>> f87a3a593 (redo buttons)
// scss-docs-start btn-size-mixin
@mixin button-size($padding-y, $padding-x, $font-size, $border-radius) {
@ -142,15 +297,11 @@
}
&:focus-visible {
color: var(--#{$prefix}btn-hover-color);
@include gradient-bg(var(--#{$prefix}btn-hover-bg));
border-color: var(--#{$prefix}btn-hover-border-color);
@include focus-ring(true);
--#{$prefix}focus-ring-offset: 1px;
}
.btn-check:focus-visible + & {
border-color: var(--#{$prefix}btn-hover-border-color);
@include focus-ring(true);
}
@ -194,6 +345,7 @@
//
// scss-docs-start btn-variant-loops
<<<<<<< HEAD
// @each $color, $value in $new-theme-colors {
// .btn-#{$color} {
// @if $color == "light" {
@ -225,6 +377,19 @@
// @include button-outline-variant($value);
// }
// }
=======
@each $color, $value in $theme-colors {
.btn-#{$color} {
@include button-variant($color, "solid");
}
}
@each $color, $value in $theme-colors {
.btn-outline-#{$color} {
@include button-variant($color, "outline");
}
}
>>>>>>> f87a3a593 (redo buttons)
// scss-docs-end btn-variant-loops

View File

@ -22,7 +22,7 @@ When using `.btn` without a modifier, be sure to add some explicit `:focus-visib
Bootstrap includes several button variants, each serving its own semantic purpose, with a few extras thrown in for more control.
<Example code={[...getData('theme-colors').map((themeColor) => `<button type="button" class="btn btn-${themeColor.name}">${themeColor.title}</button>`), `
<Example class="bd-example-buttons" code={[...getData('theme-colors').map((themeColor) => `<button type="button" class="btn btn-${themeColor.name}-solid justify-self-start">${themeColor.title}</button> <button type="button" class="btn btn-${themeColor.name}-outline justify-self-start">${themeColor.title}</button> <button type="button" class="btn btn-${themeColor.name}-subtle justify-self-start">${themeColor.title}</button> <button type="button" class="btn btn-${themeColor.name}-text justify-self-start">${themeColor.title}</button>`), `
<button type="button" class="btn btn-link">Link</button>`]} />
<Callout name="warning-color-assistive-technologies" />
@ -276,15 +276,23 @@ Heres an example of building a custom `.btn-*` modifier class as we do for th
### Sass variables
<ScssDocs name="btn-variables" file="scss/_variables.scss" />
<ScssDocs name="btn-variables" file="scss/buttons/_button-variables.scss" />
### Sass map
Button variants—including all their states—are defined in the `$button-variants` Sass map. This map identifies which theme color tokens to use for each variant's state.
For example, a solid button uses the same `bg` token for its background and border colors because we want it to have a seamless look.
<ScssDocs name="btn-variants" file="scss/buttons/_button.scss" />
### Sass mixins
There are three mixins for buttons: button and button outline variant mixins (both based on `$theme-colors`), plus a button size mixin.
{/*<ScssDocs name="btn-variant-mixin" file="scss/mixins/_buttons.scss" />
<ScssDocs name="btn-variant-mixin" file="scss/buttons/_button.scss" />
<ScssDocs name="btn-outline-variant-mixin" file="scss/mixins/_buttons.scss" />
{/*<ScssDocs name="btn-outline-variant-mixin" file="scss/mixins/_buttons.scss" />
<ScssDocs name="btn-size-mixin" file="scss/mixins/_buttons.scss" />*/}

View File

@ -145,6 +145,13 @@
border: 1px solid color-mix(in srgb, var(--bd-violet) 30%, transparent);
}
.bd-example-buttons {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: .5rem;
justify-content: start;
}
// // Grid mixins
// .example-container {
// width: 800px;