{"mappings":"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","sources":["packages/react-aria/src/grid/useGridCell.ts"],"sourcesContent":["/*\n * Copyright 2020 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 {DOMAttributes, FocusableElement, Key, RefObject} from '@react-types/shared';\nimport {focusSafely} from '../interactions/focusSafely';\nimport {getActiveElement, getEventTarget, isFocusWithin, nodeContains} from '../utils/shadowdom/DOMFunctions';\nimport {getFocusableTreeWalker} from '../focus/FocusScope';\nimport {getScrollParent} from '../utils/getScrollParent';\nimport {IGridCollection as GridCollection, GridNode} from 'react-stately/private/grid/GridCollection';\nimport {gridMap} from './utils';\nimport {GridState} from 'react-stately/private/grid/useGridState';\nimport {isFocusVisible} from '../interactions/useFocusVisible';\nimport {mergeProps} from '../utils/mergeProps';\nimport {KeyboardEvent as ReactKeyboardEvent, useRef} from 'react';\nimport {scrollIntoViewport} from '../utils/scrollIntoView';\nimport {useLocale} from '../i18n/I18nProvider';\nimport {useSelectableItem} from '../selection/useSelectableItem';\n\nexport interface GridCellProps {\n  /** An object representing the grid cell. Contains all the relevant information that makes up the grid cell. */\n  node: GridNode<unknown>,\n  /** Whether the grid cell is contained in a virtual scroller. */\n  isVirtualized?: boolean,\n  /** Whether the cell or its first focusable child element should be focused when the grid cell is focused. */\n  focusMode?: 'child' | 'cell',\n  /** Whether selection should occur on press up instead of press down. */\n  shouldSelectOnPressUp?: boolean,\n  /** Indicates how many columns the data cell spans. */\n  colSpan?: number,\n  /**\n   * Handler that is called when a user performs an action on the cell.\n   * Please use onCellAction at the collection level instead.\n   * @deprecated\n   **/\n  onAction?: () => void\n}\n\nexport interface GridCellAria {\n  /** Props for the grid cell element. */\n  gridCellProps: DOMAttributes,\n  /** Whether the cell is currently in a pressed state. */\n  isPressed: boolean\n}\n\n/**\n * Provides the behavior and accessibility implementation for a cell in a grid.\n * @param props - Props for the cell.\n * @param state - State of the parent grid, as returned by `useGridState`.\n */\nexport function useGridCell<T, C extends GridCollection<T>>(props: GridCellProps, state: GridState<T, C>, ref: RefObject<FocusableElement | null>): GridCellAria {\n  let {\n    node,\n    isVirtualized,\n    focusMode = 'child',\n    shouldSelectOnPressUp,\n    onAction\n  } = props;\n\n  let {direction} = useLocale();\n  let {keyboardDelegate, actions: {onCellAction}} = gridMap.get(state)!;\n\n  // We need to track the key of the item at the time it was last focused so that we force\n  // focus to go to the item when the DOM node is reused for a different item in a virtualizer.\n  let keyWhenFocused = useRef<Key | null>(null);\n\n  // Handles focusing the cell. If there is a focusable child,\n  // it is focused, otherwise the cell itself is focused.\n  let focus = () => {\n    if (ref.current) {\n      let treeWalker = getFocusableTreeWalker(ref.current);\n      if (focusMode === 'child') {\n        // If focus is already on a focusable child within the cell, early return so we don't shift focus\n        if (isFocusWithin(ref.current) && ref.current !== getActiveElement()) {\n          return;\n        }\n\n        let focusable = state.selectionManager.childFocusStrategy === 'last'\n          ? last(treeWalker)\n          : treeWalker.firstChild() as FocusableElement;\n        if (focusable) {\n          focusSafely(focusable);\n          return;\n        }\n      }\n\n      if (\n        (keyWhenFocused.current != null && node.key !== keyWhenFocused.current) ||\n        !isFocusWithin(ref.current)\n      ) {\n        focusSafely(ref.current);\n      }\n    }\n  };\n\n  let {itemProps, isPressed} = useSelectableItem({\n    selectionManager: state.selectionManager,\n    key: node.key,\n    ref,\n    isVirtualized,\n    focus,\n    shouldSelectOnPressUp,\n    onAction: onCellAction ? () => onCellAction(node.key) : onAction,\n    isDisabled: state.collection.size === 0\n  });\n\n  let onKeyDownCapture = (e: ReactKeyboardEvent) => {\n    let activeElement = getActiveElement();\n    if (!nodeContains(e.currentTarget, getEventTarget(e) as Element) || state.isKeyboardNavigationDisabled || !ref.current || !activeElement) {\n      return;\n    }\n\n    let walker = getFocusableTreeWalker(ref.current);\n    walker.currentNode = activeElement;\n\n    switch (e.key) {\n      case 'ArrowLeft': {\n        // Find the next focusable element within the cell.\n        let focusable: FocusableElement | null = direction === 'rtl'\n          ? walker.nextNode() as FocusableElement\n          : walker.previousNode() as FocusableElement;\n\n        // Don't focus the cell itself if focusMode is \"child\"\n        if (focusMode === 'child' && focusable === ref.current) {\n          focusable = null;\n        }\n\n        e.preventDefault();\n        e.stopPropagation();\n        if (focusable) {\n          focusSafely(focusable);\n          scrollIntoViewport(focusable, {containingElement: getScrollParent(ref.current)});\n        } else {\n          // If there is no next focusable child, then move to the next cell to the left of this one.\n          // This will be handled by useSelectableCollection. However, if there is no cell to the left\n          // of this one, only one column, and the grid doesn't focus rows, then the next key will be the\n          // same as this one. In that case we need to handle focusing either the cell or the first/last\n          // child, depending on the focus mode.\n          let prev = keyboardDelegate.getKeyLeftOf?.(node.key);\n          if (prev !== node.key) {\n            // We prevent the capturing event from reaching children of the cell, e.g. pickers.\n            // We want arrow keys to navigate to the next cell instead. We need to re-dispatch\n            // the event from a higher parent so it still bubbles and gets handled by useSelectableCollection.\n            ref.current.parentElement?.dispatchEvent(\n              new KeyboardEvent(e.nativeEvent.type, e.nativeEvent)\n            );\n            break;\n          }\n\n          if (focusMode === 'cell' && direction === 'rtl') {\n            focusSafely(ref.current);\n            scrollIntoViewport(ref.current, {containingElement: getScrollParent(ref.current)});\n          } else {\n            walker.currentNode = ref.current;\n            focusable = direction === 'rtl'\n              ? walker.firstChild() as FocusableElement\n              : last(walker);\n            if (focusable) {\n              focusSafely(focusable);\n              scrollIntoViewport(focusable, {containingElement: getScrollParent(ref.current)});\n            }\n          }\n        }\n        break;\n      }\n      case 'ArrowRight': {\n        let focusable: FocusableElement | null = direction === 'rtl'\n          ? walker.previousNode() as FocusableElement\n          : walker.nextNode() as FocusableElement;\n\n        if (focusMode === 'child' && focusable === ref.current) {\n          focusable = null;\n        }\n\n        e.preventDefault();\n        e.stopPropagation();\n        if (focusable) {\n          focusSafely(focusable);\n          scrollIntoViewport(focusable, {containingElement: getScrollParent(ref.current)});\n        } else {\n          let next = keyboardDelegate.getKeyRightOf?.(node.key);\n          if (next !== node.key) {\n            // We prevent the capturing event from reaching children of the cell, e.g. pickers.\n            // We want arrow keys to navigate to the next cell instead. We need to re-dispatch\n            // the event from a higher parent so it still bubbles and gets handled by useSelectableCollection.\n            ref.current.parentElement?.dispatchEvent(\n              new KeyboardEvent(e.nativeEvent.type, e.nativeEvent)\n            );\n            break;\n          }\n\n          if (focusMode === 'cell' && direction === 'ltr') {\n            focusSafely(ref.current);\n            scrollIntoViewport(ref.current, {containingElement: getScrollParent(ref.current)});\n          } else {\n            walker.currentNode = ref.current;\n            focusable = direction === 'rtl'\n              ? last(walker)\n              : walker.firstChild() as FocusableElement;\n            if (focusable) {\n              focusSafely(focusable);\n              scrollIntoViewport(focusable, {containingElement: getScrollParent(ref.current)});\n            }\n          }\n        }\n        break;\n      }\n      case 'ArrowUp':\n      case 'ArrowDown':\n        // Prevent this event from reaching cell children, e.g. menu buttons. We want arrow keys to navigate\n        // to the cell above/below instead. We need to re-dispatch the event from a higher parent so it still\n        // bubbles and gets handled by useSelectableCollection.\n        if (!e.altKey && nodeContains(ref.current, getEventTarget(e) as Element)) {\n          e.stopPropagation();\n          e.preventDefault();\n          ref.current.parentElement?.dispatchEvent(\n            new KeyboardEvent(e.nativeEvent.type, e.nativeEvent)\n          );\n        }\n        break;\n    }\n  };\n\n  // Grid cells can have focusable elements inside them. In this case, focus should\n  // be marshalled to that element rather than focusing the cell itself.\n  let onFocus = (e) => {\n    keyWhenFocused.current = node.key;\n    if (getEventTarget(e) !== ref.current) {\n      // useSelectableItem only handles setting the focused key when\n      // the focused element is the gridcell itself. We also want to\n      // set the focused key when a child element receives focus.\n      // If focus is currently visible (e.g. the user is navigating with the keyboard),\n      // then skip this. We want to restore focus to the previously focused row/cell\n      // in that case since the table should act like a single tab stop.\n      if (!isFocusVisible()) {\n        state.selectionManager.setFocusedKey(node.key);\n      }\n      return;\n    }\n\n    // If the cell itself is focused, wait a frame so that focus finishes propagatating\n    // up to the tree, and move focus to a focusable child if possible.\n    requestAnimationFrame(() => {\n      if (focusMode === 'child' && getActiveElement() === ref.current) {\n        focus();\n      }\n    });\n  };\n\n  let gridCellProps: DOMAttributes = mergeProps(itemProps, {\n    role: 'gridcell',\n    onKeyDownCapture,\n    'aria-colspan': node.colSpan,\n    'aria-colindex': node.colIndex != null ? node.colIndex + 1 : undefined, // aria-colindex is 1-based\n    colSpan: isVirtualized ? undefined : node.colSpan,\n    onFocus\n  });\n\n  if (isVirtualized) {\n    gridCellProps['aria-colindex'] = (node.colIndex ?? node.index) + 1; // aria-colindex is 1-based\n  }\n\n  // When pressing with a pointer and cell selection is not enabled, usePress will be applied to the\n  // row rather than the cell. However, when the row is draggable, usePress cannot preventDefault\n  // on pointer down, so the browser will try to focus the cell which has a tabIndex applied.\n  // To avoid this, remove the tabIndex from the cell briefly on pointer down.\n  if (shouldSelectOnPressUp && gridCellProps.tabIndex != null && gridCellProps.onPointerDown == null) {\n    gridCellProps.onPointerDown = (e) => {\n      let el = e.currentTarget;\n      let tabindex = el.getAttribute('tabindex');\n      el.removeAttribute('tabindex');\n      requestAnimationFrame(() => {\n        if (tabindex != null) {\n          el.setAttribute('tabindex', tabindex);\n        }\n      });\n    };\n  }\n\n  return {\n    gridCellProps,\n    isPressed\n  };\n}\n\nfunction last(walker: TreeWalker) {\n  let next: FocusableElement | null = null;\n  let last: FocusableElement | null = null;\n  do {\n    last = walker.lastChild() as FocusableElement | null;\n    if (last) {\n      next = last;\n    }\n  } while (last);\n  return next;\n}\n"],"names":[],"version":3,"file":"useGridCell.cjs.map"}