import { useMemo, useState } from "react"; import { View, TouchableOpacity } from "react-native"; import { Menu, Text, IconButton, Divider } from "react-native-paper"; import { MultiSelectGlyph } from "./filters/MultiSelectGlyph"; export type FilterOption = { value: string; label: string; icon?: React.ReactNode; }; interface FilterMultiSelectProps { label: string; options: FilterOption[]; selected: string[]; onChange: (values: string[]) => void; iconName?: string; className?: string; menuWidth?: number; showClearAll?: boolean; } export const FilterMultiSelect = ({ label, options, selected, onChange, iconName = undefined, className, menuWidth, showClearAll = true, }: FilterMultiSelectProps) => { const [visible, setVisible] = useState(false); const selectedSet = useMemo(() => new Set(selected), [selected]); const toggle = (value: string) => { const next = new Set(selectedSet); if (next.has(value)) { next.delete(value); } else { next.add(value); } onChange(Array.from(next)); }; const anchor = ( setVisible(true)} className={`flex-row items-center px-2 h-8 rounded ${className || ""}`} activeOpacity={0.7} > {label} {iconName ? ( setVisible(true)} /> ) : ( )} ); return ( setVisible(false)} anchor={anchor} contentStyle={menuWidth ? { width: menuWidth } : undefined} > {options.map((opt) => { const isSelected = selectedSet.has(opt.value); return ( toggle(opt.value)} leadingIcon={ isSelected ? "checkbox-marked" : "checkbox-blank-outline" } title={ {opt.icon ? {opt.icon} : null} {opt.label} } /> ); })} {showClearAll && ( <> onChange([])} leadingIcon="close-circle-outline" disabled={selectedSet.size === 0} title="Clear all" /> )} setVisible(false)} leadingIcon="check" title="Done" /> ); };