React Integration
The React integration provides a useWebHaptics hook that manages the haptics instance lifecycle and provides memoized trigger functions.
Installation
Install the package
npm install @accede-ai/webhaptics
Import the hook
import { useWebHaptics } from '@accede-ai/webhaptics/react' ;
Basic Usage
The hook automatically initializes the WebHaptics instance on mount and cleans it up on unmount:
import { useWebHaptics } from '@accede-ai/webhaptics/react' ;
function App () {
const { trigger , cancel , isSupported } = useWebHaptics ();
const handleClick = () => {
trigger ( 'medium' );
};
return (
< button onClick = { handleClick } >
Click me { ! isSupported && '(haptics not supported)' }
</ button >
);
}
API Reference
useWebHaptics(options?)
Returns an object with haptic control methods.
Parameters
Configuration options for the WebHaptics instance Enable debug mode with audio feedback (useful for desktop development)
Show haptic feedback toggle switch in the UI
Return Value
trigger
(input?: HapticInput, options?: TriggerOptions) => void
Triggers a haptic feedback pattern. Accepts:
A number (duration in ms)
A preset name string ('light', 'medium', 'heavy', 'success', etc.)
An array of numbers (alternating on/off durations)
An array of Vibration objects
A HapticPreset object
Cancels any currently playing haptic pattern
Indicates whether haptic feedback is supported in the current environment
Type Definitions
interface Vibration {
duration : number ; // Duration in milliseconds
intensity ?: number ; // 0-1, controls vibration strength (default: 0.5)
delay ?: number ; // Delay before this vibration in ms
}
type HapticInput =
| number // Simple duration
| string // Preset name
| number [] // Alternating on/off pattern
| Vibration [] // Full control
| HapticPreset ;
interface TriggerOptions {
intensity ?: number ; // Default intensity for vibrations without explicit intensity
}
interface WebHapticsOptions {
debug ?: boolean ;
showSwitch ?: boolean ;
}
Examples
import { useWebHaptics } from '@accede-ai/webhaptics/react' ;
import { useState } from 'react' ;
function LoginForm () {
const { trigger } = useWebHaptics ();
const [ email , setEmail ] = useState ( '' );
const [ error , setError ] = useState ( '' );
const handleSubmit = ( e : React . FormEvent ) => {
e . preventDefault ();
if ( ! email . includes ( '@' )) {
setError ( 'Invalid email' );
trigger ( 'error' );
return ;
}
setError ( '' );
trigger ( 'success' );
// Submit form...
};
return (
< form onSubmit = { handleSubmit } >
< input
type = "email"
value = { email }
onChange = { ( e ) => setEmail ( e . target . value ) }
placeholder = "Email"
/>
{ error && < span className = "error" > { error } </ span > }
< button type = "submit" > Login </ button >
</ form >
);
}
import { useWebHaptics } from '@accede-ai/webhaptics/react' ;
import { useState } from 'react' ;
function ToggleButton () {
const { trigger } = useWebHaptics ({ debug: true });
const [ isActive , setIsActive ] = useState ( false );
const handleToggle = () => {
setIsActive ( ! isActive );
trigger ( isActive ? 'light' : 'medium' );
};
return (
< button
onClick = { handleToggle }
className = { isActive ? 'active' : '' }
>
{ isActive ? 'ON' : 'OFF' }
</ button >
);
}
Slider with Haptic Feedback
import { useWebHaptics } from '@accede-ai/webhaptics/react' ;
import { useState , useRef } from 'react' ;
function HapticSlider () {
const { trigger } = useWebHaptics ();
const [ value , setValue ] = useState ( 50 );
const lastStepRef = useRef ( 5 );
const handleChange = ( e : React . ChangeEvent < HTMLInputElement >) => {
const newValue = parseInt ( e . target . value );
setValue ( newValue );
// Trigger haptic on every 10% increment
const currentStep = Math . floor ( newValue / 10 );
if ( currentStep !== lastStepRef . current ) {
trigger ( 'selection' );
lastStepRef . current = currentStep ;
}
};
return (
< div >
< input
type = "range"
min = "0"
max = "100"
value = { value }
onChange = { handleChange }
/>
< span > { value } % </ span >
</ div >
);
}
Custom Haptic Pattern
import { useWebHaptics } from '@accede-ai/webhaptics/react' ;
function CustomPatternButton () {
const { trigger } = useWebHaptics ();
const playCustomPattern = () => {
// Create a pulsing pattern
trigger ([
{ duration: 50 , intensity: 0.3 },
{ delay: 100 , duration: 50 , intensity: 0.6 },
{ delay: 100 , duration: 50 , intensity: 0.9 },
]);
};
return (
< button onClick = { playCustomPattern } >
Play Custom Pattern
</ button >
);
}
Common Patterns
Debug Mode for Desktop Development
Enable debug mode during development to hear audio feedback on devices without haptic support:
const { trigger } = useWebHaptics ({
debug: process . env . NODE_ENV === 'development'
});
Conditional Haptics
function NotificationBadge ({ count } : { count : number }) {
const { trigger , isSupported } = useWebHaptics ();
useEffect (() => {
if ( count > 0 && isSupported ) {
trigger ( 'nudge' );
}
}, [ count , isSupported , trigger ]);
return count > 0 ? < span className = "badge" > { count } </ span > : null ;
}
Preventing Haptic Spam
import { useWebHaptics } from '@accede-ai/webhaptics/react' ;
import { useCallback , useRef } from 'react' ;
function useThrottledHaptic ( minInterval = 100 ) {
const { trigger } = useWebHaptics ();
const lastTriggerRef = useRef ( 0 );
return useCallback (( input ?: HapticInput ) => {
const now = Date . now ();
if ( now - lastTriggerRef . current >= minInterval ) {
trigger ( input );
lastTriggerRef . current = now ;
}
}, [ trigger , minInterval ]);
}
// Usage
function ScrollList () {
const triggerThrottled = useThrottledHaptic ( 150 );
return (
< div onScroll = { () => triggerThrottled ( 'selection' ) } >
{ /* list items */ }
</ div >
);
}
Available Presets
Notification
Impact
Selection
Custom
trigger ( 'success' ) // Ascending double-tap
trigger ( 'warning' ) // Two taps with hesitation
trigger ( 'error' ) // Three rapid harsh taps
The hook automatically manages cleanup, so you don’t need to manually destroy the WebHaptics instance. The trigger and cancel functions are stable references that won’t cause unnecessary re-renders.