Give SearchSelect the same border + focus as native inputs

The SearchSelect wrapper had no border and no focus styling, so it looked unlike
a native input (which has border-default-medium → border-brand on focus). Add
border-default-medium + focus-within:border-brand/ring to the shared container
class — focus-within because the focusable element is the inner search box. This
also makes filter-bar comboboxes consistent with the other filter inputs, which
already have borders.

e2e asserts the wrapper border matches a native input's at rest and turns brand
on focus.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-20 08:03:08 +02:00
parent 29ba3e66e9
commit 9c25f02ddb
3 changed files with 37 additions and 3 deletions
+9 -3
View File
@@ -63,15 +63,21 @@ LabeledOption = tuple[str, str]
# widget reads as a single clickable field; the pills wrapper uses `contents`
# so its pills/hidden inputs flow as direct participants of that row, inline
# with the search input. The options panel is absolute, so it sits outside the
# flex flow. (border omitted intentionally — see if it's needed later.)
# flex flow.
# Border + focus styling mirror a native input (INPUT_CLASS): border-default-medium
# normally, brand border + ring on focus. The search input is the focusable
# element, so the focus state is expressed on the wrapper with focus-within: (and
# the inner input suppresses its own ring — see _SEARCH_CLASS).
# The widget owns its disabled appearance: when any control inside it is
# :disabled (e.g. add_purchase.ts disabling the search input), the wrapper fades
# via :has() — the same opacity-50 a disabled native input uses (see
# _DISABLED_CONTROL in games/forms.py), so the two look identical. Callers only
# toggle the control's `disabled`, never styles.
_CONTAINER_CLASS = (
"relative flex flex-wrap items-center gap-1 p-2 "
f"rounded-base bg-neutral-secondary-medium {DISABLED_WITHIN_CLASS}"
"relative flex flex-wrap items-center gap-1 p-2 rounded-base "
"bg-neutral-secondary-medium border border-default-medium "
"focus-within:border-brand focus-within:ring-1 focus-within:ring-brand "
f"{DISABLED_WITHIN_CLASS}"
)
_PILLS_CLASS = "contents"
# disabled:cursor-not-allowed matches the wrapper's cursor so hovering across