Skip to content

fix: show the chosen row in a settings dropdown, not its stored value - #140

Merged
omartelo merged 1 commit into
mainfrom
fix/select-trigger-labels
Aug 4, 2026
Merged

omartelo merged 1 commit into
mainfrom
fix/select-trigger-labels

Conversation

@omartelo

@omartelo omartelo commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

A closed Select trigger showed the stored value instead of the row that was picked. Fixing the theme pickers in #131 turned up the same thing in two more places, and this closes them.

base-ui resolves a trigger's label from the items map on Select.Root. Without it, resolveSelectedLabel falls through to stringifying the value — and since items only register themselves once the popup has been opened, a trigger the user never opened has nothing else to go on.

Three rows read wrong:

where showed should show
Providers › Default provider claude Claude Code
Version control › GitHub account __active__ gh's active account
Version control › GitHub account github.com/you you

The __active__ one is the worst of the three: it is an internal placeholder standing in for "no override", because a Select item cannot carry the empty string that setting is actually stored as. On screen it reads like something broke.

What changed

  • accountSelectItems in lib/gh-account.ts, next to accountLabel, builds the account picker's map so a row's two forms cannot drift apart. Covered by tests.
  • Providers passes its map inline — id to name is the whole mapping.
  • ACTIVE_ACCOUNT_LABEL is a constant now, so the row and the map cannot disagree about its wording.

FontSetting is deliberately untouched: its value is the family name it displays, so it was already showing the right words.

Not in this PR

There is no guard against the next Select shipping without items. The obvious one — making the prop required in components/ui/select.tsx — would force a redundant identity map on every picker whose value already equals its label, and ui/ is shadcn-CLI territory, so a regenerate would drop the guard silently. The frontend gate is node-only, so no test can catch it either. Left as a known edge rather than papered over.

Testing

  • gofmt -l ., go vet ./..., go test ./... (22 packages)
  • cd frontend && ./node_modules/.bin/tsc --noEmit
  • cd frontend && ./node_modules/.bin/vitest run — 621 passing
  • cd frontend && ./node_modules/.bin/biome check src — 11 warnings, all pre-existing, none in these files
  • cd frontend && ./node_modules/.bin/vite build

Worth a look in the running app rather than on the diff: open Settings › Providers and Settings › Version control without touching either dropdown, and read what the closed trigger says.

A closed Select renders the raw value unless the Root is handed the
value-to-label map: its items only register themselves once the popup has been
opened, so a trigger the user never opened stringifies whatever is stored.

Three rows read wrong because of it. The default provider showed claude rather
than Claude Code. The GitHub account showed __active__ — the placeholder that
stands in for "no override", which a Select item cannot carry as the empty
string — and showed github.com/you where the row it came from read you.

The account map is built by accountSelectItems, beside accountLabel, so the two
forms of a row cannot drift apart. The font picker is left alone: its value is
the family name it displays, so it was already showing the right words.
@omartelo
omartelo merged commit aae21c2 into main Aug 4, 2026
3 checks passed
@omartelo
omartelo deleted the fix/select-trigger-labels branch August 4, 2026 12:13
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