Files
paseo/packages/app/src/components/add-host-method-modal.tsx
T
Mohamed Boudra 29ce6653fd Improve mobile selectors and sheet inputs
Keep sheet text inputs native-owned to avoid React Native controlled input flicker during fast typing. Add reset keys for fields that need programmatic clears, and move model, mode, and thinking pickers onto shared combobox rows with fuzzy ranked search and native virtualization.
2026-05-18 14:56:17 +07:00

117 lines
3.3 KiB
TypeScript

import { useCallback } from "react";
import { Pressable, Text, View } from "react-native";
import { StyleSheet, useUnistyles } from "react-native-unistyles";
import { QrCode, Link2, ClipboardPaste } from "lucide-react-native";
import { AdaptiveModalSheet, type SheetHeader } from "./adaptive-modal-sheet";
import { isNative } from "@/constants/platform";
const ADD_CONNECTION_HEADER: SheetHeader = { title: "Add connection" };
const styles = StyleSheet.create((theme) => ({
option: {
flexDirection: "row",
alignItems: "center",
gap: theme.spacing[4],
padding: theme.spacing[4],
borderRadius: theme.borderRadius.xl,
backgroundColor: theme.colors.surface2,
borderWidth: 1,
borderColor: theme.colors.border,
},
optionText: {
color: theme.colors.foreground,
fontSize: theme.fontSize.base,
fontWeight: theme.fontWeight.normal,
},
optionSubtext: {
color: theme.colors.foregroundMuted,
fontSize: theme.fontSize.sm,
marginTop: theme.spacing[1],
},
optionBody: {
flex: 1,
},
}));
export interface AddHostMethodModalProps {
visible: boolean;
onClose: () => void;
onDirectConnection: () => void;
onScanQr: () => void;
onPasteLink: () => void;
}
export function AddHostMethodModal({
visible,
onClose,
onDirectConnection,
onScanQr,
onPasteLink,
}: AddHostMethodModalProps) {
const { theme } = useUnistyles();
const handleDirect = useCallback(() => {
onDirectConnection();
}, [onDirectConnection]);
const handleScan = useCallback(() => {
onScanQr();
}, [onScanQr]);
const handlePaste = useCallback(() => {
onPasteLink();
}, [onPasteLink]);
return (
<AdaptiveModalSheet
header={ADD_CONNECTION_HEADER}
visible={visible}
onClose={onClose}
testID="add-host-method-modal"
>
<Pressable
style={styles.option}
onPress={handleDirect}
accessibilityRole="button"
accessibilityLabel="Direct connection"
testID="add-host-method-direct"
>
<Link2 size={18} color={theme.colors.foreground} />
<View style={styles.optionBody}>
<Text style={styles.optionText}>Direct connection</Text>
<Text style={styles.optionSubtext}>Local network or VPN.</Text>
</View>
</Pressable>
{isNative ? (
<Pressable
style={styles.option}
onPress={handleScan}
accessibilityRole="button"
accessibilityLabel="Scan QR code"
>
<QrCode size={18} color={theme.colors.foreground} />
<View style={styles.optionBody}>
<Text style={styles.optionText}>Scan QR code</Text>
<Text style={styles.optionSubtext}>Encrypted relay connection.</Text>
</View>
</Pressable>
) : null}
<Pressable
style={styles.option}
onPress={handlePaste}
accessibilityRole="button"
accessibilityLabel="Paste pairing link"
testID="add-host-method-pair-link"
>
<ClipboardPaste size={18} color={theme.colors.foreground} />
<View style={styles.optionBody}>
<Text style={styles.optionText}>Paste pairing link</Text>
<Text style={styles.optionSubtext}>Encrypted relay connection.</Text>
</View>
</Pressable>
</AdaptiveModalSheet>
);
}