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

Commit

Permalink
Merge branch 'main' into menu_group_SR_issue
Browse files Browse the repository at this point in the history
  • Loading branch information
PK106552 authored Oct 26, 2023
2 parents a99b426 + c8fcd08 commit 2882a7b
Show file tree
Hide file tree
Showing 754 changed files with 8,870 additions and 1,441 deletions.
10 changes: 9 additions & 1 deletion packages/terra-data-grid/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# 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 All @@ -15,6 +20,9 @@
* Added
* Added base FlowsheetDataGrid component.

* Changed
* Updated prop descriptions for better consistency and accuracy in the `terra-data-grid` component.

## 0.7.0 - (October 3, 2023)

* Fixed
Expand All @@ -36,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
5 changes: 2 additions & 3 deletions packages/terra-data-grid/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@
---

The terra-data-grid package contains the following components:

**Worklist Data Grid** is a container that enables users to navigate the grid information using directional navigation keys.
The terra-data-grid package contains the **Worklist Data Grid** and **Flowsheet Data Grid** components that allow users to navigate grid information using directional navigation keys.

- [Getting Started](#getting-started)
- Documentation
- [Worklist Data Grid](https://engineering.cerner.com/terra-framework/components/cerner-terra-framework-docs/data-grid/worklist-data-grid/about)
- [Flowsheet Data Grid](https://engineering.cerner.com/terra-framework/components/cerner-terra-framework-docs/data-grid/flowsheet-data-grid/about)
- [LICENSE](#license)

## Getting Started
Expand Down
2 changes: 1 addition & 1 deletion packages/terra-data-grid/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "terra-data-grid",
"main": "lib/index.js",
"version": "0.8.1",
"description": "Package containing Terra WorklistDataGrid: A container that enables users to navigate the grid information using directional navigation keys.",
"description": "Package containing data grid container components that enable users to navigate the grid information using directional navigation keys.",
"repository": {
"type": "git",
"url": "git+https://github.com/cerner/terra-framework.git",
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
50 changes: 45 additions & 5 deletions packages/terra-data-grid/src/FlowsheetDataGrid.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import React from 'react';
import React, { useMemo } from 'react';
import PropTypes from 'prop-types';
import { injectIntl } from 'react-intl';
import classNames from 'classnames/bind';

import VisuallyHiddenText from 'terra-visually-hidden-text';

import DataGrid from './DataGrid';
import rowShape from './proptypes/rowShape';
import { columnShape } from './proptypes/columnShape';
Expand Down Expand Up @@ -64,6 +67,12 @@ const propTypes = {
* Callback function that is called when all selected cells need to be unselected. Parameters: none.
*/
onClearSelectedCells: PropTypes.func,

/**
* @private
* The intl object containing translations. This is retrieved from the context automatically by injectIntl.
*/
intl: PropTypes.shape({ formatMessage: PropTypes.func }).isRequired,
};

const defaultProps = {
Expand All @@ -86,19 +95,50 @@ function FlowsheetDataGrid(props) {
rowHeight,
onCellSelect,
onClearSelectedCells,
intl,
} = props;

const flowsheetColumns = useMemo(() => columns.map(column => ({ ...column, isResizable: false })), [columns]);
const pinnedColumns = flowsheetColumns.length ? [flowsheetColumns[0]] : [];
const overflowColumns = flowsheetColumns.length > 1 ? flowsheetColumns.slice(1) : [];

const contentHasNoResult = (content) => (content === null || content === '' || content === '--');

const flowsheetRows = useMemo(() => {
const noResultCellContent = (
<>
<span aria-hidden>{intl.formatMessage({ id: 'Terra.flowsheetDataGrid.no-result-display' })}</span>
<VisuallyHiddenText text={intl.formatMessage({ id: 'Terra.flowsheetDataGrid.no-result' })} />
</>
);

const newRows = [...rows];
newRows.forEach((row, rowIndex) => {
const newCells = [...row.cells];
newCells.forEach((cell, cellIndex) => {
// Cell content has no result and is not a row header (first column), set content to "No result".
if (contentHasNoResult(cell.content) && cellIndex !== 0) {
newCells[cellIndex].content = noResultCellContent;
}
});

newRows[rowIndex].cells = newCells;
});

return newRows;
}, [intl, rows]);

return (
<div className={cx('flowsheet-data-grid-container')}>
<DataGrid
id={id}
ariaLabel={ariaLabel}
ariaLabelledBy={ariaLabelledBy}
rows={rows}
rows={flowsheetRows}
rowHeight={rowHeight}
rowHeaderIndex={0}
pinnedColumns={columns.length ? [{ ...columns[0], isResizable: false }] : []}
overflowColumns={columns.length > 1 ? columns.slice(1).map(column => ({ ...column, isResizable: false })) : []}
pinnedColumns={pinnedColumns}
overflowColumns={overflowColumns}
defaultColumnWidth={defaultColumnWidth}
columnHeaderHeight={columnHeaderHeight}
onCellSelect={onCellSelect}
Expand All @@ -111,4 +151,4 @@ function FlowsheetDataGrid(props) {
FlowsheetDataGrid.propTypes = propTypes;
FlowsheetDataGrid.defaultProps = defaultProps;

export default FlowsheetDataGrid;
export default injectIntl(FlowsheetDataGrid);
8 changes: 4 additions & 4 deletions packages/terra-data-grid/src/WorklistDataGrid.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ const propTypes = {

/**
* Data for pinned columns. Pinned columns are the stickied leftmost columns of the grid.
* Columns will be presented in the order given.
* Columns are rendered in the order in which they are provided.
*/
pinnedColumns: PropTypes.arrayOf(columnShape),

/**
* Data for overflow columns. Overflow columns are rendered in the Worklist Data Grid's horizontal overflow.
* Columns will be presented in the order given.
* Columns are rendered in the order in which they are provided.
*/
overflowColumns: PropTypes.arrayOf(columnShape),

Expand Down Expand Up @@ -121,7 +121,7 @@ const propTypes = {
*/
onEnableRowSelection: PropTypes.func,
/**
* Boolean indicating whether or not the DataGrid should allow entire rows to be selectable. An additional column will be
* Boolean indicating whether or not the Worklist Data Grid should allow entire rows to be selectable. An additional column will be
* rendered to allow for row selection to occur.
*/
hasSelectableRows: PropTypes.bool,
Expand Down 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;
}
}
8 changes: 4 additions & 4 deletions packages/terra-data-grid/src/proptypes/cellShape.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ import PropTypes from 'prop-types';

const cellShape = PropTypes.shape({
/**
* Content that will be rendered within the Cell.
* The content to render within the cell.
*/
content: PropTypes.node,
/**
* Boolean indicating if cell contents are masked.
* A boolean indicating if the cell content is masked.
*/
isMasked: PropTypes.bool,
/**
* Boolean value indicating whether or not the column header is selectable.
* A boolean indicating if the cell is selectable.
*/
isSelectable: PropTypes.bool,
/**
* Boolean value indicating whether or not the cell should render as selected.
* A boolean indicating if the cell is selected.
*/
isSelected: PropTypes.bool,
});
Expand Down
Loading

0 comments on commit 2882a7b

Please sign in to comment.