Haptic
Haptic feedback for React on iOS and vibration-capable browsers. One target. Same handlers, ref, focus, and accessibility. Try the live demo.
- One component wrapping the original React target.
HapticandHapticTargetare aliases for a single wrapper that preserves your element's handlers, ref, focus, and accessibility. - Eleven vibration presets and custom patterns. Choose from presets like
selection,success, anderror, or specify custom durations, alternating patterns, and event objects with delay and intensity. - Native iOS physical-tap ticks. Physical taps on iOS trigger the system haptic, while vibration-capable browsers use the Vibration API with pattern and intensity support.
- Full target behavior preservation. Handlers, refs, focus, accessibility, keyboard, forms, links, and drawer integration all retain the original target's behavior.
- Server-safe rendering. Works with SSR and hydration, providing both ESM and CommonJS builds with TypeScript declarations.
- Independently written wrapper. Platform-specific code with
web-hapticsas a declared dependency.
npm install @bloxwap/hapticWorks with React 18 or newer. Requires matching React and React DOM peer versions.
0.1.0 is public; physical iPhone/Android/iPadOS/VoiceOver certification is still pending (see issues #7 and #9). Automated checks establish browser interactions and API calls, not tactile output.
Wrap any React element to add haptic feedback.
import { Haptic } from '@bloxwap/haptic';
export function SaveButton() {
return (
<Haptic feedback="success">
<button onClick={() => console.log('Saved')}>Save</button>
</Haptic>
);
}The original element keeps its handlers, ref, focus, and accessibility. The wrapper defaults to inline-grid; className and style control its layout.
<Haptic
feedback={[30, 60, 30]}
triggerOptions={{ intensity: 0.7 }}
webHapticsOptions={{ debug: false, showSwitch: false }}
style={{ display: 'grid', width: '100%' }}
>
<button>Continue</button>
</Haptic>enabled={false} or disabled={true} suppresses feedback while leaving the action available. Disabled and aria-disabled="true" hosts are detected automatically.
import {
Haptic, HapticTarget,
isIOSWebKitWithoutVibration, useIOSNativeHaptics,
type HapticTargetProps, type HapticInput, type HapticPattern,
type HapticPreset, type TriggerOptions, type Vibration, type WebHapticsOptions,
} from '@bloxwap/haptic';| Export | Description |
|---|---|
Haptic / HapticTarget |
The component that wraps a single React element and adds haptic feedback. Props: feedback (preset, duration, pattern, or object), enabled, disabled, triggerOptions, webHapticsOptions, className, style, children (single element). |
isIOSWebKitWithoutVibration() |
Returns true when running on iOS WebKit without Vibration API support, indicating native system haptics will be used. |
useIOSNativeHaptics() |
React hook that returns whether iOS native haptics are active. |
Presets: selection, light, medium, heavy, soft, rigid, success, warning, error, nudge, buzz.
feedback accepts a preset string, duration in milliseconds, alternating on/off number[], vibration event objects, or { pattern: [...] }. The default is selection.
iOS feedback requires a physical tap and always uses the native system tick. Timers, synthetic clicks, and asynchronous callbacks cannot promise physical feedback. Presets and intensity apply to vibration-capable browsers.
Desktop audio preview is opt-in with webHapticsOptions={{ debug: true }}. Hardware and browser settings determine actual feedback; iPadOS routing alone does not prove haptic hardware. Browser automation does not establish tactile output.
For Next.js, place interactive usage in a client component. The build preserves its client boundary and renders safely through React SSR.
Guides, API reference, and interactive demos: https://bloxwap.github.io/haptic/
The evaluation, compatibility contract, and task index record the independent build and release requirements.
This repository is an npm workspace: the library lives in packages/haptic and the documentation site in apps/docs.
npm ci
npm test # run the test suite
npm run coverage # tests with 100% line/branch/function coverage enforcement
npm run build # build the library
npm run typecheck # TypeScript validation
npm run test:matrix # test across React versions
npm run size # bundle size check
npm run pack:check # verify package contents
npm run test:browser # Playwright tests
npm run dev # docs dev server at http://localhost:3905Requires Node.js 24 or newer. bun run dev invokes the same development script; npm owns the lockfile.
Documentation build and preview:
NEXT_PUBLIC_BASE_PATH=/haptic npm run docs:build
npm run docs:check
npm run docs:preview| Repository | Port |
|---|---|
| hyperliquid | 3901 |
| chart | 3902 |
| sfx | 3903 |
| font | 3904 |
| haptic | 3905 |
web-haptics is independently distributed under MIT; website fonts retain their OFL license notice, which is included in the static site.