import React from "react"; import { StyleProp, ViewStyle, TextStyle, TextInput as NativeTextInput, View, StyleSheet, Platform, } from "react-native"; import TextInput, { TextInputProps } from "../TextInput"; import { CodeField, useClearByFocusCell, } from "react-native-confirmation-code-field"; import type { ReadTheme } from "@draftbit/theme"; import { withTheme } from "@draftbit/theme"; import PinInputText from "./PinInputText"; import { extractStyles } from "../../utilities"; interface CellItem { cellValue: string; index: number; isFocused: boolean; } interface PinInputProps extends Omit { onInputFull?: (value: string) => void; cellCount?: number; clearOnCellFocus?: boolean; blurOnFull?: boolean; renderItem?: ({ cellValue, index, isFocused }: CellItem) => React.JSX.Element; focusedBorderColor?: string; focusedBackgroundColor?: string; focusedBorderWidth?: number; focusedTextColor?: string; style?: StyleProp; className?: string; theme: ReadTheme; } const PinInput = React.forwardRef( ( { theme, onInputFull, cellCount = 4, clearOnCellFocus = true, blurOnFull = true, renderItem, value, onChangeText, focusedBorderColor = theme.colors.branding.primary, focusedBackgroundColor, focusedBorderWidth, focusedTextColor, secureTextEntry, style, className, ...rest }, ref ) => { const newPinInputRef = React.useRef(null); // Use the provided ref or default to new ref when not provided const pinInputRef = ref ? (ref as React.RefObject) : newPinInputRef; const { viewStyles, textStyles } = extractStyles(style); // Clears input of a cell when focused, configured as explained here (https://github.com/retyui/react-native-confirmation-code-field/blob/master/API.md#useclearbyfocuscellvalue-string-setvalue-text-string--void) const [codeFieldProps, getCellOnLayout] = useClearByFocusCell({ value, setValue: (text) => onChangeText?.(text), }); React.useEffect(() => { if (value?.length === cellCount) { if (blurOnFull) { pinInputRef.current?.blur(); } onInputFull?.(value); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [value, cellCount, blurOnFull, pinInputRef]); const renderCell = ( cellValue: string, index: number, isFocused: boolean ) => { if (secureTextEntry && cellValue) { cellValue = "•"; } const cell = renderItem?.({ cellValue, index, isFocused }) || ( {cellValue} ); return React.cloneElement(cell, { onLayout: clearOnCellFocus ? getCellOnLayout(index) : undefined, }); }; return ( // @ts-ignore ); } ); const styles = StyleSheet.create({ rootContainer: { justifyContent: "center", }, cell: { marginLeft: 5, marginRight: 5, padding: 5, borderRadius: 5, justifyContent: "center", alignItems: "center", aspectRatio: 1, maxWidth: 70, maxHeight: 70, borderWidth: 1, flex: 1, }, cellText: { fontSize: 25, }, }); export default withTheme(PinInput);