Make disabled SearchSelect read as one element

The disabled widget showed two clashing surfaces in dark mode: the wrapper
(faded via has-[:disabled]) plus the inner search input, which picked up the
global disabled-input fill from common/input.css
(`form input:disabled { background: neutral-secondary-strong }`). That rule is
unlayered, so it beat any utility override on the input.

Exclude the SearchSelect's inner search box from that global rule
(`:not([data-search-select-search])`) so it stays transparent — the wrapper is
then the single faded surface. Standalone inputs (e.g. the Name field) keep
their distinct disabled surface, unchanged.

e2e: assert the disabled inner input computes transparent background (one
element), alongside the existing wrapper-opacity check.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-19 18:35:28 +02:00
parent 885e92b775
commit b49b5f1cc3
4 changed files with 15 additions and 5 deletions
+5 -2
View File
@@ -13,8 +13,11 @@ This module imports only from ``common.components`` — it has no Django-forms o
``<div>``, which has no ``disabled`` state of its own. To disable it, set
``disabled`` on the inner search ``<input>`` (``[data-search-select-search]``);
the wrapper then greys itself via the ``has-[:disabled]:`` utilities in
``_CONTAINER_CLASS``. Callers toggle only the control's ``disabled`` — never
styles. (See ``ts/add_purchase.ts`` gating ``related_game`` on the type field.)
``_CONTAINER_CLASS``. The inner input is excluded from the global
disabled-input surface (``common/input.css``) so it stays transparent — the
widget reads as one faded element, not a nested box. Callers toggle only the
control's ``disabled`` — never styles. (See ``ts/add_purchase.ts`` gating
``related_game`` on the type field.)
Option sourcing follows two axes. *Population*: options are either rendered
inline up front (``options=``, no ``search_url``) or fetched from ``search_url``.
+5 -2
View File
@@ -127,11 +127,14 @@
}
}
form input:disabled,
/* Standalone form controls get a distinct disabled surface. The SearchSelect's
inner search box is excluded: it's a composite widget that owns its disabled
look on the wrapper (has-[:disabled] in _CONTAINER_CLASS), so painting the
inner input here would render a nested box inside the wrapper. */
form input:disabled:not([data-search-select-search]),
select:disabled,
textarea:disabled {
@apply cursor-not-allowed bg-neutral-secondary-strong text-fg-disabled;
}
.errorlist {