@grafana/ui
Version:
Grafana Components Library
136 lines (131 loc) • 5.32 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var jsxRuntime = require('react/jsx-runtime');
var css = require('@emotion/css');
var dialog = require('@react-aria/dialog');
var focus = require('@react-aria/focus');
var overlays = require('@react-aria/overlays');
var React = require('react');
var i18n = require('@grafana/i18n');
var ThemeContext = require('../../themes/ThemeContext.cjs');
var Portal = require('../Portal/Portal.cjs');
var ToolbarButton = require('./ToolbarButton.cjs');
"use strict";
const ToolbarButtonRow = React.forwardRef(
({ alignment = "left", className, children, ...rest }, ref) => {
const childrenWithoutNull = React.Children.toArray(children).filter((child) => child != null);
const [childVisibility, setChildVisibility] = React.useState(Array(childrenWithoutNull.length).fill(false));
const containerRef = React.useRef(null);
const [showOverflowItems, setShowOverflowItems] = React.useState(false);
const overflowRef = React.useRef(null);
const overflowItemsRef = React.createRef();
const { overlayProps } = overlays.useOverlay(
{
onClose: () => setShowOverflowItems(false),
isDismissable: true,
isOpen: showOverflowItems,
shouldCloseOnInteractOutside: (element) => {
var _a;
const portalContainer = Portal.getPortalContainer();
return !((_a = overflowRef.current) == null ? void 0 : _a.contains(element)) && !portalContainer.contains(element);
}
},
overflowItemsRef
);
const { dialogProps } = dialog.useDialog({}, overflowItemsRef);
const theme = ThemeContext.useTheme2();
const overflowButtonOrder = alignment === "left" ? childVisibility.indexOf(false) - 1 : childVisibility.length;
const styles = getStyles(theme, overflowButtonOrder, alignment);
React.useLayoutEffect(() => {
const intersectionObserver = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.target instanceof HTMLElement && entry.target.parentNode) {
const index = Array.prototype.indexOf.call(entry.target.parentNode.children, entry.target);
setChildVisibility((prev) => {
const newVisibility = [...prev];
newVisibility[index] = entry.isIntersecting;
return newVisibility;
});
}
});
},
{
threshold: 1,
root: containerRef.current
}
);
if (containerRef.current) {
Array.from(containerRef.current.children).forEach((item) => {
if (item instanceof HTMLElement && item !== overflowRef.current) {
intersectionObserver.observe(item);
}
});
}
return () => intersectionObserver.disconnect();
}, [children]);
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className: css.cx(styles.container, className), ...rest, children: [
childrenWithoutNull.map((child, index) => /* @__PURE__ */ jsxRuntime.jsx(
"div",
{
style: { order: index, visibility: childVisibility[index] ? "visible" : "hidden" },
className: styles.childWrapper,
children: child
},
index
)),
childVisibility.includes(false) && /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: overflowRef, className: styles.overflowButton, children: [
/* @__PURE__ */ jsxRuntime.jsx(
ToolbarButton.ToolbarButton,
{
variant: showOverflowItems ? "active" : "default",
tooltip: i18n.t("grafana-ui.toolbar-button-row.show-more", "Show more items"),
onClick: () => setShowOverflowItems(!showOverflowItems),
icon: "ellipsis-v",
iconOnly: true,
narrow: true
}
),
showOverflowItems && /* @__PURE__ */ jsxRuntime.jsx(focus.FocusScope, { contain: true, autoFocus: true, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles.overflowItems, ref: overflowItemsRef, ...overlayProps, ...dialogProps, children: childrenWithoutNull.map((child, index) => !childVisibility[index] && child) }) })
] })
] });
}
);
ToolbarButtonRow.displayName = "ToolbarButtonRow";
const getStyles = (theme, overflowButtonOrder, alignment) => ({
overflowButton: css.css({
order: overflowButtonOrder
}),
overflowItems: css.css({
alignItems: "center",
backgroundColor: theme.colors.background.primary,
borderRadius: theme.shape.radius.default,
boxShadow: theme.shadows.z2,
display: "flex",
flexWrap: "wrap",
gap: theme.spacing(1),
marginTop: theme.spacing(1),
maxWidth: "80vw",
padding: theme.spacing(0.5, 1),
position: "absolute",
right: 0,
top: "100%",
width: "max-content",
zIndex: theme.zIndex.dropdown
}),
container: css.css({
alignItems: "center",
display: "flex",
gap: theme.spacing(1),
justifyContent: alignment === "left" ? "flex-start" : "flex-end",
minWidth: 0,
position: "relative"
}),
childWrapper: css.css({
alignItems: "center",
display: "flex",
gap: theme.spacing(1)
})
});
exports.ToolbarButtonRow = ToolbarButtonRow;
//# sourceMappingURL=ToolbarButtonRow.cjs.map