{"version":3,"file":"ToolbarButtonRow.mjs","sources":["../../../../src/components/ToolbarButton/ToolbarButtonRow.tsx"],"sourcesContent":["import { css, cx } from '@emotion/css';\nimport { useDialog } from '@react-aria/dialog';\nimport { FocusScope } from '@react-aria/focus';\nimport { useOverlay } from '@react-aria/overlays';\nimport { Children, forwardRef, HTMLAttributes, useState, useRef, useLayoutEffect, createRef } from 'react';\n\nimport { GrafanaTheme2 } from '@grafana/data';\n\nimport { useTheme2 } from '../../themes';\nimport { t } from '../../utils/i18n';\nimport { getPortalContainer } from '../Portal/Portal';\n\nimport { ToolbarButton } from './ToolbarButton';\nexport interface Props extends HTMLAttributes<HTMLDivElement> {\n  className?: string;\n  /** Determine flex-alignment of child buttons. Needed for overflow behaviour. */\n  alignment?: 'left' | 'right';\n}\n\nexport const ToolbarButtonRow = forwardRef<HTMLDivElement, Props>(\n  ({ alignment = 'left', className, children, ...rest }, ref) => {\n    // null/undefined are valid react children so we need to filter them out to prevent unnecessary padding\n    const childrenWithoutNull = Children.toArray(children).filter((child) => child != null);\n    const [childVisibility, setChildVisibility] = useState<boolean[]>(Array(childrenWithoutNull.length).fill(false));\n    const containerRef = useRef<HTMLDivElement>(null);\n    const [showOverflowItems, setShowOverflowItems] = useState(false);\n    const overflowRef = useRef<HTMLDivElement>(null);\n    const overflowItemsRef = createRef<HTMLDivElement>();\n    const { overlayProps } = useOverlay(\n      {\n        onClose: () => setShowOverflowItems(false),\n        isDismissable: true,\n        isOpen: showOverflowItems,\n        shouldCloseOnInteractOutside: (element: Element) => {\n          const portalContainer = getPortalContainer();\n          return !overflowRef.current?.contains(element) && !portalContainer.contains(element);\n        },\n      },\n      overflowItemsRef\n    );\n    const { dialogProps } = useDialog({}, overflowItemsRef);\n    const theme = useTheme2();\n    const overflowButtonOrder = alignment === 'left' ? childVisibility.indexOf(false) - 1 : childVisibility.length;\n    const styles = getStyles(theme, overflowButtonOrder, alignment);\n\n    useLayoutEffect(() => {\n      const intersectionObserver = new IntersectionObserver(\n        (entries) => {\n          entries.forEach((entry) => {\n            if (entry.target instanceof HTMLElement && entry.target.parentNode) {\n              const index = Array.prototype.indexOf.call(entry.target.parentNode.children, entry.target);\n              setChildVisibility((prev) => {\n                const newVisibility = [...prev];\n                newVisibility[index] = entry.isIntersecting;\n                return newVisibility;\n              });\n            }\n          });\n        },\n        {\n          threshold: 1,\n          root: containerRef.current,\n        }\n      );\n      if (containerRef.current) {\n        Array.from(containerRef.current.children).forEach((item) => {\n          // don't observe the overflow button\n          if (item instanceof HTMLElement && item !== overflowRef.current) {\n            intersectionObserver.observe(item);\n          }\n        });\n      }\n      return () => intersectionObserver.disconnect();\n    }, [children]);\n\n    return (\n      <div ref={containerRef} className={cx(styles.container, className)} {...rest}>\n        {childrenWithoutNull.map((child, index) => (\n          <div\n            key={index}\n            style={{ order: index, visibility: childVisibility[index] ? 'visible' : 'hidden' }}\n            className={styles.childWrapper}\n          >\n            {child}\n          </div>\n        ))}\n        {childVisibility.includes(false) && (\n          <div ref={overflowRef} className={styles.overflowButton}>\n            <ToolbarButton\n              variant={showOverflowItems ? 'active' : 'default'}\n              tooltip={t('grafana-ui.toolbar-button-row.show-more', 'Show more items')}\n              onClick={() => setShowOverflowItems(!showOverflowItems)}\n              icon=\"ellipsis-v\"\n              iconOnly\n              narrow\n            />\n            {showOverflowItems && (\n              <FocusScope contain autoFocus>\n                <div className={styles.overflowItems} ref={overflowItemsRef} {...overlayProps} {...dialogProps}>\n                  {childrenWithoutNull.map((child, index) => !childVisibility[index] && child)}\n                </div>\n              </FocusScope>\n            )}\n          </div>\n        )}\n      </div>\n    );\n  }\n);\n\nToolbarButtonRow.displayName = 'ToolbarButtonRow';\n\nconst getStyles = (theme: GrafanaTheme2, overflowButtonOrder: number, alignment: Props['alignment']) => ({\n  overflowButton: css({\n    order: overflowButtonOrder,\n  }),\n  overflowItems: css({\n    alignItems: 'center',\n    backgroundColor: theme.colors.background.primary,\n    borderRadius: theme.shape.radius.default,\n    boxShadow: theme.shadows.z2,\n    display: 'flex',\n    flexWrap: 'wrap',\n    gap: theme.spacing(1),\n    marginTop: theme.spacing(1),\n    maxWidth: '80vw',\n    padding: theme.spacing(0.5, 1),\n    position: 'absolute',\n    right: 0,\n    top: '100%',\n    width: 'max-content',\n    zIndex: theme.zIndex.dropdown,\n  }),\n  container: css({\n    alignItems: 'center',\n    display: 'flex',\n    gap: theme.spacing(1),\n    justifyContent: alignment === 'left' ? 'flex-start' : 'flex-end',\n    minWidth: 0,\n    position: 'relative',\n  }),\n  childWrapper: css({\n    alignItems: 'center',\n    display: 'flex',\n    gap: theme.spacing(1),\n  }),\n});\n"],"names":[],"mappings":"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"}