@grafana/ui
Version:
Grafana Components Library
88 lines (85 loc) • 3.17 kB
JavaScript
import { jsxs, jsx } from 'react/jsx-runtime';
import { css } from '@emotion/css';
import { offset, flip, shift, useFloating, autoUpdate, useClick, useDismiss, useInteractions } from '@floating-ui/react';
import { FocusScope } from '@react-aria/focus';
import { memo, useState } from 'react';
import { useStyles2 } from '../../themes/ThemeContext.mjs';
import { Menu } from '../Menu/Menu.mjs';
import { MenuItem } from '../Menu/MenuItem.mjs';
import { ToolbarButton } from '../ToolbarButton/ToolbarButton.mjs';
const ButtonSelectComponent = (props) => {
const { className, options, value, onChange, narrow, variant, ...restProps } = props;
const styles = useStyles2(getStyles);
const [isOpen, setIsOpen] = useState(false);
const middleware = [
offset(0),
flip({
fallbackAxisSideDirection: "end",
// see https://floating-ui.com/docs/flip#combining-with-shift
crossAxis: false,
boundary: document.body
}),
shift()
];
const { context, refs, floatingStyles } = useFloating({
open: isOpen,
placement: "bottom-end",
onOpenChange: setIsOpen,
middleware,
whileElementsMounted: autoUpdate
});
const click = useClick(context);
const dismiss = useDismiss(context);
const { getReferenceProps, getFloatingProps } = useInteractions([dismiss, click]);
const onChangeInternal = (item) => {
onChange(item);
setIsOpen(false);
};
return /* @__PURE__ */ jsxs("div", { className: styles.wrapper, children: [
/* @__PURE__ */ jsx(
ToolbarButton,
{
className,
isOpen,
narrow,
variant,
ref: refs.setReference,
...getReferenceProps(),
...restProps,
children: (value == null ? void 0 : value.label) || ((value == null ? void 0 : value.value) != null ? String(value == null ? void 0 : value.value) : null)
}
),
isOpen && /* @__PURE__ */ jsx("div", { className: styles.menuWrapper, ref: refs.setFloating, ...getFloatingProps(), style: floatingStyles, children: /* @__PURE__ */ jsx(FocusScope, { contain: true, autoFocus: true, restoreFocus: true, children: /* @__PURE__ */ jsx(Menu, { tabIndex: -1, onClose: () => setIsOpen(false), children: options.map((item) => {
var _a;
return /* @__PURE__ */ jsx(
MenuItem,
{
label: (_a = item.label) != null ? _a : String(item.value),
onClick: () => onChangeInternal(item),
active: item.value === (value == null ? void 0 : value.value),
ariaChecked: item.value === (value == null ? void 0 : value.value),
ariaLabel: item.ariaLabel || item.label,
disabled: item.isDisabled,
component: item.component,
role: "menuitemradio"
},
`${item.value}`
);
}) }) }) })
] });
};
ButtonSelectComponent.displayName = "ButtonSelect";
const ButtonSelect = memo(ButtonSelectComponent);
const getStyles = (theme) => {
return {
wrapper: css({
position: "relative",
display: "inline-flex"
}),
menuWrapper: css({
zIndex: theme.zIndex.dropdown
})
};
};
export { ButtonSelect };
//# sourceMappingURL=ButtonSelect.mjs.map