import React from 'react'; import { Animated, DimensionValue, GestureResponderEvent, LayoutChangeEvent, Pressable, StyleProp, StyleSheet, Text, TextStyle, ViewStyle, } from 'react-native'; import { AdornmentSide } from './enums'; import { getTextColor } from './utils'; import { useInternalTheme } from '../../../core/theming'; import type { ThemeProp } from '../../../types'; import { getConstants } from '../helpers'; export type Props = { /** * Text to show. */ text: string; onLayout?: (event: LayoutChangeEvent) => void; /** * Function to execute on press. */ onPress?: (e: GestureResponderEvent) => void; /** * Accessibility label for the affix. This is read by the screen reader when the user taps the affix. */ accessibilityLabel?: string; /** * Style that is passed to the Text element. */ textStyle?: StyleProp; /** * @optional */ theme?: ThemeProp; }; type ContextState = { topPosition: number | null; onLayout?: (event: LayoutChangeEvent) => void; visible?: Animated.Value; textStyle?: StyleProp; side: AdornmentSide; paddingHorizontal?: DimensionValue; maxFontSizeMultiplier?: number | undefined | null; testID?: string; disabled?: boolean; }; const AffixContext = React.createContext({ textStyle: { fontFamily: '', color: '' }, topPosition: null, side: AdornmentSide.Left, }); const AffixAdornment: React.FunctionComponent< { affix: React.ReactNode; testID: string; } & ContextState > = ({ affix, side, textStyle, topPosition, onLayout, visible, paddingHorizontal, maxFontSizeMultiplier, testID, disabled, }) => { return ( {affix} ); }; /** * A component to render a leading / trailing text in the TextInput * * ## Usage * ```js * import * as React from 'react'; * import { TextInput } from 'react-native-paper'; * * const MyComponent = () => { * const [text, setText] = React.useState(''); * * return ( * } * /> * ); * }; * * export default MyComponent; * ``` */ const TextInputAffix = ({ text, textStyle: labelStyle, theme: themeOverrides, onLayout: onTextLayout, onPress, accessibilityLabel = text, }: Props) => { const theme = useInternalTheme(themeOverrides); const { AFFIX_OFFSET } = getConstants(theme.isV3); const { textStyle, onLayout, topPosition, side, visible, paddingHorizontal, maxFontSizeMultiplier, testID, disabled, } = React.useContext(AffixContext); const offset = typeof paddingHorizontal === 'number' ? paddingHorizontal : AFFIX_OFFSET; const style = { top: topPosition, [side]: offset, } as ViewStyle; const textColor = getTextColor({ theme, disabled }); const content = ( {text} ); return ( {onPress ? ( {content} ) : ( content )} ); }; TextInputAffix.displayName = 'TextInput.Affix'; const styles = StyleSheet.create({ container: { position: 'absolute', justifyContent: 'center', alignItems: 'center', }, }); export default TextInputAffix; // @component-docs ignore-next-line export { TextInputAffix, AffixAdornment };