ng-haptics
v1.2.0
Published
Angular-native haptic feedback library using Web Vibration API
Maintainers
Readme
ng-haptics
The modern, Angular-native way to add haptic feedback to web applications.
Features
- 🅰️ Angular-native — DI, standalone APIs, Signals-ready
- 🌐 SSR-safe — works with Angular Universal, no
window/navigatoron server - 📦 Zero dependencies — pure Web Vibration API, no Capacitor, no Ionic
- 🎯 Declarative — directives and service for every use case
- 🔍 Support detection — runtime
HapticsService.support()exposes platform/browser/method info - 🛡️ Cooldown protection — built-in throttling prevents accidental vibration spam
- 🪶 Accessible — respects
prefers-reduced-motionby default - 🧪 Debug mode — log clear haptics events when enabled
- 🔬 Testable — adapter pattern makes testing trivial
- 🪶 Tiny — <10kb gzip, tree-shakeable, side-effect free
Installation
npm install ng-hapticsQuick Start
1. Add the provider:
// app.config.ts
import { provideHaptics } from 'ng-haptics';
export const appConfig: ApplicationConfig = {
providers: [
provideHaptics(),
],
};2. Use the service:
import { HapticsService } from 'ng-haptics';
@Component({ ... })
export class MyComponent {
private readonly haptics = inject(HapticsService);
onSave() {
this.haptics.success();
}
}3. Or use directives:
<button ngHapticClick="success">Save</button>
<button ngHapticTap="medium">Submit</button>
<form ngHapticForm successPreset="success" errorPreset="warning" novalidate>
<input name="email" ngModel required placeholder="[email protected]" />
<button type="submit">Submit</button>
</form>API Reference
HapticsService
const haptics = inject(HapticsService);
// Impact presets
haptics.light();
haptics.medium();
haptics.heavy();
// Notification presets
haptics.success();
haptics.warning();
haptics.error();
// UI feedback
haptics.selection();
// Custom pattern (navigator.vibrate format)
haptics.pattern([50, 30, 50]);
// Sequence with delays
await haptics.sequence([
'light',
{ delay: 40 },
'success',
]);
// Check support
haptics.isSupported; // boolean
// Runtime support details
const support = haptics.support();
console.log(support);
// Example support result
// {
// supported: true,
// platform: 'ios',
// method: 'ios-switch',
// browser: 'chrome',
// reducedMotion: false,
// }Directives
| Directive | Event | Example |
|-----------|-------|---------|
| [ngHapticClick] | click | <button ngHapticClick="success"> |
| [ngHapticTap] | pointerdown | <button ngHapticTap="medium"> |
| [ngHapticHover] | pointerenter | <div [ngHapticHover]="'light'"> |
| ngHapticForm | submit | <form ngHapticForm successPreset="success" errorPreset="warning"> |
provideHaptics(config?)
interface HapticsConfig {
enabled?: boolean; // default: true
respectReducedMotion?: boolean; // default: true
debug?: boolean; // default: false
cooldown?: number; // ms, default: 0
}provideHaptics({
debug: !environment.production,
cooldown: 40,
respectReducedMotion: true,
});debug enables console logging in development, cooldown prevents accidental vibration spam, and respectReducedMotion keeps haptics silent for users who opt into reduced motion.
Browser Support
| Platform | Support | |----------|---------| | Android Chrome / Firefox | ✅ Full (Web Vibration API) | | iOS Safari / Chrome | ✅ Full (WebKit switch trick) | | Desktop browsers | — Silent no-op (no haptic hardware) | | SSR / Node.js | — Silent no-op |
Note:
ng-hapticsreports runtime support withHapticsService.support(), and it respectsprefers-reduced-motionby default unless disabled viaprovideHaptics({ respectReducedMotion: false }).
Architecture
HapticsService
↓
HapticsAdapter (interface)
↓
WebVibrationAdapter IosSwitchAdapter NoopAdapter
(Android/Firefox) (iOS Safari/Chrome) (SSR/desktop)
navigator.vibrate() <input switch>.click()The adapter pattern cleanly separates the Angular API from the browser implementation, making testing, SSR, and future extensions straightforward.
Development
# Install
npm install
# Run demo (with hot reload)
npm start
# Run demo accessible from mobile on local network
npm run start:host
# Tests
npm test
# Build library
npm run build
# Lint
npm run lintContributing
Pull requests are welcome. Please follow Conventional Commits for commit messages.
License
MIT © Nicolás Giacconi
