Combobox: Menu places itself under topnav (#96545)

This commit is contained in:
Laura Fernández 2024-11-18 12:00:24 +01:00 committed by GitHub
parent 76444c7913
commit 30bbcf8200
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -12,6 +12,7 @@ import { AutoSizeInput } from '../Input/AutoSizeInput';
import { Input, Props as InputProps } from '../Input/Input'; import { Input, Props as InputProps } from '../Input/Input';
import { Box } from '../Layout/Box/Box'; import { Box } from '../Layout/Box/Box';
import { Stack } from '../Layout/Stack/Stack'; import { Stack } from '../Layout/Stack/Stack';
import { Portal } from '../Portal/Portal';
import { ScrollContainer } from '../ScrollContainer/ScrollContainer'; import { ScrollContainer } from '../ScrollContainer/ScrollContainer';
import { getComboboxStyles, MENU_OPTION_HEIGHT } from './getComboboxStyles'; import { getComboboxStyles, MENU_OPTION_HEIGHT } from './getComboboxStyles';
@ -379,68 +380,70 @@ export const Combobox = <T extends string | number>(props: ComboboxProps<T>) =>
placeholder, placeholder,
})} })}
/> />
<div <Portal>
className={cx(styles.menu, !isOpen && styles.menuClosed)} <div
style={{ className={cx(styles.menu, !isOpen && styles.menuClosed)}
...floatStyles, style={{
}} ...floatStyles,
{...getMenuProps({ }}
ref: floatingRef, {...getMenuProps({
'aria-labelledby': ariaLabelledBy, ref: floatingRef,
})} 'aria-labelledby': ariaLabelledBy,
> })}
{isOpen && ( >
<ScrollContainer showScrollIndicators maxHeight="inherit" ref={scrollRef}> {isOpen && (
{!asyncError && ( <ScrollContainer showScrollIndicators maxHeight="inherit" ref={scrollRef}>
<ul style={{ height: rowVirtualizer.getTotalSize() }} className={styles.menuUlContainer}> {!asyncError && (
{rowVirtualizer.getVirtualItems().map((virtualRow) => { <ul style={{ height: rowVirtualizer.getTotalSize() }} className={styles.menuUlContainer}>
return ( {rowVirtualizer.getVirtualItems().map((virtualRow) => {
<li return (
key={`${items[virtualRow.index].value}-${virtualRow.index}`} <li
data-index={virtualRow.index} key={`${items[virtualRow.index].value}-${virtualRow.index}`}
className={cx( data-index={virtualRow.index}
styles.option, className={cx(
selectedItem && items[virtualRow.index].value === selectedItem.value && styles.optionSelected, styles.option,
highlightedIndex === virtualRow.index && styles.optionFocused selectedItem && items[virtualRow.index].value === selectedItem.value && styles.optionSelected,
)} highlightedIndex === virtualRow.index && styles.optionFocused
style={{
height: virtualRow.size,
transform: `translateY(${virtualRow.start}px)`,
}}
{...getItemProps({
item: items[virtualRow.index],
index: virtualRow.index,
})}
>
<div className={styles.optionBody}>
<span className={styles.optionLabel}>
{items[virtualRow.index].label ?? items[virtualRow.index].value}
</span>
{items[virtualRow.index].description && (
<span className={styles.optionDescription}>{items[virtualRow.index].description}</span>
)} )}
</div> style={{
</li> height: virtualRow.size,
); transform: `translateY(${virtualRow.start}px)`,
})} }}
</ul> {...getItemProps({
)} item: items[virtualRow.index],
<div aria-live="polite"> index: virtualRow.index,
{asyncError && ( })}
<MessageRow> >
<Icon name="exclamation-triangle" size="md" className={styles.warningIcon} /> <div className={styles.optionBody}>
<Trans i18nKey="combobox.async.error">An error occurred while loading options.</Trans> <span className={styles.optionLabel}>
</MessageRow> {items[virtualRow.index].label ?? items[virtualRow.index].value}
</span>
{items[virtualRow.index].description && (
<span className={styles.optionDescription}>{items[virtualRow.index].description}</span>
)}
</div>
</li>
);
})}
</ul>
)} )}
{items.length === 0 && !asyncError && ( <div aria-live="polite">
<MessageRow> {asyncError && (
<Trans i18nKey="combobox.options.no-found">No options found.</Trans> <MessageRow>
</MessageRow> <Icon name="exclamation-triangle" size="md" className={styles.warningIcon} />
)} <Trans i18nKey="combobox.async.error">An error occurred while loading options.</Trans>
</div> </MessageRow>
</ScrollContainer> )}
)} {items.length === 0 && !asyncError && (
</div> <MessageRow>
<Trans i18nKey="combobox.options.no-found">No options found.</Trans>
</MessageRow>
)}
</div>
</ScrollContainer>
)}
</div>
</Portal>
</div> </div>
); );
}; };