Frontend Lab
← 回到所有模式
PA01🧩 Compose · 互動組合搜索

Search Match

搜索媒合

難度 ★★★★★標籤 搜索 · Fuse.js · highlight · 狀態3 min read

模式簡述

搜尋框是「狀態最多」的 UI 之一:空、輸入中、載入、有結果、零結果、超量、錯誤。 每一個狀態都需要不同的視覺與文字提示。沒處理好就會讓使用者誤以為網頁壞了。

開始輸入以搜尋⋯

|尚未輸入 — 顯示提示

Claude Code Prompt

💬 Claude Code Prompt
參考:PA01 search-match
技術:Fuse.js(模糊匹配)+ React 狀態

具體行為:
- 輸入欄左側顯示 search icon
- 空輸入:顯示「開始輸入以搜尋⋯」
- 輸入後 debounce 200ms 再查
- 命中字用 <mark> 標出(lab-accent 30% 透明度)
- 結果超過 5 筆:只顯示前 5 + 「+ N 筆更多結果」
- 0 筆:顯示「找不到 OOO」+ 建議關鍵字
- 錯誤:顯示 retry 按鈕

限制:
- 不要在每個 keystroke 都打 API,務必 debounce
- 不要把 highlight 顏色做太花,會干擾閱讀
- mark 用 bg-lab-accent/30,不要用 fill

完整程式碼

SearchMatch.tsx
'use client'

import { useMemo, useState } from 'react'

const DATA = ['Framer Motion', 'GSAP', 'Three.js', /* ... */]

function highlight(text: string, q: string) {
if (!q) return text
const i = text.toLowerCase().indexOf(q.toLowerCase())
if (i === -1) return text
return (
  <>
    {text.slice(0, i)}
    <mark className="bg-lab-accent/30 rounded px-0.5">
      {text.slice(i, i + q.length)}
    </mark>
    {text.slice(i + q.length)}
  </>
)
}

export function SearchMatch() {
const [q, setQ] = useState('')
const results = useMemo(
  () => (q ? DATA.filter(d => d.toLowerCase().includes(q.toLowerCase())) : []),
  [q],
)

return (
  <div>
    <input value={q} onChange={e => setQ(e.target.value)} placeholder="搜尋⋯" />
    {!q && <p>開始輸入以搜尋⋯</p>}
    {q && results.length === 0 && <p>找不到「{q}</p>}
    <ul>
      {results.slice(0, 5).map((r, i) => <li key={i}>{highlight(r, q)}</li>)}
    </ul>
    {results.length > 5 && <p>+ {results.length - 5} 筆更多結果</p>}
  </div>
)
}

何時用

  • ✅ 站內搜尋(< 1000 筆資料,client side 即可)
  • ✅ Command palette / 快速跳轉
  • ✅ Select / Combobox 的篩選輸入

何時別用

  • ❌ 資料 > 10000 筆,要走 server side + 分頁
  • ❌ 需要全文檢索 / 同義詞,要走 Algolia / Meilisearch
  • ❌ 不需要即時回饋的長文搜尋(書本內文,使用者願意等)

我踩過的坑

  1. 不做 debounce 直接查 API:使用者打 "ephraim" 7 個字會打 7 次 API。 debounce 200-300ms,請求量降一個數量級。

  2. highlight 用整段背景色:早期把命中字用 bg-yellow-200 一刀切, 結果跟暗色主題打架。改成 bg-lab-accent/30 + 圓角,瞬間融入。

  3. 0 筆結果只寫「沒有」:使用者搞不清楚是查錯字還是真沒有。 解法:把搜尋詞 echo 出來 + 給建議關鍵字。

相關模式

  • PA06 Filter Sidebar — 搜尋 + 篩選的組合

搜尋

按 ⌘K 隨時開啟