Enabled set

All copy is placeholder. Real strings come from the i18n layer. STORY-041.

Not a combobox. This sets no value — every row carries a command. So it is a search input filtering a list of real buttons and checkboxes, with the match count in a live region. No role="listbox", no role="option": interactive controls nested inside an option are unreachable for most screen reader users.

Default — nothing typed

Only the enabled values render. The full set is one search away and never on screen unasked.

Enabled

  • EUR
    Euro Workspace currency · on 34 transactions
  • USD
    US Dollar On 12 transactions
  • TRY
    Turkish Lira Not used yet
The workspace currency has a genuinely disabled switch and the reason in text — “Always on”. Something must always be pickable. A greyed control with no explanation is the failure mode design.md names.

A new workspace — exactly one enabled

There is no default shortlist, anywhere. This is the state every Organisation starts in, so it has to teach.

Your team can only choose from the currencies listed here. Search above to add the ones you work in — every currency in the world is available.

Enabled

  • EUR
    Euro Workspace currency

Searching — the full set, in two groups

Already-enabled matches keep their switch. Everything else offers Add — a command, not a value.

Enabled

  • CNY
    Chinese Yuan On 3 transactions

Not enabled

  • JPY
    Japanese Yen No decimal places
  • WST
    Samoan Tala In no default and no group — and still one search away
Every button names its subject — “Add Japanese Yen”, never a bare “Add”. Twelve identical buttons is the usual failure in a list of commands. The match is bold and coloured, so nothing is lost in greyscale. WST is the test case that keeps enabled from quietly becoming supported.

Searching — no match

Never a blank pane. A list that empties without saying why reads as a broken screen.

No currency matches “qqq”. Try a code like JPY, or a name like Yen.

Disabling something in use

Permitted, warned, reversible. Nothing is deleted and nothing is rewritten.

No confirmation when the value is unused, and none for enabling — confirming a harmless, reversible action just teaches people to dismiss dialogs without reading them.

There is only ever one. A second attempt at something already awaiting an answer must not open a second dialog — spamming the switch stacked fifteen identical callouts, which is worse than the thing being warned about. The repeat attempt shakes this one (--shake, replayed above on load) and moves focus to Turn off. Focus, because a shake says nothing to a screen reader. Under prefers-reduced-motion it pulses its border instead of moving — removing the animation outright would leave the repeat attempt with no feedback at all.

Row error — the save failed

The only asynchronous step is persisting a change, so it is the only thing that can fail.

  • JPY
    Japanese Yen No decimal places

    Couldn’t save that.

The control has returned to its previous position. A list left showing a state that was never persisted is worse than an error, because it looks like success.

Timezones — the same component, the other instance

One component, two uses. Zones show their current offset; identity is always the IANA id.

Enabled

  • Europe/Amsterdam
    Amsterdam GMT+2 · workspace timezone · 1 venue
  • Europe/Istanbul
    Istanbul GMT+3 · 1 venue
  • Asia/Kolkata
    Kolkata GMT+5:30 · not used yet
A non-hour offset (+5:30) and a southern-hemisphere DST zone are the round-trip cases i18n.md names. The offset is display only — it changes twice a year, so it is never identity.

Long content

Real zone, real long compound. Nothing is truncated and the body never scrolls sideways.

  • Asia/Tokyo
    Tokyo GMT+9 · on 1 venue
  • America/Argentina/Rio_Gallegos
    Comodoro Rivadavia GMT−3 · Zeitzoneneinstellungsverwaltungsübersicht — an absurdly long token
Every name starts at the same x. Sizing each identifier to its own content put Tokyo left of Amsterdam and the list stopped reading as a column — the currency set never shows this, because three-letter codes are all one width.

Wide, the identifier is one shared grid track (subgrid) sized to the widest entry on screen, so short zones never reserve room for a long one, and a long one wraps inside its own column instead of pushing the list sideways. Narrow, it takes its own line above the name — a side column at 375px wraps Europe/Amsterdam mid-word, and aligned-but-unreadable is not the trade. Resize this page past 480px to see both.

The everyday picker — no new component

With one to five options this is a native <select>, which design.md prefers anyway. Open both, in both themes — the popup is drawn by the OS and color-scheme is the only thing that reaches it.

Only the workspace’s currencies are listed. An Owner can add more in Settings → Currencies.

This transaction already uses JPY, so it stays selectable here.

The second case is the one that prevents data loss. A record whose currency was later disabled keeps it, shows it, and stays selected on it. Dropping it would blank the field the moment someone edited an unrelated part of an old record — a loss with no error message, which is the worst kind. Same rule as an unavailable Venue in STORY-013.