From 2c21f91acbfa4797972c8ae905a255328db51d44 Mon Sep 17 00:00:00 2001 From: Mark Otto Date: Tue, 23 Sep 2025 10:05:39 -0700 Subject: [PATCH] Split Sass, update docs --- scss/_variables.scss | 6 - scss/forms/_check.scss | 102 ++++ scss/forms/_form-check.scss | 482 ------------------ scss/forms/_radio.scss | 79 +++ scss/forms/_switch.scss | 78 +++ scss/forms/index.scss | 4 +- site/data/sidebar.yml | 1 - site/src/content/docs/forms/checkbox.mdx | 12 + site/src/content/docs/forms/checks-radios.mdx | 311 ----------- site/src/content/docs/forms/radio.mdx | 12 + site/src/content/docs/forms/switch.mdx | 6 + 11 files changed, 292 insertions(+), 801 deletions(-) create mode 100644 scss/forms/_check.scss delete mode 100644 scss/forms/_form-check.scss create mode 100644 scss/forms/_radio.scss delete mode 100644 site/src/content/docs/forms/checks-radios.mdx diff --git a/scss/_variables.scss b/scss/_variables.scss index ea27464499..a2a2024159 100644 --- a/scss/_variables.scss +++ b/scss/_variables.scss @@ -588,12 +588,6 @@ $mark-bg-dark: $yellow-800 !default; // Forms // -// $form-select-indicator-color-dark: $body-color-dark !default; -// $form-select-indicator-dark: url("data:image/svg+xml,") !default; - -$form-switch-color-dark: rgba($white, .25) !default; -$form-switch-bg-image-dark: url("data:image/svg+xml,") !default; - // scss-docs-start form-validation-colors-dark $form-valid-color-dark: $green-300 !default; $form-valid-border-color-dark: $green-300 !default; diff --git a/scss/forms/_check.scss b/scss/forms/_check.scss new file mode 100644 index 0000000000..bc88beaf38 --- /dev/null +++ b/scss/forms/_check.scss @@ -0,0 +1,102 @@ +@use "../config" as *; +@use "../colors" as *; +@use "../variables" as *; +@use "../functions" as *; +@use "../vendor/rfs" as *; +@use "../mixins/border-radius" as *; +@use "../mixins/box-shadow" as *; +@use "../mixins/color-mode" as *; +@use "../mixins/focus-ring" as *; +@use "../mixins/transition" as *; +@use "form-variables" as *; + +// scss-docs-start check-variables +$check-border-color: var(--#{$prefix}border-color) !default; +$check-checked-bg: var(--#{$prefix}primary-base) !default; +$check-checked-border-color: $check-checked-bg !default; +$check-indeterminate-bg: var(--#{$prefix}primary-base) !default; +$check-indeterminate-border-color: $check-indeterminate-bg !default; +$check-disabled-bg: var(--#{$prefix}secondary-bg) !default; +$check-disabled-border-color: $check-disabled-bg !default; +$check-disabled-opacity: .65 !default; +// scss-docs-end check-variables + +@layer forms { + b-checkgroup { + display: flex; + gap: var(--#{$prefix}gap, .5rem); + align-items: var(--#{$prefix}align-items, start); + + .description { + color: var(--#{$prefix}secondary-text); + } + } + + .check { + // scss-docs-start check-css-variables + --#{$prefix}check-bg: transparent; + --#{$prefix}check-border-color: #{$check-border-color}; + --#{$prefix}check-checked-bg: #{$check-checked-bg}; + --#{$prefix}check-checked-border-color: #{$check-checked-border-color}; + --#{$prefix}check-indeterminate-bg: #{$check-indeterminate-bg}; + --#{$prefix}check-indeterminate-border-color: #{$check-indeterminate-border-color}; + --#{$prefix}check-disabled-bg: #{$check-disabled-bg}; + --#{$prefix}check-disabled-border-color: #{$check-disabled-border-color}; + --#{$prefix}check-disabled-opacity: #{$check-disabled-opacity}; + // scss-docs-end check-css-variables + + display: grid; + grid-template-columns: repeat(1, minmax(0, 1fr)); + margin-block: .125rem; + + :where(svg, input) { + flex-shrink: 0; + grid-row-start: 1; + grid-column-start: 1; + width: 1rem; + height: 1rem; + } + + :where(input) { + appearance: none; + // later: maybe set a tertiary bg color? + background-color: var(--#{$prefix}check-bg); + border: 1px solid var(--#{$prefix}check-border-color); + // stylelint-disable-next-line property-disallowed-list + border-radius: .25em; + } + + :where(input:checked, input:indeterminate) { + background-color: var(--#{$prefix}check-checked-bg); + border-color: var(--#{$prefix}check-checked-border-color); + } + + &:has(input:checked) .checked, + &:has(input:indeterminate) .indeterminate { + display: block; + color: var(--#{$prefix}primary-contrast); + stroke: currentcolor; + } + + &:has(input:disabled) { + --#{$prefix}check-bg: var(--#{$prefix}check-disabled-bg); + + ~ label { + color: var(--#{$prefix}secondary-text); + cursor: default; + } + } + + &:has(input:disabled:checked) { + opacity: var(--#{$prefix}check-disabled-opacity); + } + + :where(svg) { + pointer-events: none; + } + + :where(svg path) { + display: none; + } + } +} diff --git a/scss/forms/_form-check.scss b/scss/forms/_form-check.scss deleted file mode 100644 index eed5ad3cd2..0000000000 --- a/scss/forms/_form-check.scss +++ /dev/null @@ -1,482 +0,0 @@ -@use "../config" as *; -@use "../colors" as *; -@use "../variables" as *; -@use "../functions" as *; -@use "../vendor/rfs" as *; -@use "../mixins/border-radius" as *; -@use "../mixins/box-shadow" as *; -@use "../mixins/color-mode" as *; -@use "../mixins/focus-ring" as *; -@use "../mixins/transition" as *; -@use "form-variables" as *; - -// scss-docs-start form-check-variables -$form-check-input-width: 1em !default; -$form-check-min-height: $font-size-base * $line-height-base !default; -$form-check-padding-start: $form-check-input-width + .5em !default; -$form-check-margin-bottom: .125rem !default; -$form-check-label-color: null !default; -$form-check-label-cursor: null !default; -$form-check-transition: null !default; - -$form-check-input-active-filter: brightness(90%) !default; - -$form-check-input-bg: $input-bg !default; -$form-check-input-border: var(--#{$prefix}border-width) solid var(--#{$prefix}border-color) !default; -$form-check-input-border-radius: .25em !default; -$form-check-radio-border-radius: 50% !default; -$form-check-input-focus-border: $input-focus-border-color !default; -$form-check-input-focus-box-shadow: $focus-ring-box-shadow !default; - -$form-check-input-checked-color: $component-active-color !default; -$form-check-input-checked-bg-color: $component-active-bg !default; -$form-check-input-checked-border-color: $form-check-input-checked-bg-color !default; -$form-check-input-checked-bg-image: url("data:image/svg+xml,") !default; -$form-check-radio-checked-bg-image: url("data:image/svg+xml,") !default; - -$form-check-input-indeterminate-color: $component-active-color !default; -$form-check-input-indeterminate-bg-color: $component-active-bg !default; -$form-check-input-indeterminate-border-color: $form-check-input-indeterminate-bg-color !default; -$form-check-input-indeterminate-bg-image: url("data:image/svg+xml,") !default; - -$form-check-input-disabled-opacity: .5 !default; -$form-check-label-disabled-opacity: $form-check-input-disabled-opacity !default; -$form-check-btn-check-disabled-opacity: $btn-disabled-opacity !default; - -$form-check-inline-margin-end: 1rem !default; -// scss-docs-end form-check-variables - -// scss-docs-start form-switch-variables -$form-switch-color: rgba($black, .25) !default; -$form-switch-width: 1.5em !default; -$form-switch-padding-start: $form-switch-width + .5em !default; -$form-switch-bg-image: url("data:image/svg+xml,") !default; -$form-switch-border-radius: $form-switch-width !default; -$form-switch-transition: background-position .15s ease-in-out !default; - -$form-switch-focus-color: $input-focus-border-color !default; -$form-switch-focus-bg-image: url("data:image/svg+xml,") !default; - -$form-switch-checked-color: $component-active-color !default; -$form-switch-checked-bg-image: url("data:image/svg+xml,") !default; -$form-switch-checked-bg-position: right center !default; -// scss-docs-end form-switch-variables - -$check-border-color: var(--#{$prefix}border-color) !default; -$check-checked-bg: var(--#{$prefix}primary-base) !default; -$check-checked-border-color: $check-checked-bg !default; -$check-indeterminate-bg: var(--#{$prefix}primary-base) !default; -$check-indeterminate-border-color: $check-indeterminate-bg !default; -$check-disabled-bg: var(--#{$prefix}secondary-bg) !default; -$check-disabled-border-color: $check-disabled-bg !default; -$check-disabled-opacity: .65 !default; - -@layer forms { - b-checkgroup, - b-radiogroup { - display: flex; - gap: var(--#{$prefix}gap, .5rem); - align-items: var(--#{$prefix}align-items, start); - - .description { - color: var(--#{$prefix}secondary-text); - } - } - - .check, - .radio { - --#{$prefix}check-bg: transparent; - --#{$prefix}check-border-color: #{$check-border-color}; - --#{$prefix}check-checked-bg: #{$check-checked-bg}; - --#{$prefix}check-checked-border-color: #{$check-checked-border-color}; - --#{$prefix}check-indeterminate-bg: #{$check-indeterminate-bg}; - --#{$prefix}check-indeterminate-border-color: #{$check-indeterminate-border-color}; - --#{$prefix}check-disabled-bg: #{$check-disabled-bg}; - --#{$prefix}check-disabled-border-color: #{$check-disabled-border-color}; - --#{$prefix}check-disabled-opacity: #{$check-disabled-opacity}; - } - - .check { - display: grid; - grid-template-columns: repeat(1, minmax(0, 1fr)); - margin-block: .125rem; - - :where(svg, input) { - flex-shrink: 0; - grid-row-start: 1; - grid-column-start: 1; - width: 1rem; - height: 1rem; - } - - :where(input) { - appearance: none; - // later: maybe set a tertiary bg color? - background-color: var(--#{$prefix}check-bg); - border: 1px solid var(--#{$prefix}check-border-color); - // stylelint-disable-next-line property-disallowed-list - border-radius: .25em; - } - - :where(input:checked, input:indeterminate) { - background-color: var(--#{$prefix}check-checked-bg); - border-color: var(--#{$prefix}check-checked-border-color); - } - - &:has(input:checked) .checked, - &:has(input:indeterminate) .indeterminate { - display: block; - color: var(--#{$prefix}primary-contrast); - stroke: currentcolor; - } - - &:has(input:disabled) { - --#{$prefix}check-bg: var(--#{$prefix}check-disabled-bg); - - ~ label { - color: var(--#{$prefix}secondary-text); - cursor: default; - } - } - - &:has(input:disabled:checked) { - opacity: var(--#{$prefix}check-disabled-opacity); - } - - :where(svg) { - pointer-events: none; - } - - :where(svg path) { - display: none; - } - } - - .radio { - position: relative; - flex-shrink: 0; - width: 1rem; - height: 1rem; - margin-block: .125rem; - appearance: none; - background-color: var(--#{$prefix}check-bg); - border: 1px solid var(--#{$prefix}check-border-color); - // stylelint-disable-next-line property-disallowed-list - border-radius: 50%; - - &:checked { - color: var(--#{$prefix}primary-contrast); - background-color: var(--#{$prefix}check-checked-bg); - border-color: var(--#{$prefix}check-checked-border-color); - - &::before { - position: absolute; - inset: .25rem; - content: ""; - background-color: currentcolor; - // stylelint-disable-next-line property-disallowed-list - border-radius: 50%; - } - } - - &:disabled { - --#{$prefix}check-bg: var(--#{$prefix}check-disabled-bg); - - ~ label { - color: var(--#{$prefix}secondary-text); - cursor: default; - } - } - } - - .switch { - --#{$prefix}switch-height: 1.25rem; - --#{$prefix}switch-width: calc(var(--#{$prefix}switch-height) * 1.5); - --#{$prefix}switch-padding: .0625rem; - --#{$prefix}switch-bg: var(--#{$prefix}secondary-bg); - --#{$prefix}switch-border-width: var(--#{$prefix}border-width); - --#{$prefix}switch-border-color: var(--#{$prefix}border-color); - --#{$prefix}switch-indicator-bg: var(--#{$prefix}white); - --#{$prefix}switch-checked-bg: var(--#{$prefix}primary-base); - --#{$prefix}switch-checked-indicator-bg: var(--#{$prefix}white); - --#{$prefix}switch-disabled-bg: var(--#{$prefix}secondary-bg); - --#{$prefix}switch-disabled-indicator-bg: var(--#{$prefix}secondary-text); - - position: relative; - display: flex; - flex-shrink: 0; - align-items: stretch; - justify-content: flex-start; - width: var(--#{$prefix}switch-width); - height: var(--#{$prefix}switch-height); - padding: var(--#{$prefix}switch-padding); - background-color: var(--#{$prefix}switch-bg); - border: var(--#{$prefix}switch-border-width) solid var(--#{$prefix}switch-border-color); - // stylelint-disable-next-line property-disallowed-list - border-radius: 10rem; - box-shadow: inset 0 1px 2px rgba($black, .05); - // stylelint-disable-next-line property-disallowed-list - transition: .15s ease-in-out; - transition-property: padding-inline-start, background-color; - - &::before { - flex-shrink: 0; - width: calc(var(--#{$prefix}switch-height) - calc(var(--#{$prefix}switch-padding) * 2) - var(--#{$prefix}switch-border-width) * 2); - height: calc(var(--#{$prefix}switch-height) - calc(var(--#{$prefix}switch-padding) * 2) - var(--#{$prefix}switch-border-width) * 2); - // width: calc(var(--#{$prefix}switch-height) - calc(var(--#{$prefix}switch-padding) * 2)); - // height: calc(var(--#{$prefix}switch-height) - calc(var(--#{$prefix}switch-padding) * 2)); - content: ""; - background-color: var(--#{$prefix}switch-indicator-bg); - // stylelint-disable-next-line property-disallowed-list - border-radius: 50%; - box-shadow: 0 1px 2px rgba($black, .1); - } - - input { - position: absolute; - inset: 0; - appearance: none; - background-color: transparent; - } - - &:has(input:checked) { - padding-inline-start: calc(var(--#{$prefix}switch-height) / 2 + var(--#{$prefix}switch-padding)); - background-color: var(--#{$prefix}primary-base); - } - - &:has(input:disabled) { - --#{$prefix}switch-bg: var(--#{$prefix}switch-disabled-bg); - --#{$prefix}switch-indicator-bg: var(--#{$prefix}switch-disabled-indicator-bg); - - &::before { opacity: .4; } - - ~ label { - color: var(--#{$prefix}secondary-text); - cursor: default; - } - } - } - .switch-sm { - --#{$prefix}switch-height: 1em; - } - .switch-lg { - --#{$prefix}switch-height: 2em; - } - - .select { - display: grid; - grid-template-columns: repeat(1, minmax(0, 1fr)); - - > select, - > svg { - grid-row-start: 1; - grid-column-start: 1; - } - - > select { - padding: .5rem 3rem .5rem 1em; - font-size: 14px; - line-height: 20px; - appearance: none; - background-color: var(--#{$prefix}body-bg); - border: 1px solid var(--#{$prefix}border-color); - // stylelint-disable-next-line property-disallowed-list - border-radius: .5em; - } - - > svg { - align-self: center; - justify-self: end; - width: 1rem; - height: 1rem; - margin-right: 1rem; - } - } - - .form-check { - display: block; - min-height: $form-check-min-height; - padding-left: $form-check-padding-start; - margin-bottom: $form-check-margin-bottom; - - .form-check-input { - float: left; - margin-left: $form-check-padding-start * -1; - } - } - - .form-check-reverse { - padding-right: $form-check-padding-start; - padding-left: 0; - text-align: right; - - .form-check-input { - float: right; - margin-right: $form-check-padding-start * -1; - margin-left: 0; - } - } - - .form-check-input { - --#{$prefix}form-check-bg: #{$form-check-input-bg}; - - flex-shrink: 0; - width: $form-check-input-width; - height: $form-check-input-width; - margin-top: ($line-height-base - $form-check-input-width) * .5; // line-height minus check height - vertical-align: top; - appearance: none; - background-color: var(--#{$prefix}form-check-bg); - background-image: var(--#{$prefix}form-check-bg-image); - background-repeat: no-repeat; - background-position: center; - background-size: contain; - border: $form-check-input-border; - print-color-adjust: exact; // Keep themed appearance for print - @include transition($form-check-transition); - - &[type="checkbox"] { - @include border-radius($form-check-input-border-radius); - } - - &[type="radio"] { - // stylelint-disable-next-line property-disallowed-list - border-radius: $form-check-radio-border-radius; - } - - &:active { - filter: $form-check-input-active-filter; - } - - &:focus-visible { - border-color: $form-check-input-focus-border; - @include focus-ring(true); - --#{$prefix}focus-ring-offset: 1px; - // box-shadow: $form-check-input-focus-box-shadow; - } - - &:checked { - background-color: $form-check-input-checked-bg-color; - border-color: $form-check-input-checked-border-color; - - &[type="checkbox"] { - @if $enable-gradients { - --#{$prefix}form-check-bg-image: #{escape-svg($form-check-input-checked-bg-image)}, var(--#{$prefix}gradient); - } @else { - --#{$prefix}form-check-bg-image: #{escape-svg($form-check-input-checked-bg-image)}; - } - } - - &[type="radio"] { - @if $enable-gradients { - --#{$prefix}form-check-bg-image: #{escape-svg($form-check-radio-checked-bg-image)}, var(--#{$prefix}gradient); - } @else { - --#{$prefix}form-check-bg-image: #{escape-svg($form-check-radio-checked-bg-image)}; - } - } - } - - &[type="checkbox"]:indeterminate { - background-color: $form-check-input-indeterminate-bg-color; - border-color: $form-check-input-indeterminate-border-color; - - @if $enable-gradients { - --#{$prefix}form-check-bg-image: #{escape-svg($form-check-input-indeterminate-bg-image)}, var(--#{$prefix}gradient); - } @else { - --#{$prefix}form-check-bg-image: #{escape-svg($form-check-input-indeterminate-bg-image)}; - } - } - - &:disabled { - pointer-events: none; - filter: none; - opacity: $form-check-input-disabled-opacity; - } - - // Use disabled attribute in addition of :disabled pseudo-class - // See: https://github.com/twbs/bootstrap/issues/28247 - &[disabled], - &:disabled { - ~ .form-check-label { - cursor: default; - opacity: $form-check-label-disabled-opacity; - } - } - } - - .form-check-label { - color: $form-check-label-color; - cursor: $form-check-label-cursor; - } - - // - // Switch - // - - .form-switch { - padding-left: $form-switch-padding-start; - - .form-check-input { - --#{$prefix}form-switch-bg: #{escape-svg($form-switch-bg-image)}; - - width: $form-switch-width; - margin-left: $form-switch-padding-start * -1; - background-image: var(--#{$prefix}form-switch-bg); - background-position: left center; - @include border-radius($form-switch-border-radius, 0); - @include transition($form-switch-transition); - - &:focus { - --#{$prefix}form-switch-bg: #{escape-svg($form-switch-focus-bg-image)}; - } - - &:checked { - background-position: $form-switch-checked-bg-position; - - @if $enable-gradients { - --#{$prefix}form-switch-bg: #{escape-svg($form-switch-checked-bg-image)}, var(--#{$prefix}gradient); - } @else { - --#{$prefix}form-switch-bg: #{escape-svg($form-switch-checked-bg-image)}; - } - } - } - - &.form-check-reverse { - padding-right: $form-switch-padding-start; - padding-left: 0; - - .form-check-input { - margin-right: $form-switch-padding-start * -1; - margin-left: 0; - } - } - } - - .form-check-inline { - display: inline-block; - margin-right: $form-check-inline-margin-end; - } - - .btn-check { - position: absolute; - clip: rect(0, 0, 0, 0); - pointer-events: none; - - &[disabled], - &:disabled { - + .btn { - pointer-events: none; - filter: none; - opacity: $form-check-btn-check-disabled-opacity; - } - } - } - - @if $enable-dark-mode { - @include color-mode(dark) { - .form-switch .form-check-input:not(:checked):not(:focus) { - --#{$prefix}form-switch-bg: #{escape-svg($form-switch-bg-image-dark)}; - } - } - } -} diff --git a/scss/forms/_radio.scss b/scss/forms/_radio.scss new file mode 100644 index 0000000000..af63fb188e --- /dev/null +++ b/scss/forms/_radio.scss @@ -0,0 +1,79 @@ +@use "../config" as *; +@use "../colors" as *; +@use "../variables" as *; +@use "../functions" as *; +@use "../vendor/rfs" as *; +@use "../mixins/border-radius" as *; +@use "../mixins/box-shadow" as *; +@use "../mixins/color-mode" as *; +@use "../mixins/focus-ring" as *; +@use "../mixins/transition" as *; +@use "form-variables" as *; + +// scss-docs-start radio-variables +$radio-border-color: var(--#{$prefix}border-color) !default; +$radio-checked-bg: var(--#{$prefix}primary-base) !default; +$radio-checked-border-color: $radio-checked-bg !default; +$radio-disabled-bg: var(--#{$prefix}secondary-bg) !default; +$radio-disabled-border-color: $radio-disabled-bg !default; +$radio-disabled-opacity: .65 !default; +// scss-docs-end radio-variables + +@layer forms { + b-radiogroup { + display: flex; + gap: var(--#{$prefix}gap, .5rem); + align-items: var(--#{$prefix}align-items, start); + + .description { + color: var(--#{$prefix}secondary-text); + } + } + + .radio { + // scss-docs-start radio-css-variables + --#{$prefix}radio-bg: transparent; + --#{$prefix}radio-border-color: #{$radio-border-color}; + --#{$prefix}radio-checked-bg: #{$radio-checked-bg}; + --#{$prefix}radio-checked-border-color: #{$radio-checked-border-color}; + --#{$prefix}radio-disabled-bg: #{$radio-disabled-bg}; + --#{$prefix}radio-disabled-border-color: #{$radio-disabled-border-color}; + --#{$prefix}radio-disabled-opacity: #{$radio-disabled-opacity}; + // scss-docs-end radio-css-variables + + position: relative; + flex-shrink: 0; + width: 1rem; + height: 1rem; + margin-block: .125rem; + appearance: none; + background-color: var(--#{$prefix}radio-bg); + border: 1px solid var(--#{$prefix}radio-border-color); + // stylelint-disable-next-line property-disallowed-list + border-radius: 50%; + + &:checked { + color: var(--#{$prefix}primary-contrast); + background-color: var(--#{$prefix}radio-checked-bg); + border-color: var(--#{$prefix}radio-checked-border-color); + + &::before { + position: absolute; + inset: .25rem; + content: ""; + background-color: currentcolor; + // stylelint-disable-next-line property-disallowed-list + border-radius: 50%; + } + } + + &:disabled { + --#{$prefix}radio-bg: var(--#{$prefix}radio-disabled-bg); + + ~ label { + color: var(--#{$prefix}secondary-text); + cursor: default; + } + } + } +} diff --git a/scss/forms/_switch.scss b/scss/forms/_switch.scss index 67baf23c25..457d170a4f 100644 --- a/scss/forms/_switch.scss +++ b/scss/forms/_switch.scss @@ -9,3 +9,81 @@ @use "../mixins/focus-ring" as *; @use "../mixins/transition" as *; @use "form-variables" as *; + +@layer forms { + .switch { + // scss-docs-start switch-css-variables + --#{$prefix}switch-height: 1.25rem; + --#{$prefix}switch-width: calc(var(--#{$prefix}switch-height) * 1.5); + --#{$prefix}switch-padding: .0625rem; + --#{$prefix}switch-bg: var(--#{$prefix}secondary-bg); + --#{$prefix}switch-border-width: var(--#{$prefix}border-width); + --#{$prefix}switch-border-color: var(--#{$prefix}border-color); + --#{$prefix}switch-indicator-bg: var(--#{$prefix}white); + --#{$prefix}switch-checked-bg: var(--#{$prefix}primary-base); + --#{$prefix}switch-checked-indicator-bg: var(--#{$prefix}white); + --#{$prefix}switch-disabled-bg: var(--#{$prefix}secondary-bg); + --#{$prefix}switch-disabled-indicator-bg: var(--#{$prefix}secondary-text); + // scss-docs-end switch-css-variables + + position: relative; + display: flex; + flex-shrink: 0; + align-items: stretch; + justify-content: flex-start; + width: var(--#{$prefix}switch-width); + height: var(--#{$prefix}switch-height); + padding: var(--#{$prefix}switch-padding); + background-color: var(--#{$prefix}switch-bg); + border: var(--#{$prefix}switch-border-width) solid var(--#{$prefix}switch-border-color); + // stylelint-disable-next-line property-disallowed-list + border-radius: 10rem; + box-shadow: inset 0 1px 2px rgba($black, .05); + // stylelint-disable-next-line property-disallowed-list + transition: .15s ease-in-out; + transition-property: padding-inline-start, background-color; + + &::before { + flex-shrink: 0; + width: calc(var(--#{$prefix}switch-height) - calc(var(--#{$prefix}switch-padding) * 2) - var(--#{$prefix}switch-border-width) * 2); + height: calc(var(--#{$prefix}switch-height) - calc(var(--#{$prefix}switch-padding) * 2) - var(--#{$prefix}switch-border-width) * 2); + // width: calc(var(--#{$prefix}switch-height) - calc(var(--#{$prefix}switch-padding) * 2)); + // height: calc(var(--#{$prefix}switch-height) - calc(var(--#{$prefix}switch-padding) * 2)); + content: ""; + background-color: var(--#{$prefix}switch-indicator-bg); + // stylelint-disable-next-line property-disallowed-list + border-radius: 50%; + box-shadow: 0 1px 2px rgba($black, .1); + } + + input { + position: absolute; + inset: 0; + appearance: none; + background-color: transparent; + } + + &:has(input:checked) { + padding-inline-start: calc(var(--#{$prefix}switch-height) / 2 + var(--#{$prefix}switch-padding)); + background-color: var(--#{$prefix}primary-base); + } + + &:has(input:disabled) { + --#{$prefix}switch-bg: var(--#{$prefix}switch-disabled-bg); + --#{$prefix}switch-indicator-bg: var(--#{$prefix}switch-disabled-indicator-bg); + + &::before { opacity: .4; } + + ~ label { + color: var(--#{$prefix}secondary-text); + cursor: default; + } + } + } + .switch-sm { + --#{$prefix}switch-height: 1em; + } + .switch-lg { + --#{$prefix}switch-height: 2em; + } +} diff --git a/scss/forms/index.scss b/scss/forms/index.scss index a08cde8b39..0798f2003b 100644 --- a/scss/forms/index.scss +++ b/scss/forms/index.scss @@ -1,7 +1,9 @@ @forward "labels"; @forward "form-text"; @forward "form-control"; -@forward "form-check"; +@forward "check"; +@forward "radio"; +@forward "switch"; @forward "form-range"; @forward "floating-labels"; @forward "input-group"; diff --git a/site/data/sidebar.yml b/site/data/sidebar.yml index a930467e19..c6078956db 100644 --- a/site/data/sidebar.yml +++ b/site/data/sidebar.yml @@ -60,7 +60,6 @@ pages: - title: Overview - title: Form control - - title: Checks & radios - title: Checkbox - title: Radio - title: Switch diff --git a/site/src/content/docs/forms/checkbox.mdx b/site/src/content/docs/forms/checkbox.mdx index cd3aac1de8..409fed5195 100644 --- a/site/src/content/docs/forms/checkbox.mdx +++ b/site/src/content/docs/forms/checkbox.mdx @@ -103,3 +103,15 @@ Add the `disabled` attribute and the associated `