Smooth Caret Input
彈簧物理平滑游標輸入框:自訂游標以 spring 滑行跟隨文字位置,支援直條/方塊/底線三款形狀。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
650
42
<SmoothCaretInput />
安裝
npx shadcn@latest add https://webberui.com/r/smooth-caret-input.json安裝時會一併寫入 --wb-duration-fast、--wb-ease-out CSS 變數到你的全域樣式。
安裝依賴後,從 registry JSON(/r/smooth-caret-input.json 的 files[0].content)複製 smooth-caret-input.tsx 原始碼到你的 components/ui/ 目錄,並在全域 CSS 加入:
npm install motion clsx tailwind-merge:root {
--wb-duration-fast: 200ms;
--wb-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
}使用
import { SmoothCaretInput } from "@/components/ui/smooth-caret-input";
<SmoothCaretInput
placeholder="開始輸入⋯"
onChange={(value) => console.log(value)}
/>受控模式:
const [value, setValue] = React.useState("");
<SmoothCaretInput value={value} onChange={setValue} caretShape="block" />Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
value | string | — | 受控值;省略時元件內部自管(非受控) |
defaultValue | string | "" | 非受控模式的初始值 |
onChange | (value: string) => void | — | 值變更時觸發 |
placeholder | string | — | 佔位文字 |
disabled | boolean | false | 停用輸入 |
caretShape | "bar" | "block" | "underline" | "bar" | 游標形狀 |
caretColor | string | 文字色 | 游標顏色(任意 CSS 顏色) |
stiffness | number | 650 | 彈簧剛性,越大越快貼合 |
damping | number | 42 | 彈簧阻尼,越大回彈越少 |
name | string | — | input 的 name,供表單提交 |
id | string | — | input 的 id,供 label 綁定 |
aria-label | string | placeholder | 無障礙標籤 |
細節
- 彈簧跟隨:以隱藏鏡像 span 量測游標前文字寬度換算像素位置,交由
useSpring平滑滑行到目標位置 - 游標移動偵測:監聽
selectionchange,方向鍵、點擊、選取都會即時重算並暫停閃爍,滑行結束後恢復閃爍 - 溢出處理:文字超出寬度而水平捲動時,扣除
scrollLeft讓游標維持在可視區 - IME 安全:注音/拼音組字期間鏡像會納入組字文字,游標位置持續正確跟隨
可及性
- 自訂游標帶
aria-hidden,不干擾螢幕報讀;input承接aria-label/name/id - 使用者系統開啟「減少動態效果」時,掛載後改回原生游標並停用彈簧與閃爍動畫
- 未提供
aria-label時自動採用placeholder,確保有可讀名稱