diff --git a/packages/react/src/components/Table/Table.jsx b/packages/react/src/components/Table/Table.jsx index 26c3cbde09..1e9588ddb6 100644 --- a/packages/react/src/components/Table/Table.jsx +++ b/packages/react/src/components/Table/Table.jsx @@ -146,6 +146,8 @@ const propTypes = { preserveCellWhiteSpace: PropTypes.bool, /** display icon button in filter row */ hasFilterRowIcon: PropTypes.bool, + /** Freezes table header and footer */ + pinHeaderAndFooter: PropTypes.bool, }), /** Size prop from Carbon to shrink row height (and header height in some instances) */ @@ -409,6 +411,7 @@ export const defaultProps = (baseProps) => ({ wrapCellText: 'always', preserveCellWhiteSpace: false, hasFilterRowIcon: false, + pinHeaderAndFooter: false, }, size: undefined, view: { @@ -840,7 +843,9 @@ const Table = (props) => { { /* If there is no items being rendered in the toolbar, don't render the toolbar */ @@ -1031,7 +1036,8 @@ const Table = (props) => { 'useAutoTableLayoutForResize', 'hasMultiSort', 'preserveColumnWidths', - 'hasFilterRowIcon' + 'hasFilterRowIcon', + 'pinHeaderAndFooter' ), hasRowExpansion: !!options.hasRowExpansion, wrapCellText: options.wrapCellText, diff --git a/packages/react/src/components/Table/TableHead/FilterHeaderRow/FilterHeaderRow.jsx b/packages/react/src/components/Table/TableHead/FilterHeaderRow/FilterHeaderRow.jsx index 593a4a9733..775bb68291 100644 --- a/packages/react/src/components/Table/TableHead/FilterHeaderRow/FilterHeaderRow.jsx +++ b/packages/react/src/components/Table/TableHead/FilterHeaderRow/FilterHeaderRow.jsx @@ -130,6 +130,8 @@ class FilterHeaderRow extends Component { filterRowIconDescription: PropTypes.string, /** call back function for when icon button in filter row is clicked (evt) => {} */ onFilterRowIconClick: PropTypes.func.isRequired, + /** Freezes table header and footer */ + pinHeaderAndFooter: PropTypes.bool, }; static defaultProps = { @@ -151,6 +153,7 @@ class FilterHeaderRow extends Component { showColumnGroups: false, filterRowIcon: null, filterRowIconDescription: 'Edit filters', + pinHeaderAndFooter: false, }; state = { @@ -239,10 +242,20 @@ class FilterHeaderRow extends Component { const tableTopOffset = this.filterCellRef.current .closest(`.${iotPrefix}--table-container`) .getBoundingClientRect().top; - this.setState((prevState) => ({ - ...prevState, - filterIconTopOffset: siblingTopOffset - tableTopOffset, - })); + this.setState((prevState) => { + if (this.props.pinHeaderAndFooter) { + // Subtract 48px of toolbar height + return { + ...prevState, + filterIconTopOffset: siblingTopOffset - tableTopOffset - 48, + }; + } + + return { + ...prevState, + filterIconTopOffset: siblingTopOffset - tableTopOffset, + }; + }); } }; diff --git a/packages/react/src/components/Table/TableHead/TableHead.jsx b/packages/react/src/components/Table/TableHead/TableHead.jsx index 7e1cf9014d..f5cf7aa017 100644 --- a/packages/react/src/components/Table/TableHead/TableHead.jsx +++ b/packages/react/src/components/Table/TableHead/TableHead.jsx @@ -80,6 +80,8 @@ const propTypes = { /** Preserves the widths of existing columns when one or more columns are added, removed, hidden, shown or resized. */ preserveColumnWidths: PropTypes.bool, hasFilterRowIcon: PropTypes.bool, + /** Freezes table header and footer */ + pinHeaderAndFooter: PropTypes.bool, }), /** List of columns */ columns: TableColumnsPropTypes.isRequired, @@ -205,6 +207,7 @@ const TableHead = ({ useAutoTableLayoutForResize, preserveColumnWidths, useRadioButtonSingleSelect, + pinHeaderAndFooter, }, columns, columnGroups, @@ -689,6 +692,7 @@ const TableHead = ({ filterRowIcon={filterRowIcon} filterRowIconDescription={filterRowIconDescription} onFilterRowIconClick={onFilterRowIconClick} + pinHeaderAndFooter={pinHeaderAndFooter} /> )} {activeBar === 'column' && ( diff --git a/packages/react/src/components/Table/_table.scss b/packages/react/src/components/Table/_table.scss index 54e3298e7b..36de562b96 100644 --- a/packages/react/src/components/Table/_table.scss +++ b/packages/react/src/components/Table/_table.scss @@ -43,6 +43,25 @@ td.#{$iot-prefix}--table__cell--sortable { .addons-iot-table-container { overflow-x: auto; } + + &--pin-header-and-footer { + height: 100%; + + .addons-iot-table-container, + .#{$prefix}--data-table-content { + height: inherit; + } + + thead { + position: sticky; + top: 0; + z-index: 4; + } + + .#{$prefix}--table-toolbar { + z-index: 5; + } + } } .#{$iot-prefix}-table-container--dropdown-height-fix {