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

Commit

Permalink
[worklist-data-grid] column header enhancements (#1859)
Browse files Browse the repository at this point in the history
  • Loading branch information
sdadn authored Oct 25, 2023
1 parent 539bcc8 commit 4525785
Show file tree
Hide file tree
Showing 131 changed files with 3,252 additions and 564 deletions.
6 changes: 4 additions & 2 deletions packages/terra-data-grid/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Changelog

## Unreleased

* Added
* Added additional screen reader support to announce that column headers are interactable upon selection.
* Added keyboard support for column resizing.
* Added translations.
* Added "No Result" cells to FlowsheetDataGrid.

## 0.8.1 - (October 17, 2023)
Expand Down Expand Up @@ -42,7 +44,7 @@
* Updated the `terra-worklist-data-grid` component to set initial focus to the row selection header when row selection mode is enabled.

___
All release notes below apply to the `terra-worklist-data-grid` package (renamed to `terra-data-grid` the 0.6 release above).
All release notes below apply to the `terra-worklist-data-grid` package (renamed to `terra-data-grid` with the 0.6 release above).

## 0.5.0 - (August 31, 2023)

Expand Down
61 changes: 57 additions & 4 deletions packages/terra-data-grid/src/DataGrid.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ const propTypes = {
*/
columnHeaderHeight: PropTypes.string,

/**
* Numeric increment in pixels to adjust column width when resizing via the keyboard.
*/
columnResizeIncrement: PropTypes.number,

/**
* String that specifies the height for the rows in the grid. Any valid CSS value is accepted.
*/
Expand Down Expand Up @@ -136,6 +141,7 @@ const DataGrid = injectIntl((props) => {
onColumnResize,
defaultColumnWidth,
columnHeaderHeight,
columnResizeIncrement,
rowHeight,
onColumnSelect,
onCellSelect,
Expand Down Expand Up @@ -174,18 +180,23 @@ const DataGrid = injectIntl((props) => {
const activeColumnWidth = useRef(200);
const tableWidth = useRef(0);

// Reference variable for WorklistDataGrid table element
const grid = useRef();
const gridContainerRef = useRef();

const handleFocus = useRef(true);

const [checkResizable, setCheckResizable] = useState(false);
const [focusedRow, setFocusedRow] = useState(0);
const [focusedCol, setFocusedCol] = useState(0);
const [gridHasFocus, setGridHasFocus] = useState(false);

// Aria live region message management
const [columnHeaderAriaLiveMessage, setColumnHeaderAriaLiveMessage] = useState(null);
const [cellAriaLiveMessage, setCellAriaLiveMessage] = useState(null);

// Define ColumnContext Provider value object
const columnContextValue = useMemo(() => ({ pinnedColumnOffsets, setCellAriaLiveMessage }), [pinnedColumnOffsets]);

const columnContextValue = useMemo(() => ({ pinnedColumnOffsets, setColumnHeaderAriaLiveMessage, setCellAriaLiveMessage }), [pinnedColumnOffsets]);
const theme = useContext(ThemeContext);

// -------------------------------------
Expand Down Expand Up @@ -323,11 +334,12 @@ const DataGrid = injectIntl((props) => {
setFocusedRowCol(toCell.row, toCell.col, true);
};

const handleColumnSelect = useCallback((columnId, cellCoordinates) => {
const handleColumnSelect = useCallback((columnId, cellCoordinates, isSelectable) => {
setFocusedRow(cellCoordinates.row);
setFocusedCol(cellCoordinates.col);

if (onColumnSelect) {
// Notify consumers of column header selection
if (isSelectable && onColumnSelect) {
onColumnSelect(columnId);
}
}, [onColumnSelect]);
Expand Down Expand Up @@ -401,10 +413,12 @@ const DataGrid = injectIntl((props) => {
const cellCoordinates = { row: focusedRow, col: focusedCol };
let nextRow = cellCoordinates.row;
let nextCol = cellCoordinates.col;
setCheckResizable(false);

const targetElement = event.target;

// Allow default behavior if the event target is an editable field

if (event.keyCode !== KeyCode.KEY_TAB
&& (isTextInput(targetElement)
|| ['textarea', 'select'].indexOf(targetElement.tagName.toLowerCase()) >= 0
Expand Down Expand Up @@ -434,6 +448,7 @@ const DataGrid = injectIntl((props) => {
} else {
// Left key
nextCol -= 1;
setCheckResizable(cellCoordinates.row === 0);
}
break;
case KeyCode.KEY_RIGHT:
Expand Down Expand Up @@ -502,10 +517,31 @@ const DataGrid = injectIntl((props) => {
activeColumnPageX.current = event.pageX;
activeColumnWidth.current = resizeColumnWidth;

setFocusedRow(0);
setFocusedCol(index);

// Set the active index to the selected column
setActiveIndex(index);
}, []);

const onResizeHandleChange = useCallback((columnIndex, increment) => {
const { minimumWidth, maximumWidth, width } = dataGridColumns[columnIndex];
const newColumnWidth = Math.min(Math.max(width + increment, minimumWidth), maximumWidth);

// Update the width for the column in the state variable
const newGridColumns = [...dataGridColumns];
newGridColumns[columnIndex].width = newColumnWidth;
setDataGridColumns(newGridColumns);

// Update the column and table width
grid.current.style.width = `${grid.current.offsetWidth + increment}px`;

// Notify consumers of the new column width
if (onColumnResize) {
onColumnResize(dataGridColumns[columnIndex].id, dataGridColumns[columnIndex].width);
}
}, [dataGridColumns, onColumnResize]);

const onMouseMove = (event) => {
if (activeIndex == null) {
return;
Expand Down Expand Up @@ -540,17 +576,28 @@ const DataGrid = injectIntl((props) => {
handleFocus.current = false;
};

/**
* Establishes selection state when the WorklistDataGrid gains focus
* @param {*} event focus event data
*/
const onFocus = (event) => {
if (!event.currentTarget.contains(event.relatedTarget)) {
// Not triggered when swapping focus between children
if (handleFocus.current) {
setFocusedRowCol(focusedRow, focusedCol, true);
setGridHasFocus(true);
}
}

handleFocus.current = true;
};

const onBlur = (event) => {
if (!event.currentTarget.contains(event.relatedTarget)) {
setGridHasFocus(false);
}
};

// -------------------------------------

return (
Expand All @@ -564,6 +611,7 @@ const DataGrid = injectIntl((props) => {
className={cx('data-grid', theme.className)}
onKeyDown={handleKeyDown}
onFocus={onFocus}
onBlur={onBlur}
onMouseDown={onMouseDown}
tabIndex={0}
{...(activeIndex != null && { onMouseUp, onMouseMove, onMouseLeave: onMouseUp })}
Expand All @@ -575,8 +623,12 @@ const DataGrid = injectIntl((props) => {
columns={dataGridColumns}
headerHeight={columnHeaderHeight}
tableHeight={tableHeight}
activeColumnIndex={(gridHasFocus && focusedRow === 0) ? focusedCol : undefined}
isActiveColumnResizing={focusedRow === 0 && checkResizable}
columnResizeIncrement={columnResizeIncrement}
onColumnSelect={handleColumnSelect}
onResizeMouseDown={onResizeMouseDown}
onResizeHandleChange={onResizeHandleChange}
/>
<tbody>
{rows.map((row, index) => (
Expand All @@ -597,6 +649,7 @@ const DataGrid = injectIntl((props) => {
</tbody>
</ColumnContext.Provider>
</table>
<VisuallyHiddenText aria-live="polite" aria-atomic="true" text={columnHeaderAriaLiveMessage} />
<VisuallyHiddenText aria-live="polite" aria-atomic="true" text={cellAriaLiveMessage} />
</div>
);
Expand Down
2 changes: 2 additions & 0 deletions packages/terra-data-grid/src/DataGrid.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
// Style for the grid itself
border-collapse: separate;
border-spacing: 0;
// Allow for resizing of last grid column
margin-right: 15px;
table-layout: fixed;
user-select: none;
width: 1px;
Expand Down
2 changes: 1 addition & 1 deletion packages/terra-data-grid/src/WorklistDataGrid.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ function WorklistDataGrid(props) {
onKeyDown={handleKeyDown}
onKeyUp={handleKeyUp}
className={cx('worklist-data-grid-container')}
onFocus={!gridReceivedFocus.current && onFocus}
onFocus={!gridReceivedFocus.current ? onFocus : undefined}
>
<DataGrid
id={id}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
:local {
.clinical-lowlight-theme {
// Column resize handle styles
--terra-data-grid-resize-handle-focus-border-color: rgba(34, 42, 46, 1);
--terra-data-grid-resize-handle-active-border-color: rgba(34, 42, 46, 1);
--terra-data-grid-resize-handle-hover-border-color: rgba(34, 42, 46, 0.6);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
:local {
.orion-fusion-theme {
// Column resize handle styles
--terra-data-grid-resize-handle-focus-border-color: #517ea5;
--terra-data-grid-resize-handle-active-border-color: #517ea5;
--terra-data-grid-resize-handle-hover-border-color: #e4f1f7;
}
}
31 changes: 26 additions & 5 deletions packages/terra-data-grid/src/subcomponents/ColumnHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,48 @@ const propTypes = {
* String that specifies the column header height. Any valid CSS height value accepted.
*/
headerHeight: PropTypes.string.isRequired,

/**
* Number that specifies the height of the data grid in pixels.
*/
* Number that specifies the height of the data grid in pixels.
*/
tableHeight: PropTypes.number,

/**
* Column index for cell that can receive tab focus.
*/
activeColumnIndex: PropTypes.number,
/**
* Specifies if resize handle should be active.
*/
isActiveColumnResizing: PropTypes.bool,
/**
* Numeric increment in pixels to adjust column width when resizing via the keyboard.
*/
columnResizeIncrement: PropTypes.number,
/**
* Function that is called when a selectable header cell is selected. Parameters:
* @param {string} columnId columnId
*/
onColumnSelect: PropTypes.func,

/**
* Function that is called when the mouse down event is triggered on the column resize handle.
*/
onResizeMouseDown: PropTypes.func,
/**
* Function that is called when the the keyboard is used to adjust the column size.
*/
onResizeHandleChange: PropTypes.func,
};

const ColumnHeader = (props) => {
const {
columns,
headerHeight,
tableHeight,
activeColumnIndex,
isActiveColumnResizing,
columnResizeIncrement,
onColumnSelect,
onResizeMouseDown,
onResizeHandleChange,
} = props;

// Create ColumnHeaderCell component for each column
Expand All @@ -56,10 +73,14 @@ const ColumnHeader = (props) => {
isResizable={column.isResizable}
isSelectable={column.isSelectable}
tableHeight={tableHeight}
isActive={activeColumnIndex === columnIndex}
isResizeActive={activeColumnIndex === columnIndex && isActiveColumnResizing}
columnResizeIncrement={columnResizeIncrement}
hasError={column.hasError}
sortIndicator={column.sortIndicator}
onColumnSelect={onColumnSelect}
onResizeMouseDown={onResizeMouseDown}
onResizeHandleChange={onResizeHandleChange}
/>
);

Expand Down
Loading

0 comments on commit 4525785

Please sign in to comment.