From 02782d1bc50b24a0ea01522f83509cd8f0ffa1c2 Mon Sep 17 00:00:00 2001 From: Anna Polensky Date: Mon, 25 May 2026 20:40:29 +0200 Subject: [PATCH] feat: add search bar to dropdowns --- .../dropdown-input-field.tsx | 70 ++++++++++++++----- 1 file changed, 54 insertions(+), 16 deletions(-) diff --git a/frontend/src/components/core/shared/input-fields/dropdown-input-field/dropdown-input-field.tsx b/frontend/src/components/core/shared/input-fields/dropdown-input-field/dropdown-input-field.tsx index 68848d099..7448c0c10 100644 --- a/frontend/src/components/core/shared/input-fields/dropdown-input-field/dropdown-input-field.tsx +++ b/frontend/src/components/core/shared/input-fields/dropdown-input-field/dropdown-input-field.tsx @@ -33,12 +33,10 @@ const OptionsList = styled.ul` box-sizing: border-box; list-style: none; margin-top: 0; - overflow-y: auto; padding: 0; position: absolute; width: 100%; z-index: 1000; - max-height: calc(6 * ${size("inputFieldHeightDefault")}); `; const OptionItem = styled.li` @@ -71,6 +69,21 @@ const OptionItem = styled.li` } `; +const SearchContainer = styled.div` + padding: 8px; + border-bottom: 1px solid #ddd; + + input { + width: 100%; + box-sizing: border-box; + } +`; + +const OptionsScrollArea = styled.div` + overflow-y: auto; + max-height: calc(6 * ${size("inputFieldHeightDefault")}); +`; + export const DropdownInputField: React.FC = memo( function DropdownInputField({ options, value, onChange, ...props }) { const getCurrentOption = (): { label: string; value: string } => { @@ -82,6 +95,12 @@ export const DropdownInputField: React.FC = memo( getCurrentOption(), ); + const [search, setSearch] = useState(""); + + const filteredOptions = options.filter((option) => + option.label.toLowerCase().includes(search.toLowerCase()), + ); + // Sync state with props whenever options or value changes useEffect(() => { if (options.length === 0) { @@ -108,6 +127,12 @@ export const DropdownInputField: React.FC = memo( isOpen, ); + useEffect(() => { + if (!isOpen) { + setSearch(""); + } + }, [isOpen]); + const handleChange = (option: { label: string; value: string }) => { setSelectedOption(option); onChange(option.label); //TODO QUICKFIX this should be .value in the future @@ -142,20 +167,33 @@ export const DropdownInputField: React.FC = memo( {isOpen && ( - {options.length > 0 ? ( - options.map((option) => ( - { - handleChange(option); - }} - > - {option.label} - - )) - ) : ( - No results - )} + + { + setSearch(e.target.value); + }} + placeholder="Search..." + /> + + + + {filteredOptions.length > 0 ? ( + filteredOptions.map((option) => ( + { + handleChange(option); + }} + > + {option.label} + + )) + ) : ( + No results + )} + )}