# ADR-030: No <select> for More Than 5 Options — Use Searchable Type-Ahead or Chip-Grid

## Status

Accepted, 2026-06-22.

## Status History

```yaml
status_history:
  - date: 2026-06-22
    status: Proposed
    changed_by: hkl
    reason: Formalising explicit rule from Sales PWA design patterns for option-heavy fields
    changed_via: adr-kit (360lm)
  - date: 2026-06-22
    status: Accepted
    changed_by: hkl
    reason: Rule in force across Sales, Vendors, Finance PWAs; CiC verified
    changed_via: adr-kit (360lm)
```

## Context

Several PWAs need form fields with large option sets: selecting a vendor from 50+ registered payees, choosing a product SKU from a catalog, picking a cost center from a list of ledger accounts. Native `<select>` on mobile opens a system picker that requires scrolling through the full list — users cannot search or jump to a specific item. On Android and iOS, the native picker UX differs, adding inconsistency. With datasets of 20–100+ options, native `<select>` makes selection slow and error-prone. This rule was made explicit in Sales PWA design patterns and has been consistently applied across Vendors, Finance, and Custodian PWAs since.

## Decision

`<select>` is only acceptable for ≤5 mutually-exclusive categorical options where all options fit on one mobile screen without scrolling (e.g. "Transfer type: NEFT / IMPS / UPI / Cash / Cheque").

For any field with >5 options:
- **Searchable type-ahead input** — user types, list filters live from the full dataset. Required when options have names/labels (payees, products, employees, locations).
- **Chip-grid** — displays all options as tappable chips. Required when options are short labels and simultaneous visibility of all options is valuable (e.g. area selection across 8–12 areas).

The threshold is 5 options, not "large" — ambiguity in "large" caused inconsistent application. At 6+ options, evaluate type-ahead vs chip-grid based on: does the user need to see all options at once? → chip-grid. Do options have enough text that a full grid is cluttered? → type-ahead.

**Decision Maker:** hkl

## Alternatives Considered

- **Native `<select>` for all dropdowns regardless of count.** Rejected: on mobile, `<select>` opens a full-screen system picker for long lists; no search capability; UX tested and confirmed slow for >10 options (Sales PWA pilot feedback).
- **Custom scrollable modal list (no search).** Rejected: same UX quality as system picker but more code; scrolling through 50 items is still slow without search; does not add value over a type-ahead.
- **Autocomplete with server-side search (fetch per keystroke).** Rejected for offline-capable PWAs: requires network; the dataset (vendors, employees) is already loaded client-side; client-side filter is instant and works offline (ADR-020).

## Consequences

**Positive:**
- Users can locate any option in a 100+ item list in 1–2 keystrokes.
- Type-ahead works offline — filters the in-memory loaded dataset.
- Consistent UX across PWAs for large-option fields.

**Negative / Trade-offs:**
- Each type-ahead requires implementation: input element, filter function, dropdown overlay, keyboard/touch dismiss handling.
- Chip-grids become cluttered above ~20 options; apply only when the full set fits legibly on screen.
- The 5-option threshold is a heuristic — edge cases require judgment (e.g. 6 short options may still fit as radio buttons).

**Risks and mitigations:**
- Developer defaults to `<select>` for a 10-item list: mitigated by this ADR being referenced in adr-coding-rules.md; code review gate.
- Type-ahead matches too broadly (e.g. "a" returns 90% of vendors): mitigated by requiring minimum 2 characters before filtering; or ranking by last-used.

## Related Decisions

- ADR-027 (leave-one-out faceted filtering) — chip-grid UX for filter dimensions; same philosophy of showing all options.
- ADR-020 (offline-first IndexedDB) — dataset loaded client-side enables instant type-ahead without network.
- ADR-031 (full-screen forms) — type-ahead dropdowns within full-screen forms avoid modal-within-modal z-index issues.

## References

- `memory/dbt_sales.md` — explicit "no <select> for >5 options" rule in Sales PWA design notes
- `sales/index.html` — type-ahead implementation for vendor/product selection
- `finance/custodian/index.html` — type-ahead for payee selection in transfer form
