From 900986bad60cb01172208f526cbce7253f481666 Mon Sep 17 00:00:00 2001 From: Tomasz Kajtoch Date: Tue, 25 Jul 2023 11:52:08 +0200 Subject: [PATCH] feature: EuiDataGrid type improvements to support React 18 (#6958) --- .../babel/proptypes-from-ts-props/index.js | 2 +- .../datagrid/advanced/custom_renderer.tsx | 11 ++- src-docs/src/views/datagrid/advanced/ref.tsx | 38 +++++++--- .../datagrid/styling/row_height_auto.tsx | 15 +++- .../datagrid/styling/row_height_fixed.tsx | 11 ++- .../datagrid/styling/row_line_height.tsx | 21 ++++-- .../datagrid/toolbar/additional_controls.tsx | 7 +- .../datagrid/body/data_grid_body_custom.tsx | 3 +- .../datagrid/body/data_grid_cell.tsx | 2 + .../datagrid/body/data_grid_cell_popover.tsx | 4 +- .../datagrid/body/data_grid_row_manager.ts | 2 +- .../body/header/data_grid_header_cell.tsx | 2 +- .../datagrid/controls/data_grid_toolbar.tsx | 74 +++++++++++-------- .../controls/display_selector.test.tsx | 23 ++++-- .../datagrid/controls/display_selector.tsx | 10 ++- src/components/datagrid/data_grid_types.ts | 20 ++--- .../datagrid/utils/data_grid_pagination.tsx | 7 +- src/components/datagrid/utils/in_memory.tsx | 8 +- src/components/datagrid/utils/ref.ts | 6 +- 19 files changed, 175 insertions(+), 91 deletions(-) diff --git a/scripts/babel/proptypes-from-ts-props/index.js b/scripts/babel/proptypes-from-ts-props/index.js index eae3c76871a3..442670e3cd24 100644 --- a/scripts/babel/proptypes-from-ts-props/index.js +++ b/scripts/babel/proptypes-from-ts-props/index.js @@ -10,7 +10,7 @@ function stripTypeScript(filename, ast) { return babelCore.transform(babelCore.transformFromAst(ast).code, { filename: filename, babelrc: false, - presets: ['@babel/typescript'], + presets: [['@babel/typescript', { allowDeclareFields: true }]], }).code; } diff --git a/src-docs/src/views/datagrid/advanced/custom_renderer.tsx b/src-docs/src/views/datagrid/advanced/custom_renderer.tsx index 64a04678e731..56c37a1a74cb 100644 --- a/src-docs/src/views/datagrid/advanced/custom_renderer.tsx +++ b/src-docs/src/views/datagrid/advanced/custom_renderer.tsx @@ -16,6 +16,9 @@ import { EuiSpacer, useEuiTheme, logicalCSS, + EuiDataGridPaginationProps, + EuiDataGridSorting, + EuiDataGridColumnSortingConfig, } from '../../../../../src'; const raw_data: Array<{ [key: string]: string }> = []; @@ -166,16 +169,16 @@ export default () => { // Pagination const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 }); - const onChangePage = useCallback((pageIndex) => { + const onChangePage = useCallback((pageIndex) => { setPagination((pagination) => ({ ...pagination, pageIndex })); }, []); - const onChangePageSize = useCallback((pageSize) => { + const onChangePageSize = useCallback((pageSize) => { setPagination((pagination) => ({ ...pagination, pageSize })); }, []); // Sorting - const [sortingColumns, setSortingColumns] = useState([]); - const onSort = useCallback((sortingColumns) => { + const [sortingColumns, setSortingColumns] = useState([]); + const onSort = useCallback((sortingColumns) => { setSortingColumns(sortingColumns); }, []); diff --git a/src-docs/src/views/datagrid/advanced/ref.tsx b/src-docs/src/views/datagrid/advanced/ref.tsx index b2102e89303d..658e60e7ba69 100644 --- a/src-docs/src/views/datagrid/advanced/ref.tsx +++ b/src-docs/src/views/datagrid/advanced/ref.tsx @@ -16,6 +16,10 @@ import { EuiModalHeader, EuiModalHeaderTitle, EuiText, + EuiDataGridColumnCellAction, + EuiDataGridColumnSortingConfig, + EuiDataGridPaginationProps, + EuiDataGridSorting, } from '../../../../../src'; const raw_data: Array<{ [key: string]: string }> = []; @@ -44,13 +48,16 @@ export default () => { dataGridRef.current!.setFocusedCell(lastFocusedCell); // Set the data grid focus back to the cell that opened the modal }, [lastFocusedCell]); - const showModal = useCallback(({ rowIndex, colIndex }) => { - setIsModalVisible(true); - dataGridRef.current!.closeCellPopover(); // Close any open cell popovers - setLastFocusedCell({ rowIndex, colIndex }); // Store the cell that opened this modal - }, []); + const showModal = useCallback( + ({ rowIndex, colIndex }: { rowIndex: number; colIndex: number }) => { + setIsModalVisible(true); + dataGridRef.current!.closeCellPopover(); // Close any open cell popovers + setLastFocusedCell({ rowIndex, colIndex }); // Store the cell that opened this modal + }, + [] + ); - const openModalAction = useCallback( + const openModalAction = useCallback( ({ Component, rowIndex, colIndex }) => { return ( { // Pagination const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 25 }); - const onChangePage = useCallback((pageIndex) => { - setPagination((pagination) => ({ ...pagination, pageIndex })); - }, []); - const onChangePageSize = useCallback((pageSize) => { + const onChangePage = useCallback( + (pageIndex) => { + setPagination((pagination) => ({ ...pagination, pageIndex })); + }, + [] + ); + const onChangePageSize = useCallback< + EuiDataGridPaginationProps['onChangeItemsPerPage'] + >((pageSize) => { setPagination((pagination) => ({ ...pagination, pageSize })); }, []); // Sorting - const [sortingColumns, setSortingColumns] = useState([]); - const onSort = useCallback((sortingColumns) => { + const [sortingColumns, setSortingColumns] = useState< + EuiDataGridColumnSortingConfig[] + >([]); + const onSort = useCallback((sortingColumns) => { setSortingColumns(sortingColumns); }, []); diff --git a/src-docs/src/views/datagrid/styling/row_height_auto.tsx b/src-docs/src/views/datagrid/styling/row_height_auto.tsx index fe7c0c055b9b..b963efcdfc3e 100644 --- a/src-docs/src/views/datagrid/styling/row_height_auto.tsx +++ b/src-docs/src/views/datagrid/styling/row_height_auto.tsx @@ -18,6 +18,9 @@ import { EuiText, EuiSpacer, formatDate, + EuiDataGridSorting, + EuiDataGridColumnSortingConfig, + EuiDataGridPaginationProps, } from '../../../../../src'; interface DataShape { @@ -146,15 +149,19 @@ export default () => { const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 50 }); // Sorting - const [sortingColumns, setSortingColumns] = useState([]); - const onSort = useCallback( + const [sortingColumns, setSortingColumns] = useState< + EuiDataGridColumnSortingConfig[] + >([]); + const onSort = useCallback( (sortingColumns) => { setSortingColumns(sortingColumns); }, [setSortingColumns] ); - const onChangeItemsPerPage = useCallback( + const onChangeItemsPerPage = useCallback< + EuiDataGridPaginationProps['onChangeItemsPerPage'] + >( (pageSize) => setPagination((pagination) => ({ ...pagination, @@ -164,7 +171,7 @@ export default () => { [setPagination] ); - const onChangePage = useCallback( + const onChangePage = useCallback( (pageIndex) => setPagination((pagination) => ({ ...pagination, pageIndex })), [setPagination] diff --git a/src-docs/src/views/datagrid/styling/row_height_fixed.tsx b/src-docs/src/views/datagrid/styling/row_height_fixed.tsx index e46dfb452dc9..f2a5ebbed9d4 100644 --- a/src-docs/src/views/datagrid/styling/row_height_fixed.tsx +++ b/src-docs/src/views/datagrid/styling/row_height_fixed.tsx @@ -18,6 +18,9 @@ import { EuiText, EuiSpacer, formatDate, + EuiDataGridSorting, + EuiDataGridColumnSortingConfig, + EuiDataGridPaginationProps, } from '../../../../../src'; interface DataShape { @@ -146,15 +149,15 @@ export default () => { const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 50 }); // Sorting - const [sortingColumns, setSortingColumns] = useState([]); - const onSort = useCallback( + const [sortingColumns, setSortingColumns] = useState([]); + const onSort = useCallback( (sortingColumns) => { setSortingColumns(sortingColumns); }, [setSortingColumns] ); - const onChangeItemsPerPage = useCallback( + const onChangeItemsPerPage = useCallback( (pageSize) => setPagination((pagination) => ({ ...pagination, @@ -164,7 +167,7 @@ export default () => { [setPagination] ); - const onChangePage = useCallback( + const onChangePage = useCallback( (pageIndex) => setPagination((pagination) => ({ ...pagination, pageIndex })), [setPagination] diff --git a/src-docs/src/views/datagrid/styling/row_line_height.tsx b/src-docs/src/views/datagrid/styling/row_line_height.tsx index 636c21e42dfa..b2f87a92ef23 100644 --- a/src-docs/src/views/datagrid/styling/row_line_height.tsx +++ b/src-docs/src/views/datagrid/styling/row_line_height.tsx @@ -8,7 +8,14 @@ import React, { } from 'react'; import githubData from '../_row_auto_height_data.json'; -import { EuiDataGrid, EuiDataGridProps, formatDate } from '../../../../../src'; +import { + EuiDataGrid, + EuiDataGridColumnSortingConfig, + EuiDataGridPaginationProps, + EuiDataGridProps, + EuiDataGridSorting, + formatDate, +} from '../../../../../src'; interface DataShape { html_url: string; @@ -96,15 +103,19 @@ export default () => { const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 50 }); // Sorting - const [sortingColumns, setSortingColumns] = useState([]); - const onSort = useCallback( + const [sortingColumns, setSortingColumns] = useState< + EuiDataGridColumnSortingConfig[] + >([]); + const onSort = useCallback( (sortingColumns) => { setSortingColumns(sortingColumns); }, [setSortingColumns] ); - const onChangeItemsPerPage = useCallback( + const onChangeItemsPerPage = useCallback< + EuiDataGridPaginationProps['onChangeItemsPerPage'] + >( (pageSize) => setPagination((pagination) => ({ ...pagination, @@ -114,7 +125,7 @@ export default () => { [setPagination] ); - const onChangePage = useCallback( + const onChangePage = useCallback( (pageIndex) => setPagination((pagination) => ({ ...pagination, pageIndex })), [setPagination] diff --git a/src-docs/src/views/datagrid/toolbar/additional_controls.tsx b/src-docs/src/views/datagrid/toolbar/additional_controls.tsx index 78debdc0f25e..fa98c19745af 100644 --- a/src-docs/src/views/datagrid/toolbar/additional_controls.tsx +++ b/src-docs/src/views/datagrid/toolbar/additional_controls.tsx @@ -16,6 +16,7 @@ import { EuiContextMenuItem, EuiContextMenuPanel, EuiPopover, + EuiDataGridPaginationProps, } from '../../../../../src'; const columns = [ @@ -94,12 +95,14 @@ export default () => { columns.map(({ id }) => id) ); - const setPageIndex = useCallback( + const setPageIndex = useCallback( (pageIndex) => setPagination((pagination) => ({ ...pagination, pageIndex })), [] ); - const setPageSize = useCallback( + const setPageSize = useCallback< + EuiDataGridPaginationProps['onChangeItemsPerPage'] + >( (pageSize) => setPagination((pagination) => ({ ...pagination, diff --git a/src/components/datagrid/body/data_grid_body_custom.tsx b/src/components/datagrid/body/data_grid_body_custom.tsx index d87b5009fe01..881deb3f6428 100644 --- a/src/components/datagrid/body/data_grid_body_custom.tsx +++ b/src/components/datagrid/body/data_grid_body_custom.tsx @@ -19,6 +19,7 @@ import { useRowHeightUtils, useDefaultRowHeight } from '../utils/row_heights'; import { EuiDataGridBodyProps, + EuiDataGridCustomBodyProps, EuiDataGridSetCustomGridBodyProps, } from '../data_grid_types'; import { useDataGridHeader } from './header'; @@ -140,7 +141,7 @@ export const EuiDataGridBodyCustomRender: FunctionComponent< rowHeightUtils, }; - const _Cell = useCallback( + const _Cell = useCallback( ({ colIndex, visibleRowIndex, ...rest }) => { const style = { height: rowHeightUtils.isAutoHeight(visibleRowIndex, rowHeightsOptions) diff --git a/src/components/datagrid/body/data_grid_cell.tsx b/src/components/datagrid/body/data_grid_cell.tsx index 12af15fa8000..0cdb33969fa6 100644 --- a/src/components/datagrid/body/data_grid_cell.tsx +++ b/src/components/datagrid/body/data_grid_cell.tsx @@ -9,6 +9,7 @@ import classNames from 'classnames'; import React, { Component, + ContextType, createRef, FocusEvent, FunctionComponent, @@ -143,6 +144,7 @@ export class EuiDataGridCell extends Component< style = null; static contextType = DataGridFocusContext; + declare context: ContextType; getInteractables = () => { const tabbingRef = this.cellContentsRef; diff --git a/src/components/datagrid/body/data_grid_cell_popover.tsx b/src/components/datagrid/body/data_grid_cell_popover.tsx index 060ec7d630da..a64a894e1216 100644 --- a/src/components/datagrid/body/data_grid_cell_popover.tsx +++ b/src/components/datagrid/body/data_grid_cell_popover.tsx @@ -46,7 +46,9 @@ export const useCellPopover = (): { >({}); const closeCellPopover = useCallback(() => setPopoverIsOpen(false), []); - const openCellPopover = useCallback( + const openCellPopover = useCallback< + DataGridCellPopoverContextShape['openCellPopover'] + >( ({ rowIndex, colIndex }) => { // Prevent popover DOM issues when re-opening the same popover if ( diff --git a/src/components/datagrid/body/data_grid_row_manager.ts b/src/components/datagrid/body/data_grid_row_manager.ts index 5a19b3f29400..090f4b493658 100644 --- a/src/components/datagrid/body/data_grid_row_manager.ts +++ b/src/components/datagrid/body/data_grid_row_manager.ts @@ -18,7 +18,7 @@ export const useRowManager = ({ }): EuiDataGridRowManager => { const rowIdToElements = useRef(new Map()); - const getRow = useCallback( + const getRow = useCallback( ({ rowIndex, visibleRowIndex, top, height }) => { let rowElement = rowIdToElements.current.get(rowIndex); diff --git a/src/components/datagrid/body/header/data_grid_header_cell.tsx b/src/components/datagrid/body/header/data_grid_header_cell.tsx index 01802e4bd2ae..45ae091eb505 100644 --- a/src/components/datagrid/body/header/data_grid_header_cell.tsx +++ b/src/components/datagrid/body/header/data_grid_header_cell.tsx @@ -314,7 +314,7 @@ export const useSortingUtils = ({ export const usePopoverArrowNavigation = () => { const popoverPanelRef = useRef(null); const actionsRef = useRef(undefined); - const panelRef = useCallback((ref) => { + const panelRef = useCallback((ref: HTMLElement | null) => { popoverPanelRef.current = ref; actionsRef.current = ref ? tabbable(ref) : undefined; }, []); diff --git a/src/components/datagrid/controls/data_grid_toolbar.tsx b/src/components/datagrid/controls/data_grid_toolbar.tsx index 4c30a18d35b0..ec043048c618 100644 --- a/src/components/datagrid/controls/data_grid_toolbar.tsx +++ b/src/components/datagrid/controls/data_grid_toolbar.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { isValidElement, ReactNode } from 'react'; import { EuiDataGridProps, EuiDataGridToolbarProps, @@ -115,47 +115,61 @@ export function checkOrDefaultToolBarDisplayOptions< } } -export function renderAdditionalControls( +export const renderAdditionalControls = ( toolbarVisibility: EuiDataGridProps['toolbarVisibility'], position: 'left.prepend' | 'left.append' | 'right' -) { +): ReactNode => { if (typeof toolbarVisibility === 'boolean') return null; const { additionalControls } = toolbarVisibility || {}; if (!additionalControls) return null; - // Typescript is having obj issues, so we need to force cast to EuiDataGridToolBarAdditionalControlsOptions here - const additionalControlsObj: EuiDataGridToolBarAdditionalControlsOptions = - additionalControls?.constructor === Object ? additionalControls : {}; - // Typescript workarounds continued - const leftPositionObj: EuiDataGridToolBarAdditionalControlsLeftOptions = - additionalControlsObj.left?.constructor === Object - ? additionalControlsObj.left - : {}; + // API backwards compatability: if the consumer passed a single ReactNode + // to `additionalControls`, default to the left append position. + if (isValidElement(additionalControls) && position === 'left.append') { + return additionalControls; + } + if (typeof additionalControls !== 'object') { + return null; + } - if (position === 'right') { - if (additionalControlsObj?.right) { - return additionalControlsObj.right; + const handleLeftObjectConfig = ( + leftConfig: EuiDataGridToolBarAdditionalControlsLeftOptions + ) => { + if (position === 'left.prepend') { + return leftConfig.prepend; } - } else if (position === 'left.prepend') { - if (leftPositionObj?.prepend) { - return leftPositionObj.prepend; + if (position === 'left.append') { + return leftConfig.append; } - } else if (position === 'left.append') { - if (leftPositionObj?.append) { - return leftPositionObj.append; + }; + + const handleObjectConfig = ( + additionalControls: EuiDataGridToolBarAdditionalControlsOptions + ) => { + if (position === 'right') { + return additionalControls.right; } - if (React.isValidElement(additionalControlsObj?.left)) { - // If the consumer passed a single ReactNode to `additionalControls.left`, default to the left append position - return additionalControlsObj.left; + // API backwards compatability: If the consumer passed a single ReactNode + // to `additionalControls.left`, default to the left append position + if (isValidElement(additionalControls.left) && position === 'left.append') { + return additionalControls.left; } - if (React.isValidElement(additionalControls)) { - // API backwards compatability: if the consumer passed a single ReactNode to `additionalControls`, default to the the left append position - return additionalControls; + if ( + additionalControls.left && + typeof additionalControls.left === 'object' + ) { + return handleLeftObjectConfig( + additionalControls.left as EuiDataGridToolBarAdditionalControlsLeftOptions + ); } - } + }; - return null; -} + const rendered = handleObjectConfig( + additionalControls as EuiDataGridToolBarAdditionalControlsOptions + ); + + return rendered || null; +}; /** * Utility helper for selectors/controls that allow nested options @@ -167,7 +181,7 @@ export function getNestedObjectOptions( objectKey: keyof T ): boolean { // If the config is a boolean, nested options follow that boolean - if (controlOption === false || controlOption === true) return controlOption; + if (typeof controlOption === 'boolean') return controlOption; // If config is not defined, default to enabled if (controlOption == null) return true; // Otherwise, type should be an object of boolean values - dive into it and return the value diff --git a/src/components/datagrid/controls/display_selector.test.tsx b/src/components/datagrid/controls/display_selector.test.tsx index ede3eaedce43..dbb3629c83ed 100644 --- a/src/components/datagrid/controls/display_selector.test.tsx +++ b/src/components/datagrid/controls/display_selector.test.tsx @@ -310,10 +310,19 @@ describe('useDataGridDisplaySelector', () => { component .find('input[type="range"][data-test-subj="lineCountNumber"]') .prop('value'); - const setLineCountNumber = (component: ReactWrapper, number: number) => - component - .find('input[type="range"][data-test-subj="lineCountNumber"]') - .simulate('change', { target: { value: number } }); + const setLineCountNumber = ( + component: ReactWrapper, + number: number + ) => { + const input = component.find( + 'input[type="range"][data-test-subj="lineCountNumber"]' + ); + + // enzyme simulate() doesn't handle event.currentTarget updates well + // https://github.com/enzymejs/enzyme/issues/218 + (input.getDOMNode() as HTMLInputElement).value = number.toString(); + input.simulate('change'); + }; it('conditionally displays a line count number input when the lineCount button is selected', () => { const component = mount(); @@ -357,7 +366,11 @@ describe('useDataGridDisplaySelector', () => { ); openPopover(component); - setLineCountNumber(component, 3); + act(() => { + setLineCountNumber(component, 3); + }); + component.update(); + expect(getLineCountNumber(component)).toEqual(3); }); diff --git a/src/components/datagrid/controls/display_selector.tsx b/src/components/datagrid/controls/display_selector.tsx index 62fc651280ae..3aa96d5a5d28 100644 --- a/src/components/datagrid/controls/display_selector.tsx +++ b/src/components/datagrid/controls/display_selector.tsx @@ -18,7 +18,7 @@ import { useUpdateEffect } from '../../../services'; import { EuiI18n, useEuiI18n } from '../../i18n'; import { EuiPopover, EuiPopoverFooter } from '../../popover'; import { EuiButtonIcon, EuiButtonGroup, EuiButtonEmpty } from '../../button'; -import { EuiFormRow, EuiRange } from '../../form'; +import { EuiFormRow, EuiRange, EuiRangeProps } from '../../form'; import { EuiFlexGroup, EuiFlexItem } from '../../flex'; import { EuiToolTip } from '../../tool_tip'; @@ -137,8 +137,12 @@ export const useDataGridDisplaySelector = ( }, [lineCount] ); - const setLineCountHeight = useCallback((event) => { - const newLineCount = Number(event.target.value); + const setLineCountHeight = useCallback< + NonNullable + >((event) => { + if (!event.currentTarget) return; + + const newLineCount = Number(event.currentTarget.value); if (newLineCount < 1) return; // Don't let users set a 0 or negative line count setLineCount(newLineCount); diff --git a/src/components/datagrid/data_grid_types.ts b/src/components/datagrid/data_grid_types.ts index ce71ec8cd467..daf489cb48e8 100644 --- a/src/components/datagrid/data_grid_types.ts +++ b/src/components/datagrid/data_grid_types.ts @@ -18,6 +18,7 @@ import { Ref, Component, PropsWithChildren, + ComponentClass, } from 'react'; import { VariableSizeGridProps, @@ -582,8 +583,8 @@ export interface EuiDataGridCellProps { className?: string; popoverContext: DataGridCellPopoverContextShape; renderCellValue: - | JSXElementConstructor - | ((props: EuiDataGridCellValueElementProps) => ReactNode); + | ((props: EuiDataGridCellValueElementProps) => ReactNode) + | ComponentClass; renderCellPopover?: | JSXElementConstructor | ((props: EuiDataGridCellPopoverElementProps) => ReactNode); @@ -706,8 +707,7 @@ export interface EuiDataGridColumn { } export type EuiDataGridColumnCellAction = - | JSXElementConstructor - | ((props: EuiDataGridColumnCellActionProps) => ReactNode); + ComponentType; export interface EuiDataGridColumnActions { /** @@ -936,18 +936,20 @@ export interface EuiDataGridPaginationProps { onChangePage: (pageIndex: number) => void; } +export interface EuiDataGridColumnSortingConfig { + id: string; + direction: 'asc' | 'desc'; +} + export interface EuiDataGridSorting { /** * A function that receives updated column sort details in response to user interactions in the toolbar controls */ - onSort: (columns: EuiDataGridSorting['columns']) => void; + onSort: (columns: EuiDataGridColumnSortingConfig[]) => void; /** * An array of the column ids currently being sorted and their sort direction. The array order determines the sort order. `{ id: 'A'; direction: 'asc' }` */ - columns: Array<{ - id: string; - direction: 'asc' | 'desc'; - }>; + columns: EuiDataGridColumnSortingConfig[]; } export interface EuiDataGridInMemory { diff --git a/src/components/datagrid/utils/data_grid_pagination.tsx b/src/components/datagrid/utils/data_grid_pagination.tsx index dea8dd5424e8..bbdcd21bad54 100644 --- a/src/components/datagrid/utils/data_grid_pagination.tsx +++ b/src/components/datagrid/utils/data_grid_pagination.tsx @@ -9,7 +9,10 @@ import React, { useCallback, useContext } from 'react'; import { useEuiI18n } from '../../i18n'; // Note: this file must be named data_grid_pagination to match i18n tokens import { EuiTablePagination } from '../../table/table_pagination'; -import { EuiDataGridPaginationRendererProps } from '../data_grid_types'; +import { + EuiDataGridPaginationProps, + EuiDataGridPaginationRendererProps, +} from '../data_grid_types'; import { DataGridFocusContext } from './focus'; export const EuiDataGridPaginationRenderer = ({ @@ -34,7 +37,7 @@ export const EuiDataGridPaginationRenderer = ({ // Focus the first data cell & scroll back to the top of the grid whenever paginating to a new page const { setFocusedCell } = useContext(DataGridFocusContext); - const onChangePage = useCallback( + const onChangePage = useCallback( (pageIndex) => { _onChangePage(pageIndex); setFocusedCell([0, 0]); diff --git a/src/components/datagrid/utils/in_memory.tsx b/src/components/datagrid/utils/in_memory.tsx index 8903913eaff0..33d840e09019 100644 --- a/src/components/datagrid/utils/in_memory.tsx +++ b/src/components/datagrid/utils/in_memory.tsx @@ -33,7 +33,7 @@ export const useInMemoryValues = ( rowCount: number ): [ EuiDataGridInMemoryValues, - (rowIndex: number, columnId: string, value: string) => void + EuiDataGridInMemoryRendererProps['onCellRender'] ] => { /** * For performance, `onCellRender` below mutates the inMemoryValues object @@ -47,12 +47,14 @@ export const useInMemoryValues = ( const _inMemoryValues = useRef({}); const [inMemoryValuesVersion, setInMemoryValuesVersion] = useState(0); - const inMemoryValues = useMemo( + const inMemoryValues = useMemo( () => ({ ..._inMemoryValues.current }), [inMemoryValuesVersion] // eslint-disable-line react-hooks/exhaustive-deps ); - const onCellRender = useCallback((rowIndex, columnId, value) => { + const onCellRender = useCallback< + EuiDataGridInMemoryRendererProps['onCellRender'] + >((rowIndex, columnId, value) => { const nextInMemoryValues = _inMemoryValues.current; nextInMemoryValues[rowIndex] = nextInMemoryValues[rowIndex] || {}; if (nextInMemoryValues[rowIndex][columnId] !== value) { diff --git a/src/components/datagrid/utils/ref.ts b/src/components/datagrid/utils/ref.ts index bbf5099120bf..fa0f70be4a2f 100644 --- a/src/components/datagrid/utils/ref.ts +++ b/src/components/datagrid/utils/ref.ts @@ -50,7 +50,7 @@ export const useImperativeGridRef = ({ // the targeted cell is valid or in view (unlike our internal state, where // both of those states can be guaranteed), so we need to do some extra // checks here to make sure the grid automatically handles all cells - const setFocusedCell = useCallback( + const setFocusedCell = useCallback( ({ rowIndex, colIndex }) => { checkCellExists({ rowIndex, colIndex }); const visibleRowIndex = findVisibleRowIndex(rowIndex); @@ -67,7 +67,7 @@ export const useImperativeGridRef = ({ // the targeted cell is valid or in view (unlike our internal state, where // both of those states can be guaranteed), so we need to do some extra // checks here to make sure the grid automatically handles all cells - const openCellPopover = useCallback( + const openCellPopover = useCallback( ({ rowIndex, colIndex }) => { checkCellExists({ rowIndex, colIndex }); const visibleRowIndex = findVisibleRowIndex(rowIndex); @@ -114,7 +114,7 @@ export const useImperativeGridRef = ({ */ export const useCellLocationCheck = (rowCount: number, colCount: number) => { const checkCellExists = useCallback( - ({ rowIndex, colIndex }) => { + ({ rowIndex, colIndex }: { rowIndex: number; colIndex: number }) => { if (rowIndex >= rowCount || rowIndex < 0) { throw new Error( `Row ${rowIndex} is not a valid row. The maximum visible row index is ${