{"version":3,"file":"EditorToolbarObserver.mjs","sources":["../../../../../admin/src/pages/EditView/components/EditorToolbarObserver.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { useElementOnScreen } from '@strapi/admin/strapi-admin';\nimport { IconButton, Menu } from '@strapi/design-system';\nimport { More } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\n/* -------------------------------------------------------------------------------------------------\n * ObservedToolbarComponent\n * -----------------------------------------------------------------------------------------------*/\n\ninterface ObservedToolbarComponentProps {\n  index: number;\n  lastVisibleIndex: number;\n  setLastVisibleIndex: React.Dispatch<React.SetStateAction<number>>;\n  rootRef: React.RefObject<HTMLElement>;\n  children: React.ReactNode;\n}\n\nconst ObservedToolbarComponent = ({\n  index,\n  lastVisibleIndex,\n  setLastVisibleIndex,\n  rootRef,\n  children,\n}: ObservedToolbarComponentProps) => {\n  const isVisible = index <= lastVisibleIndex;\n\n  const containerRef = useElementOnScreen<HTMLDivElement>(\n    (isVisible) => {\n      /**\n       * It's the MoreMenu's job to make an item not visible when there's not room for it.\n       * But we need to react here to the element becoming visible again.\n       */\n      if (isVisible) {\n        setLastVisibleIndex((prev) => Math.max(prev, index));\n      }\n    },\n    { threshold: 1, root: rootRef.current }\n  );\n\n  return (\n    <div\n      ref={containerRef}\n      style={{\n        /**\n         * Use visibility so that the element occupies the space if requires even when there's not\n         * enough room for it to be visible. The empty reserved space will be clipped by the\n         * overflow:hidden rule on the parent, so it doesn't affect the UI.\n         * This way we can keep observing its visiblity and react to browser resize events.\n         */\n        visibility: isVisible ? 'visible' : 'hidden',\n      }}\n    >\n      {children}\n    </div>\n  );\n};\n\n/* -------------------------------------------------------------------------------------------------\n * EditorToolbarObserver\n * -----------------------------------------------------------------------------------------------*/\n\nexport interface ObservedComponent {\n  toolbar: React.ReactNode;\n  menu: React.ReactNode;\n  key: string;\n}\n\nexport const EditorToolbarObserver = ({\n  observedComponents,\n  menuTriggerVariant = 'ghost',\n}: {\n  observedComponents: ObservedComponent[];\n  menuTriggerVariant?: Menu.TriggerProps['variant'];\n}) => {\n  const { formatMessage } = useIntl();\n  const toolbarRef = React.useRef<HTMLElement>(null);\n\n  const [lastVisibleIndex, setLastVisibleIndex] = React.useState<number>(\n    observedComponents.length - 1\n  );\n  const hasHiddenItems = lastVisibleIndex < observedComponents.length - 1;\n  const menuIndex = lastVisibleIndex + 1;\n\n  const [open, setOpen] = React.useState(false);\n  const isMenuOpenWithContent = open && hasHiddenItems;\n  const menuTriggerRef = useElementOnScreen<HTMLButtonElement>(\n    (isVisible) => {\n      // We only react to the menu becoming invisible. When that happens, we hide the last item.\n      if (!isVisible) {\n        /**\n         * If there's no room for any item, the index can be -1.\n         * This is intentional, in that case only the more menu will be visible.\n         **/\n        setLastVisibleIndex((prev) => prev - 1);\n        // Maintain the menu state if it has content\n        setOpen(isMenuOpenWithContent);\n      }\n    },\n    { threshold: 1, root: toolbarRef.current }\n  );\n\n  return observedComponents\n    .map((component, index) => {\n      return (\n        <ObservedToolbarComponent\n          key={component.key}\n          index={index}\n          lastVisibleIndex={lastVisibleIndex}\n          setLastVisibleIndex={setLastVisibleIndex}\n          rootRef={toolbarRef}\n        >\n          {component.toolbar}\n        </ObservedToolbarComponent>\n      );\n    })\n    .toSpliced(\n      menuIndex,\n      0,\n      <Menu.Root\n        key=\"more-menu\"\n        defaultOpen={false}\n        open={isMenuOpenWithContent}\n        onOpenChange={setOpen}\n      >\n        <Menu.Trigger\n          paddingLeft={0}\n          paddingRight={0}\n          ref={menuTriggerRef}\n          variant={menuTriggerVariant}\n          style={{ visibility: hasHiddenItems ? 'visible' : 'hidden' }}\n          label={formatMessage({ id: 'global.more', defaultMessage: 'More' })}\n          tag={IconButton}\n          icon={<More />}\n        />\n        <Menu.Content\n          onCloseAutoFocus={(e) => e.preventDefault()}\n          maxHeight=\"100%\"\n          minWidth=\"256px\"\n          popoverPlacement=\"bottom-end\"\n          zIndex={2}\n        >\n          {observedComponents.slice(menuIndex).map((component) => (\n            <React.Fragment key={component.key}>{component.menu}</React.Fragment>\n          ))}\n        </Menu.Content>\n      </Menu.Root>\n    );\n};\n"],"names":["ObservedToolbarComponent","index","lastVisibleIndex","setLastVisibleIndex","rootRef","children","isVisible","containerRef","useElementOnScreen","prev","Math","max","threshold","root","current","_jsx","div","ref","style","visibility","EditorToolbarObserver","observedComponents","menuTriggerVariant","formatMessage","useIntl","toolbarRef","React","useRef","useState","length","hasHiddenItems","menuIndex","open","setOpen","isMenuOpenWithContent","menuTriggerRef","map","component","toolbar","key","toSpliced","_jsxs","Menu","Root","defaultOpen","onOpenChange","Trigger","paddingLeft","paddingRight","variant","label","id","defaultMessage","tag","IconButton","icon","More","Content","onCloseAutoFocus","e","preventDefault","maxHeight","minWidth","popoverPlacement","zIndex","slice","Fragment","menu"],"mappings":"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"}