{"mappings":";;;;;;;;;;;;;AAAA;;;;;;;;;;CAUC;;;;;;AA+BM,SAAS,yCAAW,KAAuB,EAAE,GAAkC;IACpF,MAAM,EACJ,cAAc,SAAS,EACvB,mBAAmB,cAAc,eACjC,cAAc,cACf,GAAG;IACJ,IAAI,CAAC,aAAa,aAAa,GAAG,CAAA,GAAA,qBAAO,EAAE;IAC3C,4FAA4F;IAC5F,mFAAmF;IACnF,uDAAuD;IACvD,CAAA,GAAA,yCAAc,EAAE;QACd,aAAa,CAAC,CAAE,CAAA,IAAI,OAAO,IAAI,IAAI,OAAO,CAAC,aAAa,EAAE,QAAQ,mBAAkB;IACtF;IACA,MAAM,aAAC,SAAS,EAAC,GAAG,CAAA,GAAA,mCAAQ;IAC5B,MAAM,gBAAgB,cAAc,SAAS,gBAAgB;IAC7D,IAAI,eAAe,CAAA,GAAA,4CAAiB,EAAE;IAEtC,MAAM,YAAkC,CAAC;QACvC,gCAAgC;QAChC,IAAI,CAAC,CAAA,GAAA,sCAAW,EAAE,EAAE,aAAa,EAAE,CAAA,GAAA,wCAAa,EAAE,KAChD;QAEF,IACE,AAAC,gBAAgB,gBAAgB,EAAE,GAAG,KAAK,gBACvC,gBAAgB,cAAc,EAAE,GAAG,KAAK;YAC5C,IAAI,eACF,aAAa,aAAa;iBAE1B,aAAa,SAAS;eAEnB,IACL,AAAC,gBAAgB,gBAAgB,EAAE,GAAG,KAAK,eACvC,gBAAgB,cAAc,EAAE,GAAG,KAAK;YAC5C,IAAI,eACF,aAAa,SAAS;iBAEtB,aAAa,aAAa;eAEvB,IAAI,EAAE,GAAG,KAAK,OAAO;YAC1B,qDAAqD;YACrD,oDAAoD;YACpD,oDAAoD;YACpD,kDAAkD;YAClD,EAAE,eAAe;YACjB,YAAY,OAAO,GAAG,CAAA,GAAA,0CAAe;YACrC,IAAI,EAAE,QAAQ,EACZ,aAAa,UAAU;iBAEvB,aAAa,SAAS;YAExB;QACF,OACE,wEAAwE;QACxE;QAGF,iEAAiE;QACjE,EAAE,eAAe;QACjB,EAAE,cAAc;IAClB;IAEA,qEAAqE;IACrE,MAAM,cAAc,CAAA,GAAA,mBAAK,EAAsB;IAC/C,MAAM,SAAyC,CAAC;QAC9C,IAAI,CAAC,CAAA,GAAA,sCAAW,EAAE,EAAE,aAAa,EAAE,EAAE,aAAa,KAAK,CAAC,YAAY,OAAO,EACzE,YAAY,OAAO,GAAG,CAAA,GAAA,wCAAa,EAAE;IAEzC;IAEA,+EAA+E;IAC/E,oFAAoF;IACpF,8EAA8E;IAC9E,MAAM,UAA0C,CAAC;QAC/C,IAAI,YAAY,OAAO,IAAI,CAAC,CAAA,GAAA,sCAAW,EAAE,EAAE,aAAa,EAAE,EAAE,aAAa,KAAK,CAAA,GAAA,sCAAW,EAAE,IAAI,OAAO,EAAE,CAAA,GAAA,wCAAa,EAAE,KAAK;YAC1H,YAAY,OAAO,EAAE;YACrB,YAAY,OAAO,GAAG;QACxB;IACF;IAEA,OAAO;QACL,cAAc;YACZ,GAAG,CAAA,GAAA,wCAAa,EAAE,OAAO;gBAAC,WAAW;YAAI,EAAE;YAC3C,MAAM,CAAC,cAAc,YAAY;YACjC,oBAAoB;YACpB,cAAc;YACd,mBAAmB,aAAa,OAAO,iBAAiB;YACxD,kBAAkB,CAAC,cAAc,YAAY;YAC7C,gBAAgB,CAAC,cAAc,UAAU;YACzC,eAAe,CAAC,cAAc,SAAS;QACzC;IACF;AACF","sources":["packages/react-aria/src/toolbar/useToolbar.ts"],"sourcesContent":["/*\n * Copyright 2023 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {AriaLabelingProps, Orientation, RefObject} from '@react-types/shared';\nimport {createFocusManager} from '../focus/FocusScope';\nimport {filterDOMProps} from '../utils/filterDOMProps';\nimport {FocusEventHandler, HTMLAttributes, KeyboardEventHandler, useRef, useState} from 'react';\nimport {getActiveElement, getEventTarget, nodeContains} from '../utils/shadowdom/DOMFunctions';\nimport {useLayoutEffect} from '../utils/useLayoutEffect';\nimport {useLocale} from '../i18n/I18nProvider';\n\nexport interface AriaToolbarProps extends AriaLabelingProps {\n  /**\n   * The orientation of the entire toolbar.\n   * @default 'horizontal'\n   */\n  orientation?: Orientation\n}\n\nexport interface ToolbarAria {\n  /**\n   * Props for the toolbar container.\n   */\n  toolbarProps: HTMLAttributes<HTMLElement>\n}\n\n/**\n * Provides the behavior and accessibility implementation for a toolbar.\n * A toolbar is a container for a set of interactive controls with arrow key navigation.\n * @param props - Props to be applied to the toolbar.\n * @param ref - A ref to a DOM element for the toolbar.\n */\nexport function useToolbar(props: AriaToolbarProps, ref: RefObject<HTMLElement | null>): ToolbarAria {\n  const {\n    'aria-label': ariaLabel,\n    'aria-labelledby': ariaLabelledBy,\n    orientation = 'horizontal'\n  } = props;\n  let [isInToolbar, setInToolbar] = useState(false);\n  // should be safe because re-calling set state with the same value it already has is a no-op\n  // this will allow us to react should a parent re-render and change its role though\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  useLayoutEffect(() => {\n    setInToolbar(!!(ref.current && ref.current.parentElement?.closest('[role=\"toolbar\"]')));\n  });\n  const {direction} = useLocale();\n  const shouldReverse = direction === 'rtl' && orientation === 'horizontal';\n  let focusManager = createFocusManager(ref);\n\n  const onKeyDown: KeyboardEventHandler = (e) => {\n    // don't handle portalled events\n    if (!nodeContains(e.currentTarget, getEventTarget(e) as HTMLElement)) {\n      return;\n    }\n    if (\n      (orientation === 'horizontal' && e.key === 'ArrowRight')\n      || (orientation === 'vertical' && e.key === 'ArrowDown')) {\n      if (shouldReverse) {\n        focusManager.focusPrevious();\n      } else {\n        focusManager.focusNext();\n      }\n    } else if (\n      (orientation === 'horizontal' && e.key === 'ArrowLeft')\n      || (orientation === 'vertical' && e.key === 'ArrowUp')) {\n      if (shouldReverse) {\n        focusManager.focusNext();\n      } else {\n        focusManager.focusPrevious();\n      }\n    } else if (e.key === 'Tab') {\n      // When the tab key is pressed, we want to move focus\n      // out of the entire toolbar. To do this, move focus\n      // to the first or last focusable child, and let the\n      // browser handle the Tab key as usual from there.\n      e.stopPropagation();\n      lastFocused.current = getActiveElement() as HTMLElement;\n      if (e.shiftKey) {\n        focusManager.focusFirst();\n      } else {\n        focusManager.focusLast();\n      }\n      return;\n    } else {\n      // if we didn't handle anything, return early so we don't preventDefault\n      return;\n    }\n\n    // Prevent arrow keys from being handled by nested action groups.\n    e.stopPropagation();\n    e.preventDefault();\n  };\n\n  // Record the last focused child when focus moves out of the toolbar.\n  const lastFocused = useRef<HTMLElement | null>(null);\n  const onBlur: FocusEventHandler<HTMLElement> = (e) => {\n    if (!nodeContains(e.currentTarget, e.relatedTarget) && !lastFocused.current) {\n      lastFocused.current = getEventTarget(e);\n    }\n  };\n\n  // Restore focus to the last focused child when focus returns into the toolbar.\n  // If the element was removed, do nothing, either the first item in the first group,\n  // or the last item in the last group will be focused, depending on direction.\n  const onFocus: FocusEventHandler<HTMLElement> = (e) => {\n    if (lastFocused.current && !nodeContains(e.currentTarget, e.relatedTarget) && nodeContains(ref.current, getEventTarget(e))) {\n      lastFocused.current?.focus();\n      lastFocused.current = null;\n    }\n  };\n\n  return {\n    toolbarProps: {\n      ...filterDOMProps(props, {labelable: true}),\n      role: !isInToolbar ? 'toolbar' : 'group',\n      'aria-orientation': orientation,\n      'aria-label': ariaLabel,\n      'aria-labelledby': ariaLabel == null ? ariaLabelledBy : undefined,\n      onKeyDownCapture: !isInToolbar ? onKeyDown : undefined,\n      onFocusCapture: !isInToolbar ? onFocus : undefined,\n      onBlurCapture: !isInToolbar ? onBlur : undefined\n    }\n  };\n}\n"],"names":[],"version":3,"file":"useToolbar.cjs.map"}