@brainsbeards/react-native-animated-code-input
Version:
Animated code input component for React Native, with support for iOS, Android, and React Native Web. It works with one-time code autofill on iOS and Android.
149 lines (148 loc) • 6.66 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.InputSingleItem = void 0;
const react_1 = __importStar(require("react"));
const react_native_1 = require("react-native");
const DEFAULT_BACKGROUND_COLOR = "#F3F0F3";
const NUMBER_ANIMATION_DURATION = 300;
const CURSOR_ANIMATION_DURATION = 500;
const DEFAULT_CURSOR_COLOR = "#4A72FF";
const DEFAULT_WIDTH = 55;
const DEFAULT_HEIGHT = 70;
const DEFAULT_FONT_SIZE = 30;
const DEFAULT_FONT_WEIGHT = "bold";
const DEFAULT_AFTER_INPUT_DELAY = 50;
const DEFAULT_TEXT_COLOR = "black";
exports.InputSingleItem = (props) => {
const [textValue, setTextValue] = react_1.useState("");
const [animatedValue, setAnimatedValue] = react_1.useState(new react_native_1.Animated.Value(0));
const [animatedValueCursor, setAnimatedValueCursor] = react_1.useState(new react_native_1.Animated.Value(0));
const { activeCodeContainerStyle, value, codeAnimationDuration, codeContainerStyle, cursorAnimationDuration, cursorStyle, index, textColor, afterInputDelay, } = props;
const start = react_1.useCallback(() => {
react_native_1.Animated.timing(animatedValue, {
toValue: 1,
duration: codeAnimationDuration
? codeAnimationDuration
: NUMBER_ANIMATION_DURATION,
useNativeDriver: true,
}).start();
}, [animatedValue, codeAnimationDuration]);
const startCursor = react_1.useCallback(() => {
react_native_1.Animated.timing(animatedValueCursor, {
toValue: 1,
duration: cursorAnimationDuration
? cursorAnimationDuration
: CURSOR_ANIMATION_DURATION,
useNativeDriver: true,
}).start(() => {
react_native_1.Animated.timing(animatedValueCursor, {
toValue: 0,
duration: cursorAnimationDuration
? cursorAnimationDuration
: CURSOR_ANIMATION_DURATION,
useNativeDriver: true,
}).start(() => {
startCursor();
});
});
}, [animatedValueCursor, cursorAnimationDuration]);
const resetAnimationAfterDelete = react_1.useCallback(() => {
setAnimatedValueCursor(new react_native_1.Animated.Value(0));
setAnimatedValue(new react_native_1.Animated.Value(0));
}, []);
react_1.useEffect(() => {
const currentIndex = index ? index : 0;
const text = value.length <= currentIndex ? "" : value.substr(currentIndex, 1);
if (text.length < textValue.length) {
resetAnimationAfterDelete();
}
setTextValue(text);
if (text.length === 1) {
setTimeout(() => {
start();
}, afterInputDelay ? afterInputDelay : DEFAULT_AFTER_INPUT_DELAY);
}
}, [
value,
index,
afterInputDelay,
start,
textValue,
resetAnimationAfterDelete,
]);
react_1.useEffect(() => {
if (textValue.length === 0) {
setTimeout(() => {
startCursor();
}, afterInputDelay ? afterInputDelay : DEFAULT_AFTER_INPUT_DELAY);
}
}, [textValue, afterInputDelay, startCursor]);
return (react_1.default.createElement(react_native_1.View, { style: value.length === index
? [
styles.codeContainer,
activeCodeContainerStyle,
activeCodeContainerStyle === null || activeCodeContainerStyle === void 0 ? void 0 : activeCodeContainerStyle.customStyle,
]
: [
styles.codeContainer,
codeContainerStyle,
codeContainerStyle === null || codeContainerStyle === void 0 ? void 0 : codeContainerStyle.customStyle,
], key: `code-field ${index ? index : 0}` },
react_1.default.createElement(react_native_1.Animated.View, { style: {
opacity: animatedValue,
} },
react_1.default.createElement(react_native_1.Text, { style: [
{
fontSize: (codeContainerStyle === null || codeContainerStyle === void 0 ? void 0 : codeContainerStyle.inputFontSize) ? codeContainerStyle === null || codeContainerStyle === void 0 ? void 0 : codeContainerStyle.inputFontSize : DEFAULT_FONT_SIZE,
fontWeight: (codeContainerStyle === null || codeContainerStyle === void 0 ? void 0 : codeContainerStyle.fontWeight) ? codeContainerStyle === null || codeContainerStyle === void 0 ? void 0 : codeContainerStyle.fontWeight : DEFAULT_FONT_WEIGHT,
color: textColor ? textColor : DEFAULT_TEXT_COLOR,
},
] }, textValue)),
textValue.length === 0 && value.length === index && (react_1.default.createElement(react_native_1.Animated.View, { style: {
opacity: animatedValueCursor,
} },
react_1.default.createElement(react_native_1.Text, { style: [styles.cursor, cursorStyle, cursorStyle === null || cursorStyle === void 0 ? void 0 : cursorStyle.customStyle] }, "|")))));
};
const styles = react_native_1.StyleSheet.create({
codeContainer: {
justifyContent: "center",
alignItems: "center",
width: DEFAULT_WIDTH,
height: DEFAULT_HEIGHT,
borderWidth: 1,
borderRadius: 10,
borderColor: DEFAULT_BACKGROUND_COLOR,
backgroundColor: DEFAULT_BACKGROUND_COLOR,
},
cursor: {
fontSize: 35,
width: DEFAULT_WIDTH,
height: DEFAULT_HEIGHT,
marginLeft: 20,
marginTop: react_native_1.Platform.select({
ios: 10,
android: -20,
}),
color: DEFAULT_CURSOR_COLOR,
},
});
exports.default = exports.InputSingleItem;