fix: Icons on dropdown are inconsistent when search/selecting (#7875)

* fix: improve metadata mapping for dropdown options

* fix: refactor dropdown component to streamline selected icon rendering
This commit is contained in:
Deon Sanchez 2025-05-02 08:45:04 -06:00 • committed by GitHub
commit 6ec73c5d92
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -156,17 +156,21 @@ export default function Dropdown({
// Update filteredOptions with the search results // Update filteredOptions with the search results
setFilteredOptions(filtered); setFilteredOptions(filtered);
// Update filteredMetadata to match the filtered options // Create a new metadata array that directly maps to filtered options
if (optionsMetaData) { if (optionsMetaData) {
const newMetadata = filtered // Create a map of option -> metadata for quick lookup
.filter((option) => validOptions.includes(option)) // Only map metadata for valid options const metadataMap: Record<string, any> = {};
.map((option) => { validOptions.forEach((option, index) => {
const originalIndex = validOptions.indexOf(option); if (optionsMetaData[index]) {
return optionsMetaData[originalIndex]; metadataMap[option] = optionsMetaData[index];
}
}); });
// Map each filtered option to its metadata (or undefined for custom values)
const newMetadata = filtered.map((option) => metadataMap[option]);
setFilteredMetadata(newMetadata); setFilteredMetadata(newMetadata);
} else { } else {
setFilteredMetadata(optionsMetaData); setFilteredMetadata(undefined);
} }
}; };
@ -188,9 +192,9 @@ export default function Dropdown({
}; };
const formatTooltipContent = (option: string, index: number) => { const formatTooltipContent = (option: string, index: number) => {
if (!optionsMetaData?.[index]) return option; if (!filteredMetadata?.[index]) return option;
const metadata = optionsMetaData[index]; const metadata = filteredMetadata[index];
const metadataEntries = Object.entries(metadata) const metadataEntries = Object.entries(metadata)
.filter(([key, value]) => value !== null && key !== "icon") .filter(([key, value]) => value !== null && key !== "icon")
.map(([key, value]) => { .map(([key, value]) => {
@ -223,8 +227,24 @@ export default function Dropdown({
// If there are custom values, preserve them when resetting filtered options // If there are custom values, preserve them when resetting filtered options
if (customValuesInFiltered.length > 0 && combobox) { if (customValuesInFiltered.length > 0 && combobox) {
setFilteredOptions([...validOptions, ...customValuesInFiltered]); setFilteredOptions([...validOptions, ...customValuesInFiltered]);
// Reset filteredMetadata to match the new filteredOptions
if (optionsMetaData) {
const metadataMap: Record<string, any> = {};
validOptions.forEach((option, index) => {
if (optionsMetaData[index]) {
metadataMap[option] = optionsMetaData[index];
}
});
const newMetadata = [...validOptions, ...customValuesInFiltered].map(
(option) => metadataMap[option],
);
setFilteredMetadata(newMetadata);
}
} else { } else {
setFilteredOptions(validOptions); setFilteredOptions(validOptions);
setFilteredMetadata(optionsMetaData);
} }
} }
if (!combobox && value && !validOptions.includes(value)) { if (!combobox && value && !validOptions.includes(value)) {
@ -259,6 +279,21 @@ export default function Dropdown({
</Button> </Button>
); );
const renderSelectedIcon = () => {
const selectedIndex = filteredOptions.findIndex(
(option) => option === value,
);
const iconMetadata =
selectedIndex >= 0 ? filteredMetadata?.[selectedIndex]?.icon : undefined;
return iconMetadata ? (
<ForwardedIconComponent
name={iconMetadata}
className="h-4 w-4 flex-shrink-0"
/>
) : null;
};
const renderTriggerButton = () => ( const renderTriggerButton = () => (
<div className="flex w-full flex-col"> <div className="flex w-full flex-col">
<PopoverTrigger asChild> <PopoverTrigger asChild>
@ -286,18 +321,7 @@ export default function Dropdown({
className="flex w-full items-center gap-2 overflow-hidden" className="flex w-full items-center gap-2 overflow-hidden"
data-testid={`value-dropdown-${id}`} data-testid={`value-dropdown-${id}`}
> >
{optionsMetaData?.[ {value && <>{renderSelectedIcon()}</>}
filteredOptions.findIndex((option) => option === value)
]?.icon && (
<ForwardedIconComponent
name={
optionsMetaData?.[
filteredOptions.findIndex((option) => option === value)
]?.icon
}
className="h-4 w-4 flex-shrink-0"
/>
)}
<span className="truncate"> <span className="truncate">
{disabled ? ( {disabled ? (
RECEIVING_INPUT_VALUE RECEIVING_INPUT_VALUE