Skip to content

Commit

Permalink
fix(exoflex): expose TextInput inner ref (#92)
Browse files Browse the repository at this point in the history
* use forwardRef for TextInput inner ref

* replace TextInput default props with default arguments

* fix stale props in TextInput hooks
  • Loading branch information
darcien authored Sep 27, 2019
1 parent d00e1a9 commit a48d4b7
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 34 deletions.
48 changes: 30 additions & 18 deletions packages/exoflex/src/components/TextInput/TextInput.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,70 @@
import React, { useState, useCallback } from 'react';
import { NativeSyntheticEvent, TextInputFocusEventData } from 'react-native';
import React, { useState, useCallback, forwardRef, Ref } from 'react';
import {
NativeSyntheticEvent,
TextInputFocusEventData,
TextInput as NativeTextInput,
} from 'react-native';

import Text from '../Text';
import TextInputOutlined from './TextInputOutlined';
import { TextInputProps } from './types';

function TextInput(props: TextInputProps) {
let { mode, onFocus, onBlur, onChangeText, ...otherProps } = props;
function TextInput(
{
autoCorrect = false,
disabled = false,
editable = true,
mode = 'outlined',
onFocus,
onBlur,
onChangeText,
...otherProps
}: TextInputProps,
ref: Ref<NativeTextInput>,
) {
let [isFocused, setIsFocused] = useState(false);

let _onFocus = useCallback(
(e: NativeSyntheticEvent<TextInputFocusEventData>) => {
if (props.disabled || !props.editable) {
if (disabled || !editable) {
return;
}

setIsFocused(true);
onFocus && onFocus(e);
},
[onFocus],
[onFocus, disabled, editable],
);
let _onBlur = useCallback(
(e: NativeSyntheticEvent<TextInputFocusEventData>) => {
if (props.disabled || !props.editable) {
if (disabled || !editable) {
return;
}

setIsFocused(false);
onBlur && onBlur(e);
},
[onBlur],
[onBlur, disabled, editable],
);

let _onChangeText = useCallback(
(text: string) => {
if (props.disabled || !props.editable) {
if (disabled || !editable) {
return;
}

onChangeText && onChangeText(text);
},
[onChangeText],
[onChangeText, disabled, editable],
);

return mode === 'outlined' ? (
<TextInputOutlined
{...otherProps}
ref={ref}
autoCorrect={autoCorrect}
disabled={disabled}
editable={editable}
onFocus={_onFocus}
onBlur={_onBlur}
onChangeText={_onChangeText}
Expand All @@ -56,11 +75,4 @@ function TextInput(props: TextInputProps) {
);
}

TextInput.defaultProps = {
autoCorrect: false,
disabled: false,
editable: true,
mode: 'outlined',
};

export default TextInput;
export default forwardRef(TextInput);
32 changes: 18 additions & 14 deletions packages/exoflex/src/components/TextInput/TextInputOutlined.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { forwardRef, Ref } from 'react';
import { View, TextInput, StyleSheet } from 'react-native';
import { IconButton } from 'react-native-paper';

Expand All @@ -9,18 +9,21 @@ import { ChildTextInputProps } from './types';

export type Props = ChildTextInputProps;

function TextInputOutlined({
errorMessage,
label,
disabled,
editable,
isFocused,
style,
containerStyle,
labelStyle,
errorMessageStyle,
...otherProps
}: Props) {
function TextInputOutlined(
{
errorMessage,
label,
disabled,
editable,
isFocused,
style,
containerStyle,
labelStyle,
errorMessageStyle,
...otherProps
}: Props,
ref: Ref<TextInput>,
) {
let { colors, roundness } = useTheme();

let isError = errorMessage != null;
Expand All @@ -45,6 +48,7 @@ function TextInputOutlined({
>
<Label style={labelStyle}>{label}</Label>
<TextInput
ref={ref}
editable={!disabled && editable}
underlineColorAndroid="transparent"
// TODO: This color should use colors.text with 0.6 opacity.
Expand Down Expand Up @@ -97,4 +101,4 @@ let styles = StyleSheet.create({
},
});

export default TextInputOutlined;
export default forwardRef(TextInputOutlined);
7 changes: 5 additions & 2 deletions packages/exoflex/src/components/TextInput/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import {
StyleProp,
ViewStyle,
TextStyle,
TextInput,
} from 'react-native';
import { Ref } from 'react';

type ModeProps = 'flat' | 'outlined';

Expand All @@ -21,12 +23,12 @@ export type TextInputProps = BaseTextInputProps & {
* When set to true, will disable all interaction with the text input
* Defaults to 'false'.
*/
disabled: boolean;
disabled?: boolean;
/**
* Determine how the text input is displayed.
* Defaults to 'outlined'.
*/
mode: ModeProps;
mode?: ModeProps;
/**
* Additional style passed to the container of the TextInput
*/
Expand All @@ -42,5 +44,6 @@ export type TextInputProps = BaseTextInputProps & {
};

export type ChildTextInputProps = Omit<TextInputProps, 'mode'> & {
ref?: Ref<TextInput>;
isFocused: boolean;
};

0 comments on commit a48d4b7

Please sign in to comment.