From 464a52255b163d4f4ae1b44b011e27dd1021b468 Mon Sep 17 00:00:00 2001 From: Bartosz-Do Date: Wed, 12 Aug 2026 20:37:42 +0200 Subject: [PATCH] Fix oversized validation icons on `.form-select` (#2861) Co-authored-by: codecalm --- .changeset/fix-select-validation-icons.md | 5 +++++ .../__snapshots__/css-var-prefix.test.mjs.snap | 2 ++ core/scss/ui/forms/_validation.scss | 16 ++++++++++++++++ core/scss/vendor/_tom-select.scss | 14 ++++++++++++++ 4 files changed, 37 insertions(+) create mode 100644 .changeset/fix-select-validation-icons.md diff --git a/.changeset/fix-select-validation-icons.md b/.changeset/fix-select-validation-icons.md new file mode 100644 index 000000000..f2c981d41 --- /dev/null +++ b/.changeset/fix-select-validation-icons.md @@ -0,0 +1,5 @@ +--- +"@tabler/core": patch +--- + +Fixed oversized and mismatched validation icons on `.form-select` and Tom Select selects. diff --git a/core/scss/tests/__snapshots__/css-var-prefix.test.mjs.snap b/core/scss/tests/__snapshots__/css-var-prefix.test.mjs.snap index 2bd2e2824..a6e852438 100644 --- a/core/scss/tests/__snapshots__/css-var-prefix.test.mjs.snap +++ b/core/scss/tests/__snapshots__/css-var-prefix.test.mjs.snap @@ -43,6 +43,8 @@ exports[`css custom-property prefixing > leaves vendor-owned names alone and pre "--tblr-font-size-h5", "--tblr-font-weight-medium", "--tblr-font-weight-semibold", + "--tblr-form-select-bg-icon", + "--tblr-form-select-bg-img", "--tblr-gray-500", "--tblr-icon-size", "--tblr-info", diff --git a/core/scss/ui/forms/_validation.scss b/core/scss/ui/forms/_validation.scss index 8c4ac67c9..d29c93fdd 100644 --- a/core/scss/ui/forms/_validation.scss +++ b/core/scss/ui/forms/_validation.scss @@ -30,6 +30,18 @@ background-position: top var(--form-feedback-icon-inset) right var(--form-feedback-icon-inset) !important; } +// `.form-select` layers a second background (the feedback icon) behind its +// own caret, so it needs its own override alongside %validation-icon-size — +// same oversized-icon bug, but the caret's background-size must stay first. +// Tom Select copies the select's classes onto its `.ts-wrapper`, which is +// what actually paints these backgrounds, so this rule reaches that too. +%validation-icon-size-select { + --form-feedback-icon-size: #{$input-btn-icon-size}; + background-size: + #{$form-select-bg-size}, + var(--form-feedback-icon-size) var(--form-feedback-icon-size) !important; +} + @each $state, $data in $form-validation-states { .form-control.is-#{$state}-lite { @extend %validation-lite; @@ -43,6 +55,10 @@ @extend %validation-icon-size; } + .form-select.is-#{$state} { + @extend %validation-icon-size-select; + } + .form-control-sm.is-#{$state} { @extend %validation-icon-size-sm; } diff --git a/core/scss/vendor/_tom-select.scss b/core/scss/vendor/_tom-select.scss index 28f968948..b4a60b393 100644 --- a/core/scss/vendor/_tom-select.scss +++ b/core/scss/vendor/_tom-select.scss @@ -38,6 +38,20 @@ $input-border-width: 1px; --ts-pr-clear-button: 1.5rem; } } + + // Tom Select's Bootstrap 5 stylesheet hardcodes Bootstrap's own caret and + // valid/invalid icons on `.ts-wrapper.is-valid` / `.is-invalid`, and those + // selectors outrank `.form-select`. Hand the backgrounds back to the + // `.form-select` custom properties so a validated select shows the same + // icons as a validated `.form-control`. `:not(.single)` matches the + // specificity of the vendor rule for multi selects. + &.form-select.is-invalid, + &.form-select.is-valid { + &, + &:not(.single) { + background-image: var(--form-select-bg-img), var(--form-select-bg-icon, none); + } + } } .ts-dropdown {