Browse React Native
React NativeUtilitiesNo. 22 of 22
Haptics
haptic("selection" | "light" | "success" …): a fire-and-forget vibration through expo-haptics that never throws and does nothing on the web, plus setHapticsEnabled() for an app-wide setting.
Preview
Loading the preview
The gallery's web build, through react-native-web. On a phone the same code draws native views.
Installation
First the native modules, in the versions your Expo SDK expects:
npx expo install expo-hapticsThen the item:
npx shadcn@latest add @corsair-native/hapticsInstall the native module for your Expo SDK first: npx expo install expo-haptics
The app's components.json needs the @corsair-native registry first; see Installation. The files land in your project as source: edit them like your own code.
- npm
expo-haptics
API
Read from the source's own comments and types. Props marked * are required.
hapticFunction
Plays a short vibration through expo-haptics. It is fire-and-forget: it does nothing on the web, while turned off with setHapticsEnabled(false), or on a device without a haptic engine, and it never throws. Keep it for moments that answer the user's own touch.
| Parameter | Type | Default |
|---|---|---|
kind
| "selection" | "light" | "medium" | "heavy" | "success" | "warning" | "error" | "selection" |
Returns void.
haptic("selection"); // a star lit up under the finger
haptic("success"); // the booking went throughsetHapticsEnabledFunction
Turns every Corsair haptic on or off at once, for example from a "Vibration" setting.
| Parameter | Type | Default |
|---|---|---|
value * | boolean | — |
Compatibility
- Expo SDK
- 54 and 57, both checked in CI
- React Native
- 0.81 and 0.86, New Architecture
- Web
- Expo's web target, through react-native-web
- Haptics
- expo-haptics; silent on the web
Source
1 file, installed as source you own
haptics.tsView on GitHubimport * as Haptics from "expo-haptics";
import { Platform } from "react-native";
/**
* - `selection`: a tick, for a value stepping (a star, a slider notch).
* - `light` / `medium` / `heavy`: a tap of that weight, for presses and drops.
* - `success` / `warning` / `error`: the result of an action.
*/
type HapticKind = "selection" | "light" | "medium" | "heavy" | "success" | "warning" | "error";
let enabled = true;
/** Turns every Corsair haptic on or off at once, for example from a "Vibration" setting. */
function setHapticsEnabled(value: boolean) {
enabled = value;
}
function play(kind: HapticKind): Promise<void> {
switch (kind) {
case "selection":
return Haptics.selectionAsync();
case "light":
return Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
case "medium":
return Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
case "heavy":
return Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Heavy);
case "success":
return Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
case "warning":
return Haptics.notificationAsync(Haptics.NotificationFeedbackType.Warning);
case "error":
return Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error);
}
}
/**
* Plays a short vibration through expo-haptics. It is fire-and-forget: it
* does nothing on the web, while turned off with `setHapticsEnabled(false)`,
* or on a device without a haptic engine, and it never throws. Keep it for
* moments that answer the user's own touch.
*
* @example
* haptic("selection"); // a star lit up under the finger
* haptic("success"); // the booking went through
*/
function haptic(kind: HapticKind = "selection"): void {
if (!enabled || Platform.OS === "web") return;
try {
play(kind).catch(() => {});
} catch {
// The native module is missing (Expo Go on the web, tests): stay silent.
}
}
export { haptic, setHapticsEnabled, type HapticKind };