Files
lamp/features/im/components/conversation-search-bar.tsx

88 lines
2.0 KiB
TypeScript

import MaterialIcons from "@expo/vector-icons/MaterialIcons";
import { useRef, useState } from "react";
import { Animated, Easing, StyleSheet, TextInput } from "react-native";
type ConversationSearchBarProps = {
value: string;
onChangeText: (value: string) => void;
};
export function ConversationSearchBar({
value,
onChangeText,
}: ConversationSearchBarProps) {
const [isFocused, setIsFocused] = useState(false);
const focusAnim = useRef(new Animated.Value(0)).current;
const animateFocus = (toValue: 0 | 1) => {
Animated.timing(focusAnim, {
toValue,
duration: 140,
easing: Easing.out(Easing.quad),
useNativeDriver: true,
}).start();
};
return (
<Animated.View
style={[
styles.wrapper,
isFocused && styles.wrapperFocused,
{
transform: [
{
scale: focusAnim.interpolate({
inputRange: [0, 1],
outputRange: [1, 1.01],
}),
},
],
},
]}
>
<MaterialIcons color="#A2A2A7" name="search" size={28} />
<TextInput
onBlur={() => {
setIsFocused(false);
animateFocus(0);
}}
onChangeText={onChangeText}
onFocus={() => {
setIsFocused(true);
animateFocus(1);
}}
placeholder="搜索联系人备注/昵称/ID"
placeholderTextColor="#B8B8BC"
style={styles.input}
value={value}
/>
</Animated.View>
);
}
const styles = StyleSheet.create({
wrapper: {
alignItems: "center",
backgroundColor: "#F0F0F2",
borderColor: "transparent",
borderCurve: "continuous",
borderWidth: 1,
borderRadius: 20,
flexDirection: "row",
gap: 8,
height: 52,
marginHorizontal: 20,
paddingHorizontal: 16,
},
wrapperFocused: {
backgroundColor: "#F4FAF8",
borderColor: "#BEEEDB",
},
input: {
color: "#2A2A2A",
flex: 1,
fontSize: 16,
fontWeight: "400",
},
});