UI Sound Kit
用 Web Audio 即時合成 click、hover、success、error 等輕量介面音效,內建音量控制、全域開關與偏好尊重,零音檔零額外請求。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
0.5
<UiSoundKit />
安裝
npx shadcn@latest add https://webberui.com/r/ui-sound-kit.json或在 components.json 設定 registries 後,改用 @webberui/ui-sound-kit 安裝。
安裝依賴後,從 registry JSON(/r/ui-sound-kit.json 的 files[0].content)複製 ui-sound-kit.tsx 原始碼到你的 components/ui/ 目錄:
npm install motion lucide-react clsx tailwind-merge使用
在需要音效的範圍外層包一次 SoundProvider,內部任何元件即可透過 useSound() 取得 play() 與開關/音量控制:
import {
SoundProvider,
useSound,
} from "@/components/ui/ui-sound-kit";
function App() {
return (
<SoundProvider defaultVolume={0.5}>
<SaveButton />
</SoundProvider>
);
}
function SaveButton() {
const { play } = useSound();
return (
<button
onClick={async () => {
try {
await save();
play("success");
} catch {
play("error");
}
}}
>
儲存
</button>
);
}內建音效名稱:"click"、"hover"、"success"、"error"、"toggle"、"notification"(可從 SOUND_NAMES 取得完整清單)。
內建元件
SoundButton 是會發聲的按鈕,點擊(與可選的 hover)時自動播放;SoundToggle 是全域開關按鈕:
import {
SoundButton,
SoundToggle,
} from "@/components/ui/ui-sound-kit";
<SoundButton sound="click" hoverSound="hover">
播放
</SoundButton>
<SoundToggle />Props
SoundProvider
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
defaultEnabled | boolean | true | 初始是否開啟音效(有持久化偏好時掛載後覆蓋) |
defaultVolume | number | 0.5 | 初始全域音量 0~1 |
storageKey | string | null | "wb-sound-kit" | 持久化開關與音量的 localStorage 鍵;null 停用持久化 |
respectReducedMotion | boolean | true | 系統開啟「減少動態效果」時是否一併靜音 |
useSound() 回傳
| 名稱 | 型別 | 說明 |
|---|---|---|
play | (name, options?) => void | 合成並播放內建音效,options.volume 為單次音量倍率 |
enabled | boolean | 全域音效是否開啟 |
setEnabled | (enabled: boolean) => void | 開啟/關閉全域音效 |
volume | number | 全域音量 0~1 |
setVolume | (volume: number) => void | 設定全域音量(自動夾在 0~1) |
SoundButton
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
sound | SoundName | "click" | 點擊時播放的音效 |
hoverSound | SoundName | — | 指定時,游標移入也會播放此音效 |
其餘原生 button 屬性皆透傳。SoundToggle 亦透傳原生 button 屬性,並以 chime(預設 true)控制開啟時是否播放確認音。
細節
- 即時合成,零資源:以 Web Audio 的
OscillatorNode+GainNode即時合成音效,不載入任何音檔、不發任何額外請求。 - 惰性初始化:
AudioContext於首次play()(通常來自使用者點擊手勢)才建立並自動resume,符合瀏覽器自動播放政策;分頁切回若被suspend也會嘗試恢復。 - 單一音訊圖:整個 Provider 共用一個
AudioContext與主音量節點;每次播放另接一段獨立 bus 增益,套用單次音量倍率後回收。 - 持久化偏好:開關與音量預設寫入
localStorage,重新整理後沿用;可用storageKey={null}關閉。
可及性
SoundToggle以aria-pressed表示開關狀態,並隨狀態切換aria-label(開啟音效/關閉音效)與圖示。- 音量滑桿為原生
<input type="range">,帶aria-label,可鍵盤操作。 - 使用者系統開啟「減少動態效果」時,
respectReducedMotion預設會一併靜音,尊重降噪偏好;音效關閉時互動行為(onClick等)不受影響,只是不發聲。