Skip to content

Dark-mode styling for select2 and tom-select dropdowns - #62

Open
Fivell wants to merge 4 commits into
masterfrom
feature/select2-tomselect-dark-mode
Open

Fivell wants to merge 4 commits into
masterfrom
feature/select2-tomselect-dark-mode

Conversation

@Fivell

@Fivell Fivell commented Oct 8, 2026

Copy link
Copy Markdown
Member

Problem

The theme styles the jQuery-UI datepicker for dark mode but has zero rules for select2 or tom-select. Both ship their own light chrome and render their dropdown panel on <body> / in place, so with dark mode enabled the dropdown panel stays white with white (or near-invisible) text — unreadable.

select2 is used by most ActiveAdmin apps; tom-select is used by e.g. yeti.

Measured on a real dark-mode admin page before this change, the open select2 dropdown computes:

  • panel background: rgb(255, 255, 255) (white)
  • option text: rgb(255, 255, 255) (white)

→ white-on-white.

Fix

Inside @mixin aa-content, right after the jQuery-UI datepicker block, drive select2 and tom-select from the theme's existing --aa-* tokens so both the control and the dropdown follow both light and dark automatically (the tokens are repointed per mode by aa-dark-palette).

!important is required on the color/background/border declarations because select2/tom-select ship their own same-specificity rules that load later in the bundle — the same reason the existing datepicker overrides use it.

Covered:

  • select2: single/multiple selection control (--aa-input-bg / --aa-input-border / --aa-text), rendered value, placeholder (--aa-text-muted), multiple-select choices (--aa-surface-2 / --aa-border), search field, dropdown panel (--aa-surface / --aa-border), results options (--aa-text), highlighted option (--aa-surface-hover), selected option (--aa-selected).
  • tom-select: .ts-control (bg/border/text, inner input + placeholder, .item on --aa-surface-2), .ts-dropdown (--aa-surface, optgroup header on --aa-surface-2/--aa-text-muted, options, active option on --aa-surface-hover, selected on --aa-selected).

No new tokens are introduced — all nine --aa-* tokens used already exist in both the light and dark palettes, so the change is mode-agnostic and the README declarations table is unaffected.

After this change the same dropdown computes:

  • panel background: rgb(37, 41, 47) (dark surface)
  • option text: rgb(221, 226, 232) (light)

Verification

bundle exec rake css passes: 13 overrides compile clean, 17 bad ones rejected, README table matches 81 declarations.

Before / after

Same ActiveAdmin index (dark mode), select2 filter dropdown open.

Before (3.1.1) After (this PR)
before after

Fivell added 4 commits October 8, 2026 11:08
The theme styled the jQuery-UI datepicker for dark mode but had no rules
for select2 or tom-select. Both ship their own light chrome and render
their dropdown panel on <body>/in place, so in dark mode the panel stayed
white with white or near-invisible text — unreadable.

Drive select2 and tom-select from the theme's --aa-* tokens so both the
control and the dropdown follow light and dark. !important is required
because select2/tom-select ship same-specificity rules that load later in
the bundle — the same reason the datepicker overrides use it.
Both are now the same page and the same open dropdown in dark mode, differing
only in the select2 colors: before = released theme (select2's default white
panel, option text unreadable in dark), after = this PR (dark panel, readable).
The previous pair showed the dropdown open in one shot and closed in the other,
so they could not be compared side by side.
ActiveAdmin lays #wrapper out as display:table (content cell + sidebar cell),
which sizes to its content. A wide index table therefore grows the whole page:
it overflows horizontally, the header stretches with it and the utility nav +
theme toggle get pushed off the right edge (only reachable by scrolling); a
narrow table on a wide screen conversely leaves the header not spanning the
full width. Pin the layout table to the viewport (width:100% + table-layout:
fixed, min-width:0 on the content cell) and let #main_content scroll its own
wide table instead. Applies to every consumer from one place.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant