{
  "version": 3,
  "sources": ["../../src/navigable-container/container.tsx"],
  "sourcesContent": ["/**\n * External dependencies\n */\n\n/**\n * WordPress dependencies\n */\nimport { Component, forwardRef } from '@wordpress/element';\nimport { focus } from '@wordpress/dom';\n\n/**\n * Internal dependencies\n */\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nconst noop = () => {};\nconst MENU_ITEM_ROLES = ['menuitem', 'menuitemradio', 'menuitemcheckbox'];\nfunction cycleValue(value, total, offset) {\n  const nextValue = value + offset;\n  if (nextValue < 0) {\n    return total + nextValue;\n  } else if (nextValue >= total) {\n    return nextValue - total;\n  }\n  return nextValue;\n}\nclass NavigableContainer extends Component {\n  constructor(args) {\n    super(args);\n    this.onKeyDown = this.onKeyDown.bind(this);\n    this.bindContainer = this.bindContainer.bind(this);\n    this.getFocusableContext = this.getFocusableContext.bind(this);\n    this.getFocusableIndex = this.getFocusableIndex.bind(this);\n  }\n  componentDidMount() {\n    if (!this.container) {\n      return;\n    }\n\n    // We use DOM event listeners instead of React event listeners\n    // because we want to catch events from the underlying DOM tree\n    // The React Tree can be different from the DOM tree when using\n    // portals. Block Toolbars for instance are rendered in a separate\n    // React Trees.\n    this.container.addEventListener('keydown', this.onKeyDown);\n  }\n  componentWillUnmount() {\n    if (!this.container) {\n      return;\n    }\n    this.container.removeEventListener('keydown', this.onKeyDown);\n  }\n  bindContainer(ref) {\n    const {\n      forwardedRef\n    } = this.props;\n    this.container = ref;\n    if (typeof forwardedRef === 'function') {\n      forwardedRef(ref);\n    } else if (forwardedRef && 'current' in forwardedRef) {\n      forwardedRef.current = ref;\n    }\n  }\n  getFocusableContext(target) {\n    if (!this.container) {\n      return null;\n    }\n    const {\n      onlyBrowserTabstops\n    } = this.props;\n    const finder = onlyBrowserTabstops ? focus.tabbable : focus.focusable;\n    const focusables = finder.find(this.container);\n    const index = this.getFocusableIndex(focusables, target);\n    if (index > -1 && target) {\n      return {\n        index,\n        target,\n        focusables\n      };\n    }\n    return null;\n  }\n  getFocusableIndex(focusables, target) {\n    return focusables.indexOf(target);\n  }\n  onKeyDown(event) {\n    if (this.props.onKeyDown) {\n      this.props.onKeyDown(event);\n    }\n    const {\n      getFocusableContext\n    } = this;\n    const {\n      cycle = true,\n      eventToOffset,\n      onNavigate = noop,\n      stopNavigationEvents\n    } = this.props;\n    const offset = eventToOffset(event);\n\n    // eventToOffset returns undefined if the event is not handled by the component.\n    if (offset !== undefined && stopNavigationEvents) {\n      // Prevents arrow key handlers bound to the document directly interfering.\n      event.stopImmediatePropagation();\n\n      // When navigating a collection of items, prevent scroll containers\n      // from scrolling. The preventDefault also prevents Voiceover from\n      // 'handling' the event, as voiceover will try to use arrow keys\n      // for highlighting text.\n      const targetRole = event.target?.getAttribute('role');\n      const targetHasMenuItemRole = !!targetRole && MENU_ITEM_ROLES.includes(targetRole);\n      if (targetHasMenuItemRole) {\n        event.preventDefault();\n      }\n    }\n    if (!offset) {\n      return;\n    }\n    const activeElement = event.target?.ownerDocument?.activeElement;\n    if (!activeElement) {\n      return;\n    }\n    const context = getFocusableContext(activeElement);\n    if (!context) {\n      return;\n    }\n    const {\n      index,\n      focusables\n    } = context;\n    const nextIndex = cycle ? cycleValue(index, focusables.length, offset) : index + offset;\n    if (nextIndex >= 0 && nextIndex < focusables.length) {\n      focusables[nextIndex].focus();\n      onNavigate(nextIndex, focusables[nextIndex]);\n\n      // `preventDefault()` on tab to avoid having the browser move the focus\n      // after this component has already moved it.\n      if (event.code === 'Tab') {\n        event.preventDefault();\n      }\n    }\n  }\n  render() {\n    const {\n      children,\n      stopNavigationEvents,\n      eventToOffset,\n      onNavigate,\n      onKeyDown,\n      cycle,\n      onlyBrowserTabstops,\n      forwardedRef,\n      ...restProps\n    } = this.props;\n    return /*#__PURE__*/_jsx(\"div\", {\n      ref: this.bindContainer,\n      ...restProps,\n      children: children\n    });\n  }\n}\nconst forwardedNavigableContainer = (props, ref) => {\n  return /*#__PURE__*/_jsx(NavigableContainer, {\n    ...props,\n    forwardedRef: ref\n  });\n};\nforwardedNavigableContainer.displayName = 'NavigableContainer';\nexport default forwardRef(forwardedNavigableContainer);"],
  "mappings": "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",
  "names": ["_jsx"]
}
