import { css, cx } from '@emotion/css'; import React, { FormEvent } from 'react'; import { GrafanaTheme2, SelectableValue } from '@grafana/data'; import { CustomScrollbar, getSelectStyles, Icon, Tooltip, useStyles2, useTheme2 } from '@grafana/ui'; import { MENU_MAX_HEIGHT } from './constants'; interface Props { options: Array>; onSelect: (option: SelectableValue) => void; offset: { vertical: number; horizontal: number }; minWidth?: number; selected?: number; } export const MetricPickerMenu = ({ options, offset, minWidth, selected, onSelect }: Props) => { const theme = useTheme2(); const styles = getSelectStyles(theme); const customStyles = useStyles2(getStyles(minWidth)); return (
0 }, css` bottom: ${offset.vertical > 0 ? `${offset.vertical}px` : 'unset'}; top: ${offset.vertical < 0 ? `${Math.abs(offset.vertical)}px` : 'unset'}; ` )} >
{options?.map((option, i) => ( ))}
); }; interface MenuOptionProps { data: SelectableValue; onClick: (value: SelectableValue) => void; isFocused?: boolean; disabled?: boolean; hideDescription?: boolean; } const MenuOption = React.forwardRef>>( ({ data, isFocused, disabled, onClick, hideDescription }, ref) => { const theme = useTheme2(); const styles = getSelectStyles(theme); const customStyles = useStyles2(getStyles()); const wrapperClassName = cx( styles.option, customStyles.menuOptionWrapper, isFocused && styles.optionFocused, disabled && customStyles.menuOptionDisabled ); const onClickInternal = (event: FormEvent) => { if (disabled) { return; } event.preventDefault(); event.stopPropagation(); onClick(data); }; return (
{data.label || data.value} {!hideDescription && data.description &&
{data.description}
}
{data.description && ( )}
); } ); MenuOption.displayName = 'MenuOption'; export const getStyles = (menuWidth?: number) => (theme: GrafanaTheme2) => { return { menuWrapper: css` display: flex; max-height: 650px; position: absolute; z-index: ${theme.zIndex.dropdown}; overflow: hidden; min-width: auto; `, menu: css` min-width: ${theme.spacing(menuWidth || 0)}; & > div { padding-top: ${theme.spacing(1)}; } `, menuLeft: css` right: 0; flex-direction: row-reverse; `, container: css` padding: ${theme.spacing(1)}; border: 1px ${theme.colors.border.weak} solid; border-radius: ${theme.shape.borderRadius(1)}; background-color: ${theme.colors.background.primary}; z-index: ${theme.zIndex.modal}; `, menuOptionWrapper: css` padding: ${theme.spacing(0.5)}; `, menuOptionBody: css` font-weight: ${theme.typography.fontWeightRegular}; padding: ${theme.spacing(0, 1.5, 0, 0)}; `, menuOptionDisabled: css` color: ${theme.colors.text.disabled}; cursor: not-allowed; `, menuOptionInfoSign: css` color: ${theme.colors.text.disabled}; `, }; };