Skip to content
This repository has been archived by the owner on May 24, 2024. It is now read-only.

Commit

Permalink
Cell auto focus property (#2123)
Browse files Browse the repository at this point in the history
  • Loading branch information
cm9361 authored Apr 8, 2024
1 parent de3cf99 commit b7d65f7
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 3 deletions.
3 changes: 3 additions & 0 deletions packages/terra-data-grid/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

* Added
* Added `isAutoFocusEnabled` prop to allow auto focus of interactable elements when the only interactable element is a button or hyperlink.

## 1.25.0 - (April 4, 2024)

* Changed
Expand Down
13 changes: 10 additions & 3 deletions packages/terra-data-grid/src/DataGrid.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,11 @@ const propTypes = {
* With this property the height of the cell will grow to fit the cell content.
*/
rowMinimumHeight: PropTypes.string,

/**
* Determines if focus is moved to the interactive element of a cell when a single button or hyperlink element is the only interactive element.
*/
isAutoFocusEnabled: PropTypes.bool,
};

const defaultProps = {
Expand Down Expand Up @@ -186,6 +191,7 @@ const DataGrid = forwardRef((props, ref) => {
rows,
sections,
rowMinimumHeight,
isAutoFocusEnabled,
} = props;

const displayedColumns = (hasSelectableRows ? [WorklistDataGridUtils.ROW_SELECTION_COLUMN] : []).concat(pinnedColumns).concat(overflowColumns);
Expand Down Expand Up @@ -228,7 +234,8 @@ const DataGrid = forwardRef((props, ref) => {
setCellAriaLiveMessage,
tableRef: grid,
tableContainerRef,
}), [grid, tableContainerRef]);
isAutoFocusEnabled,
}), [grid, isAutoFocusEnabled, tableContainerRef]);

// -------------------------------------
// functions
Expand Down Expand Up @@ -282,7 +289,7 @@ const DataGrid = forwardRef((props, ref) => {

// Set focus to a single header button or hyperlink if they are the only content in cell
const cellButtonOrHyperlink = focusedCell.querySelector('a, button');
if ((isHeaderRow && !focusedCell.hasAttribute('tabindex')) || cellButtonOrHyperlink) {
if ((isHeaderRow && !focusedCell.hasAttribute('tabindex')) || (isAutoFocusEnabled && cellButtonOrHyperlink)) {
focusedCell = focusedCell.querySelector('a, button, [role="button"]');
focusedCell?.focus();
return;
Expand All @@ -297,7 +304,7 @@ const DataGrid = forwardRef((props, ref) => {
}

focusedCell?.focus();
}, [displayedColumns, isSection, isRowSelectionCell, hasColumnHeaderActions]);
}, [displayedColumns, isSection, hasColumnHeaderActions, isAutoFocusEnabled, isRowSelectionCell]);

// The focus is handled by the DataGrid. However, there are times
// when the other components may want to change the currently focus
Expand Down
7 changes: 7 additions & 0 deletions packages/terra-data-grid/src/FlowsheetDataGrid.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ const propTypes = {
* Boolean to show/hide column headers. By default, it is set to `true` and column headers are visible.
*/
hasVisibleColumnHeaders: PropTypes.bool,

/**
* Determines if focus is moved to the interactive element of a cell when a single button or hyperlink element is the only interactive element.
*/
isAutoFocusEnabled: PropTypes.bool,
};

const defaultProps = {
Expand Down Expand Up @@ -138,6 +143,7 @@ function FlowsheetDataGrid(props) {
intl,
hasVisibleColumnHeaders,
rowMinimumHeight,
isAutoFocusEnabled,
} = props;

const anchorCell = useRef(null);
Expand Down Expand Up @@ -424,6 +430,7 @@ function FlowsheetDataGrid(props) {
hasVisibleColumnHeaders={hasVisibleColumnHeaders}
ref={dataGridFuncRef}
rowMinimumHeight={rowMinimumHeight}
isAutoFocusEnabled={isAutoFocusEnabled}
/>
<VisuallyHiddenText aria-live="polite" text={cellSelectionAriaLiveMessage} />
</div>
Expand Down
7 changes: 7 additions & 0 deletions packages/terra-data-grid/src/WorklistDataGrid.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ const propTypes = {
* rendered to allow for row selection to occur.
*/
hasSelectableRows: PropTypes.bool,

/**
* Determines if focus is moved to the interactive element of a cell when a single button or hyperlink element is the only interactive element.
*/
isAutoFocusEnabled: PropTypes.bool,
};

const defaultProps = {
Expand Down Expand Up @@ -158,6 +163,7 @@ function WorklistDataGrid(props) {
onEnableRowSelection,
hasSelectableRows,
rowHeaderIndex,
isAutoFocusEnabled,
} = props;

const inShiftUpDownMode = useRef(false);
Expand Down Expand Up @@ -388,6 +394,7 @@ function WorklistDataGrid(props) {
onClearSelection={handleClearSelection}
onRangeSelection={onRangeSelection}
hasSelectableRows={hasSelectableRows}
isAutoFocusEnabled={isAutoFocusEnabled}
ref={dataGridFuncRef}
/>
</div>
Expand Down
3 changes: 3 additions & 0 deletions packages/terra-framework-docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

* Added
* Added examples and tests for `isAutoFocusEnabled` prop for `terra-data-grid`.

* Changed
* Updated `date-time-picker` KeyboardShortcuts doc for +/- Keys for DateTime input.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import WorklistDataGridAutoFocusableCell from './WorklistDataGridAutoFocusableCell?dev-site-example';

# Auto Focusable Cell Navigation

### Description

The content of a cell in the [Worklist Data Grid](/components/cerner-terra-framework-docs/data-grid/worklist-data-grid/about) may be empty, text, numerical, or any combination of widgets.
When the only interactable element in the cell is a button or hyperlink element and the isAutoFocusable property is set to true, navigation to the cell will focus the button or hyperlink element directly.


#### Keyboard Interactions

|Key Interaction|Description|
|-|-|
|*Enter*|Moves focus to the button or hyperlink element when the table cell has focus.|
|*Escape*|Moves focus to the parent table cell element.|


<WorklistDataGridAutoFocusableCell />
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React, { useState } from 'react';
import { WorklistDataGrid } from 'terra-data-grid';
import NotificationDialog from 'terra-notification-dialog';

const WorklistDataGridAutoFocusableCell = () => {
const rowHeaderIndex = 0;

const [isOpen, setIsOpen] = useState(false);

const handleCloseModal = () => {
setIsOpen(false);
};

const handleButtonOpenModal = () => {
setIsOpen(true);
};

const buttonCell = <button type="button" aria-label="Alert" onClick={handleButtonOpenModal}>Alert</button>;
// eslint-disable-next-line react/forbid-dom-props
const anchorCell = <a href="https://www.oracle.com/" aria-label="Visit Oracle">Visit Oracle</a>;

const gridDataJSON = {
cols: [
{ id: 'Column-0', displayName: 'Patient' },
{ id: 'Column-1', displayName: 'Action A' },
{ id: 'Column-2', displayName: 'Action B' },
],
rows: [
{
id: '1',
cells: [
{ content: 'Fleck, Arthur' },
{ content: buttonCell },
{ content: anchorCell },
],
},
],
};

const { cols, rows } = gridDataJSON;

return (
<>
{isOpen && (
<NotificationDialog
variant="hazard-low"
dialogTitle="Button from Focusable Cell"
startMessage="Button Selected"
acceptAction={{
text: 'OK',
onClick: handleCloseModal,
}}
/>
)}
<WorklistDataGrid
id="default-terra-worklist-data-grid-focusable-cell"
overflowColumns={cols}
defaultColumnWidth={170}
rows={rows}
rowHeaderIndex={rowHeaderIndex}
rowHeight="50px"
ariaLabel="Worklist Data Grid"
isAutoFocusEnabled
/>
</>
);
};

export default WorklistDataGridAutoFocusableCell;
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ const DataGridFocusableCell = () => {
rows={rows}
rowHeaderIndex={rowHeaderIndex}
ariaLabel="Data Grid"
isAutoFocusEnabled
/>
</div>
<button id="next-focus-button" type="button" aria-label="Next Element">Test Next</button>
Expand Down
3 changes: 3 additions & 0 deletions packages/terra-table/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Unreleased

* Changed
* Updated the cell component auto focus logic to be configured by the grid context.

## 5.18.0 - (April 4, 2024)

* Added
Expand Down
5 changes: 5 additions & 0 deletions packages/terra-table/src/subcomponents/Cell.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,10 @@ function Cell(props) {
* @returns The auto focusable button or anchor element. If there is no auto focusable element, null is returned.
*/
const getAutoFocusableElement = () => {
if (!gridContext.isAutoFocusEnabled) {
return null;
}

const focusableElements = getFocusableElements(cellRef.current);
if (focusableElements.length > 1) {
return null;
Expand Down Expand Up @@ -241,6 +245,7 @@ function Cell(props) {
setIsInteractable(hasFocusableElements());
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [gridContext, intl, isGridContext]);

const handleMouseDown = (event) => {
Expand Down

0 comments on commit b7d65f7

Please sign in to comment.