web-haptics-toast
v1.0.1
Published
Standalone React toasts with built-in haptics and a Sonner-compatible API. Single dependency—no separate haptics package.
Maintainers
Readme
web-haptics-toast
Standalone React toasts with haptics built in: one npm install, and you get the UI, styles, and vibration/audio engine together—no extra packages for haptics.
The toast() and <Toaster /> API is compatible with Sonner, so you can migrate or adopt without new mental models (including an optional npm alias so imports can stay from 'sonner').
By DesignByte · GitHub
Already using Sonner? (zero code change)
Replace your package and keep all existing imports. Your app keeps import { Toaster, toast } from 'sonner':
# npm
npm uninstall sonner && npm install sonner@npm:web-haptics-toast
# pnpm
pnpm remove sonner && pnpm add sonner@npm:web-haptics-toast
# yarn
yarn remove sonner && yarn add sonner@npm:web-haptics-toast
# bun
bun remove sonner && bun add sonner@npm:web-haptics-toastNo import changes needed. Haptics are on by default; disable with <Toaster haptics={false} />.
On the docs site in this repo, see Migrate from Sonner (route /migration-from-sonner when you run the website) for both migration paths, CSS notes, and a checklist.
New install
npm install web-haptics-toastimport { Toaster, toast } from 'web-haptics-toast';
import 'web-haptics-toast/dist/styles.css';
function App() {
return (
<div>
<Toaster />
<button onClick={() => toast('My first toast')}>Toast</button>
<button onClick={() => toast.success('Done!')}>Success</button>
<button onClick={() => toast.error('Failed')}>Error</button>
</div>
);
}Disable haptics
<Toaster haptics={false} />Customize haptic pattern per toast type
<Toaster
hapticPatternMap={{
info: 'selection',
loading: 'light',
}}
/>Built-in pattern names: success, error, warning, light, medium, heavy, soft, rigid, selection, nudge, buzz.
Test haptics on desktop (play sound)
When vibration isn’t available (e.g. desktop), you can still verify patterns by playing a short sound for each pulse:
<Toaster hapticsDebug />Use this during development to confirm which pattern runs for each toast type. On devices that support vibration, you still get real haptics; sound plays in addition when hapticsDebug is true.
Show an on-screen haptics toggle
<Toaster hapticsShowSwitch />Renders a small built-in control so users can turn feedback on or off without you wiring custom UI.
Haptics on a button (or anywhere), not on every toast
<Toaster haptics={false}> stops toast-driven vibration. You can still call triggerHaptic from any onClick, onSubmit, shortcut handler, etc.:
import { Toaster, toast, triggerHaptic } from 'web-haptics-toast';
<Toaster haptics={false} />
<button
type="button"
onClick={() => {
triggerHaptic('success');
toast('Done');
}}
>
Save
</button>You can also skip haptics for individual toasts: toast('…', { haptics: false }) while leaving <Toaster haptics /> on. Full write-up: /haptics#manual-haptics on the docs site.
Other API
isHapticsSupported–trueifnavigator.vibrateis available.triggerHaptic(patternName, options?)– fire a built-in preset by name. Options:{ intensity?: number; debug?: boolean }. UsetriggerHaptic('success', { debug: true })to hear the pattern on desktop.WebHaptics– low-level class included in this package. Create instances withnew WebHaptics({ debug, showSwitch }), call.trigger(input),.destroy().defaultPatterns– the preset map shipped with the library (success, error, warning, light, etc.).
Sonner-style props still work the same (position, duration, theme, richColors, etc.).
Credits
Toast UX and API follow Sonner. Haptic presets and the WebHaptics model are vendored inside this repo—aligned with the ideas behind web-haptics, but not installed as a separate dependency.
License
MIT © DesignByte
