Skip to content

Commit

Permalink
Data grid: Take scrollbar into account (#4468)
Browse files Browse the repository at this point in the history
* take scrollbar into account

* add changelog and clean up

* make sure to always adjust column widths

* move new logic in custom hook

* Update CHANGELOG.md

Co-authored-by: Dave Snider <dave.snider@gmail.com>

* fix lint issue

Co-authored-by: Chandler Prall <chandler.prall@gmail.com>
Co-authored-by: Dave Snider <dave.snider@gmail.com>
  • Loading branch information
3 people authored Feb 10, 2021
1 parent 4388422 commit 708c3b6
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- Fixed `onClose` invoking with unexpected parameter in `EuiFlyout` ([#4505](https://github.com/elastic/eui/pull/4505))
- Fixed invalid color entry passed to `EuiBadge` color prop ([#4481](https://github.com/elastic/eui/pull/4481))
- Fixed `EuiCodeBlock` focus-state if content overflows ([#4463]https://github.com/elastic/eui/pull/4463)
- Fixed issues in `EuiDataGrid` around unnecessary scroll bars and container heights not updating ([#4468](https://github.com/elastic/eui/pull/4468))

## [`31.5.0`](https://github.com/elastic/eui/tree/v31.5.0)

Expand Down
52 changes: 50 additions & 2 deletions src/components/datagrid/data_grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ import {
import { EuiDataGridCellProps } from './data_grid_cell';
import { EuiButtonEmpty } from '../button';
import { keys, htmlIdGenerator } from '../../services';
import { EuiDataGridBody } from './data_grid_body';
import { EuiDataGridBody, VIRTUALIZED_CONTAINER_CLASS } from './data_grid_body';
import { useDataGridColumnSelector } from './column_selector';
import { useDataGridStyleSelector, startingStyles } from './style_selector';
import { EuiTablePagination } from '../table/table_pagination';
Expand Down Expand Up @@ -297,6 +297,47 @@ function renderPagination(props: EuiDataGridProps, controls: string) {
);
}

/**
* Returns the size of the cell container minus the scroll bar width.
* To do so, this hook is listening for size changes of the container itself,
* as well as pagination changes to make sure every update is caught.
*
* This is necessary because there is no callback/event fired by the browser
* indicating the scroll bar state has changed.
* @param resizeRef the wrapper element containging the data grid
* @param pageSize the currently applied page size
*/
function useVirtualizeContainerWidth(
resizeRef: HTMLDivElement | null,
pageSize: number | undefined
) {
const [virtualizeContainerWidth, setVirtualizeContainerWidth] = useState(0);
const virtualizeContainer = resizeRef?.getElementsByClassName(
VIRTUALIZED_CONTAINER_CLASS
)[0] as HTMLDivElement | null;

// re-render data grid on size changes
useResizeObserver(virtualizeContainer);

useEffect(() => {
if (virtualizeContainer?.clientWidth) {
setVirtualizeContainerWidth(virtualizeContainer.clientWidth);
}
}, [virtualizeContainer?.clientWidth]);

useEffect(() => {
// wait for layout to settle, then measure virtualize container
setTimeout(() => {
if (virtualizeContainer?.clientWidth) {
const containerWidth = virtualizeContainer.clientWidth;
setVirtualizeContainerWidth(containerWidth);
}
}, 100);
}, [pageSize, virtualizeContainer]);

return virtualizeContainerWidth;
}

function useDefaultColumnWidth(
gridWidth: number,
leadingControlColumns: EuiDataGridControlColumn[],
Expand Down Expand Up @@ -730,6 +771,11 @@ export const EuiDataGrid: FunctionComponent<EuiDataGridProps> = (props) => {
}
}, [resizeRef, gridDimensions]);

const virtualizeContainerWidth = useVirtualizeContainerWidth(
resizeRef,
pagination?.pageSize
);

const hasRoomForGridControls = IS_JEST_ENVIRONMENT
? true
: gridWidth > minSizeForControls || isFullScreen;
Expand Down Expand Up @@ -801,7 +847,9 @@ export const EuiDataGrid: FunctionComponent<EuiDataGridProps> = (props) => {

// compute the default column width from the container's clientWidth and count of visible columns
const defaultColumnWidth = useDefaultColumnWidth(
gridDimensions.width,
// use clientWidth of the virtualization container to take scroll bar into account
// if that's not possible fall back to the size of the wrapper element
virtualizeContainerWidth || gridDimensions.width,
leadingControlColumns,
trailingControlColumns,
orderedVisibleColumns
Expand Down
10 changes: 6 additions & 4 deletions src/components/datagrid/data_grid_body.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ export interface EuiDataGridBodyProps {
toolbarHeight: number;
}

export const VIRTUALIZED_CONTAINER_CLASS = 'euiDataGrid__virtualized';

const defaultComparator: NonNullable<
EuiDataGridSchemaDetector['comparator']
> = (a, b, direction) => {
Expand Down Expand Up @@ -290,7 +292,7 @@ const InnerElement: VariableSizeGridProps['innerElementType'] = forwardRef<
InnerElement.displayName = 'EuiDataGridInnerElement';

const INITIAL_ROW_HEIGHT = 34;
const SCROLLBAR_HEIGHT = 15;
const SCROLLBAR_HEIGHT = 16;
const IS_JEST_ENVIRONMENT = global.hasOwnProperty('_isJest');

export const EuiDataGridBody: FunctionComponent<EuiDataGridBodyProps> = (
Expand Down Expand Up @@ -524,10 +526,10 @@ export const EuiDataGridBody: FunctionComponent<EuiDataGridBodyProps> = (
const [height, setHeight] = useState<number | undefined>(undefined);
const [width, setWidth] = useState<number | undefined>(undefined);

// reset height constraint when rowCount changes
// reset height constraint when rowCount or fullscreen setting changes
useEffect(() => {
setHeight(undefined);
}, [rowCount]);
}, [rowCount, isFullScreen]);

const wrapperRef = useRef<HTMLDivElement | null>(null);
const wrapperDimensions = useResizeObserver(wrapperRef.current);
Expand Down Expand Up @@ -584,7 +586,7 @@ export const EuiDataGridBody: FunctionComponent<EuiDataGridBodyProps> = (
<Grid
ref={gridRef}
innerElementType={InnerElement}
className="euiDataGrid__virtualized"
className={VIRTUALIZED_CONTAINER_CLASS}
columnCount={
leadingControlColumns.length +
columns.length +
Expand Down

0 comments on commit 708c3b6

Please sign in to comment.