Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 3f6a483

Browse files
lfernandezsmaurobender
authored andcommittedSep 27, 2022
Added eye and input container to TextInput
Added onFocus and disabled states Added __container __icon and __textInput pseudoprops
1 parent 029ac5a commit 3f6a483

File tree

5 files changed

+77
-11
lines changed

5 files changed

+77
-11
lines changed
 

‎src/components/hooks/useIsFocused.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { useCallback, useState } from 'react';
2-
import type { PressableProps, NativeSyntheticEvent, TargetedEvent } from 'react-native';
2+
import type { PressableProps, TextInputProps } from 'react-native';
33

44
interface IUseIsFocusedState {
5-
onFocus?: PressableProps[ 'onFocus' ],
6-
onBlur?: PressableProps[ 'onBlur' ]
5+
onFocus?: PressableProps[ 'onFocus' ] | TextInputProps[ 'onFocus' ],
6+
onBlur?: PressableProps[ 'onBlur' ] | TextInputProps[ 'onBlur' ]
77
}
88

99
const useIsFocused = ( {
@@ -12,12 +12,12 @@ const useIsFocused = ( {
1212
}: IUseIsFocusedState ) => {
1313
const [ isFocused, setIsFocused ] = useState( false );
1414

15-
const onFocus = useCallback( ( event: NativeSyntheticEvent<TargetedEvent> ) => {
15+
const onFocus = useCallback( ( event ) => {
1616
onFocusProp?.( event );
1717
setIsFocused( true );
1818
}, [ setIsFocused ] );
1919

20-
const onBlur = useCallback( ( event: NativeSyntheticEvent<TargetedEvent> ) => {
20+
const onBlur = useCallback( ( event ) => {
2121
onBlurProp?.( event );
2222
setIsFocused( false );
2323
}, [ setIsFocused ] );
+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { useMemo } from 'react';
2+
import { useIsFocused } from '../../hooks';
3+
import { useComponentPropsResolver } from '../../../hooks';
4+
import type { ITextInputProps } from './types';
5+
6+
interface IUseTextInputPropsResolverType {
7+
containerProps: ITextInputProps['__container'],
8+
iconProps: ITextInputProps['__icon'],
9+
textInputProps: ITextInputProps['__textInput'],
10+
restProps: Omit<ITextInputProps, '__icon' | '__container' | 'textInput'>
11+
}
12+
13+
const useTextInputPropsResolver = ( props: ITextInputProps ): IUseTextInputPropsResolverType => {
14+
const { disabled } = props;
15+
const { isFocused, onFocus, onBlur } = useIsFocused( props );
16+
17+
const state = useMemo( () => ( {
18+
isDisabled: disabled || false,
19+
isFocused
20+
} ), [ disabled, isFocused ] );
21+
22+
const {
23+
__container: containerProps,
24+
__icon: iconProps,
25+
__textInput: textInputProps,
26+
...restProps
27+
} = useComponentPropsResolver( 'TextInput', props, state ) as ITextInputProps;
28+
29+
restProps.onFocus = onFocus;
30+
restProps.onBlur = onBlur;
31+
restProps.editable = !disabled;
32+
33+
return {
34+
containerProps, iconProps, textInputProps, restProps
35+
};
36+
};
37+
38+
export default useTextInputPropsResolver;
+18-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,26 @@
11
import React from 'react';
22
import { TextInput as TextInputRN } from 'react-native';
3-
import { useComponentPropsResolver, useStyleFromPropsResolver } from '../../../hooks';
3+
import UIKitIcon from '../../../icons/UIKitIcon';
4+
import { useStyleFromPropsResolver } from '../../../hooks';
5+
import { HStack } from '../Stack';
6+
import useTextInputPropsResolver from './hooks';
47
import type { ITextInputProps } from './types';
8+
import IconButton from '../IconButton';
9+
10+
const passwordIcon = <IconButton name='eye' as={UIKitIcon} />;
511

612
const TextInput = ( props: ITextInputProps ) => {
7-
const resolvedProps = useComponentPropsResolver( 'TextInput', props );
8-
const [ style, restProps ] = useStyleFromPropsResolver( 'TextInput', resolvedProps );
9-
return <TextInputRN style={style} {...restProps}/>;
13+
const {
14+
containerProps, textInputProps, iconProps, restProps
15+
} = useTextInputPropsResolver( props );
16+
const [ style ] = useStyleFromPropsResolver( 'TextInput', textInputProps || {} );
17+
return (
18+
<HStack {...containerProps} height={56}>
19+
<TextInputRN style={style} {...restProps}/>
20+
{props.isPassword && React.cloneElement( props.passwordIcon || passwordIcon, iconProps )}
21+
</HStack>
22+
23+
);
1024
};
1125

1226
export default TextInput;
+7-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1+
import type { ReactElement } from 'react';
12
import type { TextInputProps } from 'react-native';
23
import type { ComponentStyledProps } from '../../../core/components/types';
4+
import type { IIconProps } from '../Icon/types';
35

4-
export interface ITextInputProps extends Omit<ComponentStyledProps<'TextInput'>, 'textAlign'>, TextInputProps {}
6+
export interface ITextInputProps extends Omit<ComponentStyledProps<'TextInput'>, 'textAlign'>, TextInputProps {
7+
disabled?: boolean,
8+
passwordIcon?: ReactElement<IIconProps>
9+
isPassword?: boolean
10+
}

‎src/core/components/types/pseudoProps.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,21 @@ interface IFormControlPseudoProps {
4949
__errorIcon: ComponentBaseStyledProps<'Icon'>
5050
}
5151

52+
// TextInput pseudoprops
53+
interface ITextInputPseudoProps {
54+
__icon: ComponentBaseStyledProps<'Icon'>
55+
__container: ComponentBaseStyledProps<'Box'>
56+
__textInput: ComponentBaseStyledProps<'TextInput'>
57+
}
58+
5259
// Pseudoprops config for all components
5360
interface ComponentsPseudoPropsConfig {
5461
Button: IButtonPseudoProps,
5562
Checkbox: ICheckboxPseudoProps,
5663
IconButton: IIconButtonPseudoProps,
5764
Radio: IRadioPseudoProps
58-
FormControl: IFormControlPseudoProps
65+
FormControl: IFormControlPseudoProps,
66+
TextInput: ITextInputPseudoProps
5967
}
6068

6169
// Template type to get pseudoprops for a given component

0 commit comments

Comments
 (0)
Please sign in to comment.