UNPKG

@gooddata/react-components

Version:

GoodData.UI - A powerful JavaScript library for building analytical applications

94 lines (81 loc) 4.16 kB
// (C) 2007-2019 GoodData Corporation import { GridApi, RowNode } from "ag-grid-community"; import { IGroupingProvider } from "./GroupingProvider"; import { colIdIsSimpleAttribute, getGridIndex } from "./agGridUtils"; import ApiWrapper from "./agGridApiWrapper"; import { getScrollbarWidth } from "../../../helpers/domUtils"; export interface IScrollPosition { readonly top: number; readonly left: number; } export const initializeStickyRow = (gridApi: GridApi) => { gridApi.setPinnedTopRowData([{}]); }; export const updateStickyRowPosition = (gridApi: GridApi, apiWrapper: any = ApiWrapper) => { const headerHeight = apiWrapper.getHeaderHeight(gridApi); apiWrapper.setPinnedTopRowStyle(gridApi, "top", `${headerHeight}px`); apiWrapper.setPinnedTopRowStyle(gridApi, "padding-right", `${getScrollbarWidth()}px`); }; export function stickyRowExists(gridApi: GridApi, apiWrapper: any = ApiWrapper): boolean { return !!apiWrapper.getPinnedTopRowElement(gridApi); } function shouldUpdate( currentScrollPosition: IScrollPosition, lastScrollPosition: IScrollPosition, rowHeight: number, ) { const initialUpdate = currentScrollPosition.top === 0; const currentRowIndex = getGridIndex(currentScrollPosition.top, rowHeight); const lastRowIndex = getGridIndex(lastScrollPosition.top, rowHeight); const differentRow = currentRowIndex !== lastRowIndex; // when scrolling horizontally update with the same cadence as rows as we don't know where the column borders are const horizontalBreakpointDistance = rowHeight; const currentHorizontalBreakpoint = getGridIndex( currentScrollPosition.left, horizontalBreakpointDistance, ); const lastHorizontalBreakpoint = getGridIndex(lastScrollPosition.left, horizontalBreakpointDistance); const differentHorizontalBreakpoint = currentHorizontalBreakpoint !== lastHorizontalBreakpoint; return initialUpdate || differentRow || differentHorizontalBreakpoint; } export const updateStickyRowContentClasses = ( currentScrollPosition: IScrollPosition, lastScrollPosition: IScrollPosition, rowHeight: number, gridApi: GridApi, groupingProvider: IGroupingProvider, apiWrapper: any, ) => { if (!shouldUpdate(currentScrollPosition, lastScrollPosition, rowHeight)) { return; } const firstVisibleRowIndex = getGridIndex(currentScrollPosition.top, rowHeight); const firstVisibleRow: RowNode = gridApi.getDisplayedRowAtIndex(firstVisibleRowIndex); const firstVisibleNodeData = firstVisibleRow && firstVisibleRow.data ? firstVisibleRow.data : null; if (firstVisibleNodeData === null) { apiWrapper.removePinnedTopRowClass(gridApi, "gd-visible-sticky-row"); return; } apiWrapper.addPinnedTopRowClass(gridApi, "gd-visible-sticky-row"); const lastRowIndex = getGridIndex(lastScrollPosition.top, rowHeight); const attributeKeys = Object.keys(firstVisibleNodeData).filter(colIdIsSimpleAttribute); attributeKeys.forEach((columnId: string) => { apiWrapper.removeCellClass(gridApi, columnId, lastRowIndex, "gd-cell-show-hidden"); // the following value is the same as the current one if (groupingProvider.isRepeatedValue(columnId, firstVisibleRowIndex + 1)) { // set the sticky header text apiWrapper.setPinnedTopRowCellText(gridApi, columnId, firstVisibleNodeData[columnId]); // show the sticky header apiWrapper.removePinnedTopRowCellClass(gridApi, columnId, "gd-hidden-sticky-column"); } else { // hide the sticky header apiWrapper.addPinnedTopRowCellClass(gridApi, columnId, "gd-hidden-sticky-column"); // if the column has some groups if (groupingProvider.isColumnWithGrouping(columnId)) { // show the last cell of the group temporarily so it scrolls out of the viewport nicely const currentRowIndex = getGridIndex(currentScrollPosition.top, rowHeight); apiWrapper.addCellClass(gridApi, columnId, currentRowIndex, "gd-cell-show-hidden"); } } }); };