Skip to content
Source
Sign inSign up

SearchField.tsx

77 lines2.3 KB

1import type { RefObject } from "react";
2import { Pressable, TextInput, type TextInputInstance, View } from "react-native";
3​
4import { SymbolView } from "./AppSymbol";
5import { useAndroidControlSizing } from "./useAndroidControlSizing";
6​
7export interface SearchFieldProps {
8 readonly autoFocus?: boolean;
9 readonly inputRef: RefObject<TextInputInstance | null>;
10 readonly accessibilityLabel: string;
11 readonly clearAccessibilityLabel: string;
12 readonly placeholder: string;
13 readonly value: string;
14 readonly onChangeText: (value: string) => void;
16​
17export function SearchField({
18 inputRef,
19 autoFocus = true,
20 accessibilityLabel,
21 clearAccessibilityLabel,
22 placeholder,
23 value,
24 onChangeText,
25}: SearchFieldProps) {
26 const { scale, mediumIconSize } = useAndroidControlSizing();
27 return (
28 <View
29 className="min-w-0 flex-1 flex-row items-center rounded-full border border-input-border bg-input"
30 style={{
31 minHeight: Math.max(48, 42 * scale),
32 gap: 7 * scale,
33 paddingHorizontal: 10.5 * scale,
34 }}
35 >
36 <SymbolView
37 name="magnifyingglass"
38 size={mediumIconSize}
39 tintColorClassName="accent-foreground-muted"
40 />
41 <TextInput
42 ref={inputRef}
43 accessibilityLabel={accessibilityLabel}
44 autoFocus={autoFocus}
45 autoCapitalize="none"
46 autoCorrect={false}
47 returnKeyType="search"
48 placeholder={placeholder}
49 placeholderTextColorClassName="accent-placeholder"
50 selectionColorClassName="accent-focus/32"
51 cursorColorClassName="accent-focus"
52 selectionHandleColorClassName="accent-focus"
53 className="min-w-0 flex-1 font-sans text-base text-foreground"
54 style={{ paddingVertical: 7 * scale }}
55 value={value}
56 onChangeText={onChangeText}
57 />
58 {value.length > 0 ? (
59 <Pressable
60 accessibilityLabel={clearAccessibilityLabel}
61 accessibilityRole="button"
62 hitSlop={10}
63 onPress={() => {
64 onChangeText("");
65 inputRef.current?.focus();
66 }}
67 >
68 <SymbolView
69 name="xmark.circle.fill"
70 size={mediumIconSize}
71 tintColorClassName="accent-foreground-muted"
72 />
73 </Pressable>
74 ) : null}
75 </View>
76 );