react-native-keypad-component
Version:
Customizable keypad component for react native
229 lines (228 loc) • 9.42 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = Keypad;
var _react = _interopRequireWildcard(require("react"));
var _reactNative = require("react-native");
var _reactNativeReanimated = _interopRequireWildcard(require("react-native-reanimated"));
var _constants = require("./constants.js");
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
function Keypad({
onPinEntered,
onPinErrored,
errorMessageComponent,
pinLength = _constants.DEFAULTS.pinLength,
containerStyle,
buttonStyle,
buttonTextStyle,
keypadTextSize = _constants.DEFAULTS.keypadTextSize,
disableKeypadBackground = _constants.DEFAULTS.displayKeypadBg,
usesFaceId = _constants.DEFAULTS.useFaceId,
keypadRadius = _constants.DEFAULTS.borderRadius,
theme = _constants.DEFAULTS.theme,
activeDotColor,
emptyDotColor = _constants.DEFAULTS.emptyDotColor,
keypadColor,
textColor,
dotWidth = _constants.DEFAULTS.dotWidth,
dotHeight = _constants.DEFAULTS.dotHeight,
gridGap = _constants.DEFAULTS.gridGap,
renderFaceIdIcon,
applyBackgroundToFaceIdButton = _constants.DEFAULTS.applyFaceIdButtonBackground
}) {
const isDarkTheme = theme === 'dark';
const dotColor = isDarkTheme ? _constants.DEFAULTS.dotColorDark : _constants.DEFAULTS.dotColorLight;
const defaultTextColor = isDarkTheme ? _constants.DEFAULTS.textColorDark : _constants.DEFAULTS.textColorLight;
const defaultKeypadColor = isDarkTheme ? _constants.DEFAULTS.keyboardColorDark : _constants.DEFAULTS.keyboardColorLight;
const [pin, setPin] = (0, _react.useState)('');
const offset = (0, _reactNativeReanimated.useSharedValue)(0);
const animatedStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
return {
transform: [{
translateX: offset.value
}]
};
});
const dotScales = [(0, _reactNativeReanimated.useSharedValue)(1), (0, _reactNativeReanimated.useSharedValue)(1), (0, _reactNativeReanimated.useSharedValue)(1), (0, _reactNativeReanimated.useSharedValue)(1)];
const animatedDotStyles = [(0, _reactNativeReanimated.useAnimatedStyle)(() => ({
transform: [{
scale: dotScales[0]?.value ?? 1
}]
})), (0, _reactNativeReanimated.useAnimatedStyle)(() => ({
transform: [{
scale: dotScales[1]?.value ?? 2
}]
})), (0, _reactNativeReanimated.useAnimatedStyle)(() => ({
transform: [{
scale: dotScales[2]?.value ?? 3
}]
})), (0, _reactNativeReanimated.useAnimatedStyle)(() => ({
transform: [{
scale: dotScales[3]?.value ?? 4
}]
}))];
const applyShakeAnimation = (0, _react.useCallback)(() => {
offset.value = (0, _reactNativeReanimated.withSequence)((0, _reactNativeReanimated.withTiming)(-_constants.ANIMATION_VALUES.offset, {
duration: _constants.ANIMATION_VALUES.timing / 2
}), (0, _reactNativeReanimated.withRepeat)((0, _reactNativeReanimated.withTiming)(_constants.ANIMATION_VALUES.offset, {
duration: _constants.ANIMATION_VALUES.timing
}), 4, true), (0, _reactNativeReanimated.withTiming)(0, {
duration: _constants.ANIMATION_VALUES.timing / 2
}));
}, [offset]);
(0, _react.useEffect)(() => {
if (onPinErrored) {
applyShakeAnimation();
}
}, [onPinErrored, applyShakeAnimation]);
function handlePress(digit) {
const newPin = pin + digit;
if (newPin.length <= pinLength) {
setPin(newPin);
const nextIndex = newPin.length - 1;
const dot = dotScales[nextIndex];
if (dot) {
dot.value = (0, _reactNativeReanimated.withSequence)((0, _reactNativeReanimated.withTiming)(1.2, {
duration: 100
}), (0, _reactNativeReanimated.withTiming)(1, {
duration: 100
}));
}
if (newPin.length === pinLength) {
onPinEntered(newPin);
setTimeout(() => setPin(''), 200);
}
}
}
function handleDelete() {
if (pin.length > 0) {
const indexToAnimate = pin.length - 1;
const dot = dotScales[indexToAnimate];
if (dot) {
dot.value = (0, _reactNativeReanimated.withSequence)((0, _reactNativeReanimated.withTiming)(1.2, {
duration: 100
}), (0, _reactNativeReanimated.withTiming)(1, {
duration: 100
}));
}
setPin(prev => prev.slice(0, -1));
}
}
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: [styles.container, containerStyle],
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
style: [styles.dotsContainer, animatedStyle],
children: Array.from({
length: pinLength
}).map((_, index) => {
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
testID: index < pin.length ? 'pin-dot-filled' : 'pin-dot',
style: [styles.dot, {
backgroundColor: index < pin.length ? activeDotColor ?? dotColor : emptyDotColor,
borderRadius: keypadRadius,
width: dotWidth,
height: dotHeight
}, animatedDotStyles[index]]
}, index);
})
}), onPinErrored && errorMessageComponent && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
layout: _reactNativeReanimated.LinearTransition.springify().damping(_constants.ANIMATION_VALUES.damping),
entering: _reactNativeReanimated.ZoomIn,
exiting: _reactNativeReanimated.ZoomOut,
style: {
marginBottom: 10
},
children: errorMessageComponent()
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
layout: _reactNativeReanimated.LinearTransition.springify().damping(_constants.ANIMATION_VALUES.damping),
style: [styles.grid, {
gap: gridGap
}],
children: ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'face', '0', 'del'].map((key, index) => {
if (key === 'face') {
return usesFaceId ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.Fragment, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
activeOpacity: 0.6,
style: [styles.button, {
borderRadius: keypadRadius,
backgroundColor: disableKeypadBackground ? 'transparent' : applyBackgroundToFaceIdButton ? buttonStyle && buttonStyle.backgroundColor || keypadColor || defaultKeypadColor : 'transparent'
}, buttonStyle],
children: renderFaceIdIcon ? renderFaceIdIcon() : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
children: "\uD83D\uDD10"
})
})
}, key) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: [styles.button, {
backgroundColor: disableKeypadBackground ? 'transparent' : keypadColor ?? defaultKeypadColor,
borderRadius: keypadRadius,
opacity: 0
}]
}, index);
}
if (key === 'del') {
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
activeOpacity: 0.6,
style: [styles.button, {
backgroundColor: disableKeypadBackground ? 'transparent' : keypadColor ?? defaultKeypadColor,
borderRadius: keypadRadius
}, buttonStyle],
onPress: handleDelete,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
style: [{
color: textColor ?? defaultTextColor,
fontSize: keypadTextSize
}, buttonTextStyle],
children: "\u232B"
})
}, key);
}
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
activeOpacity: 0.6,
testID: `key-${key}`,
style: [styles.button, {
backgroundColor: disableKeypadBackground ? 'transparent' : keypadColor ?? defaultKeypadColor,
borderRadius: keypadRadius
}, buttonStyle],
onPress: () => handlePress(key),
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
style: [{
color: textColor ?? defaultTextColor,
fontSize: keypadTextSize
}, buttonTextStyle],
children: key
})
}, index);
})
})]
});
}
const styles = _reactNative.StyleSheet.create({
container: {
alignItems: 'center'
},
dotsContainer: {
flexDirection: 'row',
marginBottom: 20,
gap: 5
},
dot: {
margin: 8,
borderRadius: 8
},
grid: {
flexDirection: 'row',
flexWrap: 'wrap',
width: 240,
justifyContent: 'center'
},
button: {
width: 60,
height: 60,
margin: 5,
justifyContent: 'center',
alignItems: 'center'
}
});
//# sourceMappingURL=index.js.map