fix(ui): unify form comboboxes and align controls (SearchableSelect review)#635
Conversation
There was a problem hiding this comment.
Code Review
This pull request refactors the SearchableSelect component to unify the single and multi-select layouts under a single design where selected values are displayed as chips next to the search input. It also updates the positioning strategy of the combobox popup from body-portalled to inline with fixed positioning to resolve focus trap issues in modal dialogs. Additionally, various CSS styles for forms, native select elements, and date fields are updated to ensure visual consistency, and corresponding test suites are updated to align with these changes. There are no review comments to address, so I have no feedback to provide.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
…eview) SearchableSelect now uses one layout for single and multi: the input is the search field, the value(s) show as chips, and opening always lists all options (the current selection highlights, it no longer pre-filters). The popup renders inline with a fixed positioning strategy, so a modal dialog's focus trap can no longer inert it — the Billing (Monatsabrechnung) selects open again. - Drop the leading search magnifier; the trailing ▾ is the single affordance. - Native <select> gets appearance:none + the same ▾ as the combobox. - Date field: neutral 1px resting border + 44px min-height, matching sibling inputs. - stack-form: right-aligned labels; checkboxes/radios align to the control column. comboboxParts: the popup search row is gated by an explicit popupSearch prop instead of `multiple`, so the grid cell editor (ChipSelect) keeps its in-popup search for narrow columns while the form control searches inline. Tests updated for the shared chip layout (single now renders a value chip) and for the OptionSelect search inputs that precede the Auswertung ticket field. The Auswertung filter e2e specs (interpretation.spec.ts) follow the same structure: default-all reads as an empty control, and the change-a-filter flow types to open and filter before picking an option. Signed-off-by: Sebastian Mendel <info@sebastianmendel.de>
39ac9a7 to
bf811e7
Compare
|
…s pages The #635 stack-form rules were verified against Billing/Auswertung but not the settings pages, where two layouts broke: - A DateField's "YYYY-MM-DD" hint floated to the far right: the label right-align (`.field > span`) also caught the hint span, which spans the full width. Scope the right-align to the label (`:first-child`) and place a field's hint under its control (column 2). - A checkbox with its own hint (Personio) stranded the box above its label: sparse grid auto-placement — the box has an explicit column and precedes the label in the DOM — can't put the later label back on row 1. Pin the rows: label + box on row 1, hint under the box on row 2. Verified at 1440px on the sync and account settings pages. Signed-off-by: Sebastian Mendel <info@sebastianmendel.de>
…s pages (#636) ## Summary Fixes two form-layout regressions from #635 (shipped in v6.3.1) that landed on the settings pages. #635's `.stack-form` rules were verified against Billing/Auswertung but not the settings, where the field and checkbox structures differ (a `.field` can hold a `.field-hint`; a `.field-check` can hold three children). ## Fixes - **Date-field hint floated to the far right** (`/ui/settings/sync`): the label right-align (`.stack-form .field > span`) also caught the DateField's `.field-hint` span, which spans the full width — pushing "YYYY-MM-DD" to the right edge. Scoped the right-align to the label (`:first-child`); a field's hint now sits under its control (column 2). - **A checkbox with its own hint stranded the box above its label** (Personio opt-in): sparse grid auto-placement — the checkbox has an explicit column 2 and precedes the label in the DOM — pushed the label onto row 2, leaving the box alone above it. Pinned the rows explicitly: label + box on row 1, the hint under the box on row 2. ## Verification Visual check at 1440px on `/ui/settings/sync` and `/ui/settings/account`: date hints sit under the date fields, checkboxes align with their labels on one row, and a per-checkbox hint sits below the box. CSS-only — CI re-verifies tests/typecheck/lint.



Summary
Addresses an 8-point UX review of the searchable form selects (
SearchableSelect/OptionSelect) as they appear on Auswertung and in the Billing (Monatsabrechnung) modal.Changes
Combobox behaviour (
SearchableSelect)fixedpositioning strategy instead of a body portal, so a modal dialog's focus trap can no longer inert it — the Billing modal's selects open again (a body-portalled popup was a sibling of the dialog and gotinert).fixedstill lets the popup escape card/tableoverflowand clamp to the viewport.Control consistency
<select>getsappearance:none+ the same neutral ▾ as the combobox (Billing renders both in one form)..date-field-wrap): neutral1pxresting border +44pxmin-height, matching the sibling.fieldinputs (was an always-on1.5pxaccent border that read taller/heavier). Calendar icon unchanged..stack-form: labels right-aligned; checkboxes/radios join the two-column grid so input, select, checkbox and radio share one left edge.Shared helper
comboboxParts.ComboboxContent: the popup search row is gated by an explicitpopupSearchprop instead ofmultiple, so the grid cell editor (ChipSelect) keeps its in-popup search for narrow columns (unchanged) while the form control searches inline.Scope
Forms only. The worklog grid cell editor (
ChipSelect) is left untouched — its single-select already routes search into a roomy, content-sized popup for narrow columns, and its keyboard/commit flow is intentionally out of scope.Verification
bun run test— 576 pass;bun run typecheckandbun run lintclean.