diff --git a/packages/grafana-ui/package.json b/packages/grafana-ui/package.json index 1969f86d804..c480fa45c7e 100644 --- a/packages/grafana-ui/package.json +++ b/packages/grafana-ui/package.json @@ -39,8 +39,11 @@ "@grafana/slate-react": "0.22.10-grafana", "@monaco-editor/react": "4.3.1", "@popperjs/core": "2.5.4", + "@react-aria/button": "3.3.4", "@react-aria/focus": "3.5.0", + "@react-aria/menu": "3.3.0", "@react-aria/overlays": "3.7.2", + "@react-stately/menu": "3.2.3", "@sentry/browser": "6.15.0", "ansicolor": "1.1.95", "calculate-size": "1.1.1", diff --git a/packages/grafana-ui/src/components/Dropdown/ButtonSelect.tsx b/packages/grafana-ui/src/components/Dropdown/ButtonSelect.tsx index 45f2ce981eb..74b3075783e 100644 --- a/packages/grafana-ui/src/components/Dropdown/ButtonSelect.tsx +++ b/packages/grafana-ui/src/components/Dropdown/ButtonSelect.tsx @@ -1,4 +1,4 @@ -import React, { useState, HTMLAttributes } from 'react'; +import React, { HTMLAttributes } from 'react'; import { PopoverContent } from '../Tooltip/Tooltip'; import { GrafanaTheme2, SelectableValue } from '@grafana/data'; import { ToolbarButtonVariant, ToolbarButton, ButtonGroup } from '../Button'; @@ -8,6 +8,9 @@ import { useStyles2 } from '../../themes/ThemeContext'; import { Menu } from '../Menu/Menu'; import { MenuItem } from '../Menu/MenuItem'; import { FocusScope } from '@react-aria/focus'; +import { useMenuTriggerState } from '@react-stately/menu'; +import { useMenuTrigger } from '@react-aria/menu'; +import { useButton } from '@react-aria/button'; export interface Props extends HTMLAttributes { className?: string; @@ -25,49 +28,36 @@ export interface Props extends HTMLAttributes { */ const ButtonSelectComponent = (props: Props) => { const { className, options, value, onChange, narrow, variant, ...restProps } = props; - const [isOpen, setIsOpen] = useState(false); const styles = useStyles2(getStyles); + const state = useMenuTriggerState({}); - const onCloseMenu = () => { - setIsOpen(false); - }; - - const onToggle = (event: React.MouseEvent) => { - event.stopPropagation(); - event.preventDefault(); - setIsOpen(!isOpen); - }; - - const onArrowKeyDown = (event: React.KeyboardEvent) => { - event.stopPropagation(); - if (event.key === 'ArrowDown' || event.key === 'Enter') { - setIsOpen(!isOpen); - } - }; + const ref = React.useRef(null); + const { menuTriggerProps, menuProps } = useMenuTrigger({}, state, ref); + const { buttonProps } = useButton(menuTriggerProps, ref); const onChangeInternal = (item: SelectableValue) => { onChange(item); - setIsOpen(false); + state.close(); }; return ( {value?.label || value?.value} - {isOpen && ( + {state.isOpen && (
- + - + {options.map((item) => (