mirror of
https://github.com/tabler/tabler.git
synced 2026-10-12 05:06:55 +04:00
Merge dev into combobox-component
This commit is contained in:
commit
f7fe901483
32 files changed
+791
-288
No files matched your search
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@tabler/core": minor
|
||||
"@tabler/docs": patch
|
||||
---
|
||||
|
||||
Added `--tblr-form-check-*` and `--tblr-form-switch-*` variables, with shared `--tblr-control-checked-bg` and disabled tokens on `:root`.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@tabler/core": minor
|
||||
"@tabler/docs": patch
|
||||
---
|
||||
|
||||
Added `--tblr-control-*` variables to `.form-control` and `.form-select`; sizes and the file button now follow them.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@tabler/core": minor
|
||||
---
|
||||
|
||||
Updated icon addons, select groups, `.col-form-label`, validation icons, OTP and Tom Select to read the `--tblr-control-*` and `--tblr-btn-input-*` variables.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@tabler/core": minor
|
||||
---
|
||||
|
||||
Fixed `.form-select-sm` and `.form-select-lg` height to match `.form-control-sm` and `.form-control-lg`. Small buttons, inputs and selects are now 32px tall instead of 28px. Fixed the font size of a small Tom Select to match a small native select.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@tabler/docs": patch
|
||||
---
|
||||
|
||||
Added the Forms → CSS variables page: the control scale, state colors and every `--tblr-control-*`, add-on, floating, range, check and switch token.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@tabler/core": minor
|
||||
"@tabler/docs": patch
|
||||
---
|
||||
|
||||
Added `--tblr-input-group-addon-*`, `--tblr-form-floating-*` and `--tblr-range-*` variables to input groups, floating labels and range inputs.
|
||||
+2
-2
@@ -148,7 +148,7 @@
|
||||
},
|
||||
{
|
||||
"path": "./dist/css/tabler-props.css",
|
||||
"maxSize": "4.2 kB"
|
||||
"maxSize": "4.3 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/css/tabler-props.min.css",
|
||||
@@ -156,7 +156,7 @@
|
||||
},
|
||||
{
|
||||
"path": "./dist/css/tabler-props.rtl.css",
|
||||
"maxSize": "4.2 kB"
|
||||
"maxSize": "4.3 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/css/tabler-props.rtl.min.css",
|
||||
|
||||
@@ -52,6 +52,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
// deprecated(2.0): `--form-select-bg-img` is the old name of `--control-select-bg`
|
||||
// (from `bootstrap/forms/_form-select.scss`). Still read by `.form-select`,
|
||||
// so a project that set it keeps its arrow.
|
||||
.form-select {
|
||||
--form-select-bg-img: var(--control-select-bg);
|
||||
}
|
||||
|
||||
// `.form-hint` is deprecated, use `.form-text` instead
|
||||
// (from `bootstrap/forms/_form-text.scss`).
|
||||
.form-hint {
|
||||
|
||||
@@ -125,6 +125,14 @@
|
||||
--btn-input-xl-min-height: calc(var(--btn-input-xl-line-height) + var(--btn-input-xl-padding-y) * 2 + #{$input-btn-border-width} * 2);
|
||||
// scss-docs-end btn-input-css-vars
|
||||
|
||||
/** Checks, radios and switches: shared state colors, in the names Bootstrap 6 uses */
|
||||
// scss-docs-start control-state-css-vars
|
||||
--control-checked-bg: #{$form-check-input-checked-bg-color};
|
||||
--control-checked-border-color: #{$form-check-input-checked-border-color};
|
||||
--control-disabled-bg: #{$input-disabled-bg};
|
||||
--control-disabled-opacity: #{$form-check-input-disabled-opacity};
|
||||
// scss-docs-end control-state-css-vars
|
||||
|
||||
/** Backdrops */
|
||||
--backdrop-opacity: #{$backdrop-opacity};
|
||||
--backdrop-bg: #{$backdrop-bg};
|
||||
|
||||
@@ -1063,7 +1063,7 @@ $badge-padding-x-lg: 0.5rem !default;
|
||||
$input-btn-border-width: var(--border-width) !default;
|
||||
$input-btn-font-family: var(--body-font-family) !default;
|
||||
|
||||
$input-btn-padding-y-sm: 0.3125rem !default;
|
||||
$input-btn-padding-y-sm: 0.4375rem !default;
|
||||
$input-btn-padding-x-sm: 0.5rem !default;
|
||||
$input-btn-font-size-sm: $h5-font-size !default;
|
||||
$input-btn-line-height-sm: 1rem !default;
|
||||
|
||||
@@ -1,14 +1,33 @@
|
||||
@use '../../config' as *;
|
||||
|
||||
.form-floating {
|
||||
// scss-docs-start form-floating-css-vars
|
||||
--form-floating-height: #{$form-floating-height};
|
||||
--form-floating-line-height: #{$form-floating-line-height};
|
||||
--form-floating-padding-x: #{var-if-default($form-floating-padding-x, $input-btn-padding-x, '--btn-input-padding-x')};
|
||||
--form-floating-padding-y: #{$form-floating-padding-y};
|
||||
--form-floating-input-padding-t: #{$form-floating-input-padding-t};
|
||||
--form-floating-input-padding-b: #{$form-floating-input-padding-b};
|
||||
--form-floating-label-height: #{$form-floating-label-height};
|
||||
// The textarea label masks the text under it. It is a sibling of the control,
|
||||
// so it cannot read the control's `--control-bg` and mirrors the scale instead.
|
||||
--form-floating-label-bg: #{var-if-default($input-bg, var(--bg-forms), '--btn-input-bg')};
|
||||
--form-floating-label-disabled-bg: #{$input-disabled-bg};
|
||||
--form-floating-label-border-radius: #{var-if-default($input-border-radius, var(--border-radius), '--btn-input-border-radius')};
|
||||
--form-floating-label-opacity: #{$form-floating-label-opacity};
|
||||
--form-floating-label-transform: #{$form-floating-label-transform};
|
||||
--form-floating-label-disabled-color: #{$form-floating-label-disabled-color};
|
||||
--form-floating-transition: #{$form-floating-transition};
|
||||
// scss-docs-end form-floating-css-vars
|
||||
|
||||
position: relative;
|
||||
|
||||
> .form-control,
|
||||
> .form-control-plaintext,
|
||||
> .form-select {
|
||||
height: $form-floating-height;
|
||||
min-height: $form-floating-height;
|
||||
line-height: $form-floating-line-height;
|
||||
height: var(--form-floating-height);
|
||||
min-height: var(--form-floating-height);
|
||||
line-height: var(--form-floating-line-height);
|
||||
}
|
||||
|
||||
> label {
|
||||
@@ -18,21 +37,21 @@
|
||||
z-index: 2;
|
||||
max-width: 100%;
|
||||
height: 100%; // allow textareas
|
||||
padding: $form-floating-padding-y $form-floating-padding-x;
|
||||
padding: var(--form-floating-padding-y) var(--form-floating-padding-x);
|
||||
overflow: hidden;
|
||||
color: color-transparent(var(--body-color), $form-floating-label-opacity);
|
||||
color: color-transparent(var(--body-color), calc(var(--form-floating-label-opacity) * 100%));
|
||||
text-align: start;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
pointer-events: none;
|
||||
border: $input-border-width solid transparent; // Required for aligning label's text with the input as it affects inner box model
|
||||
transform-origin: 0 0;
|
||||
@include transition($form-floating-transition);
|
||||
@include transition(var(--form-floating-transition));
|
||||
}
|
||||
|
||||
> .form-control,
|
||||
> .form-control-plaintext {
|
||||
padding: $form-floating-padding-y $form-floating-padding-x;
|
||||
padding: var(--form-floating-padding-y) var(--form-floating-padding-x);
|
||||
|
||||
&::placeholder {
|
||||
color: transparent;
|
||||
@@ -40,20 +59,20 @@
|
||||
|
||||
&:focus,
|
||||
&:not(:placeholder-shown) {
|
||||
padding-top: $form-floating-input-padding-t;
|
||||
padding-bottom: $form-floating-input-padding-b;
|
||||
padding-top: var(--form-floating-input-padding-t);
|
||||
padding-bottom: var(--form-floating-input-padding-b);
|
||||
}
|
||||
// Duplicated because `:-webkit-autofill` invalidates other selectors when grouped
|
||||
&:-webkit-autofill {
|
||||
padding-top: $form-floating-input-padding-t;
|
||||
padding-bottom: $form-floating-input-padding-b;
|
||||
padding-top: var(--form-floating-input-padding-t);
|
||||
padding-bottom: var(--form-floating-input-padding-b);
|
||||
}
|
||||
}
|
||||
|
||||
> .form-select {
|
||||
padding-top: $form-floating-input-padding-t;
|
||||
padding-bottom: $form-floating-input-padding-b;
|
||||
padding-inline-start: $form-floating-padding-x;
|
||||
padding-top: var(--form-floating-input-padding-t);
|
||||
padding-bottom: var(--form-floating-input-padding-b);
|
||||
padding-inline-start: var(--form-floating-padding-x);
|
||||
}
|
||||
|
||||
> .form-control:focus,
|
||||
@@ -61,29 +80,29 @@
|
||||
> .form-control-plaintext,
|
||||
> .form-select {
|
||||
~ label {
|
||||
transform: $form-floating-label-transform;
|
||||
transform: var(--form-floating-label-transform);
|
||||
}
|
||||
}
|
||||
// Duplicated because `:-webkit-autofill` invalidates other selectors when grouped
|
||||
> .form-control:-webkit-autofill {
|
||||
~ label {
|
||||
transform: $form-floating-label-transform;
|
||||
transform: var(--form-floating-label-transform);
|
||||
}
|
||||
}
|
||||
> textarea:focus,
|
||||
> textarea:not(:placeholder-shown) {
|
||||
~ label::after {
|
||||
position: absolute;
|
||||
inset: $form-floating-padding-y ($form-floating-padding-x * 0.5);
|
||||
inset: var(--form-floating-padding-y) calc(var(--form-floating-padding-x) * 0.5);
|
||||
z-index: -1;
|
||||
height: $form-floating-label-height;
|
||||
height: var(--form-floating-label-height);
|
||||
content: '';
|
||||
background-color: $input-bg;
|
||||
@include border-radius($input-border-radius);
|
||||
background-color: var(--form-floating-label-bg);
|
||||
@include border-radius(var(--form-floating-label-border-radius));
|
||||
}
|
||||
}
|
||||
> textarea:disabled ~ label::after {
|
||||
background-color: $input-disabled-bg;
|
||||
background-color: var(--form-floating-label-disabled-bg);
|
||||
}
|
||||
|
||||
> .form-control-plaintext {
|
||||
@@ -95,6 +114,6 @@
|
||||
> :disabled ~ label,
|
||||
> .form-control:disabled ~ label {
|
||||
// Required for `.form-control`s because of specificity
|
||||
color: $form-floating-label-disabled-color;
|
||||
color: var(--form-floating-label-disabled-color);
|
||||
}
|
||||
}
|
||||
@@ -5,44 +5,67 @@
|
||||
@use '../../config' as *;
|
||||
|
||||
.form-check {
|
||||
// scss-docs-start form-check-css-vars
|
||||
--form-check-min-height: #{$form-check-min-height};
|
||||
--form-check-padding-start: #{$form-check-padding-start};
|
||||
--form-check-margin-bottom: #{$form-check-margin-bottom};
|
||||
// scss-docs-end form-check-css-vars
|
||||
|
||||
display: block;
|
||||
min-height: $form-check-min-height;
|
||||
padding-inline-start: $form-check-padding-start;
|
||||
margin-bottom: $form-check-margin-bottom;
|
||||
min-height: var(--form-check-min-height);
|
||||
padding-inline-start: var(--form-check-padding-start);
|
||||
margin-bottom: var(--form-check-margin-bottom);
|
||||
|
||||
.form-check-input {
|
||||
float: inline-start;
|
||||
margin-inline-start: $form-check-padding-start * -1;
|
||||
margin-inline-start: calc(var(--form-check-padding-start) * -1);
|
||||
}
|
||||
}
|
||||
|
||||
.form-check-reverse {
|
||||
padding-inline-end: $form-check-padding-start;
|
||||
padding-inline-end: var(--form-check-padding-start);
|
||||
padding-inline-start: 0;
|
||||
text-align: end;
|
||||
|
||||
.form-check-input {
|
||||
float: inline-end;
|
||||
margin-inline-end: $form-check-padding-start * -1;
|
||||
margin-inline-end: calc(var(--form-check-padding-start) * -1);
|
||||
margin-inline-start: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// The checked, indeterminate and disabled tokens read the shared state colors
|
||||
// on `:root` (`--control-checked-bg` and friends) until the Sass variable is
|
||||
// configured, so one override retunes checks, radios and switches together.
|
||||
.form-check-input {
|
||||
// scss-docs-start form-check-input-css-vars
|
||||
--form-check-input-width: #{$form-check-input-width};
|
||||
--form-check-bg: #{$form-check-input-bg};
|
||||
--form-check-border: #{$form-check-input-border};
|
||||
--form-check-border-radius: #{$form-check-input-border-radius};
|
||||
--form-check-box-shadow: #{$form-check-input-box-shadow};
|
||||
--form-check-icon-color: #{$form-check-input-checked-color};
|
||||
--form-check-focus-border-color: #{$form-check-input-focus-border};
|
||||
--form-check-active-filter: #{$form-check-input-active-filter};
|
||||
--form-check-checked-bg: #{var-if-default($form-check-input-checked-bg-color, var(--primary), '--control-checked-bg')};
|
||||
--form-check-checked-border-color: #{var-if-default($form-check-input-checked-border-color, var(--border-color-translucent), '--control-checked-border-color')};
|
||||
--form-check-indeterminate-bg: #{var-if-default($form-check-input-indeterminate-bg-color, var(--primary), '--control-checked-bg')};
|
||||
--form-check-indeterminate-border-color: #{var-if-default($form-check-input-indeterminate-border-color, var(--primary), '--form-check-indeterminate-bg')};
|
||||
--form-check-disabled-opacity: #{var-if-default($form-check-input-disabled-opacity, 0.5, '--control-disabled-opacity')};
|
||||
--form-check-transition: #{$form-check-transition};
|
||||
// scss-docs-end form-check-input-css-vars
|
||||
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
width: $form-check-input-width;
|
||||
height: $form-check-input-width;
|
||||
width: var(--form-check-input-width);
|
||||
height: var(--form-check-input-width);
|
||||
margin-top: ($line-height-base - $form-check-input-width) * 0.5; // line-height minus check height
|
||||
vertical-align: top;
|
||||
appearance: none;
|
||||
background-color: var(--form-check-bg);
|
||||
border: $form-check-input-border;
|
||||
border: var(--form-check-border);
|
||||
print-color-adjust: exact; // Keep themed appearance for print
|
||||
@include transition($form-check-transition);
|
||||
@include transition(var(--form-check-transition));
|
||||
// Start the focus ring's `outline-color` transition from transparent, not `currentcolor`.
|
||||
outline-color: transparent;
|
||||
|
||||
@@ -62,7 +85,7 @@
|
||||
&[type='checkbox'] {
|
||||
--form-check-icon: #{escape-svg($form-check-input-checked-bg-image)};
|
||||
|
||||
@include border-radius($form-check-input-border-radius);
|
||||
@include border-radius(var(--form-check-border-radius));
|
||||
}
|
||||
|
||||
&[type='radio'] {
|
||||
@@ -73,17 +96,17 @@
|
||||
}
|
||||
|
||||
&:active {
|
||||
filter: $form-check-input-active-filter;
|
||||
filter: var(--form-check-active-filter);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
border-color: $form-check-input-focus-border;
|
||||
border-color: var(--form-check-focus-border-color);
|
||||
@include focus-ring(true);
|
||||
}
|
||||
|
||||
&:checked {
|
||||
background-color: $form-check-input-checked-bg-color;
|
||||
border-color: $form-check-input-checked-border-color;
|
||||
background-color: var(--form-check-checked-bg);
|
||||
border-color: var(--form-check-checked-border-color);
|
||||
|
||||
&::before {
|
||||
opacity: 1;
|
||||
@@ -94,8 +117,8 @@
|
||||
--form-check-icon: #{escape-svg($form-check-input-indeterminate-bg-image)};
|
||||
--form-check-icon-color: #{$form-check-input-indeterminate-color};
|
||||
|
||||
background-color: $form-check-input-indeterminate-bg-color;
|
||||
border-color: $form-check-input-indeterminate-border-color;
|
||||
background-color: var(--form-check-indeterminate-bg);
|
||||
border-color: var(--form-check-indeterminate-border-color);
|
||||
|
||||
&::before {
|
||||
opacity: 1;
|
||||
@@ -105,7 +128,7 @@
|
||||
&:disabled {
|
||||
pointer-events: none;
|
||||
filter: none;
|
||||
opacity: $form-check-input-disabled-opacity;
|
||||
opacity: var(--form-check-disabled-opacity);
|
||||
}
|
||||
|
||||
// Use disabled attribute in addition of :disabled pseudo-class
|
||||
@@ -129,18 +152,29 @@
|
||||
//
|
||||
|
||||
.form-switch {
|
||||
padding-inline-start: $form-switch-padding-start;
|
||||
// scss-docs-start form-switch-css-vars
|
||||
--form-switch-width: #{$form-switch-width};
|
||||
--form-switch-height: #{$form-switch-height};
|
||||
--form-switch-padding-start: #{if(sass($form-switch-padding-start == $form-switch-width + 0.5rem): calc(var(--form-switch-width) + 0.5rem); else: $form-switch-padding-start)};
|
||||
--form-switch-border-radius: #{if(sass($form-switch-border-radius == $form-switch-width): var(--form-switch-width); else: $form-switch-border-radius)};
|
||||
--form-switch-focus-color: #{$form-switch-focus-color};
|
||||
--form-switch-checked-color: #{$form-switch-checked-color};
|
||||
--form-switch-disabled-bg: #{var-if-default($form-switch-disabled-bg, var(--bg-forms-disabled), '--control-disabled-bg')};
|
||||
--form-switch-disabled-color: #{$form-switch-disabled-color};
|
||||
// scss-docs-end form-switch-css-vars
|
||||
|
||||
padding-inline-start: var(--form-switch-padding-start);
|
||||
|
||||
.form-check-input {
|
||||
--form-switch-color: #{$form-switch-color};
|
||||
// The knob is a circle three quarters of the track height, inset by an eighth
|
||||
// — the same geometry the old `viewBox='-4 -4 8 8'` svg had.
|
||||
--form-switch-knob-size: calc(#{$form-switch-height} * 0.75);
|
||||
--form-switch-knob-offset: calc(#{$form-switch-height} * 0.125);
|
||||
--form-switch-knob-size: calc(var(--form-switch-height) * 0.75);
|
||||
--form-switch-knob-offset: calc(var(--form-switch-height) * 0.125);
|
||||
|
||||
width: $form-switch-width;
|
||||
margin-inline-start: $form-switch-padding-start * -1;
|
||||
@include border-radius($form-switch-border-radius, 0);
|
||||
width: var(--form-switch-width);
|
||||
margin-inline-start: calc(var(--form-switch-padding-start) * -1);
|
||||
@include border-radius(var(--form-switch-border-radius), 0);
|
||||
@include transition($form-switch-transition);
|
||||
|
||||
// The knob replaces the masked check icon: a plain circle that slides.
|
||||
@@ -159,11 +193,11 @@
|
||||
}
|
||||
|
||||
&:focus {
|
||||
--form-switch-color: #{$form-switch-focus-color};
|
||||
--form-switch-color: var(--form-switch-focus-color);
|
||||
}
|
||||
|
||||
&:checked {
|
||||
--form-switch-color: #{$form-switch-checked-color};
|
||||
--form-switch-color: var(--form-switch-checked-color);
|
||||
|
||||
&::before {
|
||||
inset-inline-start: calc(100% - var(--form-switch-knob-size) - var(--form-switch-knob-offset));
|
||||
@@ -172,11 +206,11 @@
|
||||
}
|
||||
|
||||
&.form-check-reverse {
|
||||
padding-inline-end: $form-switch-padding-start;
|
||||
padding-inline-end: var(--form-switch-padding-start);
|
||||
padding-inline-start: 0;
|
||||
|
||||
.form-check-input {
|
||||
margin-inline-end: $form-switch-padding-start * -1;
|
||||
margin-inline-end: calc(var(--form-switch-padding-start) * -1);
|
||||
margin-inline-start: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,25 +6,57 @@
|
||||
|
||||
@use '../../config' as *;
|
||||
|
||||
// The control tokens, in the names Bootstrap 6 uses. One block serves every
|
||||
// text-like control: `.form-select` and `.form-control-plaintext` stand alone
|
||||
// (no `.form-control`), so they need the same declarations. A token seeded from
|
||||
// a size variable reads the `:root` scale until the Sass variable is configured.
|
||||
.form-select,
|
||||
.form-control-plaintext,
|
||||
.form-control {
|
||||
// scss-docs-start control-css-vars
|
||||
--control-min-height: calc(var(--control-line-height) + var(--control-padding-y) * 2 + var(--control-border-width) * 2);
|
||||
--control-padding-y: #{var-if-default($input-padding-y, $input-btn-padding-y, '--btn-input-padding-y')};
|
||||
--control-padding-x: #{var-if-default($input-padding-x, $input-btn-padding-x, '--btn-input-padding-x')};
|
||||
@include rfs(var-if-default($input-font-size, $input-btn-font-size, '--btn-input-font-size'), --control-font-size);
|
||||
--control-line-height: #{var-if-default($input-line-height, $input-btn-line-height, '--btn-input-line-height')};
|
||||
--control-fg: #{var-if-default($input-color, var(--body-color), '--btn-input-fg')};
|
||||
--control-bg: #{var-if-default($input-bg, var(--bg-forms), '--btn-input-bg')};
|
||||
--control-border-width: #{$input-border-width};
|
||||
--control-border-color: #{$input-border-color};
|
||||
--control-border-radius: #{var-if-default($input-border-radius, var(--border-radius), '--btn-input-border-radius')};
|
||||
--control-box-shadow: #{$input-box-shadow};
|
||||
--control-focus-fg: #{var-if-default($input-focus-color, $input-color, '--control-fg')};
|
||||
--control-focus-bg: #{var-if-default($input-focus-bg, $input-bg, '--control-bg')};
|
||||
--control-focus-border-color: #{$input-focus-border-color};
|
||||
--control-placeholder-color: #{$input-placeholder-color};
|
||||
--control-disabled-color: #{if(sass($input-disabled-color): $input-disabled-color; else: $form-secondary-color)};
|
||||
--control-disabled-bg: #{$input-disabled-bg};
|
||||
--control-disabled-border-color: #{if(sass($input-disabled-border-color): $input-disabled-border-color; else: var(--control-border-color))};
|
||||
--control-action-bg: #{$form-file-button-bg};
|
||||
--control-action-hover-bg: #{$form-file-button-hover-bg};
|
||||
--control-transition: #{$input-transition};
|
||||
// scss-docs-end control-css-vars
|
||||
}
|
||||
|
||||
.form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: $input-padding-y $input-padding-x;
|
||||
padding: var(--control-padding-y) var(--control-padding-x);
|
||||
font-family: $input-font-family;
|
||||
@include font-size($input-font-size);
|
||||
@include font-size(var(--control-font-size));
|
||||
font-weight: $input-font-weight;
|
||||
line-height: $input-line-height;
|
||||
color: $input-color;
|
||||
line-height: var(--control-line-height);
|
||||
color: var(--control-fg);
|
||||
appearance: none; // Fix appearance for date inputs in Safari
|
||||
background-color: $input-bg;
|
||||
background-color: var(--control-bg);
|
||||
background-clip: padding-box;
|
||||
border: $input-border-width solid $input-border-color;
|
||||
border: var(--control-border-width) solid var(--control-border-color);
|
||||
|
||||
// Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.
|
||||
@include border-radius($input-border-radius, 0);
|
||||
@include border-radius(var(--control-border-radius), 0);
|
||||
|
||||
@include box-shadow($input-box-shadow);
|
||||
@include transition($input-transition);
|
||||
@include box-shadow(var(--control-box-shadow));
|
||||
@include transition(var(--control-transition));
|
||||
// Start the focus ring's `outline-color` transition from transparent, not `currentcolor`.
|
||||
outline-color: transparent;
|
||||
|
||||
@@ -38,9 +70,9 @@
|
||||
|
||||
// Customize the `:focus` state to imitate native WebKit styles.
|
||||
&:focus {
|
||||
color: $input-focus-color;
|
||||
background-color: $input-focus-bg;
|
||||
border-color: $input-focus-border-color;
|
||||
color: var(--control-focus-fg);
|
||||
background-color: var(--control-focus-bg);
|
||||
border-color: var(--control-focus-border-color);
|
||||
--focus-ring-offset: -1px;
|
||||
@include focus-ring(true);
|
||||
}
|
||||
@@ -74,7 +106,7 @@
|
||||
|
||||
// Placeholder
|
||||
&::placeholder {
|
||||
color: $input-placeholder-color;
|
||||
color: var(--control-placeholder-color);
|
||||
// Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.
|
||||
opacity: 1;
|
||||
}
|
||||
@@ -85,31 +117,31 @@
|
||||
// disabled if the fieldset is disabled. Due to implementation difficulty, we
|
||||
// don't honor that edge case; we style them as disabled anyway.
|
||||
&:disabled {
|
||||
color: $input-disabled-color;
|
||||
background-color: $input-disabled-bg;
|
||||
border-color: $input-disabled-border-color;
|
||||
color: var(--control-disabled-color);
|
||||
background-color: var(--control-disabled-bg);
|
||||
border-color: var(--control-disabled-border-color);
|
||||
// iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
// File input buttons theming
|
||||
&::file-selector-button {
|
||||
padding: $input-padding-y $input-padding-x;
|
||||
margin: (-$input-padding-y) (-$input-padding-x);
|
||||
margin-inline-end: $input-padding-x;
|
||||
padding: var(--control-padding-y) var(--control-padding-x);
|
||||
margin: calc(var(--control-padding-y) * -1) calc(var(--control-padding-x) * -1);
|
||||
margin-inline-end: var(--control-padding-x);
|
||||
color: $form-file-button-color;
|
||||
@include gradient-bg($form-file-button-bg);
|
||||
@include gradient-bg(var(--control-action-bg));
|
||||
pointer-events: none;
|
||||
border-color: inherit;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
border-inline-end-width: $input-border-width;
|
||||
border-inline-end-width: var(--control-border-width);
|
||||
border-radius: 0; // stylelint-disable-line property-disallowed-list
|
||||
@include transition($btn-transition);
|
||||
}
|
||||
|
||||
&:hover:not(:disabled):not([readonly])::file-selector-button {
|
||||
background-color: $form-file-button-hover-bg;
|
||||
background-color: var(--control-action-hover-bg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,13 +153,13 @@
|
||||
.form-control-plaintext {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: $input-padding-y 0;
|
||||
padding: var(--control-padding-y) 0;
|
||||
margin-bottom: 0; // match inputs if this class comes on inputs with default margins
|
||||
line-height: $input-line-height;
|
||||
color: $input-plaintext-color;
|
||||
line-height: var(--control-line-height);
|
||||
color: #{var-if-default($input-plaintext-color, $input-color, '--control-fg')};
|
||||
background-color: transparent;
|
||||
border: solid transparent;
|
||||
border-width: $input-border-width 0;
|
||||
border-width: var(--control-border-width) 0;
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
@@ -143,36 +175,29 @@
|
||||
// Form control sizing
|
||||
//
|
||||
// Build on `.form-control` with modifier classes to decrease or increase the
|
||||
// height and font-size of form controls.
|
||||
// height and font-size of form controls. A size only moves the tokens; the
|
||||
// height, the file button and the color swatch follow.
|
||||
//
|
||||
// Repeated in `_input_group.scss` to avoid Sass extend issues.
|
||||
|
||||
.form-control-sm {
|
||||
line-height: $input-line-height-sm;
|
||||
min-height: $input-height-sm;
|
||||
padding: $input-padding-y-sm $input-padding-x-sm;
|
||||
@include font-size($input-font-size-sm);
|
||||
@include border-radius($input-border-radius-sm);
|
||||
|
||||
&::file-selector-button {
|
||||
padding: $input-padding-y-sm $input-padding-x-sm;
|
||||
margin: (-$input-padding-y-sm) (-$input-padding-x-sm);
|
||||
margin-inline-end: $input-padding-x-sm;
|
||||
}
|
||||
min-height: var(--control-min-height);
|
||||
@include font-size(var(--control-font-size));
|
||||
--control-padding-y: #{var-if-default($input-padding-y-sm, $input-btn-padding-y-sm, '--btn-input-sm-padding-y')};
|
||||
--control-padding-x: #{var-if-default($input-padding-x-sm, $input-btn-padding-x-sm, '--btn-input-sm-padding-x')};
|
||||
@include rfs(var-if-default($input-font-size-sm, $input-btn-font-size-sm, '--btn-input-sm-font-size'), --control-font-size);
|
||||
--control-line-height: #{var-if-default($input-line-height-sm, $input-btn-line-height-sm, '--btn-input-sm-line-height')};
|
||||
--control-border-radius: #{var-if-default($input-border-radius-sm, var(--border-radius-sm), '--btn-input-sm-border-radius')};
|
||||
}
|
||||
|
||||
.form-control-lg {
|
||||
line-height: $input-line-height-lg;
|
||||
min-height: $input-height-lg;
|
||||
padding: $input-padding-y-lg $input-padding-x-lg;
|
||||
@include font-size($input-font-size-lg);
|
||||
@include border-radius($input-border-radius-lg);
|
||||
|
||||
&::file-selector-button {
|
||||
padding: $input-padding-y-lg $input-padding-x-lg;
|
||||
margin: (-$input-padding-y-lg) (-$input-padding-x-lg);
|
||||
margin-inline-end: $input-padding-x-lg;
|
||||
}
|
||||
min-height: var(--control-min-height);
|
||||
@include font-size(var(--control-font-size));
|
||||
--control-padding-y: #{var-if-default($input-padding-y-lg, $input-btn-padding-y-lg, '--btn-input-lg-padding-y')};
|
||||
--control-padding-x: #{var-if-default($input-padding-x-lg, $input-btn-padding-x-lg, '--btn-input-lg-padding-x')};
|
||||
@include rfs(var-if-default($input-font-size-lg, $input-btn-font-size-lg, '--btn-input-lg-font-size'), --control-font-size);
|
||||
--control-line-height: #{var-if-default($input-line-height-lg, $input-btn-line-height-lg, '--btn-input-lg-line-height')};
|
||||
--control-border-radius: #{var-if-default($input-border-radius-lg, var(--border-radius-lg), '--btn-input-lg-border-radius')};
|
||||
}
|
||||
|
||||
// Make sure textareas don't shrink too much when resized
|
||||
@@ -180,15 +205,7 @@
|
||||
// stylelint-disable selector-no-qualifying-type
|
||||
textarea {
|
||||
&.form-control {
|
||||
min-height: $input-height;
|
||||
}
|
||||
|
||||
&.form-control-sm {
|
||||
min-height: $input-height-sm;
|
||||
}
|
||||
|
||||
&.form-control-lg {
|
||||
min-height: $input-height-lg;
|
||||
min-height: var(--control-min-height);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,8 +213,8 @@ textarea {
|
||||
|
||||
.form-control-color {
|
||||
width: $form-color-width;
|
||||
height: $input-height;
|
||||
padding: $input-padding-y;
|
||||
height: var(--control-min-height);
|
||||
padding: var(--control-padding-y);
|
||||
|
||||
&:not(:disabled):not([readonly]) {
|
||||
cursor: pointer;
|
||||
@@ -205,19 +222,11 @@ textarea {
|
||||
|
||||
&::-moz-color-swatch {
|
||||
border: 0 !important; // stylelint-disable-line declaration-no-important
|
||||
@include border-radius($input-border-radius);
|
||||
@include border-radius(var(--control-border-radius));
|
||||
}
|
||||
|
||||
&::-webkit-color-swatch {
|
||||
border: 0 !important; // stylelint-disable-line declaration-no-important
|
||||
@include border-radius($input-border-radius);
|
||||
}
|
||||
|
||||
&.form-control-sm {
|
||||
height: $input-height-sm;
|
||||
}
|
||||
|
||||
&.form-control-lg {
|
||||
height: $input-height-lg;
|
||||
@include border-radius(var(--control-border-radius));
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,26 @@
|
||||
@use '../../config' as *;
|
||||
|
||||
.form-range {
|
||||
// scss-docs-start range-css-vars
|
||||
--range-track-width: #{$form-range-track-width};
|
||||
--range-track-height: #{$form-range-track-height};
|
||||
--range-track-cursor: #{$form-range-track-cursor};
|
||||
--range-track-bg: #{$form-range-track-bg};
|
||||
--range-track-border-radius: #{$form-range-track-border-radius};
|
||||
--range-track-box-shadow: #{$form-range-track-box-shadow};
|
||||
--range-thumb-width: #{$form-range-thumb-width};
|
||||
--range-thumb-height: #{$form-range-thumb-height};
|
||||
--range-thumb-bg: #{$form-range-thumb-bg};
|
||||
--range-thumb-border: #{$form-range-thumb-border};
|
||||
--range-thumb-border-radius: #{$form-range-thumb-border-radius};
|
||||
--range-thumb-box-shadow: #{$form-range-thumb-box-shadow};
|
||||
--range-thumb-active-bg: #{$form-range-thumb-active-bg};
|
||||
--range-thumb-disabled-bg: #{$form-range-thumb-disabled-bg};
|
||||
--range-thumb-transition: #{$form-range-thumb-transition};
|
||||
// scss-docs-end range-css-vars
|
||||
|
||||
width: 100%;
|
||||
height: add($form-range-thumb-height, $form-range-thumb-focus-box-shadow-width * 2);
|
||||
height: calc(var(--range-thumb-height) + #{$form-range-thumb-focus-box-shadow-width * 2});
|
||||
padding: 0; // Need to reset padding
|
||||
appearance: none;
|
||||
background-color: transparent;
|
||||
@@ -31,69 +49,69 @@
|
||||
}
|
||||
|
||||
&::-webkit-slider-thumb {
|
||||
width: $form-range-thumb-width;
|
||||
height: $form-range-thumb-height;
|
||||
margin-top: ($form-range-track-height - $form-range-thumb-height) * 0.5; // Webkit specific
|
||||
width: var(--range-thumb-width);
|
||||
height: var(--range-thumb-height);
|
||||
margin-top: calc((var(--range-track-height) - var(--range-thumb-height)) / 2); // Webkit specific
|
||||
appearance: none;
|
||||
@include gradient-bg($form-range-thumb-bg);
|
||||
border: $form-range-thumb-border;
|
||||
@include border-radius($form-range-thumb-border-radius);
|
||||
@include box-shadow($form-range-thumb-box-shadow);
|
||||
@include transition($form-range-thumb-transition);
|
||||
@include gradient-bg(var(--range-thumb-bg));
|
||||
border: var(--range-thumb-border);
|
||||
@include border-radius(var(--range-thumb-border-radius));
|
||||
@include box-shadow(var(--range-thumb-box-shadow));
|
||||
@include transition(var(--range-thumb-transition));
|
||||
outline-color: transparent;
|
||||
|
||||
&:active {
|
||||
@include gradient-bg($form-range-thumb-active-bg);
|
||||
@include gradient-bg(var(--range-thumb-active-bg));
|
||||
}
|
||||
}
|
||||
|
||||
&::-webkit-slider-runnable-track {
|
||||
width: $form-range-track-width;
|
||||
height: $form-range-track-height;
|
||||
width: var(--range-track-width);
|
||||
height: var(--range-track-height);
|
||||
color: transparent; // Why?
|
||||
cursor: $form-range-track-cursor;
|
||||
background-color: $form-range-track-bg;
|
||||
cursor: var(--range-track-cursor);
|
||||
background-color: var(--range-track-bg);
|
||||
border-color: transparent;
|
||||
@include border-radius($form-range-track-border-radius);
|
||||
@include box-shadow($form-range-track-box-shadow);
|
||||
@include border-radius(var(--range-track-border-radius));
|
||||
@include box-shadow(var(--range-track-box-shadow));
|
||||
}
|
||||
|
||||
&::-moz-range-thumb {
|
||||
width: $form-range-thumb-width;
|
||||
height: $form-range-thumb-height;
|
||||
width: var(--range-thumb-width);
|
||||
height: var(--range-thumb-height);
|
||||
appearance: none;
|
||||
@include gradient-bg($form-range-thumb-bg);
|
||||
border: $form-range-thumb-border;
|
||||
@include border-radius($form-range-thumb-border-radius);
|
||||
@include box-shadow($form-range-thumb-box-shadow);
|
||||
@include transition($form-range-thumb-transition);
|
||||
@include gradient-bg(var(--range-thumb-bg));
|
||||
border: var(--range-thumb-border);
|
||||
@include border-radius(var(--range-thumb-border-radius));
|
||||
@include box-shadow(var(--range-thumb-box-shadow));
|
||||
@include transition(var(--range-thumb-transition));
|
||||
outline-color: transparent;
|
||||
|
||||
&:active {
|
||||
@include gradient-bg($form-range-thumb-active-bg);
|
||||
@include gradient-bg(var(--range-thumb-active-bg));
|
||||
}
|
||||
}
|
||||
|
||||
&::-moz-range-track {
|
||||
width: $form-range-track-width;
|
||||
height: $form-range-track-height;
|
||||
width: var(--range-track-width);
|
||||
height: var(--range-track-height);
|
||||
color: transparent;
|
||||
cursor: $form-range-track-cursor;
|
||||
background-color: $form-range-track-bg;
|
||||
cursor: var(--range-track-cursor);
|
||||
background-color: var(--range-track-bg);
|
||||
border-color: transparent; // Firefox specific?
|
||||
@include border-radius($form-range-track-border-radius);
|
||||
@include box-shadow($form-range-track-box-shadow);
|
||||
@include border-radius(var(--range-track-border-radius));
|
||||
@include box-shadow(var(--range-track-box-shadow));
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
pointer-events: none;
|
||||
|
||||
&::-webkit-slider-thumb {
|
||||
background-color: $form-range-thumb-disabled-bg;
|
||||
background-color: var(--range-thumb-disabled-bg);
|
||||
}
|
||||
|
||||
&::-moz-range-thumb {
|
||||
background-color: $form-range-thumb-disabled-bg;
|
||||
background-color: var(--range-thumb-disabled-bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,75 +5,111 @@
|
||||
|
||||
@use '../../config' as *;
|
||||
|
||||
// The `--control-*` tokens come from the shared block in `_form-control.scss`.
|
||||
// A `$form-select-*` variable defaults to its `$input-*` twin; only a value a
|
||||
// project changed on its own has to be written again here.
|
||||
@mixin -select-token($token, $value, $default) {
|
||||
@if $value != $default {
|
||||
#{$token}: #{$value};
|
||||
}
|
||||
}
|
||||
|
||||
.form-select {
|
||||
--form-select-bg-img: #{escape-svg($form-select-indicator)};
|
||||
// scss-docs-start form-select-css-vars
|
||||
--control-select-bg: #{escape-svg($form-select-indicator)};
|
||||
--control-select-bg-dark: #{escape-svg($form-select-indicator-dark)};
|
||||
--control-select-bg-position: #{$form-select-bg-position};
|
||||
--control-select-bg-size: #{$form-select-bg-size};
|
||||
// Room for the arrow. Reads the root scale, not `--control-padding-x`, so the
|
||||
// size modifiers keep the same 3rem they always had.
|
||||
--control-select-indicator-padding: #{if(sass($form-select-indicator-padding == $form-select-padding-x * 3 and $form-select-padding-x == $input-btn-padding-x): calc(var(--btn-input-padding-x) * 3); else: $form-select-indicator-padding)};
|
||||
// scss-docs-end form-select-css-vars
|
||||
@include -select-token(--control-padding-y, $form-select-padding-y, $input-padding-y);
|
||||
@include -select-token(--control-padding-x, $form-select-padding-x, $input-padding-x);
|
||||
@include -select-token(--control-font-size, $form-select-font-size, $input-font-size);
|
||||
@include -select-token(--control-line-height, $form-select-line-height, $input-line-height);
|
||||
@include -select-token(--control-fg, $form-select-color, $input-color);
|
||||
@include -select-token(--control-bg, $form-select-bg, $input-bg);
|
||||
@include -select-token(--control-border-width, $form-select-border-width, $input-border-width);
|
||||
@include -select-token(--control-border-color, $form-select-border-color, $input-border-color);
|
||||
@include -select-token(--control-border-radius, $form-select-border-radius, $input-border-radius);
|
||||
@include -select-token(--control-box-shadow, $form-select-box-shadow, $input-box-shadow);
|
||||
@include -select-token(--control-focus-border-color, $form-select-focus-border-color, $input-focus-border-color);
|
||||
@include -select-token(--control-disabled-color, $form-select-disabled-color, $input-disabled-color);
|
||||
@include -select-token(--control-disabled-bg, $form-select-disabled-bg, $input-disabled-bg);
|
||||
@include -select-token(--control-disabled-border-color, $form-select-disabled-border-color, $input-disabled-border-color);
|
||||
@include -select-token(--control-transition, $form-select-transition, $input-transition);
|
||||
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: $form-select-padding-y $form-select-indicator-padding $form-select-padding-y $form-select-padding-x;
|
||||
padding: var(--control-padding-y) var(--control-padding-x);
|
||||
padding-inline-end: var(--control-select-indicator-padding);
|
||||
font-family: $form-select-font-family;
|
||||
@include font-size($form-select-font-size);
|
||||
@include font-size(var(--control-font-size));
|
||||
font-weight: $form-select-font-weight;
|
||||
line-height: $form-select-line-height;
|
||||
color: $form-select-color;
|
||||
line-height: var(--control-line-height);
|
||||
color: var(--control-fg);
|
||||
appearance: none;
|
||||
background-color: $form-select-bg;
|
||||
background-image: var(--form-select-bg-img), var(--form-select-bg-icon, none);
|
||||
background-color: var(--control-bg);
|
||||
// deprecated(2.0): `--form-select-bg-img` is the old name of `--control-select-bg`
|
||||
background-image: var(--form-select-bg-img, var(--control-select-bg)), var(--form-select-bg-icon, none);
|
||||
background-repeat: no-repeat;
|
||||
background-position: $form-select-bg-position;
|
||||
background-size: $form-select-bg-size;
|
||||
border: $form-select-border-width solid $form-select-border-color;
|
||||
@include border-radius($form-select-border-radius, 0);
|
||||
@include box-shadow($form-select-box-shadow);
|
||||
@include transition($form-select-transition);
|
||||
background-position: var(--control-select-bg-position);
|
||||
background-size: var(--control-select-bg-size);
|
||||
border: var(--control-border-width) solid var(--control-border-color);
|
||||
@include border-radius(var(--control-border-radius), 0);
|
||||
@include box-shadow(var(--control-box-shadow));
|
||||
@include transition(var(--control-transition));
|
||||
// Start the focus ring's `outline-color` transition from transparent, not `currentcolor`.
|
||||
outline-color: transparent;
|
||||
|
||||
&:focus {
|
||||
border-color: $form-select-focus-border-color;
|
||||
border-color: var(--control-focus-border-color);
|
||||
--focus-ring-offset: -1px;
|
||||
@include focus-ring(true);
|
||||
}
|
||||
|
||||
&[multiple],
|
||||
&[size]:not([size='1']) {
|
||||
padding-inline-end: $form-select-padding-x;
|
||||
padding-inline-end: var(--control-padding-x);
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
color: $form-select-disabled-color;
|
||||
background-color: $form-select-disabled-bg;
|
||||
border-color: $form-select-disabled-border-color;
|
||||
color: var(--control-disabled-color);
|
||||
background-color: var(--control-disabled-bg);
|
||||
border-color: var(--control-disabled-border-color);
|
||||
}
|
||||
|
||||
// Remove outline from select box in FF
|
||||
&:-moz-focusring {
|
||||
color: transparent;
|
||||
text-shadow: 0 0 0 $form-select-color;
|
||||
text-shadow: 0 0 0 var(--control-fg);
|
||||
}
|
||||
}
|
||||
|
||||
// A size moves the same tokens as `.form-control-sm/-lg`, line height
|
||||
// included, so a select and an input of one size are equally tall.
|
||||
.form-select-sm {
|
||||
padding-top: $form-select-padding-y-sm;
|
||||
padding-bottom: $form-select-padding-y-sm;
|
||||
padding-inline-start: $form-select-padding-x-sm;
|
||||
@include font-size($form-select-font-size-sm);
|
||||
@include border-radius($form-select-border-radius-sm);
|
||||
--control-padding-y: #{var-if-default($form-select-padding-y-sm, $input-btn-padding-y-sm, '--btn-input-sm-padding-y')};
|
||||
--control-padding-x: #{var-if-default($form-select-padding-x-sm, $input-btn-padding-x-sm, '--btn-input-sm-padding-x')};
|
||||
@include rfs(var-if-default($form-select-font-size-sm, $input-btn-font-size-sm, '--btn-input-sm-font-size'), --control-font-size);
|
||||
--control-line-height: #{var-if-default($input-line-height-sm, $input-btn-line-height-sm, '--btn-input-sm-line-height')};
|
||||
--control-border-radius: #{var-if-default($form-select-border-radius-sm, var(--border-radius-sm), '--btn-input-sm-border-radius')};
|
||||
}
|
||||
|
||||
.form-select-lg {
|
||||
padding-top: $form-select-padding-y-lg;
|
||||
padding-bottom: $form-select-padding-y-lg;
|
||||
padding-inline-start: $form-select-padding-x-lg;
|
||||
@include font-size($form-select-font-size-lg);
|
||||
@include border-radius($form-select-border-radius-lg);
|
||||
--control-padding-y: #{var-if-default($form-select-padding-y-lg, $input-btn-padding-y-lg, '--btn-input-lg-padding-y')};
|
||||
--control-padding-x: #{var-if-default($form-select-padding-x-lg, $input-btn-padding-x-lg, '--btn-input-lg-padding-x')};
|
||||
@include rfs(var-if-default($form-select-font-size-lg, $input-btn-font-size-lg, '--btn-input-lg-font-size'), --control-font-size);
|
||||
--control-line-height: #{var-if-default($input-line-height-lg, $input-btn-line-height-lg, '--btn-input-lg-line-height')};
|
||||
--control-border-radius: #{var-if-default($form-select-border-radius-lg, var(--border-radius-lg), '--btn-input-lg-border-radius')};
|
||||
}
|
||||
|
||||
@if $enable-dark-mode {
|
||||
@include color-mode(dark) {
|
||||
.form-select {
|
||||
--form-select-bg-img: #{escape-svg($form-select-indicator-dark)};
|
||||
--control-select-bg: var(--control-select-bg-dark);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,21 @@
|
||||
|
||||
@use '../../config' as *;
|
||||
|
||||
// Addon tokens, in the names Bootstrap 6 uses. The addon sits next to the
|
||||
// control, not inside it, so it reads the `:root` scale rather than the
|
||||
// control's own `--control-*` tokens.
|
||||
.input-group {
|
||||
// scss-docs-start input-group-css-vars
|
||||
--input-group-addon-padding-y: #{var-if-default($input-group-addon-padding-y, $input-btn-padding-y, '--btn-input-padding-y')};
|
||||
--input-group-addon-padding-x: #{var-if-default($input-group-addon-padding-x, $input-btn-padding-x, '--btn-input-padding-x')};
|
||||
@include rfs(var-if-default($input-font-size, $input-btn-font-size, '--btn-input-font-size'), --input-group-addon-font-size);
|
||||
--input-group-addon-line-height: #{var-if-default($input-line-height, $input-btn-line-height, '--btn-input-line-height')};
|
||||
--input-group-addon-color: #{$input-group-addon-color};
|
||||
--input-group-addon-bg: #{$input-group-addon-bg};
|
||||
--input-group-addon-border-color: #{$input-group-addon-border-color};
|
||||
--input-group-addon-border-radius: #{var-if-default($input-border-radius, var(--border-radius), '--btn-input-border-radius')};
|
||||
// scss-docs-end input-group-css-vars
|
||||
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-wrap: wrap; // For form validation feedback
|
||||
@@ -51,48 +65,88 @@
|
||||
.input-group-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: $input-group-addon-padding-y $input-group-addon-padding-x;
|
||||
@include font-size($input-font-size); // Match inputs
|
||||
padding: var(--input-group-addon-padding-y) var(--input-group-addon-padding-x);
|
||||
@include font-size(var(--input-group-addon-font-size)); // Match inputs
|
||||
font-weight: $input-group-addon-font-weight;
|
||||
line-height: $input-line-height;
|
||||
color: $input-group-addon-color;
|
||||
line-height: var(--input-group-addon-line-height);
|
||||
color: var(--input-group-addon-color);
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
background-color: $input-group-addon-bg;
|
||||
border: $input-border-width solid $input-group-addon-border-color;
|
||||
@include border-radius($input-border-radius);
|
||||
background-color: var(--input-group-addon-bg);
|
||||
border: $input-border-width solid var(--input-group-addon-border-color);
|
||||
@include border-radius(var(--input-group-addon-border-radius));
|
||||
}
|
||||
|
||||
// Sizing
|
||||
//
|
||||
// Remix the default form control sizing classes into new ones for easier
|
||||
// manipulation.
|
||||
// A size moves the addon and control tokens; the button keeps its own rules
|
||||
// until `.btn` reads the scale too.
|
||||
|
||||
.input-group-lg > .form-control,
|
||||
.input-group-lg > .form-select,
|
||||
.input-group-lg > .input-group-text,
|
||||
.input-group-lg > .btn {
|
||||
line-height: $input-line-height-lg;
|
||||
min-height: $input-height-lg;
|
||||
padding: $input-padding-y-lg $input-padding-x-lg;
|
||||
@include font-size($input-font-size-lg);
|
||||
@include border-radius($input-border-radius-lg);
|
||||
@mixin -input-group-size($size) {
|
||||
--input-group-addon-padding-y: #{var-if-default(map.get($-input-group-sizes, $size, 'padding-y'), map.get($-input-group-sizes, $size, 'scale-padding-y'), '--btn-input-#{$size}-padding-y')};
|
||||
--input-group-addon-padding-x: #{var-if-default(map.get($-input-group-sizes, $size, 'padding-x'), map.get($-input-group-sizes, $size, 'scale-padding-x'), '--btn-input-#{$size}-padding-x')};
|
||||
@include rfs(var-if-default(map.get($-input-group-sizes, $size, 'font-size'), map.get($-input-group-sizes, $size, 'scale-font-size'), '--btn-input-#{$size}-font-size'), --input-group-addon-font-size);
|
||||
--input-group-addon-line-height: #{var-if-default(map.get($-input-group-sizes, $size, 'line-height'), map.get($-input-group-sizes, $size, 'scale-line-height'), '--btn-input-#{$size}-line-height')};
|
||||
--input-group-addon-border-radius: #{var-if-default(map.get($-input-group-sizes, $size, 'border-radius'), map.get($-input-group-sizes, $size, 'scale-border-radius'), '--btn-input-#{$size}-border-radius')};
|
||||
|
||||
> .form-control,
|
||||
> .form-select {
|
||||
--control-padding-y: var(--input-group-addon-padding-y);
|
||||
--control-padding-x: var(--input-group-addon-padding-x);
|
||||
--control-font-size: var(--input-group-addon-font-size);
|
||||
--control-line-height: var(--input-group-addon-line-height);
|
||||
--control-border-radius: var(--input-group-addon-border-radius);
|
||||
min-height: var(--control-min-height);
|
||||
}
|
||||
|
||||
> .form-select {
|
||||
padding-inline-end: calc(#{var-if-default($form-select-padding-x, $input-btn-padding-x, '--btn-input-padding-x')} + var(--control-select-indicator-padding));
|
||||
}
|
||||
|
||||
> .btn {
|
||||
line-height: map.get($-input-group-sizes, $size, 'line-height');
|
||||
min-height: map.get($-input-group-sizes, $size, 'height');
|
||||
padding: map.get($-input-group-sizes, $size, 'padding-y') map.get($-input-group-sizes, $size, 'padding-x');
|
||||
@include font-size(map.get($-input-group-sizes, $size, 'font-size'));
|
||||
@include border-radius(map.get($-input-group-sizes, $size, 'border-radius'));
|
||||
}
|
||||
}
|
||||
|
||||
.input-group-sm > .form-control,
|
||||
.input-group-sm > .form-select,
|
||||
.input-group-sm > .input-group-text,
|
||||
.input-group-sm > .btn {
|
||||
line-height: $input-line-height-sm;
|
||||
min-height: $input-height-sm;
|
||||
padding: $input-padding-y-sm $input-padding-x-sm;
|
||||
@include font-size($input-font-size-sm);
|
||||
@include border-radius($input-border-radius-sm);
|
||||
$-input-group-sizes: (
|
||||
'sm': (
|
||||
'padding-y': $input-padding-y-sm,
|
||||
'padding-x': $input-padding-x-sm,
|
||||
'font-size': $input-font-size-sm,
|
||||
'line-height': $input-line-height-sm,
|
||||
'border-radius': $input-border-radius-sm,
|
||||
'height': $input-height-sm,
|
||||
'scale-padding-y': $input-btn-padding-y-sm,
|
||||
'scale-padding-x': $input-btn-padding-x-sm,
|
||||
'scale-font-size': $input-btn-font-size-sm,
|
||||
'scale-line-height': $input-btn-line-height-sm,
|
||||
'scale-border-radius': var(--border-radius-sm),
|
||||
),
|
||||
'lg': (
|
||||
'padding-y': $input-padding-y-lg,
|
||||
'padding-x': $input-padding-x-lg,
|
||||
'font-size': $input-font-size-lg,
|
||||
'line-height': $input-line-height-lg,
|
||||
'border-radius': $input-border-radius-lg,
|
||||
'height': $input-height-lg,
|
||||
'scale-padding-y': $input-btn-padding-y-lg,
|
||||
'scale-padding-x': $input-btn-padding-x-lg,
|
||||
'scale-font-size': $input-btn-font-size-lg,
|
||||
'scale-line-height': $input-btn-line-height-lg,
|
||||
'scale-border-radius': var(--border-radius-lg),
|
||||
),
|
||||
);
|
||||
|
||||
.input-group-lg {
|
||||
@include -input-group-size('lg');
|
||||
}
|
||||
|
||||
.input-group-lg > .form-select,
|
||||
.input-group-sm > .form-select {
|
||||
padding-inline-end: $form-select-padding-x + $form-select-indicator-padding;
|
||||
.input-group-sm {
|
||||
@include -input-group-size('sm');
|
||||
}
|
||||
|
||||
// Rounded corners
|
||||
|
||||
@@ -15,24 +15,24 @@
|
||||
// For use with horizontal and inline forms, when you need the label (or legend)
|
||||
// text to align with the form controls.
|
||||
.col-form-label {
|
||||
padding-top: add($input-padding-y, $input-border-width);
|
||||
padding-bottom: add($input-padding-y, $input-border-width);
|
||||
padding-top: calc(#{var-if-default($input-padding-y, $input-btn-padding-y, '--btn-input-padding-y')} + #{$input-border-width});
|
||||
padding-bottom: calc(#{var-if-default($input-padding-y, $input-btn-padding-y, '--btn-input-padding-y')} + #{$input-border-width});
|
||||
margin-bottom: 0; // Override the `<legend>` default
|
||||
@include font-size(inherit); // Override the `<legend>` default
|
||||
font-style: $form-label-font-style;
|
||||
font-weight: $form-label-font-weight;
|
||||
line-height: $input-line-height;
|
||||
line-height: #{var-if-default($input-line-height, $input-btn-line-height, '--btn-input-line-height')};
|
||||
color: $form-label-color;
|
||||
}
|
||||
|
||||
.col-form-label-lg {
|
||||
padding-top: add($input-padding-y-lg, $input-border-width);
|
||||
padding-bottom: add($input-padding-y-lg, $input-border-width);
|
||||
@include font-size($input-font-size-lg);
|
||||
padding-top: calc(#{var-if-default($input-padding-y-lg, $input-btn-padding-y-lg, '--btn-input-lg-padding-y')} + #{$input-border-width});
|
||||
padding-bottom: calc(#{var-if-default($input-padding-y-lg, $input-btn-padding-y-lg, '--btn-input-lg-padding-y')} + #{$input-border-width});
|
||||
@include font-size(var-if-default($input-font-size-lg, $input-btn-font-size-lg, '--btn-input-lg-font-size'));
|
||||
}
|
||||
|
||||
.col-form-label-sm {
|
||||
padding-top: add($input-padding-y-sm, $input-border-width);
|
||||
padding-bottom: add($input-padding-y-sm, $input-border-width);
|
||||
@include font-size($input-font-size-sm);
|
||||
padding-top: calc(#{var-if-default($input-padding-y-sm, $input-btn-padding-y-sm, '--btn-input-sm-padding-y')} + #{$input-border-width});
|
||||
padding-bottom: calc(#{var-if-default($input-padding-y-sm, $input-btn-padding-y-sm, '--btn-input-sm-padding-y')} + #{$input-border-width});
|
||||
@include font-size(var-if-default($input-font-size-sm, $input-btn-font-size-sm, '--btn-input-sm-font-size'));
|
||||
}
|
||||
@@ -117,3 +117,20 @@
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
// `$input-height` and its sizes as a token: the `:root` scale's min height
|
||||
// (`--btn-input-min-height`) while the input metrics keep their defaults, the
|
||||
// configured Sass value otherwise. Elements that sit next to a control (an icon
|
||||
// addon, a select-group tile, an otp slot) match its height through it.
|
||||
@function input-height-token($size: null) {
|
||||
@if $size == 'sm' {
|
||||
$default: add($input-btn-line-height-sm, add(calc($input-btn-padding-y-sm * 2), calc(#{$input-btn-border-width} * 2), false));
|
||||
@return if(sass($input-height-sm == $default): var(--btn-input-sm-min-height); else: $input-height-sm);
|
||||
}
|
||||
@if $size == 'lg' {
|
||||
$default: add($input-btn-line-height-lg, add(calc($input-btn-padding-y-lg * 2), calc(#{$input-btn-border-width} * 2), false));
|
||||
@return if(sass($input-height-lg == $default): var(--btn-input-lg-min-height); else: $input-height-lg);
|
||||
}
|
||||
$default: add($input-btn-line-height, add(calc($input-btn-padding-y * 2), calc(#{$input-btn-border-width} * 2), false));
|
||||
@return if(sass($input-height == $default): var(--btn-input-min-height); else: $input-height);
|
||||
}
|
||||
@@ -56,6 +56,11 @@ exports[`css custom-property prefixing > leaves vendor-owned names alone and pre
|
||||
"--tblr-chart-3",
|
||||
"--tblr-chart-4",
|
||||
"--tblr-chart-5",
|
||||
"--tblr-control-font-size",
|
||||
"--tblr-control-line-height",
|
||||
"--tblr-control-padding-x",
|
||||
"--tblr-control-padding-y",
|
||||
"--tblr-control-placeholder-color",
|
||||
"--tblr-danger",
|
||||
"--tblr-focus-ring",
|
||||
"--tblr-focus-ring-color",
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// Tests for `input-height-token()` in scss/mixins/_mixins.scss: the height of
|
||||
// a control as a token that reads the `:root` scale while the input metrics
|
||||
// keep their defaults.
|
||||
|
||||
@use 'sass:meta';
|
||||
@use '../config' as *;
|
||||
|
||||
@include describe('input-height-token') {
|
||||
@include it('reads the root scale for the default metrics') {
|
||||
@include assert-equal(meta.inspect(input-height-token()), 'var(--btn-input-min-height)');
|
||||
@include assert-equal(meta.inspect(input-height-token('sm')), 'var(--btn-input-sm-min-height)');
|
||||
@include assert-equal(meta.inspect(input-height-token('lg')), 'var(--btn-input-lg-min-height)');
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,10 @@
|
||||
@include assert-equal(var-if-default(1rem, 0.5625rem, --btn-input-padding-y), 1rem);
|
||||
}
|
||||
|
||||
@include it('takes the token name as a string too') {
|
||||
@include assert-equal(meta.inspect(var-if-default(1rem, 1rem, '--btn-input-padding-x')), 'var(--btn-input-padding-x)');
|
||||
}
|
||||
|
||||
@include it('compares var() defaults by value') {
|
||||
@include assert-equal(meta.inspect(var-if-default(var(--border-radius), var(--border-radius), --btn-input-border-radius)), 'var(--btn-input-border-radius)');
|
||||
@include assert-equal(meta.inspect(var-if-default(0, var(--border-radius), --btn-input-border-radius)), '0');
|
||||
|
||||
@@ -53,7 +53,7 @@ Form control
|
||||
|
||||
&:disabled,
|
||||
&.disabled {
|
||||
color: $form-secondary-color;
|
||||
color: var(--control-disabled-color);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ Input group
|
||||
*/
|
||||
.input-group {
|
||||
box-shadow: $input-box-shadow;
|
||||
@include border-radius($input-border-radius);
|
||||
@include border-radius(var(--input-group-addon-border-radius));
|
||||
|
||||
.form-control,
|
||||
.form-select,
|
||||
@@ -173,7 +173,7 @@ Input group
|
||||
&:focus-within {
|
||||
--focus-ring-offset: -1px;
|
||||
@include focus-ring(true);
|
||||
@include border-radius($input-border-radius);
|
||||
@include border-radius(var(--input-group-addon-border-radius));
|
||||
|
||||
.form-control,
|
||||
.input-group-text {
|
||||
@@ -183,7 +183,7 @@ Input group
|
||||
|
||||
.form-control {
|
||||
&:focus {
|
||||
border-color: $input-border-color;
|
||||
border-color: var(--control-border-color);
|
||||
outline: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
@@ -199,7 +199,7 @@ Input group
|
||||
|
||||
.input-group-text {
|
||||
z-index: 10;
|
||||
background: $form-check-input-bg;
|
||||
background: #{var-if-default($form-check-input-bg, var(--bg-forms), '--btn-input-bg')};
|
||||
@include transition($input-transition);
|
||||
|
||||
&:first-child {
|
||||
|
||||
@@ -24,11 +24,9 @@ Form check
|
||||
}
|
||||
|
||||
.form-check-input {
|
||||
--form-check-input-width: #{$form-check-input-width};
|
||||
margin-top: ($form-check-min-height - $form-check-input-width) * 0.5;
|
||||
|
||||
margin-top: calc((#{$form-check-min-height} - var(--form-check-input-width)) / 2);
|
||||
background-size: var(--form-check-input-width);
|
||||
box-shadow: $form-check-input-box-shadow;
|
||||
box-shadow: var(--form-check-box-shadow);
|
||||
}
|
||||
|
||||
.form-check-label {
|
||||
@@ -67,15 +65,15 @@ Form switch
|
||||
*/
|
||||
.form-switch {
|
||||
.form-check-input {
|
||||
height: $form-switch-height;
|
||||
margin-top: ($form-check-min-height - $form-switch-height) * 0.5;
|
||||
height: var(--form-switch-height);
|
||||
margin-top: calc((#{$form-check-min-height} - var(--form-switch-height)) / 2);
|
||||
@include transition(background-color $transition-time, background-position $transition-time, $focus-ring-transition);
|
||||
|
||||
// An off switch that is disabled fills its track like a disabled input,
|
||||
// so it no longer looks like an off switch that can still be toggled.
|
||||
&:disabled:not(:checked) {
|
||||
--form-switch-color: #{$form-switch-disabled-color};
|
||||
background-color: $form-switch-disabled-bg;
|
||||
--form-switch-color: var(--form-switch-disabled-color);
|
||||
background-color: var(--form-switch-disabled-bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ Icon input
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: var(--input-icon-addon-width);
|
||||
height: $input-height;
|
||||
height: input-height-token();
|
||||
font-size: 1.2em;
|
||||
color: var(--icon-color);
|
||||
pointer-events: none;
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
|
||||
.otp-input:disabled ~ .otp-slots .otp-slot {
|
||||
color: var(--disabled-color);
|
||||
background-color: $input-disabled-bg;
|
||||
background-color: #{var-if-default($input-disabled-bg, var(--bg-forms-disabled), '--control-disabled-bg')};
|
||||
}
|
||||
|
||||
// Zero gap with shared, merged borders; only the first and last slot keep a
|
||||
@@ -149,12 +149,12 @@
|
||||
}
|
||||
|
||||
.otp-sm {
|
||||
--otp-size: #{$input-height-sm};
|
||||
--otp-size: #{input-height-token('sm')};
|
||||
--otp-font-size: #{$input-font-size-sm};
|
||||
}
|
||||
|
||||
.otp-lg {
|
||||
--otp-size: #{$input-height-lg};
|
||||
--otp-size: #{input-height-token('lg')};
|
||||
--otp-font-size: #{$input-font-size-lg};
|
||||
}
|
||||
|
||||
|
||||
@@ -36,11 +36,11 @@ Select group
|
||||
.form-selectgroup-label {
|
||||
position: relative;
|
||||
display: block;
|
||||
min-width: $input-height;
|
||||
padding: $input-btn-padding-y $input-btn-padding-x;
|
||||
min-width: input-height-token();
|
||||
padding: var(--btn-input-padding-y) var(--btn-input-padding-x);
|
||||
margin: 0;
|
||||
font-size: $input-btn-font-size;
|
||||
line-height: $input-line-height;
|
||||
font-size: var(--btn-input-font-size);
|
||||
line-height: #{var-if-default($input-line-height, $input-btn-line-height, '--btn-input-line-height')};
|
||||
color: var(--secondary);
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
@@ -95,8 +95,8 @@ Select group
|
||||
|
||||
.form-selectgroup-check-floated {
|
||||
position: absolute;
|
||||
inset-inline-end: $input-btn-padding-y;
|
||||
top: $input-btn-padding-y;
|
||||
inset-inline-end: var(--btn-input-padding-y);
|
||||
top: var(--btn-input-padding-y);
|
||||
}
|
||||
|
||||
.form-selectgroup-input:checked + .form-selectgroup-label {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
// `.btn`/`.btn-sm`/`.btn-lg` use for their own icons (see ui/_buttons.scss).
|
||||
%validation-icon-size {
|
||||
--form-feedback-icon-size: #{$input-btn-icon-size};
|
||||
--form-feedback-icon-inset: #{$input-padding-x};
|
||||
--form-feedback-icon-inset: #{var-if-default($input-padding-x, $input-btn-padding-x, '--btn-input-padding-x')};
|
||||
padding-inline-end: calc(var(--form-feedback-icon-size) + var(--form-feedback-icon-inset) * 2) !important;
|
||||
background-position: right var(--form-feedback-icon-inset) center !important;
|
||||
background-size: var(--form-feedback-icon-size) var(--form-feedback-icon-size) !important;
|
||||
@@ -19,12 +19,12 @@
|
||||
|
||||
%validation-icon-size-sm {
|
||||
--form-feedback-icon-size: #{$input-btn-icon-size-sm};
|
||||
--form-feedback-icon-inset: #{$input-padding-x-sm};
|
||||
--form-feedback-icon-inset: #{var-if-default($input-padding-x-sm, $input-btn-padding-x-sm, '--btn-input-sm-padding-x')};
|
||||
}
|
||||
|
||||
%validation-icon-size-lg {
|
||||
--form-feedback-icon-size: #{$input-btn-icon-size-lg};
|
||||
--form-feedback-icon-inset: #{$input-padding-x-lg};
|
||||
--form-feedback-icon-inset: #{var-if-default($input-padding-x-lg, $input-btn-padding-x-lg, '--btn-input-lg-padding-x')};
|
||||
}
|
||||
|
||||
%validation-icon-size-textarea {
|
||||
|
||||
Vendored
+14
-38
@@ -72,49 +72,25 @@
|
||||
|
||||
// The bootstrap5 preset hardcodes Bootstrap's own input metrics on
|
||||
// `.ts-control` (0.375rem 0.75rem padding, 1.5 line-height), so a Tom Select
|
||||
// came out 5px shorter than a `.form-control` next to it (#2567). Use Tabler's
|
||||
// input tokens instead, in every size. The multi-value control follows the
|
||||
// preset's formula: take the item's 1px padding, 1px border and 3px bottom
|
||||
// margin out of the control's padding so the chips fill the same height.
|
||||
// came out 5px shorter than a `.form-control` next to it (#2567). The wrapper
|
||||
// carries the `.form-control` / `.form-select` class, so it holds the
|
||||
// `--control-*` tokens: read them and every size follows on its own. The
|
||||
// multi-value control follows the preset's formula: take the item's 1px
|
||||
// padding, 1px border and 3px bottom margin out of the control's padding so
|
||||
// the chips fill the same height. The font size is `!important` because the
|
||||
// preset sets its own on `.form-select-sm.has-items .ts-control`, which
|
||||
// outranks this selector.
|
||||
.ts-wrapper.form-control,
|
||||
.ts-wrapper.form-select {
|
||||
.ts-control {
|
||||
padding: $input-padding-y $input-padding-x;
|
||||
font-size: $input-font-size;
|
||||
line-height: $input-line-height;
|
||||
padding: var(--control-padding-y) var(--control-padding-x);
|
||||
font-size: var(--control-font-size) !important;
|
||||
line-height: var(--control-line-height);
|
||||
}
|
||||
|
||||
&.multi.has-items .ts-control {
|
||||
padding-top: calc(#{$input-padding-y} - 2px) !important;
|
||||
padding-bottom: calc(#{$input-padding-y} - 5px);
|
||||
}
|
||||
|
||||
&.form-control-sm,
|
||||
&.form-select-sm {
|
||||
.ts-control {
|
||||
padding: $input-padding-y-sm $input-padding-x-sm;
|
||||
font-size: $input-font-size-sm;
|
||||
line-height: $input-line-height-sm;
|
||||
}
|
||||
|
||||
&.multi.has-items .ts-control {
|
||||
padding-top: calc(#{$input-padding-y-sm} - 2px) !important;
|
||||
padding-bottom: calc(#{$input-padding-y-sm} - 5px);
|
||||
}
|
||||
}
|
||||
|
||||
&.form-control-lg,
|
||||
&.form-select-lg {
|
||||
.ts-control {
|
||||
padding: $input-padding-y-lg $input-padding-x-lg;
|
||||
font-size: $input-font-size-lg;
|
||||
line-height: $input-line-height-lg;
|
||||
}
|
||||
|
||||
&.multi.has-items .ts-control {
|
||||
padding-top: calc(#{$input-padding-y-lg} - 2px) !important;
|
||||
padding-bottom: calc(#{$input-padding-y-lg} - 5px);
|
||||
}
|
||||
padding-top: calc(var(--control-padding-y) - 2px) !important;
|
||||
padding-bottom: calc(var(--control-padding-y) - 5px);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +148,7 @@
|
||||
|
||||
.ts-control input {
|
||||
&::placeholder {
|
||||
color: $input-placeholder-color;
|
||||
color: var(--control-placeholder-color, #{$input-placeholder-color});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,259 @@
|
||||
---
|
||||
title: CSS variables
|
||||
seoTitle: Form CSS variables
|
||||
order: 11
|
||||
summary: Every form control reads its size, colors and states from CSS variables, so you can restyle inputs, selects, checks and switches at runtime without recompiling Sass.
|
||||
description: Reference of the CSS variables that size and color Tabler form controls, with examples of runtime overrides.
|
||||
related: [/ui/forms/elements, /ui/forms/floating-labels, /ui/getting-started/customize]
|
||||
---
|
||||
import Example from '@components/Example.astro';
|
||||
|
||||
## Overview
|
||||
|
||||
Form controls are built on three layers of custom properties. Each layer reads the one above it, so you can change a single value or a single control.
|
||||
|
||||
1. **The control scale on `:root`.** `--tblr-btn-input-*` holds the padding, font size, line height, radius and minimum height of a control, with a `-sm-*`, `-lg-*` and `-xl-*` set for each size. `--tblr-control-checked-bg` and its siblings hold the state colors that checks, radios and switches share.
|
||||
2. **Component tokens on the control.** `.form-control` and `.form-select` carry `--tblr-control-*`, `.input-group` carries `--tblr-input-group-addon-*`, `.form-floating` carries `--tblr-form-floating-*`, and so on. By default each token points at the scale.
|
||||
3. **The declarations.** Every `padding`, `color` or `border` in the stylesheet reads a token, never a fixed value.
|
||||
|
||||
The names follow Bootstrap 6, so a project that moves to a future major keeps its overrides.
|
||||
|
||||
Sass still works. A `$input-*`, `$form-select-*` or `$form-check-*` variable that you set in Sass is compiled into the token as a fixed value. That control then ignores the scale on `:root`, as it did before the tokens existed.
|
||||
|
||||
## Usage
|
||||
|
||||
### Change every control at once
|
||||
|
||||
Override the scale on `:root`. Inputs, selects, add-ons, floating labels, select-group tiles and column labels all follow.
|
||||
|
||||
```css
|
||||
:root {
|
||||
--tblr-btn-input-padding-y: 0.75rem;
|
||||
--tblr-btn-input-padding-x: 1.25rem;
|
||||
--tblr-btn-input-border-radius: 0;
|
||||
}
|
||||
```
|
||||
|
||||
The scale inherits, so the same variables on a container change only the controls inside it.
|
||||
|
||||
<Example column>
|
||||
<div style="--tblr-btn-input-padding-y: 0.75rem; --tblr-btn-input-border-radius: 0">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Taller, square controls</label>
|
||||
<input type="text" class="form-control" placeholder="Input" />
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">@</span>
|
||||
<input type="text" class="form-control" placeholder="Username" />
|
||||
</div>
|
||||
</div>
|
||||
</Example>
|
||||
|
||||
### Change one control
|
||||
|
||||
Set a component token on the element. Tokens on the element win over the scale.
|
||||
|
||||
<Example column>
|
||||
<input type="text" class="form-control mb-3" placeholder="Pill input" style="--tblr-control-border-radius: 2rem; --tblr-control-padding-x: 1.5rem" />
|
||||
<select class="form-select" style="--tblr-control-bg: var(--tblr-bg-surface-secondary); --tblr-control-border-color: transparent">
|
||||
<option>Flat select</option>
|
||||
</select>
|
||||
</Example>
|
||||
|
||||
### Make a custom size
|
||||
|
||||
The size classes only move the size tokens, so a custom size is a few tokens on a class of your own.
|
||||
|
||||
```css
|
||||
.form-control-xs {
|
||||
--tblr-control-padding-y: 0.125rem;
|
||||
--tblr-control-padding-x: 0.5rem;
|
||||
--tblr-control-font-size: 0.75rem;
|
||||
--tblr-control-line-height: 1rem;
|
||||
}
|
||||
```
|
||||
|
||||
The minimum height, the file selector button and the color swatch follow the tokens on their own.
|
||||
|
||||
### Recolor checks, radios and switches
|
||||
|
||||
The checked and disabled colors of every check control come from `:root`.
|
||||
|
||||
<Example column>
|
||||
<div style="--tblr-control-checked-bg: var(--tblr-green)">
|
||||
<label class="form-check"><input class="form-check-input" type="checkbox" checked /><span class="form-check-label">Checkbox</span></label>
|
||||
<label class="form-check"><input class="form-check-input" type="radio" checked /><span class="form-check-label">Radio</span></label>
|
||||
<label class="form-check form-switch"><input class="form-check-input" type="checkbox" checked /><span class="form-check-label">Switch</span></label>
|
||||
</div>
|
||||
</Example>
|
||||
|
||||
## Reference
|
||||
|
||||
### Control scale on `:root`
|
||||
|
||||
| Variable | Default |
|
||||
| --- | --- |
|
||||
| `--tblr-btn-input-fg` | `var(--tblr-body-color)` |
|
||||
| `--tblr-btn-input-bg` | `var(--tblr-bg-forms)` |
|
||||
| `--tblr-btn-input-padding-y` | `0.5625rem` |
|
||||
| `--tblr-btn-input-padding-x` | `1rem` |
|
||||
| `--tblr-btn-input-font-size` | `0.875rem` |
|
||||
| `--tblr-btn-input-line-height` | `1.25rem` |
|
||||
| `--tblr-btn-input-border-radius` | `var(--tblr-border-radius)` |
|
||||
| `--tblr-btn-input-min-height` | line height + 2 × padding + 2 × border |
|
||||
|
||||
The same set exists per size as `--tblr-btn-input-sm-*`, `--tblr-btn-input-lg-*` and `--tblr-btn-input-xl-*`.
|
||||
|
||||
| Size | Padding | Font size | Line height | Radius |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `sm` | `0.4375rem 0.5rem` | `0.75rem` | `1rem` | `var(--tblr-border-radius-sm)` |
|
||||
| `lg` | `0.6875rem 1.5rem` | `1rem` | `1.5rem` | `var(--tblr-border-radius-lg)` |
|
||||
| `xl` | `0.6875rem 1.75rem` | `1.5rem` | `2rem` | `var(--tblr-border-radius)` |
|
||||
|
||||
### State colors on `:root`
|
||||
|
||||
| Variable | Default | Read by |
|
||||
| --- | --- | --- |
|
||||
| `--tblr-control-checked-bg` | `var(--tblr-primary)` | checked and indeterminate checks, radios, switches |
|
||||
| `--tblr-control-checked-border-color` | `var(--tblr-border-color-translucent)` | checked checks and radios |
|
||||
| `--tblr-control-disabled-bg` | `var(--tblr-bg-forms-disabled)` | disabled switches and OTP slots |
|
||||
| `--tblr-control-disabled-opacity` | `0.5` | disabled checks, radios, switches |
|
||||
|
||||
### Inputs and selects
|
||||
|
||||
Set on `.form-control`, `.form-control-plaintext` and `.form-select`. `.form-control-sm/-lg` and `.form-select-sm/-lg` override the first five with the matching size of the scale.
|
||||
|
||||
| Variable | Default |
|
||||
| --- | --- |
|
||||
| `--tblr-control-padding-y` | `var(--tblr-btn-input-padding-y)` |
|
||||
| `--tblr-control-padding-x` | `var(--tblr-btn-input-padding-x)` |
|
||||
| `--tblr-control-font-size` | `var(--tblr-btn-input-font-size)` |
|
||||
| `--tblr-control-line-height` | `var(--tblr-btn-input-line-height)` |
|
||||
| `--tblr-control-border-radius` | `var(--tblr-btn-input-border-radius)` |
|
||||
| `--tblr-control-min-height` | line height + 2 × padding + 2 × border |
|
||||
| `--tblr-control-fg` | `var(--tblr-btn-input-fg)` |
|
||||
| `--tblr-control-bg` | `var(--tblr-btn-input-bg)` |
|
||||
| `--tblr-control-border-width` | `var(--tblr-border-width)` |
|
||||
| `--tblr-control-border-color` | `var(--tblr-border-color)` |
|
||||
| `--tblr-control-box-shadow` | `var(--tblr-shadow-input)` |
|
||||
| `--tblr-control-focus-fg` | `var(--tblr-control-fg)` |
|
||||
| `--tblr-control-focus-bg` | `var(--tblr-control-bg)` |
|
||||
| `--tblr-control-focus-border-color` | primary mixed with white |
|
||||
| `--tblr-control-placeholder-color` | `var(--tblr-tertiary)` |
|
||||
| `--tblr-control-disabled-color` | `var(--tblr-secondary)` |
|
||||
| `--tblr-control-disabled-bg` | `var(--tblr-bg-forms-disabled)` |
|
||||
| `--tblr-control-disabled-border-color` | `var(--tblr-control-border-color)` |
|
||||
| `--tblr-control-action-bg` | `var(--tblr-tertiary-bg)` (file selector button) |
|
||||
| `--tblr-control-action-hover-bg` | `var(--tblr-secondary-bg)` |
|
||||
| `--tblr-control-transition` | border color, outline color and shadow, `0.15s` |
|
||||
|
||||
`.form-select` adds the arrow: `--tblr-control-select-bg`, `--tblr-control-select-bg-dark`, `--tblr-control-select-bg-position`, `--tblr-control-select-bg-size` and `--tblr-control-select-indicator-padding` (the room kept for the arrow, `3 ×` the scale's horizontal padding).
|
||||
|
||||
Tom Select copies the `.form-control` or `.form-select` class onto its wrapper, so its control reads the same tokens.
|
||||
|
||||
### Input groups
|
||||
|
||||
Set on `.input-group`. `.input-group-sm/-lg` override the size tokens and pass them to the controls in the group.
|
||||
|
||||
| Variable | Default |
|
||||
| --- | --- |
|
||||
| `--tblr-input-group-addon-padding-y` | `var(--tblr-btn-input-padding-y)` |
|
||||
| `--tblr-input-group-addon-padding-x` | `var(--tblr-btn-input-padding-x)` |
|
||||
| `--tblr-input-group-addon-font-size` | `var(--tblr-btn-input-font-size)` |
|
||||
| `--tblr-input-group-addon-line-height` | `var(--tblr-btn-input-line-height)` |
|
||||
| `--tblr-input-group-addon-color` | `var(--tblr-gray-500)` |
|
||||
| `--tblr-input-group-addon-bg` | `var(--tblr-bg-surface-secondary)` |
|
||||
| `--tblr-input-group-addon-border-color` | `var(--tblr-border-color)` |
|
||||
| `--tblr-input-group-addon-border-radius` | `var(--tblr-btn-input-border-radius)` |
|
||||
|
||||
### Floating labels
|
||||
|
||||
Set on `.form-floating`.
|
||||
|
||||
| Variable | Default |
|
||||
| --- | --- |
|
||||
| `--tblr-form-floating-height` | `3.5rem` + 2 × border |
|
||||
| `--tblr-form-floating-line-height` | `1.25` |
|
||||
| `--tblr-form-floating-padding-x` | `var(--tblr-btn-input-padding-x)` |
|
||||
| `--tblr-form-floating-padding-y` | `1rem` |
|
||||
| `--tblr-form-floating-input-padding-t` | `1.625rem` |
|
||||
| `--tblr-form-floating-input-padding-b` | `0.625rem` |
|
||||
| `--tblr-form-floating-label-height` | `1.5em` |
|
||||
| `--tblr-form-floating-label-bg` | `var(--tblr-btn-input-bg)` (masks the text under a textarea label) |
|
||||
| `--tblr-form-floating-label-disabled-bg` | `var(--tblr-bg-forms-disabled)` |
|
||||
| `--tblr-form-floating-label-border-radius` | `var(--tblr-btn-input-border-radius)` |
|
||||
| `--tblr-form-floating-label-opacity` | `0.65` |
|
||||
| `--tblr-form-floating-label-transform` | `scale(0.85) translateY(-0.5rem) translateX(0.15rem)` |
|
||||
| `--tblr-form-floating-label-disabled-color` | gray `600` in light mode, `400` in dark |
|
||||
| `--tblr-form-floating-transition` | opacity and transform, `0.1s` |
|
||||
|
||||
### Range inputs
|
||||
|
||||
Set on `.form-range`.
|
||||
|
||||
| Variable | Default |
|
||||
| --- | --- |
|
||||
| `--tblr-range-track-width` | `100%` |
|
||||
| `--tblr-range-track-height` | `0.25rem` |
|
||||
| `--tblr-range-track-cursor` | `pointer` |
|
||||
| `--tblr-range-track-bg` | `var(--tblr-border-color)` |
|
||||
| `--tblr-range-track-border-radius` | `1rem` |
|
||||
| `--tblr-range-track-box-shadow` | `var(--tblr-box-shadow-inset)` |
|
||||
| `--tblr-range-thumb-width` | `1rem` |
|
||||
| `--tblr-range-thumb-height` | `1rem` |
|
||||
| `--tblr-range-thumb-bg` | `var(--tblr-primary)` |
|
||||
| `--tblr-range-thumb-border` | `2px` white |
|
||||
| `--tblr-range-thumb-border-radius` | `1rem` |
|
||||
| `--tblr-range-thumb-box-shadow` | soft black shadow |
|
||||
| `--tblr-range-thumb-active-bg` | primary mixed with white |
|
||||
| `--tblr-range-thumb-disabled-bg` | `var(--tblr-secondary-color)` |
|
||||
| `--tblr-range-thumb-transition` | background, border, outline and shadow, `0.15s` |
|
||||
|
||||
### Checks and radios
|
||||
|
||||
`.form-check` carries the layout: `--tblr-form-check-min-height` (`1.25rem`), `--tblr-form-check-padding-start` (`2rem`) and `--tblr-form-check-margin-bottom` (`0.75rem`). The input itself carries the look.
|
||||
|
||||
| Variable on `.form-check-input` | Default |
|
||||
| --- | --- |
|
||||
| `--tblr-form-check-input-width` | `1.25rem` |
|
||||
| `--tblr-form-check-bg` | `var(--tblr-bg-forms)` |
|
||||
| `--tblr-form-check-border` | `var(--tblr-border-width) var(--tblr-border-style) var(--tblr-border-color)` |
|
||||
| `--tblr-form-check-border-radius` | `var(--tblr-border-radius)` |
|
||||
| `--tblr-form-check-box-shadow` | `var(--tblr-shadow-input)` |
|
||||
| `--tblr-form-check-icon-color` | `#fff` |
|
||||
| `--tblr-form-check-focus-border-color` | primary mixed with white |
|
||||
| `--tblr-form-check-active-filter` | `brightness(90%)` |
|
||||
| `--tblr-form-check-checked-bg` | `var(--tblr-control-checked-bg)` |
|
||||
| `--tblr-form-check-checked-border-color` | `var(--tblr-control-checked-border-color)` |
|
||||
| `--tblr-form-check-indeterminate-bg` | `var(--tblr-control-checked-bg)` |
|
||||
| `--tblr-form-check-indeterminate-border-color` | `var(--tblr-form-check-indeterminate-bg)` |
|
||||
| `--tblr-form-check-disabled-opacity` | `var(--tblr-control-disabled-opacity)` |
|
||||
| `--tblr-form-check-transition` | outline color, `0.15s` |
|
||||
|
||||
### Switches
|
||||
|
||||
Set on `.form-switch`. The knob is three quarters of the height and slides by the width, so both follow these two tokens.
|
||||
|
||||
| Variable | Default |
|
||||
| --- | --- |
|
||||
| `--tblr-form-switch-width` | `2rem` |
|
||||
| `--tblr-form-switch-height` | `1.25rem` |
|
||||
| `--tblr-form-switch-padding-start` | width + `0.5rem` |
|
||||
| `--tblr-form-switch-border-radius` | `var(--tblr-form-switch-width)` |
|
||||
| `--tblr-form-switch-focus-color` | primary mixed with white |
|
||||
| `--tblr-form-switch-checked-color` | `var(--tblr-white)` (the knob) |
|
||||
| `--tblr-form-switch-disabled-bg` | `var(--tblr-control-disabled-bg)` |
|
||||
| `--tblr-form-switch-disabled-color` | gray `400` in light mode, `600` in dark |
|
||||
|
||||
`.form-switch-lg` keeps its own `--tblr-form-switch-lg-*` set.
|
||||
|
||||
## Sass variables
|
||||
|
||||
The tokens are seeded from the Sass variables of the same component: `$input-*` for inputs, `$form-select-*` for selects, `$input-group-addon-*`, `$form-floating-*`, `$form-range-*`, `$form-check-*` and `$form-switch-*`. Configure them through `@use` as before. A configured variable becomes a fixed token value, so it no longer follows `--tblr-btn-input-*` at runtime; leave it at its default to keep the runtime link.
|
||||
|
||||
```scss
|
||||
@use '@tabler/core/scss/tabler' with (
|
||||
$input-padding-y: 0.75rem,
|
||||
$input-border-radius: 0
|
||||
);
|
||||
```
|
||||
@@ -6,6 +6,7 @@ docs-libs: [nouislider]
|
||||
description: Styled inputs, selects, checkboxes and radios, with states, sizes and layout options.
|
||||
order: 1
|
||||
related: [/ui/forms/validation, /ui/forms/helpers, /ui/forms/fieldset, /ui/plugins/date-picker, /ui/plugins/advanced-select]
|
||||
css-vars: control
|
||||
sass-vars: input
|
||||
---
|
||||
import Example from '@components/Example.astro';
|
||||
@@ -287,6 +288,8 @@ Use radio buttons for the parts of your form which require users to choose one o
|
||||
|
||||
Use checkboxes if you want to allow users to select more than one option from a set of predefined options or to turn an option on or off.
|
||||
|
||||
Checks, radios and switches share their state colors through `--tblr-control-checked-bg`, `--tblr-control-checked-border-color`, `--tblr-control-disabled-bg` and `--tblr-control-disabled-opacity` on `:root`. Each control also has its own tokens: `--tblr-form-check-*` on `.form-check-input` and `--tblr-form-switch-*` on `.form-switch`.
|
||||
|
||||
<Example column>
|
||||
<div class="mb-3">
|
||||
<div class="form-label">Checkboxes</div>
|
||||
@@ -328,6 +331,8 @@ Use checkboxes if you want to allow users to select more than one option from a
|
||||
|
||||
Add a [range slider](/ui/plugins/range-slider) to make it possible for users to set a value or range, such as a price range or a time frame.
|
||||
|
||||
The track and the thumb read `--tblr-range-*` custom properties on `.form-range`: `--tblr-range-track-height`, `--tblr-range-track-bg`, `--tblr-range-thumb-width`, `--tblr-range-thumb-bg`, `--tblr-range-thumb-border` and the rest of the `track-*` and `thumb-*` set.
|
||||
|
||||
<Example column>
|
||||
<div class="mb-3"> <label class="form-label">Range input</label> <input type="range" class="form-range mb-2" value="40" min="0" max="100" step="10" /> <div class="form-range mb-2 text-green" id="range-color"></div> </div> <script>{`document.addEventListener("DOMContentLoaded", function () { window.noUiSlider && noUiSlider.create(document.getElementById("range-color"), { start: 40, connect: [true, false], step: 10, range: { min: 0, max: 100, }, }); });`}</script>
|
||||
</Example>
|
||||
@@ -336,6 +341,8 @@ Add a [range slider](/ui/plugins/range-slider) to make it possible for users to
|
||||
|
||||
Create a group of input controls and place add-ons on either side of an input.
|
||||
|
||||
The add-on reads `--tblr-input-group-addon-*` custom properties on `.input-group` (`padding-y`, `padding-x`, `font-size`, `line-height`, `color`, `bg`, `border-color`, `border-radius`). `.input-group-sm` and `.input-group-lg` only change these tokens and pass them on to the controls in the group.
|
||||
|
||||
<Example column>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Input group</label>
|
||||
|
||||
@@ -3,6 +3,7 @@ title: Floating labels
|
||||
order: 3
|
||||
summary: Floating labels put the label inside the field. The label sits over the empty control and moves up when the user types or selects a value.
|
||||
description: Show labels inside form controls.
|
||||
css-vars: form-floating
|
||||
---
|
||||
import Example from '@components/Example.astro';
|
||||
|
||||
|
||||
@@ -387,6 +387,10 @@
|
||||
{
|
||||
"title": "Combobox",
|
||||
"url": "/ui/forms/combobox"
|
||||
},
|
||||
{
|
||||
"title": "CSS variables",
|
||||
"url": "/ui/forms/css-variables"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user