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:
parent
7c0beedcab
commit
6ec73c5d92
1 changed files with 46 additions and 22 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue