您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

ClearableInput.js 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // @flow
  2. import React, { useCallback, useEffect, useState } from 'react';
  3. import { View, TextInput, TouchableOpacity } from 'react-native';
  4. import { withTheme } from 'react-native-paper';
  5. import { Icon, IconCloseSolid } from '../../../base/icons';
  6. import styles from './styles';
  7. type Props = {
  8. /**
  9. * If the input should be focused on display.
  10. */
  11. autoFocus?: boolean,
  12. /**
  13. * Custom styles for the component.
  14. */
  15. customStyles?: Object,
  16. /**
  17. * Callback for the onBlur event of the field.
  18. */
  19. onBlur?: Function,
  20. /**
  21. * Callback for the onChange event of the field.
  22. */
  23. onChange: Function,
  24. /**
  25. * Callback for the onFocus event of the field.
  26. */
  27. onFocus?: Function,
  28. /**
  29. * Callback to be used when the user hits Enter in the field.
  30. */
  31. onSubmit?: Function,
  32. /**
  33. * Placeholder text for the field.
  34. */
  35. placeholder: string,
  36. /**
  37. * Placeholder text color.
  38. */
  39. placeholderColor?: string,
  40. /**
  41. * Component to be added to the beginning of the the input.
  42. */
  43. prefixComponent?: React$Node,
  44. /**
  45. * The type of the return key.
  46. */
  47. returnKeyType?: 'done' | 'go' | 'next' | 'search' | 'send' | 'none' | 'previous' | 'default',
  48. /**
  49. * Color of the caret and selection.
  50. */
  51. selectionColor?: string,
  52. /**
  53. * Theme used for styles.
  54. */
  55. theme: Object,
  56. /**
  57. * Externally provided value.
  58. */
  59. value?: string
  60. };
  61. /**
  62. * Implements a pre-styled clearable input field.
  63. *
  64. * @param {Props} props - The props of the component.
  65. * @returns {ReactElement}
  66. */
  67. function ClearableInput({
  68. autoFocus = false,
  69. customStyles = {},
  70. onBlur,
  71. onChange,
  72. onFocus,
  73. onSubmit,
  74. placeholder,
  75. placeholderColor,
  76. prefixComponent,
  77. returnKeyType = 'search',
  78. selectionColor,
  79. theme,
  80. value
  81. }: Props) {
  82. const [ val, setVal ] = useState(value || '');
  83. const [ focused, setFocused ] = useState(false);
  84. const inputRef = React.createRef();
  85. useEffect(() => {
  86. if (value && value !== val) {
  87. setVal(value);
  88. }
  89. }, [ value ]);
  90. /**
  91. * Callback for the onBlur event of the field.
  92. *
  93. * @returns {void}
  94. */
  95. const _onBlur = useCallback(() => {
  96. setFocused(false);
  97. onBlur && onBlur();
  98. }, [ onBlur ]);
  99. /**
  100. * Callback for the onChange event of the field.
  101. *
  102. * @param {Object} evt - The static event.
  103. * @returns {void}
  104. */
  105. const _onChange = useCallback(evt => {
  106. const { nativeEvent: { text } } = evt;
  107. setVal(text);
  108. onChange && onChange(text);
  109. }, [ onChange ]);
  110. /**
  111. * Callback for the onFocus event of the field.
  112. *
  113. * @returns {void}
  114. */
  115. const _onFocus = useCallback(() => {
  116. setFocused(true);
  117. onFocus && onFocus();
  118. }, [ onFocus ]);
  119. /**
  120. * Clears the input.
  121. *
  122. * @returns {void}
  123. */
  124. const _clearInput = useCallback(() => {
  125. if (inputRef.current) {
  126. inputRef.current.focus();
  127. }
  128. setVal('');
  129. onChange && onChange('');
  130. }, [ onChange ]);
  131. return (
  132. <View
  133. style = { [
  134. styles.clearableInput,
  135. focused ? styles.clearableInputFocus : {},
  136. customStyles?.wrapper
  137. ] }>
  138. {prefixComponent}
  139. <TextInput
  140. autoCorrect = { false }
  141. autoFocus = { autoFocus }
  142. onBlur = { _onBlur }
  143. onChange = { _onChange }
  144. onFocus = { _onFocus }
  145. onSubmitEditing = { onSubmit }
  146. placeholder = { placeholder }
  147. placeholderTextColor = { placeholderColor ?? theme.palette.text01 }
  148. ref = { inputRef }
  149. returnKeyType = { returnKeyType }
  150. selectionColor = { selectionColor }
  151. style = { [ styles.clearableInputTextInput, customStyles?.input ] }
  152. value = { val } />
  153. {val !== '' && (
  154. <TouchableOpacity
  155. onPress = { _clearInput }
  156. style = { [ styles.clearButton, customStyles?.clearButton ] }>
  157. <Icon
  158. size = { 22 }
  159. src = { IconCloseSolid }
  160. style = { [ styles.clearIcon, customStyles?.clearIcon ] } />
  161. </TouchableOpacity>
  162. )}
  163. </View>
  164. );
  165. }
  166. export default withTheme(ClearableInput);