Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify ARIA table API and make more consistent #2034

Merged
merged 5 commits into from
Jun 17, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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