From 612a6302b4f29c33da3b887a035ab222119f8d11 Mon Sep 17 00:00:00 2001 From: Mathias Jakobsen Date: Wed, 8 Jul 2026 11:29:22 +0100 Subject: [PATCH] Merge pull request #35219 from overleaf/mj-themed-select [web] Add dark mode for Select and OLFormSelect GitOrigin-RevId: f71b95ff31720e898b33b508c5948b3219b28046 --- .../frontend/stylesheets/components/all.scss | 2 +- .../frontend/stylesheets/components/form.scss | 89 ++++++++++++++++--- .../stylesheets/components/modal.scss | 4 +- .../stylesheets/components/select.scss | 64 ++++++++++++- 4 files changed, 144 insertions(+), 15 deletions(-) diff --git a/services/web/frontend/stylesheets/components/all.scss b/services/web/frontend/stylesheets/components/all.scss index e4bb2d3921..9a885d84cc 100644 --- a/services/web/frontend/stylesheets/components/all.scss +++ b/services/web/frontend/stylesheets/components/all.scss @@ -15,6 +15,7 @@ @import 'icon'; @import 'input-suggestions'; @import 'list'; +@import 'select'; @import 'modal'; @import 'quote'; @import 'footer'; @@ -26,7 +27,6 @@ @import 'tabs'; @import 'beta-badges'; @import 'list-group'; -@import 'select'; @import 'dictionary'; @import 'link'; @import 'pagination'; diff --git a/services/web/frontend/stylesheets/components/form.scss b/services/web/frontend/stylesheets/components/form.scss index 6331481266..3367d7d62d 100644 --- a/services/web/frontend/stylesheets/components/form.scss +++ b/services/web/frontend/stylesheets/components/form.scss @@ -10,6 +10,10 @@ @return url("data:image/svg+xml,"); } +@function form-select-caret-svg($color) { + @return url("data:image/svg+xml,"); +} + @mixin form-check-light { --checkbox-label-color: var(--content-primary); --checkbox-border-color: var(--border-primary); @@ -94,6 +98,36 @@ )}; } +@mixin form-select-light { + --form-select-bg: var(--bg-light-primary); + --form-select-color: var(--content-primary); + --form-select-border-color: var(--border-primary); + --form-select-bg-img: #{escape-svg(form-select-caret-svg($content-primary))}; + --form-select-disabled-bg-img: #{escape-svg( + form-select-caret-svg($content-disabled) + )}; + --form-select-disabled-bg: var(--bg-light-disabled); + --form-select-disabled-color: var(--content-disabled); + --form-select-label-color: var(--content-primary); + --form-select-option-disabled-color: var(--content-disabled); +} + +@mixin form-select-dark { + --form-select-bg: var(--bg-dark-primary); + --form-select-color: var(--content-primary-dark); + --form-select-border-color: var(--border-primary-dark); + --form-select-bg-img: #{escape-svg( + form-select-caret-svg($content-primary-dark) + )}; + --form-select-disabled-bg-img: #{escape-svg( + form-select-caret-svg($content-disabled-dark) + )}; + --form-select-disabled-bg: var(--bg-light-disabled); + --form-select-disabled-color: var(--content-disabled-dark); + --form-select-label-color: var(--content-primary); + --form-select-option-disabled-color: var(--content-disabled-dark); +} + @mixin light-input { --input-field-color: var(--content-primary); --input-field-bg: var(--bg-light-primary); @@ -115,10 +149,12 @@ :root { @include form-check-light; @include light-input; + @include form-select-light; } @include theme('default') { @include form-check-dark; + @include form-select-dark; .form-control, .form-control-wrapper { @@ -395,8 +431,14 @@ } } -.form-control, -.form-select { +.form-control { + &[disabled], + &:disabled { + &::placeholder { + color: var(--input-field-content-disabled); + } + } + &:focus, &:invalid:focus, &.is-invalid:focus, @@ -411,6 +453,40 @@ } } +.form-select { + &:focus, + &:invalid:focus, + &.is-invalid:focus, + &:focus-visible, + &:invalid:focus-visible, + &.is-invalid:focus-visible { + color: var(--form-select-color); + background-color: var(--form-select-bg); + outline: 0; + border-color: var(--form-select-border-color); + box-shadow: $input-focus-box-shadow; + } + + --bs-form-select-bg-img: var(--form-select-bg-img); + + color: var(--form-select-color); + background-color: var(--form-select-bg); + border-color: var(--form-select-border-color); + + &[disabled], + &:disabled { + --bs-form-select-bg-img: var(--form-select-disabled-bg-img); + + background-color: var(--form-select-disabled-bg); + color: var(--form-select-disabled-color); + } + + option[disabled], + option:disabled { + color: var(--form-select-option-disabled-color); + } +} + .website-redesign { label { color: $form-text-color; @@ -453,15 +529,6 @@ input[type='range'] { @include form-control-validation($bg-danger-01); } -.form-control { - &[disabled], - &:disabled { - &::placeholder { - color: var(--input-field-content-disabled); - } - } -} - input.form-control[type='text'], input.form-control[type='search'] { color: var(--input-field-color); diff --git a/services/web/frontend/stylesheets/components/modal.scss b/services/web/frontend/stylesheets/components/modal.scss index 5cc2e358cb..9f79057004 100644 --- a/services/web/frontend/stylesheets/components/modal.scss +++ b/services/web/frontend/stylesheets/components/modal.scss @@ -5,10 +5,12 @@ @include theme('default') { .modal:not(.modal-themed) { // Until we add a dark modal version, all core components in modals should use light theme + @include light-themed-variables; @include light-dropdown-menu; @include light-notification; + @include light-select; @include form-check-light; - @include light-themed-variables; + @include form-select-light; .form-control, .form-control-wrapper { diff --git a/services/web/frontend/stylesheets/components/select.scss b/services/web/frontend/stylesheets/components/select.scss index 2ed554bb62..e4e2a3e5b1 100644 --- a/services/web/frontend/stylesheets/components/select.scss +++ b/services/web/frontend/stylesheets/components/select.scss @@ -1,9 +1,69 @@ +@mixin light-select { + --select-bg-highlighted: var(--bg-light-secondary); + --select-bg: var(--bg-light-primary); + --select-color: var(--content-primary); + --select-bg-disabled: var(--bg-light-disabled); + --select-border: var(--border-primary); + --select-color-disabled: var(--content-disabled); + --select-border-disabled: var(--border-disabled); +} + +@mixin dark-select { + --select-bg-highlighted: var(--bg-dark-secondary); + --select-bg: var(--bg-dark-primary); + --select-color: var(--content-primary-dark); + + // Intentional use of a light bg + --select-bg-disabled: var(--bg-light-disabled); + --select-color-disabled: var(--content-disabled-dark); + --select-border: var(--border-primary-dark); + --select-border-disabled: var(--border-disabled); +} + :root { - --select-background-highlighted: var(--bg-light-secondary); + @include light-select; +} + +@include theme('default') { + @include dark-select; } .select-wrapper { position: relative; + + .form-control { + background: var(--select-bg); + color: var(--select-color); + border-color: var(--select-border); + user-select: none; + + &:disabled { + color: var(--select-color-disabled); + background-color: var(--select-bg-disabled); + border-color: var(--select-border-disabled); + + .form-control-end-icon { + color: var(--select-color-disabled); + } + } + + &:focus, + &:invalid:focus, + &.is-invalid:focus, + &:focus-visible, + &:invalid:focus-visible, + &.is-invalid:focus-visible { + background: var(--select-bg); + color: var(--select-color); + border-color: var(--select-border); + outline: 0; + box-shadow: $input-focus-box-shadow; + } + } + + .form-control-end-icon { + color: var(--select-color); + } } .select-trigger { @@ -15,7 +75,7 @@ } .select-highlighted { - background-color: var(--select-background-highlighted); + background-color: var(--select-bg-highlighted); } .select-portal-popover {