Skip to content
Corsair UI
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-haptics

Then the item:

npx shadcn@latest add @corsair-native/haptics

Install 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.

Parameters of haptic
ParameterTypeDefault
kind
  • 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.
"selection" | "light" | "medium" | "heavy" | "success" | "warning" | "error""selection"

Returns void.

haptic("selection"); // a star lit up under the finger
haptic("success"); // the booking went through

setHapticsEnabledFunction

Turns every Corsair haptic on or off at once, for example from a "Vibration" setting.

Parameters of setHapticsEnabled
ParameterTypeDefault
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 GitHub
import * 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 };