UNPKG

@elastic/eui

Version:

Elastic UI Component Library

143 lines (134 loc) 6.1 kB
/* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0 and the Server Side Public License, v 1; you may not use this file except * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ import { useImperativeHandle, useCallback } from 'react'; export var useImperativeGridRef = function useImperativeGridRef(_ref) { var ref = _ref.ref, gridRef = _ref.gridRef, setIsFullScreen = _ref.setIsFullScreen, focusContext = _ref.focusContext, cellPopoverContext = _ref.cellPopoverContext, sortedRowMap = _ref.sortedContext.sortedRowMap, pagination = _ref.pagination, rowCount = _ref.rowCount, visibleColCount = _ref.visibleColCount; // Cell location helpers var _useCellLocationCheck = useCellLocationCheck(rowCount, visibleColCount), checkCellExists = _useCellLocationCheck.checkCellExists; var _useSortPageCheck = useSortPageCheck(pagination, sortedRowMap), findVisibleRowIndex = _useSortPageCheck.findVisibleRowIndex; // Focus APIs var _setFocusedCell = focusContext.setFocusedCell; // eslint complains about the dependency array otherwise // When we pass this API to the consumer, we can't know for sure that // 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 var setFocusedCell = useCallback(function (_ref2) { var rowIndex = _ref2.rowIndex, colIndex = _ref2.colIndex; checkCellExists({ rowIndex: rowIndex, colIndex: colIndex }); var visibleRowIndex = findVisibleRowIndex(rowIndex); _setFocusedCell([colIndex, visibleRowIndex]); // Transmog args from obj to array }, [_setFocusedCell, checkCellExists, findVisibleRowIndex]); // Popover APIs var _openCellPopover = cellPopoverContext.openCellPopover, closeCellPopover = cellPopoverContext.closeCellPopover; // When we pass this API to the consumer, we can't know for sure that // 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 var openCellPopover = useCallback(function (_ref3) { var rowIndex = _ref3.rowIndex, colIndex = _ref3.colIndex; checkCellExists({ rowIndex: rowIndex, colIndex: colIndex }); var visibleRowIndex = findVisibleRowIndex(rowIndex); _openCellPopover({ rowIndex: visibleRowIndex, colIndex: colIndex }); }, [_openCellPopover, checkCellExists, findVisibleRowIndex]); var scrollTo = useCallback(function () { var _gridRef$current; for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return (_gridRef$current = gridRef.current) === null || _gridRef$current === void 0 ? void 0 : _gridRef$current.scrollTo.apply(_gridRef$current, args); }, [gridRef]); var scrollToItem = useCallback(function () { var _gridRef$current2; for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } return (_gridRef$current2 = gridRef.current) === null || _gridRef$current2 === void 0 ? void 0 : _gridRef$current2.scrollToItem.apply(_gridRef$current2, args); }, [gridRef]); // Set the ref APIs useImperativeHandle(ref, function () { return { setIsFullScreen: setIsFullScreen, setFocusedCell: setFocusedCell, openCellPopover: openCellPopover, closeCellPopover: closeCellPopover, scrollTo: scrollTo, scrollToItem: scrollToItem }; }, [setIsFullScreen, setFocusedCell, openCellPopover, closeCellPopover, scrollTo, scrollToItem]); }; /** * Throw a digestible error if the consumer attempts to focus into an invalid * cell range, which should also stop the APIs from continuing */ export var useCellLocationCheck = function useCellLocationCheck(rowCount, colCount) { var checkCellExists = useCallback(function (_ref4) { var rowIndex = _ref4.rowIndex, colIndex = _ref4.colIndex; if (rowIndex >= rowCount || rowIndex < 0) { throw new Error("Row ".concat(rowIndex, " is not a valid row. The maximum visible row index is ").concat(rowCount - 1, ".")); } if (colIndex >= colCount) { throw new Error("Column ".concat(colIndex, " is not a valid column. The maximum visible column index is ").concat(colCount - 1, ".")); } }, [rowCount, colCount]); return { checkCellExists: checkCellExists }; }; /** * The rowIndex passed from the consumer is the unsorted and unpaginated * index derived from their original data. We need to convert that rowIndex * into a visibleRowIndex (which is what our internal cell APIs use) and, if * the row is not on the current page, the grid should automatically handle * paginating to that row. */ export var useSortPageCheck = function useSortPageCheck(pagination, sortedRowMap) { var findVisibleRowIndex = useCallback(function (rowIndex) { // Account for sorting var visibleRowIndex = sortedRowMap.length ? sortedRowMap.findIndex(function (mappedIndex) { return mappedIndex === rowIndex; }) : rowIndex; // Account for pagination if (pagination && pagination.pageSize > 0) { var pageIndex = Math.floor(visibleRowIndex / pagination.pageSize); // If the targeted row is on a different page than the current page, // we should automatically navigate the user to the correct page if (pageIndex !== pagination.pageIndex) { pagination.onChangePage(pageIndex); } // Get the row's visible row index on that page return visibleRowIndex % pagination.pageSize; } return visibleRowIndex; }, [pagination, sortedRowMap]); return { findVisibleRowIndex: findVisibleRowIndex }; };