Select: Better styling for virtualized group separators (#90127)

* better styling for group separators

* update comment

* revert back to 37
This commit is contained in:
Ashley Harrison 2024-07-08 10:32:15 +01:00 committed by GitHub
parent aaf23c64c3
commit 675457fb10
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 12 additions and 19 deletions

View File

@ -3,7 +3,7 @@ import { max } from 'lodash';
import { RefCallback, useEffect, useMemo, useRef } from 'react'; import { RefCallback, useEffect, useMemo, useRef } from 'react';
import * as React from 'react'; import * as React from 'react';
import { MenuListProps } from 'react-select'; import { MenuListProps } from 'react-select';
import { VariableSizeList as List } from 'react-window'; import { FixedSizeList as List } from 'react-window';
import { SelectableValue, toIconName } from '@grafana/data'; import { SelectableValue, toIconName } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors'; import { selectors } from '@grafana/e2e-selectors';
@ -36,10 +36,8 @@ export const SelectMenu = ({ children, maxHeight, innerRef, innerProps }: React.
SelectMenu.displayName = 'SelectMenu'; SelectMenu.displayName = 'SelectMenu';
const VIRTUAL_LIST_ITEM_HEIGHT = 37; const VIRTUAL_LIST_ITEM_HEIGHT = 37;
const VIRTUAL_DIVIDER_HEIGHT = 1;
const VIRTUAL_LIST_WIDTH_ESTIMATE_MULTIPLIER = 8; const VIRTUAL_LIST_WIDTH_ESTIMATE_MULTIPLIER = 8;
const VIRTUAL_LIST_PADDING = 8; const VIRTUAL_LIST_PADDING = 8;
const DIVIDER_KEY = 'divider';
// Some list items have icons or checkboxes so we need some extra width // Some list items have icons or checkboxes so we need some extra width
const VIRTUAL_LIST_WIDTH_EXTRA = 36; const VIRTUAL_LIST_WIDTH_EXTRA = 36;
@ -91,8 +89,16 @@ export const VirtualizedSelectMenu = ({
}); });
return [ return [
childWithoutChildren, childWithoutChildren,
...child.props.children, ...child.props.children.slice(0, -1),
<div key={`${DIVIDER_KEY}-${flattenedOptions[index].label}`} className={styles.virtualizedSeparator} />, // add a bottom divider to the last item in the category
React.cloneElement(child.props.children.at(-1), {
innerProps: {
style: {
borderBottom: `1px solid ${theme.colors.border.weak}`,
height: VIRTUAL_LIST_ITEM_HEIGHT,
},
},
}),
]; ];
} }
return [child]; return [child];
@ -103,15 +109,6 @@ export const VirtualizedSelectMenu = ({
longestOption * VIRTUAL_LIST_WIDTH_ESTIMATE_MULTIPLIER + VIRTUAL_LIST_PADDING * 2 + VIRTUAL_LIST_WIDTH_EXTRA; longestOption * VIRTUAL_LIST_WIDTH_ESTIMATE_MULTIPLIER + VIRTUAL_LIST_PADDING * 2 + VIRTUAL_LIST_WIDTH_EXTRA;
const heightEstimate = Math.min(flattenedChildren.length * VIRTUAL_LIST_ITEM_HEIGHT, maxHeight); const heightEstimate = Math.min(flattenedChildren.length * VIRTUAL_LIST_ITEM_HEIGHT, maxHeight);
const getRowHeight = (rowIndex: number) => {
const row = flattenedChildren[rowIndex];
if (row.key.includes(DIVIDER_KEY)) {
return VIRTUAL_DIVIDER_HEIGHT;
}
return VIRTUAL_LIST_ITEM_HEIGHT;
};
return ( return (
<List <List
ref={listRef} ref={listRef}
@ -120,8 +117,7 @@ export const VirtualizedSelectMenu = ({
width={widthEstimate} width={widthEstimate}
aria-label="Select options menu" aria-label="Select options menu"
itemCount={flattenedChildren.length} itemCount={flattenedChildren.length}
itemSize={getRowHeight} itemSize={VIRTUAL_LIST_ITEM_HEIGHT}
estimatedItemSize={VIRTUAL_LIST_ITEM_HEIGHT}
> >
{({ index, style }) => <div style={{ ...style, overflow: 'hidden' }}>{flattenedChildren[index]}</div>} {({ index, style }) => <div style={{ ...style, overflow: 'hidden' }}>{flattenedChildren[index]}</div>}
</List> </List>

View File

@ -163,8 +163,5 @@ export const getSelectStyles = stylesFactory((theme: GrafanaTheme2) => {
borderBottom: `1px solid ${theme.colors.border.weak}`, borderBottom: `1px solid ${theme.colors.border.weak}`,
}, },
}), }),
virtualizedSeparator: css({
borderTop: `1px solid ${theme.colors.border.weak}`,
}),
}; };
}); });