react-native-haptic-feedback
Version:
Basic haptic feedback for iOS and android
110 lines (108 loc) • 4.01 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _types = require("./types");
/**
* Web platform implementation of react-native-haptic-feedback.
* Uses the Web Vibration API (navigator.vibrate) where supported.
* Silently no-ops on browsers that don't support vibration.
*/
// Duration map for single-pulse haptics (milliseconds)
const WEB_DURATION = {
[_types.HapticFeedbackTypes.impactLight]: 20,
[_types.HapticFeedbackTypes.impactMedium]: 40,
[_types.HapticFeedbackTypes.impactHeavy]: 60,
[_types.HapticFeedbackTypes.rigid]: 50,
[_types.HapticFeedbackTypes.soft]: 15,
[_types.HapticFeedbackTypes.selection]: 15,
[_types.HapticFeedbackTypes.notificationSuccess]: [30, 40, 20],
[_types.HapticFeedbackTypes.notificationWarning]: [20, 40, 30],
[_types.HapticFeedbackTypes.notificationError]: [20, 30, 30, 30, 40],
[_types.HapticFeedbackTypes.effectClick]: 20,
[_types.HapticFeedbackTypes.effectDoubleClick]: [20, 40, 20],
[_types.HapticFeedbackTypes.effectHeavyClick]: 50,
[_types.HapticFeedbackTypes.effectTick]: 15,
[_types.HapticFeedbackTypes.clockTick]: 15,
[_types.HapticFeedbackTypes.contextClick]: 20,
[_types.HapticFeedbackTypes.keyboardPress]: 20,
[_types.HapticFeedbackTypes.keyboardRelease]: 10,
[_types.HapticFeedbackTypes.keyboardTap]: 20,
[_types.HapticFeedbackTypes.longPress]: 40,
[_types.HapticFeedbackTypes.textHandleMove]: 10,
[_types.HapticFeedbackTypes.virtualKey]: 20,
[_types.HapticFeedbackTypes.virtualKeyRelease]: 10,
[_types.HapticFeedbackTypes.confirm]: [30, 40, 20],
[_types.HapticFeedbackTypes.reject]: [50, 40, 30],
[_types.HapticFeedbackTypes.gestureStart]: 15,
[_types.HapticFeedbackTypes.gestureEnd]: 20,
[_types.HapticFeedbackTypes.segmentTick]: 10,
[_types.HapticFeedbackTypes.segmentFrequentTick]: 8,
[_types.HapticFeedbackTypes.toggleOn]: [15, 30, 25],
[_types.HapticFeedbackTypes.toggleOff]: [25, 30, 15],
[_types.HapticFeedbackTypes.dragStart]: 15,
[_types.HapticFeedbackTypes.gestureThresholdActivate]: 20,
[_types.HapticFeedbackTypes.gestureThresholdDeactivate]: 10
// noHaptics: intentionally absent — no vibration
};
function vibrate(pattern) {
if (typeof navigator !== "undefined" && "vibrate" in navigator) {
navigator.vibrate(pattern);
}
}
let _enabled = true;
const RNHapticFeedback = {
setEnabled(value) {
_enabled = value;
},
isEnabled() {
return _enabled;
},
trigger(type = _types.HapticFeedbackTypes.selection, _options = {}) {
if (!_enabled) return;
const pattern = WEB_DURATION[type] ?? 40;
vibrate(pattern);
},
stop() {
if (typeof navigator !== "undefined" && "vibrate" in navigator) {
navigator.vibrate(0);
}
},
isSupported() {
return typeof navigator !== "undefined" && "vibrate" in navigator;
},
triggerPattern(events, _options = {}) {
if (!_enabled) return;
if (!events.length) return;
const sorted = [...events].sort((a, b) => a.time - b.time);
const pattern = [];
let prevEnd = 0;
for (const evt of sorted) {
const gap = Math.max(0, evt.time - prevEnd);
const duration = evt.duration ?? 50;
pattern.push(gap, duration);
prevEnd = evt.time + duration;
}
vibrate(pattern);
},
impact(type = _types.HapticFeedbackTypes.impactMedium, intensity = 0.7, _options = {}) {
if (!_enabled) return;
const base = WEB_DURATION[type] ?? 40;
const clamped = Math.max(0, Math.min(1, intensity));
const pattern = Array.isArray(base) ? base.map(d => Math.round(d * clamped)) : Math.round(base * clamped);
vibrate(pattern);
},
playAHAP(_fileName) {
return Promise.resolve();
},
async getSystemHapticStatus() {
const supported = typeof navigator !== "undefined" && "vibrate" in navigator;
return {
vibrationEnabled: supported,
ringerMode: null
};
}
};
var _default = exports.default = RNHapticFeedback;
//# sourceMappingURL=hapticFeedback.web.js.map