diff --git a/packages/@adobe/react-spectrum/src/table/Resizer.tsx b/packages/@adobe/react-spectrum/src/table/Resizer.tsx index 648e4720197..c3af2c5d954 100644 --- a/packages/@adobe/react-spectrum/src/table/Resizer.tsx +++ b/packages/@adobe/react-spectrum/src/table/Resizer.tsx @@ -8,7 +8,7 @@ import intlMessages from '../../intl/table/*.json'; import {isWebKit} from 'react-aria/private/utils/platform'; import {Key, RefObject} from '@react-types/shared'; import {mergeProps} from 'react-aria/mergeProps'; -import React, {createContext, ForwardedRef, useContext, useEffect, useState} from 'react'; +import React, {createContext, ForwardedRef, useContext} from 'react'; import ReactDOM from 'react-dom'; import styles from '@adobe/spectrum-css-temp/components/table/vars.css'; import {useLocale} from 'react-aria/I18nProvider'; @@ -63,27 +63,7 @@ export const Resizer = React.forwardRef(function Resizer( let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-spectrum/table'); let {direction} = useLocale(); - let [isPointerDown, setIsPointerDown] = useState(false); - useEffect(() => { - let setDown = e => { - if (e.pointerType === 'mouse') { - setIsPointerDown(true); - } - }; - let setUp = e => { - if (e.pointerType === 'mouse') { - setIsPointerDown(false); - } - }; - document.addEventListener('pointerdown', setDown, {capture: true}); - document.addEventListener('pointerup', setUp, {capture: true}); - return () => { - document.removeEventListener('pointerdown', setDown, {capture: true}); - document.removeEventListener('pointerup', setUp, {capture: true}); - }; - }, []); - - let {inputProps, resizerProps} = useTableColumnResize( + let {inputProps, resizerProps, isMouseResizing} = useTableColumnResize( mergeProps(props, { 'aria-label': stringFormatter.format('columnResizer'), isDisabled: isEmpty @@ -128,7 +108,7 @@ export const Resizer = React.forwardRef(function Resizer( role="presentation" className={classNames(styles, 'spectrum-Table-columnResizerPlaceholder')} /> - +
diff --git a/packages/react-aria-components/src/Table.tsx b/packages/react-aria-components/src/Table.tsx index 1385b0704e9..45eb1d488bf 100644 --- a/packages/react-aria-components/src/Table.tsx +++ b/packages/react-aria-components/src/Table.tsx @@ -1374,7 +1374,7 @@ export const ColumnResizer = forwardRef(function ColumnResizer( let {onResizeStart, onResize, onResizeEnd} = useContext(ResizableTableContainerContext)!; let {column, triggerRef} = useContext(ColumnResizerContext)!; let inputRef = useRef(null); - let {resizerProps, inputProps, isResizing} = useTableColumnResize( + let {resizerProps, inputProps, isResizing, isMouseResizing} = useTableColumnResize( { column, 'aria-label': props['aria-label'] || stringFormatter.format('tableResizer'), @@ -1425,24 +1425,15 @@ export const ColumnResizer = forwardRef(function ColumnResizer( } }); - let [isMouseDown, setMouseDown] = useState(false); - let onPointerDown = (e: PointerEvent) => { - if (e.pointerType === 'mouse') { - setMouseDown(true); - } - }; - - if (!isResizing && isMouseDown) { - setMouseDown(false); - } - let DOMProps = filterDOMProps(props, {global: true}); + // Cursor overlay is used to style the cursor against the entire screen. + // Do not turn off pointer events or the cursor will no longer be styled. return ( {isResizing && - isMouseDown && + isMouseResizing && ReactDOM.createPortal( -
, +
, document.body )} diff --git a/packages/react-aria/src/table/useTableColumnResize.ts b/packages/react-aria/src/table/useTableColumnResize.ts index caea29c6eca..e3c1ae89334 100644 --- a/packages/react-aria/src/table/useTableColumnResize.ts +++ b/packages/react-aria/src/table/useTableColumnResize.ts @@ -10,7 +10,7 @@ * governing permissions and limitations under the License. */ -import {ChangeEvent, useCallback, useEffect, useRef} from 'react'; +import {ChangeEvent, useCallback, useEffect, useRef, useState} from 'react'; import {ColumnSize} from 'react-stately/useTableState'; import {DOMAttributes, FocusableElement, Key, RefObject} from '@react-types/shared'; import {focusSafely} from '../interactions/focusSafely'; @@ -38,6 +38,11 @@ export interface TableColumnResizeAria { resizerProps: DOMAttributes; /** Whether this column is currently being resized. */ isResizing: boolean; + /** + * Whether this column is currently being resized via a mouse drag (e.g. to render a cursor + * overlay). + */ + isMouseResizing: boolean; } export interface AriaTableColumnResizeProps { @@ -94,6 +99,9 @@ export function useTableColumnResize( let lastSize = useRef | null>(null); let wasFocusedOnResizeStart = useRef(false); let editModeEnabled = state.tableState.isKeyboardNavigationDisabled; + // Whether a mouse drag-resize is active. Set on the first move (not on press) so a cursor + // overlay only mounts during an actual drag. + let [isMouseResizing, setMouseResizing] = useState(false); let {direction} = useLocale(); @@ -172,8 +180,11 @@ export function useTableColumnResize( const columnResizeWidthRef = useRef(0); const {moveProps} = useMove({ - onMoveStart() { + onMoveStart(e) { columnResizeWidthRef.current = state.getColumnWidth(item.key); + if (e.pointerType === 'mouse') { + setMouseResizing(true); + } startResize(item); }, onMove(e) { @@ -196,6 +207,7 @@ export function useTableColumnResize( onMoveEnd(e) { let {pointerType} = e; columnResizeWidthRef.current = 0; + setMouseResizing(false); if (pointerType === 'mouse' || (pointerType === 'touch' && wasFocusedOnResizeStart.current)) { endResize(item); } @@ -332,6 +344,7 @@ export function useTableColumnResize( }, ariaProps ), - isResizing + isResizing, + isMouseResizing }; }