Search view
components specs/components/search-view.kmd
Full-screen / overlay search experience triggered from a search field — shows suggestions, recent queries, and live results as the user types. Material parity (`/components/search`). Distinguished from the static inline search bar (a text field with leading 🔍 icon).
Quando esta spec se aplica
Triggers primários
- Add a search view
Todos os triggers
- Replace inline search field with an immersive search overlay
- Build an in-app search with suggestions + recent + filters
- Surface search history while user is typing
Corpo da especificação
Spec — Search view
Facet Visual of Koder Design. Material parity: https://m3.material.io/components/search.
Search bar vs search view
| Surface | What it is | When |
|---|---|---|
| Search bar | Inline text field with 🔍 leading icon, sometimes mic | Persistent search affordance in toolbar / hero |
| Search view | Full-screen overlay with results / suggestions | Active typing / browsing recent queries |
User flow: tap the search bar → search view OPENS over current screen → user types / browses suggestions → user picks a result OR dismisses → returns to underlying screen.
Anatomy
┌──────────────────────────────────────────────┐
│ ← 🔍 Type to search... ⊗ 🎤 │ ← header (always visible)
│ ──────────────────────────────────────────── │
│ Recent │
│ 🕐 swift adoption metrics │ ← list of recent queries
│ 🕐 release planning Q3 │
│ 🕐 customer feedback summary │
│ ──────────────────────────────────────────── │
│ Suggestions │
│ 💡 switch to dark mode (Settings) │ ← contextual suggestions
│ 💡 team standup notes (Documents) │
│ ──────────────────────────────────────────── │
│ [Files] [Messages] [People] [Settings] │ ← filter chips (optional)
└──────────────────────────────────────────────┘
- Container bg:
surface(full-screen, no transparency) - Header: 64 px tall, contains back arrow / dismiss / mic / clear-text actions
- Field:
body-largetext, hint textbody-largetext-muted - Section subheaders:
label-large,text-muted, 16 px padding - Recent / suggestion rows: list rows per
lists.kmd(single-line default; leading icon 24 px)
R1 — Header layout
| Slot | Element |
|---|---|
| Leading | Back arrow (← or arrow-down depending on platform) — dismisses search view |
| Field | Editable text input; expands across remaining width |
| Trailing 1 | Clear-text × (visible when field has text) |
| Trailing 2 | Mic / voice search button (if voice supported) |
| Trailing 3 | Avatar / settings icon (optional) |
R2 — Empty state (no text typed)
Shows:
- Recent searches — last 5-10, with clock icon
- Suggestions — contextual (recent items, popular actions)
- Filter chips — scope of search (Files / Messages / People)
If no recent + no suggestions: show illustration + "Start typing to search" hint text.
R3 — Typing state (autocomplete)
As user types:
- Live results filter in (motion-fast)
- Sections rearrange: matching recent first, then suggestions, then results
- Highlight matched substring in results (bold or underline)
- Debounce: 150-250 ms before triggering remote search
For local-only data (settings, recent files), no debounce — filter instantly.
R4 — Results state (after submit OR sufficient text)
Replaces empty / autocomplete state with grouped results:
3 results in Files
📄 swift-adoption-metrics.csv
📄 swift-q3-plan.md
📄 swift-velocity.xlsx
1 result in People
👤 Swift Tanaka
No results in Messages
- Group results by source type
- Show count per group
- "No results" entry for empty sources (helpful — user knows search ran)
- Up to ~20 results visible; "Show more in [source]" link at end of each group
R5 — Filter chips
Optional filter row above results:
- Filter chips per source type (Files / Messages / People / Settings)
- Multi-select: each chip narrows scope
- Use
chips.kmdfilter variant
When chips are selected, results limit to selected sources.
R6 — Recent management
- Tap × on a recent row → remove from list + persist removal
- "Clear all" link at end of recent section
- Recent search persistence: per-user, per-device (not synced cross-device unless documented)
Privacy: don't include sensitive queries in recents (e.g., DM content); only top-level search strings.
R7 — Voice search
Voice / mic button in header:
- Tap → mic permission prompt (first time)
- Granted: opens voice listening overlay (
voice/wake-word.kmd § Talk Modeanalog UX — push-to-talk variant) - Recognized text inserts into field; user can edit or submit
- Disabled when voice backend not available (see
voice/wake-word.kmd § R5 backend availability)
R8 — Keyboard navigation
| Key | Action |
|---|---|
| Arrow Up / Down | Move focus through results / recents |
| Enter | Submit current text as full search OR select focused result |
| Esc | Dismiss search view, return to underlying screen |
| Tab | Move focus across filter chips |
| Backspace (in field) | Delete char; if field empty, focus stays in field |
R9 — Animation
- Open: search bar transforms into search view (motion-medium, ~300 ms emphasized) — bar grows to fill screen
- Close: reverse animation; search view shrinks back to bar
- Result update: cross-fade old → new (motion-fast, ~150 ms)
- Filter chip toggle: results re-shuffle with fade
- Reduced motion: instant open / close; no shrink-grow
R10 — Persistence
| Field state on dismiss | Behavior |
|---|---|
| Empty field, no submitted search | Don't add to recents |
| Submitted search | Add to recents (most recent first) |
| Typed text but didn't submit | Discard (don't add) |
Recent list deduped by exact-match string.
R11 — Mobile-specific
- Soft keyboard opens automatically when search view opens
- Voice button always visible (if mic supported on device)
- Results list scrolls under keyboard area; insets respect keyboard height
R12 — Accessibility
- Container:
role="dialog"+aria-modal="true"+aria-label="Search" - Field:
role="searchbox"+aria-label - Results:
role="listbox"+ each resultrole="option"+aria-selectedon focused - Recent items: same
listbox/optionsemantics witharia-labelindicating "recent" - Voice button:
aria-label="Voice search" - Live region: announces "N results" when results update
- Screen reader announces transition to search view on open
R13 — Density
| Density | Header height | Result row height |
|---|---|---|
| Compact | 56 px | 48 px |
| Default | 64 px | 56 px |
| Comfortable | 72 px | 64 px |
R14 — Per-preset variation
| Preset | Header | Result row |
|---|---|---|
material3 | Surface bg, no border below | Tonal hover |
material2 | Solid bg, 4 dp shadow | Filled hover |
ios_cupertino | Cancel button (text) instead of back arrow | Inset list rows |
gnome | Adwaita header bar, integrated mic | Boxed list |
windows_11 | Mica backdrop, Fluent fonts | Highlight bar on hover |
brutalist | Sharp solid header, thick border-bottom | Sharp result rows |
terminal_classic | Single line /search>, results below as text | Numbered list 1) ... |
R15 — Forbidden patterns
- ❌ Search view that doesn't focus the field on open
- ❌ Search view without back / dismiss affordance
- ❌ Results that mix sources without grouping (loses scannability)
- ❌ Submitting on every keystroke for remote search (over-fetches)
- ❌ Showing "0 results" without telling user what they searched for
- ❌ Hiding recents entirely when user starts typing (recents that match should still appear)
- ❌ Saving sensitive recent queries (DM content, credentials, PII)
- ❌ Search view as a sub-page (NOT full-screen / overlay) — defeats the immersive purpose
- ❌ Static search bar that pretends to be a search view (no suggestions / recents) — pick one pattern, don't mix
Cross-link
components/text-fields.kmd— base field anatomycomponents/chips.kmd— filter chip variantcomponents/lists.kmd— result row patternsthemes/elevation.kmd— search view sits at base surface (overlay, not elevated)themes/color-roles.kmd—surfacefor containervoice/wake-word.kmd— voice trigger contractinteraction/states.kmd— focused result tintfoundations/elements.kmd— Container + Control families
Referências
specs/foundations/elements.kmdspecs/themes/color-roles.kmdspecs/themes/elevation.kmdspecs/themes/typography.kmdspecs/components/text-fields.kmdspecs/components/chips.kmdspecs/components/lists.kmdspecs/interaction/states.kmd