Open
Description
Is your feature request related to a problem? Please describe.
I have been using native paper for different projects and I came across a problem several times where I needed an autocomplete component, I tried 2 packages but I would love to have a component from the native paper so that my UI remains consistent
Describe the solution you'd like
I implemented an autocomplete component with the use of TextInput + Menu component from native paper
interface Props<T extends Record<string, any>> {
theme?: AppTheme;
value: {
origValue: string | undefined;
};
label: string;
data: T[];
displayKey: keyof T;
containerStyle?: StyleProp<ViewStyle>;
onChange: (text: string) => void;
leadingIcon?: IconSource;
trailingIcon?: IconSource;
textInputstyle?: StyleProp<TextStyle>;
menuStyle?: StyleProp<ViewStyle>;
textInputRight?: ReactNode;
textInputLeft?: ReactNode;
}
const Autocomplete = <T extends Record<string, any>>({
theme = lightTheme,
value: propValue,
label,
data,
displayKey,
containerStyle = {},
onChange: originOnChange,
textInputstyle = {},
leadingIcon = "",
trailingIcon = "",
menuStyle = {},
textInputRight = null,
textInputLeft = null,
}: Props<T>) => {
const [value, setValue] = useState<string | undefined>(propValue.origValue);
const [menuVisible, setMenuVisible] = useState<boolean>(false);
return (
<View
style={
containerStyle,
}
>
<TextInput
theme={theme}
mode="outlined"
onFocus={() => {
if (value || value?.length === 0) {
setMenuVisible(true);
}
}}
outlineStyle={
menuVisible
? {
borderBottomRightRadius: 0,
borderBottomLeftRadius: 0,
}
: {}
}
onBlur={() => setMenuVisible(false)}
label={label}
{...(textInputRight ? { right: textInputRight } : {})}
{...(textInputLeft ? { left: textInputLeft } : {})}
style={textInputstyle}
onChangeText={(text) => {
originOnChange(text);
setMenuVisible(true);
setValue(text);
}}
value={value}
/>
{menuVisible && (
<View
style={{
flex: 1,
width: "100%",
backgroundColor: "white",
borderWidth: 1,
borderColor: theme.colors.primary,
borderBottomRightRadius: 4,
borderBottomLeftRadius: 4,
flexDirection: "column",
position: "absolute",
top: "100%",
left: 0,
zIndex: 10,
}}
>
{data.length === 0 && (
<Text style={{ padding: 10 }}>
<Text style={{ textAlign: "center" }}>
No result found
</Text>
</Text>
)}
{data.map((item, index) => (
<Menu.Item
key={index}
style={ menuStyle}
leadingIcon={leadingIcon}
trailingIcon={trailingIcon}
onPress={() => {
const selectedValue = String(item[displayKey]);
console.log(selectedValue);
setValue(selectedValue);
setMenuVisible(false);
originOnChange(selectedValue);
}}
title={String(item[displayKey])}
/>
))}
</View>
)}
</View>
);
};
Describe alternatives you've considered
I have tried two alternatives:
react-native-autocomplete-dropdown and react-native-autocomplete-input
I dropped those packages out of fear since they were backed only by one contributor.
Additional context
N/A