Skip to content

Commit

Permalink
Simplify ARIA table API and make more consistent (#2034)
Browse files Browse the repository at this point in the history
* Simplify ARIA table API and make more consistent

* replacing table css hover pseudo class with is-hovered

fixes doc examples where hovering was highlighting rows for tableview w/o selection enebaled

* Fix ActionBar import

Co-authored-by: Daniel Lu <[email protected]>
Co-authored-by: Danni <[email protected]>
  • Loading branch information
3 people authored Jun 17, 2021
1 parent 19cb13d commit d04e70b
Show file tree
Hide file tree
Showing 30 changed files with 211 additions and 250 deletions.
10 changes: 5 additions & 5 deletions packages/@adobe/spectrum-css-temp/components/table/skin.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ governing permissions and limitations under the License.
color: var(--spectrum-table-header-sort-icon-color);
}

&:hover {
&.is-hovered {
color: var(--spectrum-table-header-text-color-hover);

.spectrum-Table-sortedIcon {
Expand Down Expand Up @@ -119,7 +119,7 @@ tbody.spectrum-Table-body {

/* We apply background color to the cell rather than the row so that
* cells can overlap (e.g. sticky row headers). */
&:hover .spectrum-Table-cell {
&.is-hovered .spectrum-Table-cell {
background-color: var(--spectrum-table-row-background-color-hover);
}

Expand All @@ -143,7 +143,7 @@ tbody.spectrum-Table-body {
background-color: var(--spectrum-table-row-background-color-selected);
}

&:hover .spectrum-Table-cell {
&.is-hovered .spectrum-Table-cell {
background-color: var(--spectrum-table-row-background-color-selected-hover);
}

Expand Down Expand Up @@ -191,7 +191,7 @@ tbody.spectrum-Table-body {
background-color: var(--spectrum-alias-background-color-default);
}

&:hover .spectrum-Table-cell {
&.is-hovered .spectrum-Table-cell {
background-color: var(--spectrum-table-quiet-row-background-color-hover);
}

Expand All @@ -209,7 +209,7 @@ tbody.spectrum-Table-body {
background-color: var(--spectrum-table-quiet-row-background-color-selected);
}

&:hover .spectrum-Table-cell {
&.is-hovered .spectrum-Table-cell {
background-color: var(--spectrum-table-quiet-row-background-color-selected-hover);
}

Expand Down
12 changes: 3 additions & 9 deletions packages/@react-aria/dnd/stories/DraggableCollection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,9 @@ function DraggableCollection(props) {

let {gridProps} = useGrid({
...props,
ref,
'aria-label': 'Draggable list',
focusMode: 'cell'
}, gridState);
}, gridState, ref);

return (
<div
Expand All @@ -146,17 +145,12 @@ function DraggableCollectionItem({item, state, dragState}) {
let cellNode = [...item.childNodes][0];
let isSelected = state.selectionManager.isSelected(item.key);

let {rowProps} = useGridRow({
node: item,
ref: rowRef,
isSelected
}, state);
let {rowProps} = useGridRow({node: item}, state, rowRef);
let {gridCellProps} = useGridCell({
node: cellNode,
ref: cellRef,
focusMode: 'cell',
shouldSelectOnPressUp: true
}, state);
}, state, cellRef);

let {dragProps, dragButtonProps} = useDraggableItem({key: item.key}, dragState);

Expand Down
13 changes: 3 additions & 10 deletions packages/@react-aria/dnd/stories/DroppableGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -226,10 +226,9 @@ const DroppableGrid = React.forwardRef(function (props: any, ref) {

let {gridProps} = useGrid({
...props,
ref: domRef,
'aria-label': 'List',
focusMode: 'cell'
}, gridState);
}, gridState, domRef);

let isDropTarget = dropState.isDropTarget({type: 'root'});
let dropRef = React.useRef();
Expand Down Expand Up @@ -285,18 +284,12 @@ function CollectionItem({item, state, dropState, onPaste}) {
let rowRef = React.useRef();
let cellRef = React.useRef();
let cellNode = [...item.childNodes][0];
let isSelected = state.selectionManager.isSelected(item.key);

let {rowProps} = useGridRow({
node: item,
ref: rowRef,
isSelected
}, state);
let {rowProps} = useGridRow({node: item}, state, rowRef);
let {gridCellProps} = useGridCell({
node: cellNode,
ref: cellRef,
focusMode: 'cell'
}, state);
}, state, cellRef);

let dropIndicatorRef = React.useRef();
let {dropIndicatorProps} = useDropIndicator({
Expand Down
13 changes: 3 additions & 10 deletions packages/@react-aria/dnd/stories/Reorderable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -204,10 +204,9 @@ function ReorderableGrid(props) {

let {gridProps} = useGrid({
...props,
ref,
'aria-label': 'Reorderable list',
focusMode: 'cell'
}, gridState);
}, gridState, ref);

let isDropTarget = dropState.isDropTarget({type: 'root'});
let dropRef = React.useRef();
Expand Down Expand Up @@ -260,19 +259,13 @@ function CollectionItem({item, state, dragState, dropState}) {
let rowRef = React.useRef();
let cellRef = React.useRef();
let cellNode = [...item.childNodes][0];
let isSelected = state.selectionManager.isSelected(item.key);

let {rowProps} = useGridRow({
node: item,
ref: rowRef,
isSelected
}, state);
let {rowProps} = useGridRow({node: item}, state, rowRef);
let {gridCellProps} = useGridCell({
node: cellNode,
ref: cellRef,
focusMode: 'cell',
shouldSelectOnPressUp: true
}, state);
}, state, cellRef);

let {dragProps, dragButtonProps} = useDraggableItem({key: item.key}, dragState);

Expand Down
12 changes: 3 additions & 9 deletions packages/@react-aria/dnd/stories/dnd.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -367,10 +367,9 @@ function DraggableCollection(props) {

let {gridProps} = useGrid({
...props,
ref,
'aria-label': 'Draggable list',
focusMode: 'cell'
}, gridState);
}, gridState, ref);

return (
<div
Expand Down Expand Up @@ -398,17 +397,12 @@ function DraggableCollectionItem({item, state, dragState, onCut}) {
let cellNode = [...item.childNodes][0];
let isSelected = state.selectionManager.isSelected(item.key);

let {rowProps} = useGridRow({
node: item,
ref: rowRef,
isSelected
}, state);
let {rowProps} = useGridRow({node: item}, state, rowRef);
let {gridCellProps} = useGridCell({
node: cellNode,
ref: cellRef,
focusMode: 'cell',
shouldSelectOnPressUp: true
}, state);
}, state, cellRef);

let {dragProps, dragButtonProps} = useDraggableItem({key: item.key}, dragState);

Expand Down
6 changes: 2 additions & 4 deletions packages/@react-aria/grid/src/useGrid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ import {useCollator, useLocale, useMessageFormatter} from '@react-aria/i18n';
import {useSelectableCollection} from '@react-aria/selection';

export interface GridProps extends DOMProps, AriaLabelingProps {
/** The ref attached to the grid element. */
ref: RefObject<HTMLElement>,
/** Whether the grid uses virtual scrolling. */
isVirtualized?: boolean,
/**
Expand Down Expand Up @@ -55,10 +53,10 @@ export interface GridAria {
* A grid displays data in one or more rows and columns and enables a user to navigate its contents via directional navigation keys.
* @param props - Props for the grid.
* @param state - State for the grid, as returned by `useGridState`.
* @param ref - The ref attached to the grid element.
*/
export function useGrid<T>(props: GridProps, state: GridState<T, GridCollection<T>>): GridAria {
export function useGrid<T>(props: GridProps, state: GridState<T, GridCollection<T>>, ref: RefObject<HTMLElement>): GridAria {
let {
ref,
isVirtualized,
keyboardDelegate,
focusMode,
Expand Down
9 changes: 2 additions & 7 deletions packages/@react-aria/grid/src/useGridCell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,8 @@ import {useSelectableItem} from '@react-aria/selection';
interface GridCellProps {
/** An object representing the grid cell. Contains all the relevant information that makes up the grid cell. */
node: RSNode<unknown>,
/** The ref attached to the grid cell element. */
ref: RefObject<HTMLElement>,
/** Whether the grid cell is contained in a virtual scroller. */
isVirtualized?: boolean,
/** Whether the grid cell is disabled. */
isDisabled?: boolean,
/** Whether the cell or its first focusable child element should be focused when the grid cell is focused. */
focusMode?: 'child' | 'cell',
/** Whether selection should occur on press up instead of press down. */
Expand All @@ -46,12 +42,10 @@ interface GridCellAria {
* @param props - Props for the cell.
* @param state - State of the parent grid, as returned by `useGridState`.
*/
export function useGridCell<T, C extends GridCollection<T>>(props: GridCellProps, state: GridState<T, C>): GridCellAria {
export function useGridCell<T, C extends GridCollection<T>>(props: GridCellProps, state: GridState<T, C>, ref: RefObject<HTMLElement>): GridCellAria {
let {
node,
ref,
isVirtualized,
isDisabled,
focusMode = 'child',
shouldSelectOnPressUp
} = props;
Expand Down Expand Up @@ -88,6 +82,7 @@ export function useGridCell<T, C extends GridCollection<T>>(props: GridCellProps
});

// TODO: move into useSelectableItem?
let isDisabled = state.disabledKeys.has(node.key) || state.disabledKeys.has(node.parentKey);
let {pressProps} = usePress({...itemProps, isDisabled});

let onKeyDown = (e: ReactKeyboardEvent) => {
Expand Down
14 changes: 4 additions & 10 deletions packages/@react-aria/grid/src/useGridRow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,8 @@ import {useSelectableItem} from '@react-aria/selection';
export interface GridRowProps<T> {
/** An object representing the grid row. Contains all the relevant information that makes up the grid row. */
node: Node<T>,
/** The ref attached to the grid row. */
ref?: RefObject<HTMLElement>,
/** Whether the grid row is contained in a virtual scroller. */
isVirtualized?: boolean,
/** Whether the grid row is selected. */
isSelected?: boolean,
/** Whether the grid row is disabled. */
isDisabled?: boolean,
/** Whether selection should occur on press up instead of press down. */
shouldSelectOnPressUp?: boolean
}
Expand All @@ -42,13 +36,10 @@ export interface GridRowAria {
* @param props - Props for the row.
* @param state - State of the parent grid, as returned by `useGridState`.
*/
export function useGridRow<T, C extends GridCollection<T>, S extends GridState<T, C>>(props: GridRowProps<T>, state: S): GridRowAria {
export function useGridRow<T, C extends GridCollection<T>, S extends GridState<T, C>>(props: GridRowProps<T>, state: S, ref: RefObject<HTMLElement>): GridRowAria {
let {
node,
ref,
isVirtualized,
isSelected,
isDisabled,
shouldSelectOnPressUp
} = props;

Expand All @@ -60,6 +51,9 @@ export function useGridRow<T, C extends GridCollection<T>, S extends GridState<T
shouldSelectOnPressUp
});

let isSelected = state.selectionManager.isSelected(node.key);
let isDisabled = state.disabledKeys.has(node.key);

// TODO: move into useSelectableItem?
let {pressProps} = usePress({...itemProps, isDisabled});

Expand Down
11 changes: 3 additions & 8 deletions packages/@react-aria/grid/stories/example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,9 @@ export function Grid(props) {

let ref = React.useRef();
let {gridProps} = useGrid({
ref,
'aria-label': 'Grid',
focusMode: gridFocusMode
}, gridState);
}, gridState, ref);

return (
<div {...gridProps} ref={ref}>
Expand All @@ -48,15 +47,11 @@ function Row({state, item, focusMode}) {
let rowRef = React.useRef();
let cellRef = React.useRef();
let cellNode = [...item.childNodes][0];
let {rowProps} = useGridRow({
node: item,
ref: rowRef
}, state);
let {rowProps} = useGridRow({node: item}, state, rowRef);
let {gridCellProps} = useGridCell({
node: cellNode,
ref: cellRef,
focusMode
}, state);
}, state, cellRef);

let [isRowFocused, setRowFocused] = React.useState(false);
let {focusProps: rowFocusProps} = useFocus({
Expand Down
4 changes: 2 additions & 2 deletions packages/@react-aria/table/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
export * from './useTable';
export * from './useTableColumnHeader';
export * from './useTableRow';
export * from './useTableRowHeader';
export * from './useTableHeaderRow';
export * from './useTableCell';
export * from './useTableSelectionCheckbox';

export {useGridCell as useTableCell} from '@react-aria/grid';
export {useGridRowGroup as useTableRowGroup} from '@react-aria/grid';
11 changes: 6 additions & 5 deletions packages/@react-aria/table/src/useTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import {GridAria, GridProps, useGrid} from '@react-aria/grid';
import {gridIds} from './utils';
import {Layout} from '@react-stately/virtualizer';
import {Node} from '@react-types/shared';
import {RefObject, useMemo} from 'react';
import {TableKeyboardDelegate} from './TableKeyboardDelegate';
import {TableState} from '@react-stately/table';
import {useCollator, useLocale} from '@react-aria/i18n';
import {useId} from '@react-aria/utils';
import {useMemo} from 'react';

interface TableProps<T> extends GridProps {
/** The layout object for the table. Computes what content is visible and how to position and style them. */
Expand All @@ -27,13 +27,14 @@ interface TableProps<T> extends GridProps {

/**
* Provides the behavior and accessibility implementation for a table component.
* A table displays data in one or more rows and columns and enables a user to navigate its contents via directional navigation keys.
* A table displays data in rows and columns and enables a user to navigate its contents via directional navigation keys,
* and optionally supports row selection and sorting.
* @param props - Props for the table.
* @param state - State for the table, as returned by `useTableState`.
* @param ref - The ref attached to the table element.
*/
export function useTable<T>(props: TableProps<T>, state: TableState<T>): GridAria {
export function useTable<T>(props: TableProps<T>, state: TableState<T>, ref: RefObject<HTMLElement>): GridAria {
let {
ref,
keyboardDelegate,
isVirtualized,
layout
Expand Down Expand Up @@ -87,7 +88,7 @@ export function useTable<T>(props: TableProps<T>, state: TableState<T>): GridAri

return '';
}
}, state);
}, state, ref);

// Override to include header rows
if (isVirtualized) {
Expand Down
Loading

0 comments on commit d04e70b

Please sign in to comment.