85 lines
2.4 KiB
TypeScript
85 lines
2.4 KiB
TypeScript
import React, { useState } from "react";
|
|
import { View, TouchableOpacity } from "react-native";
|
|
import { Text } from "~/components/ui/text";
|
|
import BottomSheet from "~/components/ui/bottomSheet";
|
|
import { ChevronDown, Check } from "lucide-react-native";
|
|
|
|
export interface DropdownOption {
|
|
label: string;
|
|
value: string;
|
|
}
|
|
|
|
interface DropdownProps {
|
|
value: string | null;
|
|
options: DropdownOption[];
|
|
onSelect: (value: string) => void;
|
|
placeholder?: string;
|
|
}
|
|
|
|
const Dropdown: React.FC<DropdownProps> = ({
|
|
value,
|
|
options,
|
|
onSelect,
|
|
placeholder = "Select",
|
|
}) => {
|
|
const [open, setOpen] = useState(false);
|
|
|
|
const selectedOption = options.find((opt) => opt.value === value) || null;
|
|
|
|
return (
|
|
<>
|
|
<TouchableOpacity
|
|
activeOpacity={0.8}
|
|
onPress={() => setOpen(true)}
|
|
className="flex-row items-center justify-between w-full border border-[#D9DBE9] bg-white rounded-md px-3 py-4"
|
|
>
|
|
<Text className="text-[#000] text-sm">
|
|
{selectedOption ? selectedOption.label : placeholder}
|
|
</Text>
|
|
<ChevronDown size={18} color="#9CA3AF" />
|
|
</TouchableOpacity>
|
|
|
|
<BottomSheet
|
|
visible={open}
|
|
onClose={() => setOpen(false)}
|
|
maxHeightRatio={0.4}
|
|
>
|
|
<View className="w-full py-2">
|
|
{options.map((opt) => {
|
|
const selected = value === opt.value;
|
|
return (
|
|
<TouchableOpacity
|
|
key={opt.value}
|
|
activeOpacity={0.8}
|
|
onPress={() => {
|
|
onSelect(opt.value);
|
|
setOpen(false);
|
|
}}
|
|
className="py-3 flex-row items-center border-b border-gray-100"
|
|
>
|
|
{/* Radio indicator on the left */}
|
|
<View className="mr-3">
|
|
{selected ? (
|
|
<View className="w-4 h-4 rounded-full bg-primary items-center justify-center">
|
|
<Check size={10} color="#ffffff" />
|
|
</View>
|
|
) : (
|
|
<View className="w-4 h-4 rounded-full border border-gray-300" />
|
|
)}
|
|
</View>
|
|
|
|
{/* Label */}
|
|
<Text className="text-base font-dmsans text-gray-800">
|
|
{opt.label}
|
|
</Text>
|
|
</TouchableOpacity>
|
|
);
|
|
})}
|
|
</View>
|
|
</BottomSheet>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default Dropdown;
|