@elastic/eui
Version:
Elastic UI Component Library
149 lines (139 loc) • 6.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useSortPageCheck = exports.useImperativeGridRef = exports.useCellLocationCheck = void 0;
var _react = require("react");
/*
* 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.
*/
var useImperativeGridRef = exports.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 = (0, _react.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 = (0, _react.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 = (0, _react.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 = (0, _react.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
(0, _react.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
*/
var useCellLocationCheck = exports.useCellLocationCheck = function useCellLocationCheck(rowCount, colCount) {
var checkCellExists = (0, _react.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.
*/
var useSortPageCheck = exports.useSortPageCheck = function useSortPageCheck(pagination, sortedRowMap) {
var findVisibleRowIndex = (0, _react.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
};
};