85 lines
2.5 KiB
TypeScript
Executable file
85 lines
2.5 KiB
TypeScript
Executable file
import tw from "../lib/tailwind";
|
|
import React from "react";
|
|
import { Text, View } from "react-native";
|
|
import { Dropdown } from "react-native-element-dropdown";
|
|
import type { DropdownOption } from '@packages/shared';
|
|
|
|
export type { DropdownOption } from '@packages/shared';
|
|
|
|
// Common dropdown scaffold — value/onValueChange stay per-variant because the
|
|
// single dropdown carries a scalar and the bottom/multi one carries arrays.
|
|
// The option element type is generic: the bottom/multi dropdown extends the
|
|
// shared DropdownOption with a per-option disabled flag.
|
|
export interface DropdownBaseProps<O = DropdownOption> {
|
|
label: string;
|
|
options: O[];
|
|
error?: boolean;
|
|
style?: any;
|
|
placeholder?: string;
|
|
disabled?: boolean;
|
|
className?: string;
|
|
}
|
|
|
|
interface Props extends DropdownBaseProps {
|
|
value: string | number;
|
|
onValueChange: (value: string | number) => void;
|
|
}
|
|
|
|
const CustomDropdown: React.FC<Props> = ({
|
|
label,
|
|
value,
|
|
options,
|
|
onValueChange,
|
|
error,
|
|
style,
|
|
placeholder,
|
|
disabled,
|
|
className,
|
|
}) => {
|
|
return (
|
|
<View style={[tw``, style]}>
|
|
<Dropdown
|
|
data={options}
|
|
labelField="label"
|
|
valueField="value"
|
|
value={value}
|
|
onChange={(item) => onValueChange(item.value)}
|
|
placeholder={placeholder ?? label}
|
|
placeholderStyle={[tw`text-gray-500`, disabled && tw`text-gray-400`]}
|
|
style={[
|
|
tw`border rounded-md px-3 py-2 bg-white`,
|
|
error ? tw`border-red-500` : tw`border-gray-300`,
|
|
disabled && tw`bg-gray-100 border-gray-200`,
|
|
tw`${className || ''}`,
|
|
]}
|
|
disable={disabled}
|
|
renderItem={(item: DropdownOption) => {
|
|
const isSelected = value === item.value;
|
|
return (
|
|
<View
|
|
style={[
|
|
tw`px-3 py-2 rounded-md my-1`,
|
|
isSelected ? tw`bg-blue-50` : tw`bg-white`,
|
|
]}
|
|
>
|
|
<Text
|
|
style={[
|
|
isSelected ? tw`text-blue-800 font-semibold` : tw`text-gray-800`,
|
|
disabled && tw`text-gray-400`,
|
|
]}
|
|
>
|
|
{item.label}
|
|
</Text>
|
|
</View>
|
|
);
|
|
}}
|
|
selectedTextStyle={disabled ? tw`text-gray-400` : tw`text-gray-800 font-medium`}
|
|
// the dropdown's listProps / containerProps can be tuned if needed:
|
|
// dropdownStyle etc. Example:
|
|
// dropdownStyle={tw`bg-white`}
|
|
/>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
export default CustomDropdown;
|