WebberUI

Tag Input

標籤輸入器:Enter/逗號新增膠囊 chip(去空白去重),空輸入時 Backspace 刪最後一個;chip 以 spring 彈入、移除時其餘以 FLIP 收攏補位,IME 組字中不誤觸新增。

載入預覽⋯

Playground

即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。

6
<TagInput />

安裝

npx shadcn@latest add https://webberui.com/r/tag-input.json

或在 components.json 設定 registries 後,改用 @webberui/tag-input 安裝。

安裝依賴後,從 registry JSON(/r/tag-input.jsonfiles[0].content)複製 tag-input.tsx 原始碼到你的 components/ui/ 目錄:

npm install motion lucide-react clsx tailwind-merge

使用

import { TagInput } from "@/components/ui/tag-input";

<TagInput
  value={["設計", "動畫"]}
  onChange={(tags) => console.log(tags)}
  maxTags={8}
/>

未提供 value 時由元件內部管理狀態(非受控);提供 value 搭配 onChange 則為受控模式。onChange 在新增與移除時都會帶入最新的 string[]

Props

Prop型別預設值說明
valuestring[]受控標籤陣列;未提供時由元件內部管理
onChange(tags: string[]) => void標籤變更時觸發(新增或移除),帶入最新標籤陣列
placeholderstring"新增標籤⋯"輸入框的 placeholder 文字
maxTagsnumber最大標籤數,達到後停止新增
disabledbooleanfalse停用整個輸入器
classNamestring附加到最外層容器的 class

細節

  • 新增:輸入按 Enter 或逗號即新增一顆 chip,值會先去除前後空白;空字串或與現有標籤完全相等(重複)皆略過,並清空輸入
  • 刪除:每顆 chip 帶移除 ×;輸入框為空時按 Backspace 刪除最後一個標籤
  • 彈入進場:新標籤以 scale + y 的 spring 從下方彈入排列
  • FLIP 收攏:移除時該 chip 縮小退場(AnimatePresence mode="popLayout" 先脫離文件流),其餘 chip 與輸入框同時以 layout FLIP 平滑補位;多標籤時以 flex-wrap 自動換行
  • IME 安全:中文等輸入法組字中按 Enter/逗號不會誤觸新增(同時檢查 isComposingkeyCode !== 229,涵蓋 Safari 於 compositionend 後才發 keydown 的情形)
  • 上限:設定 maxTags 後達到數量即停止新增(既有標籤仍可移除)

可及性

  • 使用者系統開啟「減少動態效果」時,彈入與 FLIP 全部停用,狀態直接切換(DOM 結構與 SSR 一致)
  • 最外層容器帶 role="group"aria-label;點空白處會把焦點導向輸入框
  • 每顆 chip 的移除鈕為原生 <button>,帶「移除標籤某某」的 aria-label,可 Tab 循序聚焦,focus-visible 時顯示外框
  • 輸入框帶 aria-label,停用時 disabled 一併套用於移除鈕

On this page