Coder Social home page Coder Social logo

retyui / react-native-confirmation-code-field Goto Github PK

View Code? Open in Web Editor NEW

This project forked from ttdung11t2/react-native-confirmation-code-input

1.0K 5.0 117.0 11.58 MB

A react-native confirmation code field compatible with iOS, Android and Web

License: MIT License

JavaScript 4.08% TypeScript 95.92%
react-native react-native-component react-native-library code-verification react-native-web otp-inputs one-time-password android ios pin-code

react-native-confirmation-code-field's Introduction

react-native-confirmation-code-field

react-native-confirmation-code-field on npm react-native-confirmation-code-field downloads react-native-confirmation-code-field install size CI status

A simple react-native confirmation code field compatible with iOS, Android.

Links

Component features:

  • ๐Ÿ”ฎ Simple and tiny 3.8 KB. Easy to use;
  • ๐Ÿšฎ Clearing part of the code by clicking on the cell;
  • ๐ŸŽ Support "fast paste SMS-code" on iOS. And custom code paste for Android;
  • โšก TextInput ref support;
  • ๐Ÿ›  Highly customizable. Can be used as masked TextInput;
  • ๐Ÿค“ Readable changelog.

Screenshots

react-native-confirmation-code-field animated example react-native-confirmation-code-field mask example
react-native-confirmation-code-field unmask example
react-native-confirmation-code-field underline example
react-native-confirmation-code-field formatting example

Install

yarn add react-native-confirmation-code-field

How it works

I use an invisible <TextInput/> component that will be stretched over <Cell/> components.

JSX structure looks like that:

// Root view (rectangle with a red border on 3d visualization below)
<View style={rootStyle}>
  // Each Cell element is result of a `renderCell` function (gray boxes)
  <Cell>1</Cell>
  <Cell>2</Cell>
  <Cell>3</Cell>
  <Cell>|</Cell>
  <Cell></Cell>
  <Cell></Cell>
  // Invisible Text Input with absolute position (gray rectangle with text '123')
  <TextInput value="123"/>
</View>

3d layout of component

It needs to solve next problems:

  • When user pastes code from SMS on iOS issue#25
  • Better UX when user types fast, or system sluggish, characters might lost when component switching focus between <TextInput/>.

Basic example

I took a minimal implementation approach. It mean that this component provides low-level functionality so you can create incredible UI without tears ๐Ÿ˜ญ. I recommend you start with creating your own wrapper where you apply all styles and basic configuration.

You can use a ready-made solution out of the box:

import React, {useState} from 'react';
import {SafeAreaView, Text, StyleSheet} from 'react-native';

import {
  CodeField,
  Cursor,
  useBlurOnFulfill,
  useClearByFocusCell,
} from 'react-native-confirmation-code-field';

const styles = StyleSheet.create({
  root: {flex: 1, padding: 20},
  title: {textAlign: 'center', fontSize: 30},
  codeFieldRoot: {marginTop: 20},
  cell: {
    width: 40,
    height: 40,
    lineHeight: 38,
    fontSize: 24,
    borderWidth: 2,
    borderColor: '#00000030',
    textAlign: 'center',
  },
  focusCell: {
    borderColor: '#000',
  },
});

const CELL_COUNT = 6;

const App = () => {
  const [value, setValue] = useState('');
  const ref = useBlurOnFulfill({value, cellCount: CELL_COUNT});
  const [props, getCellOnLayoutHandler] = useClearByFocusCell({
    value,
    setValue,
  });

  return (
    <SafeAreaView style={styles.root}>
      <Text style={styles.title}>Verification</Text>
      <CodeField
        ref={ref}
        {...props}
        // Use `caretHidden={false}` when users can't paste a text value, because context menu doesn't appear
        value={value}
        onChangeText={setValue}
        cellCount={CELL_COUNT}
        rootStyle={styles.codeFieldRoot}
        keyboardType="number-pad"
        textContentType="oneTimeCode"
        autoComplete={Platform.select({ android: 'sms-otp', default: 'one-time-code' })}
        testID="my-code-input"
        renderCell={({index, symbol, isFocused}) => (
          <Text
            key={index}
            style={[styles.cell, isFocused && styles.focusCell]}
            onLayout={getCellOnLayoutHandler(index)}>
            {symbol || (isFocused ? <Cursor/> : null)}
          </Text>
        )}
      />
    </SafeAreaView>
  );
};

export default App;

Compatibility

For [email protected] and below use yarn add react-native-confirmation-code-field@6, otherwise use the latest version yarn add react-native-confirmation-code-field

react-native-confirmation-code-field's People

Contributors

arvinio avatar bamlhs avatar codebutler avatar denisfrezzato avatar francescopersico avatar joelwee avatar leozzitowned avatar murtraja avatar muslumsezgin avatar necipallef avatar paitoanderson avatar reedyrm avatar retyui avatar salomaoluiz avatar ttdung11t2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

react-native-confirmation-code-field's Issues

Issue with testID

Hello,
I'm trying to add a testID to my CodeInput but it's not working, it seems that it's not added to the input nor anywhere else in the view.

Here is my code:

<CodeInput
     ref="codeInput"
     activeColor='rgba(0, 0, 0, 1)'
     codeLength={4}
     keyboardType="number-pad"
     inactiveColor='rgba(0, 0, 0, 1.3)'
     autoFocus={true}
     inputPosition='center'
     testID="code_input"
     size={56}
     onFulfill={(code) => this._onFinishCheckingCode1(code)}
     containerProps={{ marginTop: 20 }} />

Am I doing something wrong?
Thanks in advance :)

Spread operator over string is not supported on device

I'm running into an issue in production with the library with the following stack trace.

TypeError: Invalid attempt to spread non-iterable instance
  at taggedTemplateLiteralLoose(node_modules/react-native/Libraries/polyfills/babelHelpers.js:498:23)
  at toConsumableArray(node_modules/react-native/Libraries/polyfills/babelHelpers.js:568:14)
  at onChangeText(node_modules/react-native-confirmation-code-field/src/components/ConfirmationCodeInput/ConfirmationCodeInput.js:222:28)
  at onChangeText(node_modules/react-native-confirmation-code-field/src/components/TextInput/TextInput.js:16:47)
  at apply(node_modules/react-native/Libraries/Components/TextInput/TextInput.js:1119:43)
  at invokeGuardedCallbackImpl(node_modules/react-native/Libraries/Renderer/oss/ReactNativeRenderer-prod.js:47:10)
  at invokeGuardedCallback(node_modules/react-native/Libraries/Renderer/oss/ReactNativeRenderer-prod.js:65:29)
  at invokeGuardedCallbackAndCatchFirstError(node_modules/react-native/Libraries/Renderer/oss/ReactNativeRenderer-prod.js:78:25)
  at executeDispatch(node_modules/react-native/Libraries/Renderer/oss/ReactNativeRenderer-prod.js:172:3)
  at executeDispatchesAndReleaseTopLevel(node_modules/react-native/Libraries/Renderer/oss/ReactNativeRenderer-prod.js:221:9)
  at forEachAccumulated(node_modules/react-native/Libraries/Renderer/oss/ReactNativeRenderer-prod.js:205:59)
  at fn(node_modules/react-native/Libraries/Renderer/oss/ReactNativeRenderer-prod.js:1065:8)
  at _batchedUpdatesImpl(node_modules/react-native/Libraries/Renderer/oss/ReactNativeRenderer-prod.js:5841:12)
  at batchedUpdates(node_modules/react-native/Libraries/Renderer/oss/ReactNativeRenderer-prod.js:1026:12)
  at _receiveRootNodeIDEvent(node_modules/react-native/Libraries/Renderer/oss/ReactNativeRenderer-prod.js:1046:3)
  at getTime(node_modules/react-native/Libraries/Renderer/oss/ReactNativeRenderer-prod.js:1083:5)
  at _this2(node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:355:34)
  at DebuggerInternal(node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:116:5)
  at flushedQueue(node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:312:14)
  at value(node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:109:17)

The source map shows that line

const newCodeSymbols = this.normalizeNewCode([...codeSymbols, ...text]);

is failing. I had canPasteCode=true and the user was able to type 2 characters into the same box which is when the error occurred. It looks like the react-native polyfill doesn't see text as an iteratable array. I'm not sure what version of javascript is running on the device, but its Android Samsung S7.

I was trying to replicate it on an emulator, but I'm not having much luck.

Changing
...text
to
...text.split()
guarantees that that string is turned into a list of characters and copied into the new array.

Text and cursor are misaligned when using big font sizes

Hello,

Using basic options + custom styling with cellProps={{ style: {} }} to change the font size, I have strange behaviours on Android and iOS.

iOS
Small font: OK
Screenshot 2019-05-24 at 17 34 35

Big font: KO, the cursor is not vertically centered
Screenshot 2019-05-24 at 17 32 35

Android
Small font: OK
Screenshot_20190524-174553

Big font: KO, the text is cropped and the cursor is misaligned
Screenshot_20190524-175340

I tried to play with padding, lineHeight, and other props, but without success.

Animated example failed to show Verification button and input keyboard

I am copying the animated example code from https://github.com/retyui/react-native-confirmation-code-field/blob/master/examples/src/realDemo/AnimatedExample/README.md. But there are a few issues. I don't understand how exactly the code works. Here is the animated scrren on android:

Capture

Mine is missing Verification button and also clicking the code box does not enable the input keyboard. I think I copy the exact code. Here is my code (except a few name changes):

export default class Verif extends React.Component {
static navigationOptions = {
title: 'ๆ ธๅฏน้ชŒ่ฏ็ '
};

/* constructor(props) {
    super(props);
    console.log("Props in Verif : ", this.props);
    
    this.state = {
      
    };
}; */

_animationsColor = [...new Array(codeLength)].map(
    () => new Animated.Value(0),
  );
_animationsScale = [...new Array(codeLength)].map(
() => new Animated.Value(1),
);

onFinishCheckingCode = code => {
    if (code !== '1234') {
      return Alert.alert(
        'Confirmation Code',
        'Code not match! Try 1234',
        [{ text: 'OK' }],
        { cancelable: false },
      );
    }

    Alert.alert('Confirmation Code', 'Successful!', [{ text: 'OK' }], {
      cancelable: false,
    });
};

animateCell({ hasValue, index, isFocused }) {
    Animated.parallel([
      Animated.timing(this._animationsColor[index], {
        toValue: isFocused ? 1 : 0,
        duration: 250,
      }),
      Animated.spring(this._animationsScale[index], {
        toValue: hasValue ? 0 : 1,
        duration: hasValue ? 300 : 250,
      }),
    ]).start();
}

cellProps = ({ hasValue, index, isFocused }) => {
    const animatedCellStyle = {
      backgroundColor: hasValue
        ? this._animationsScale[index].interpolate({
            inputRange: [0, 1],
            outputRange: [NOT_EMPTY_CELL_BG_COLOR, ACTIVE_CELL_BG_COLOR],
          })
        : this._animationsColor[index].interpolate({
            inputRange: [0, 1],
            outputRange: [DEFAULT_CELL_BG_COLOR, ACTIVE_CELL_BG_COLOR],
          }),
      borderRadius: this._animationsScale[index].interpolate({
        inputRange: [0, 1],
        outputRange: [CELL_SIZE, CELL_BORDER_RADIUS],
      }),
      transform: [
        {
          scale: this._animationsScale[index].interpolate({
            inputRange: [0, 1],
            outputRange: [0.2, 1],
          }),
        },
      ],
    };

    // Run animation on next event loop tik
    // Because we need first return new style prop and then animate this value
    setTimeout(() => {
      this.animateCell({ hasValue, index, isFocused });
    }, 0);

    return {
      style: [styles.input, animatedCellStyle],
    };
};

containerProps = { style: styles.inputWrapStyle };

render() {
    return (
        <View style={styles.inputWrapper}>
          <Text style={styles.inputLabel}>Verification</Text>
          <Image style={styles.icon} source={source} />
          <Text style={styles.inputSubLabel}>
            {'่พ“ๅ…ฅ็Ÿญไฟกๆ”ถๅˆฐ็š„้ชŒ่ฏ็ '}
          </Text>
          <CodeFiled
            maskSymbol="*"
            variant="clear"
            codeLength={codeLength}
            keyboardType="numeric"
            cellProps={this.cellProps}
            containerProps={this.containerProps}
            onFulfill={this.onFinishCheckingCode}
            CellComponent={Animated.Text}
          />
          <View style={styles.nextButton}>
            <Text style={styles.nextButtonText}>Verify</Text>
          </View>
        </View>
    );
}

}

What I am missing here?

Focus Order Issue

Thanks for the update to support cell props, was very helpful!

I have a new problem now that I've been trying to fix for the last day and a half, but can't figure out. The TextInputCustom gets pinched between the 1st and 3rd Cell when I'm going through it with the screen reader focus. The 2nd cell gets pushed out to the end.

So when I focus it goes like this:
Cell 1, TextInputCustom, Cell 3, Cell 4, Cell 5, Cell 6, Cell 7, Cell 2

Tried working around it with tab index and aria-hidden but it hasn't worked. I thought maybe it was a render order issue and tried doing converting it into async, but couldn't get that working ( still a beginner here). The last idea I have is to add an offset option to so that the element moves out of the way, but the findindex and other functions compensate for the offset position.

How to get the keyboard back after dismiss()?

I've got a TouchableWithoutFeedback that dismisses the keyboard. If this happens, and I click on the first input box for the code, the keyboard doesn't come back and I can't input again.

What am I missing?

Desynchronized onFocus and setState

This is an amazing library, however I have ran into a problem while making it work for web using react-native-web (it works perfectly fine on android)

The problem is that after inputting a character, it stays on the 1st Input. After inputting 2nd character, it goes to the next. I tried to understand the problem by keeping logs and i found the following

  1. Input is given to the 1st widget
  2. Forcing focus to be on the next (2nd) widget (<--- A)
  3. onFocus again forces the focus to be on the 1st widget because state isn't updated (yet) (<---C)
  4. The second step now continues and sets the state which was not updated above (<---B)

Please go through the logs below to better understand the situation.

[rnccf][handlerOnFocus] index:  0 
[rnccf][onKeyPress] 
[rnccf][onInputCode] character,index:  7 0 
[rnccf][onInputCode] calling setFocus                <--- A
[rnccf][setFocus] index:  1 
[rnccf][handlerOnFocus] index:  1 
[rnccf][handlerOnFocus] calling setFocus          <--- C
[rnccf][setFocus] index:  0 
[rnccf][handlerOnFocus] index:  0 
[rnccf][onInputCode] calling setState                 <--- B
[rnccf][onInputCode] setState completed

Clearly, the sequence should have been A then B then C.

Do you have any ideas regarding how can this be fixed for the web at the same time not breaking it for native?

P.S. the complete code used to produce the logs:

Code

// @flow
import React, { PureComponent } from 'react';
import { View, TextInput as TextInputNative, StyleSheet } from 'react-native';
import PropTypes from 'prop-types';

import { getClassStyle, getInputSpaceStyle, isMatchingCode } from '../../utils';
import TextInput from '../TextInput';
import { getContainerStyle, styles } from './styles';
import { validateCompareCode, validateInputProps } from './validation';

import type { SyntheticEvent } from 'react-native/Libraries/Types/CoreEventTypes';
import type { VariantNames, INDEX } from '../../types';
import type { Props, State } from './types';

// eslint-disable-next-line
type DP = typeof ConfirmationCodeInput.defaultProps;

const getDefaultCodeSymbols: number => Array<string> = codeLength =>
  new Array(codeLength).fill('');

export default class ConfirmationCodeInput extends PureComponent<
  $Diff<Props, DP> & $Shape<DP>,
  State,
> {
  styles: Object;

  constructor(...args: any) {
    super(...args);

    const { defaultCode, codeLength, size } = this.props;

    this.state = {
      codeSymbols:
        typeof defaultCode === 'string'
          ? defaultCode.split('')
          : getDefaultCodeSymbols(codeLength),
      currentIndex: 0,
    };

    this.styles = StyleSheet.create({
      input: {
        width: size,
        height: size,
      },
      container: { height: size },
    });
  }

  onChangeCb = () => {
    //console.log("[rnccf][onChangeCb] ");
    const { onChangeCode } = this.props;

    if (onChangeCode) {
      onChangeCode(this.state.codeSymbols.join(''));
    }
  };

  clear() {
    this.setState(
      {
        currentIndex: 0,
        codeSymbols: getDefaultCodeSymbols(this.props.codeLength),
      },
      () => {
        this.setFocus(0);
      },
    );
  }

  detectFirstFocus: boolean = false;

  handlerOnFocus = (index: INDEX) => {
    console.log("[rnccf][handlerOnFocus] index: ", index);
    const newCodeArr = [...this.state.codeSymbols];
    const currentEmptyIndex = newCodeArr.findIndex(c => !c);

    if (currentEmptyIndex !== -1 && currentEmptyIndex < index) {
    console.log("[rnccf][handlerOnFocus] calling setFocus");
      return this.setFocus(currentEmptyIndex);
    }

    this.setState(
      {
        codeSymbols: newCodeArr.map((e, ind) => {
          if (ind >= index) {
            return '';
          }

          return e;
        }),
        currentIndex: index,
      },
      () => {
        if (this.detectFirstFocus) {
          this.onChangeCb();
        } else {
          this.detectFirstFocus = true;
        }
      },
    );
  };

  getClassStyle(variant: VariantNames, active: boolean) {
    const {
      activeColor,
      cellBorderWidth,
      inactiveColor,
      inputPosition,
      space,
    } = this.props;

    return getClassStyle(variant, active, {
      activeColor,
      cellBorderWidth,
      inactiveColor,
      inputSpaceStyle: getInputSpaceStyle(space, inputPosition),
    });
  }

  static IOS_MINIMAL_DELAY = 20;

  lastKeyEventTimestamp: number = 0;

  onKeyPress = (e: SyntheticEvent<*>) => {
    console.log("[rnccf][onKeyPress]");
    if (e.nativeEvent.key === 'Backspace') {
      /**
       * Due to a bug in RN iOS TextInput implementation, an unwanted backspace
       * event is fired on key press after clearing out the text input.
       * Typically this backspace event follows the actual event
       * and the time duration is under 10ms.
       * Added a check to see if we receive a backspace event under ~20ms
       * after the last key press event. If found, do nothing.
       *
       * Bug link: https://github.com/facebook/react-native/issues/18374
       */
      if (
        Math.abs(this.lastKeyEventTimestamp - e.timeStamp) <
        ConfirmationCodeInput.IOS_MINIMAL_DELAY
      ) {
        return;
      }

      const { currentIndex } = this.state;
      const nextIndex = currentIndex > 0 ? currentIndex - 1 : 0;

      this.setFocus(nextIndex);
    } else {
      // Record non-backspace key event time stamp
      this.lastKeyEventTimestamp = e.timeStamp;
    }
  };

  isLastIndex(index: INDEX): boolean {
    return index === this.props.codeLength - 1;
  }

  onInputCode = (character: string, index: INDEX) => {
    console.log("[rnccf][onInputCode] character,index: ", character, index);
    // on Android: text code is filled very slowly
    if (!this.isLastIndex(index)) {
      console.log("[rnccf][onInputCode] calling setFocus");
      this.setFocus(this.state.currentIndex + 1);
    }

    const {
      onFulfill,
      compareWithCode,
      ignoreCaseWhenCompareCode,
    } = this.props;
    const { currentIndex, codeSymbols } = this.state;
    const newCodeSymbols = [...codeSymbols];

    newCodeSymbols[index] = character;

    if (this.isLastIndex(index)) {
      const code = newCodeSymbols.join('');

      if (compareWithCode) {
        const isMatching = isMatchingCode(
          code,
          compareWithCode,
          ignoreCaseWhenCompareCode,
        );

        onFulfill(code, isMatching);

        if (isMatching) {
          this.clear();
        }
      } else {
        onFulfill(code);
      }

      this.blur(currentIndex);
    }

    console.log("[rnccf][onInputCode] calling setState");
    this.setState(prevState => ({
      codeSymbols: newCodeSymbols,
      currentIndex: prevState.currentIndex + 1,
    }), console.log("[rnccf][onInputCode] setState completed"))
  };

  codeInputRefs: Array<{ blur: () => void, focus: () => void }> = [];

  setFocus(index: INDEX) {
    console.log("[rnccf][setFocus] index: ", index);
    this.codeInputRefs[index].focus();
  }

  blur(index: INDEX) {
    this.codeInputRefs[index].blur();
  }

  setInputRef = (ref: any, idx: INDEX) => {
    this.codeInputRefs[idx] = ref;
  };

  getValue(value: string): string {
    const { maskSymbol } = this.props;

    return value ? maskSymbol || value.toString() : '';
  }

  renderInput(value: string, index: INDEX) {
    const {
      getInputStyle,
      autoFocus,
      variant,
      activeColor,
      getInputProps,
      keyboardType,
    } = this.props;
    const { currentIndex } = this.state;

    const customInputProps = getInputProps ? getInputProps(index) : null;

    if (process.env.NODE_ENV !== 'production') {
      validateInputProps(customInputProps);
    }

    const finalValue = this.getValue(value);

    return (
      <TextInput
        key={index}
        id={index}
        forwardRef={this.setInputRef}
        underlineColorAndroid="transparent"
        keyboardType={keyboardType}
        returnKeyType="done"
        selectionColor={activeColor}
        autoFocus={autoFocus && index === 0}
        value={finalValue}
        {...customInputProps}
        style={[
          styles.codeInput,
          this.styles.input,
          this.getClassStyle(variant, currentIndex === index),
          customInputProps && customInputProps.style,
          getInputStyle
            ? getInputStyle(index, currentIndex === index, Boolean(value))
            : null,
        ]}
        // fix for emoji  '๐Ÿ˜‚'.length // 2
        maxLength={finalValue ? finalValue.length : 1}
        onChangeText={this.onInputCode}
        onFocus={this.handlerOnFocus}
        onKeyPress={this.onKeyPress}
      />
    );
  }

  render() {
    const { inputPosition, containerProps } = this.props;
    const { codeSymbols } = this.state;

    return (
      <View
        {...containerProps}
        style={[
          styles.container,
          getContainerStyle(inputPosition),
          this.styles.container,
          containerProps.style,
        ]}
      >
        {codeSymbols.map((value, id) => this.renderInput(value, id))}
      </View>
    );
  }

  static propTypes = {
    activeColor: PropTypes.string,
    autoFocus: PropTypes.bool,
    cellBorderWidth: PropTypes.number,
    codeLength: PropTypes.number,
    compareWithCode: validateCompareCode,
    containerProps: PropTypes.object,
    defaultCode: validateCompareCode,
    getInputProps: PropTypes.func,
    ignoreCaseWhenCompareCode: PropTypes.bool,
    inactiveColor: PropTypes.string,
    inputPosition: PropTypes.oneOf(['center', 'left', 'right', 'full-width']),
    onChangeCode: PropTypes.func,
    onFulfill: PropTypes.func.isRequired,
    size: PropTypes.number,
    space: PropTypes.number,
    variant: PropTypes.oneOf([
      'border-box',
      'border-circle',
      'border-b',
      'border-b-t',
      'border-l-r',
      'clear',
    ]),
    keyboardType: TextInputNative.propTypes.keyboardType,
    maskSymbol: PropTypes.string,
  };

  static defaultProps = {
    activeColor: '#fff',
    autoFocus: false,
    cellBorderWidth: 1,
    codeLength: 5,
    compareWithCode: null,
    containerProps: {},
    defaultCode: null,
    getInputProps: null,
    ignoreCaseWhenCompareCode: false,
    inactiveColor: '#ffffff40',
    inputPosition: 'center',
    onChangeCode: null,
    size: 40,
    space: 8,
    variant: 'border-box',
    keyboardType: 'default',
    maskSymbol: null,
  };
}

`tmpVsmwGj` was published in 3.7.1

When I installed version 3.7.1 with yarn, in node_modules/react-native-confirmation-code-field It contain an folder as named tmpVsmwGj. Content of that folder look like version 3.7.0

Screen Shot 2019-08-20 at 1 04 47 AM

Screen Shot 2019-08-20 at 1 08 00 AM

Is this a mistake in publishing progress?

Allow more customisation

Hi thanks for the maintaining this module, previously i was using the react-native-confirmation-code-input, I'm able to set borderRadius for the cell, so even though its a box it has a slight curve.

I was wondering if you can allow that as well. Thanks #

Secure type is not available as a prop

Secure the input values by enabling a prop.

Ex: When Code is being typed, Typed Code will be replaced by * character or โ€ข character.

As an additional request, It's better to have dynamic secure typing. What I mean is when changing the value for secure type prop, all the already typed values are being changed.

Add documentation for manual verification pattern

A missing pattern on the documentation that I believe could be common case is when you have a button for manual code confirmation.
The "Verify" button might be disabled initially and enabled when the use fulfill the code. But if the user changes the code for any reason you need to determine when the user has edited the code. You have to re-set the button to a disabled state until the code is fulfilled again.

I've done it this way, as I assume that whenever the user re-focus the input the previous code gets partially deleted and the confirmation button should be disabled.

const [canVerify, setCanVerify] = useState(false);

<CodeInput
  blurOnSubmit={true}
  inputProps={{
    onFocus: () => setCanVerify(false),
  }}
  onFulfill={() => setCanVerify(true)}
/>
<Button
  title="Verify"
  disabled={!canVerify}
/>

Unable to autofill code with sms code

Hi there,
First of all - Love your work. This library saved me a lot of time :)
I currently have an issue with it - when I try to "paste" a code using the SMS code autocomplete (when you receive a code via SMS, and you can press on in like other auto complete suggestions), I get the wrong code.
Tried to debug it a bit, and it seems that handlerOnChangeText receives the code one char at a time, but as a whole. for example, if the code is 123456. then the text will be 1 for the first time, 12 for the second, 123 for the third etc.
As a workaround, I've changed text = text[0]; to text = text[text.length - 1]; (and changed maxLength to code length) but this is probably not the best idea..
BTW, tried canPasteCode but as you can understand it didn't solve the issue.
Any ideas?

Thanks!

How can I control onFulfill ?

The default behavior when the user is done with the input of code, it executes onFulfill but what if I don't want this behavior and rather wait for the user to press a button and then run onFulfill function? can I do that!

Why onCodeChange was deleted?

Why onCodeChange was deleted? Now to mimic it's behavior I must use ref. I'm using ^4.1.0. onChangeText that was added in 4.1.0 is not working. @retyi Look what you've done to my code

image

Wrong props

node_modules/react-native-confirmation-code-field/index.d.ts(36,51): error TS2694: Namespace '".../node_modules/@types/react-native/index"' has no exported member 'TextInputProps'.
node_modules/react-native-confirmation-code-field/index.d.ts(43,34): error TS2694: Namespace '".../node_modules/@types/react-native/index"' has no exported member 'ViewProps'.
10:23:25 - Compilation complete. Watching for file changes.

Height between Code and Underline

I just tried to reduce the height between Code we type and Underline which happens using variant = 'border-b' using getInputStyle={this.getInputStyle} as you have mentioned. But it does not reduce the gap. Can I have a method suggestion to reduce the gap ?

What I get
screen shot 2018-08-30 at 9 47 50 am

What I want
screen shot 2018-08-30 at 9 48 57 am

Show text before mask

Is there a way to see the entered text before the mask is applied?
It would be nice to see the text before mask is applied for better user experience.
Similar to when secureTextEntry is enabled on TextInput

Cannot Focus on Input my Manually Pressing

Hello,

I cannot focus on the input by manually pressing it, I have to instead set autoFocus={true}, but when I clear the input fields with the clear() function and then try to re-focus with focus() it does not focus.

Can you please explain why manually clicking on the input fields does not focus?

Include blurOnSubmit prop

When I complete the code, I would like to keep the focus in the input.

Is it possible to do without .focus()? Because it generates a keyboard flicking.

Thanks for the component, by the way.

Cannot Focus Code Input Cell once all fields are populated

Thank you for getting out a fix to #32 I'm just now getting back into my mobile app and updating all dependencies.

When AutoFocus=true, everything is working as intended, but I'm running into a scenario where once all the inputs are populated, I cannot select the input again.

My scenario is where I typo the last number, I cannot select it and delete it. I have to either add a clear button for the entire code or submit it with a wrong code. I understand the push towards pasting code from SMS, but not all devices that I'm working with have SIM cards.

How to add BackgroundColor for each cell without hint text

I have a problem putting the background color on each cell. The background looks good, but the background also applies to the text.
how to remedy it?

Code

import React, { useCallback } from 'react';
import ConfirmInput from 'react-native-confirmation-code-field';
import { StyleSheet } from 'react-native';
import Color from '../../themes/Color';

const styles = StyleSheet.create({
  inputContainer: {
    borderRadius: 8,
    color: Color.white.pure,
    // backgroundColor: Color.white.blurEffect,
    backgroundColor: 'rgba(255,255,255,0.5)',
  },
});

interface Props {
  setCode(code: string): void;
  length: number;
}

const CodeInput: React.FC<Props> = props => {
  const { setCode, length } = props;
  const handlerOnFulfill = useCallback(code => setCode(code), [setCode]);
  return (
    <ConfirmInput
      onFulfill={handlerOnFulfill}
      codeLength={length}
      size={50}
      cellProps={{ style: styles.inputContainer }}
    />
  );
};
export default CodeInput;

codeInput

Add an option to disable the cursor

Hello,

Would it be possible to add an option to disable the cursor?
I currently have a design that is completely doable with your library, except for this small feature.
I think it would be interesting to have this option, as UX-wise using activeColor and inactiveColor can already by themselves indicate to the user which cell is active.

Release verison blank screen

In debug version all is displayed correctly, but when compiled APK is only displayed blank screen.
version RN 0.60

Deleting one character causes input to not work

This seems to only happen on iOS. Steps to reproduce:

  1. Write the first character
  2. Write the second character
  3. Press backspace once to delete the second character
  4. Write the second character again: the whole input gets deleted
  5. Now everytime I reach the second character, it wipes all the characters

It looks like the "backspace" event is fired everytime I write something on the second input.

autoCapitalize

Need to have some way to set the autoCapitalize property.

Cursor should not inherit all styles from cell.

Hi! I need the cell text to be semi bold, but when fontWeight is set to cell, also is applied to Cursor component. So I need to apply this hack:

cellProps={({ hasValue }) => ({
          style: {
              fontWeight: hasValue ? '500' : '300' 
          },
        })}

Cannot select inputs

I'm running into an issue where if autoFocus={false}, the input boxes are not selectable(can get focus).

When autoFocus={true}, the input boxes are not selectable once there is a value, so if I mis-type a number, there is no way to change it.

Everything is working on version 2.0.5. I'll look into this later, but curious if anyone has run into this issue.

Libraries:
"react-native": "0.57.8",
"react-native-confirmation-code-field": "^3.1.2"

My Code:

2.0.5

  inputWrapStyle: {
    height: 60,
    marginTop: 30,
  },
...
static containerProps = { style: styles.inputWrapStyle };
...
  getInputStyle = (index, isActive, hasValue) => {
    if (hasValue) {
      return styles.inputNotEmpty;
    }
    return null;
  };
...
  getInputProps = () => ({
    keyboardType: 'numeric',
    style: styles.input,
  });
...
                <CodeInput codeLength={4}
                           keyboardType={'numeric'}
                           getInputProps={this.getInputProps}
                           getInputStyle={this.getInputStyle}
                           containerProps={AddPhoneNumber.containerProps}
                           onFulfill={this.codePopulated}
                           onChangeCode={this.onCodeChanged}
                           canPasteCode={false}
                />

3.1.2

                <CodeInput codeLength={4}
                           containerProps={AddPhoneNumber.containerProps}
                           onFulfill={this.codePopulated}
                           onChangeCode={this.onCodeChanged}
                />

Accessibility - Differentiate between each input

Each digit of the input has the same name when read by an accessibility assistant. Was wondering if there was a way to be able to differentiate between them? (Example, First Digit, Second Digit.. etc)

How to update the default value?

For example, we receive an OTP in the SMS. We somehow get the 6 digits code from the SMS using regex, now how to prefill the ConfirmationCodeInput with that new value? If i try to set this.setState({defValue:'123456'}). It doesn't reflect visually on the view.
NOTE
defValue: '222222' in the start.

How to auto-fill for ios 12 >

I think this case only applicable to ios12 and above.

Steps to reproduce:

  1. Receive confirmation code sms, it will show up above keypad automatically.
  2. When tap on it, it will fill in to first text box only

Suspecting it was due to confirmation code is combined from single text boxes. Any idea how to support this?

Wrong 'onTextChange' function name

In ConfirmationCodeInput.js, method handlerOnTextChange, the methodName to be inherited must be onChangeText, not onTextChange.
I think this only is a typo coz inputProps is of type ReactNative.TextInputProps, so it only has onChangeText, not onTextChange.

No way for autofocus to be true when default input has a value set

I have autofocus set to true which works great, however when I add default input value autofocus doesn't work. Would love to be able to set a placeholder for the input cell or have the default input value to act like palceholders instead of block autofocus because it thinks all cells are filled.

variant border-b is not work

<CodeInput
                variant="border-b"
                space={10}
                size={50}
                cellBorderWidth={2}
                activeColor="white"
                inactiveColor="rgba(255, 255, 255, 0.25)"
                inputPosition="center"
                onFulfill={value => this.setState({ otp: value })}
              />

The border of Cell does not appear

how can i change font family for code input

in forked repo react-native-confirmation-code-input we have codeInputStyle which accept object and i assumed we can change fontFamily but seem's it's removed from your fork.
I want to change font to a persian font for showing correctly persian digits.

[error] Invalid attempt to spread non-iterable instance

I have this error with [email protected] and the plugin is version 3.4.1. I find out after some debug that it was coming from this component. It was working properly before I don't really know what happened. It's seems to be only on Android.

Does someone has the same issue?

Edit: It's weird, when I use the remote live reload, it's working properly

Not working on ios

Autofocus and onFulfill not working on ios. Fresh build. It shows the warning "-[RCTRootView cancelTouches] is deprecated and will be deleted soon". Android is working well. RN 0.61.2. Workaround is to add import 'react-native-gesture-handler' on top of index.js. onFulfill is working, but autofocus is still not. When manually focusing it show the same warning

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.