react-konva-grid
Version:
Declarative React Canvas Grid primitive for Data table, Pivot table, Excel Worksheets
99 lines • 4.17 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ResizeStrategy = void 0;
const react_1 = require("react");
const helpers_1 = require("./../helpers");
const tiny_invariant_1 = __importDefault(require("tiny-invariant"));
var ResizeStrategy;
(function (ResizeStrategy) {
ResizeStrategy["lazy"] = "lazy";
ResizeStrategy["full"] = "full";
})(ResizeStrategy = exports.ResizeStrategy || (exports.ResizeStrategy = {}));
/**
* Auto sizer hook
* @param param
*
* TODO
* Dynamically resize columns after user has scrolled down/view port changed ?
*/
const useAutoSizer = ({ gridRef, getValue, initialVisibleRows = 20, cellSpacing = 10, minColumnWidth = 60, timeout = 300, resizeStrategy = ResizeStrategy.lazy, rowCount, resizeOnScroll = true, font = "12px Arial", autoResize = true, }) => {
tiny_invariant_1.default(!(resizeStrategy === ResizeStrategy.full && rowCount === void 0), "Row count should be specified if resize stragtegy is full");
const autoSizer = react_1.useRef(helpers_1.AutoSizerCanvas(font));
const [viewport, setViewport] = react_1.useState({
rowStartIndex: 0,
rowStopIndex: 0,
columnStartIndex: 0,
columnStopIndex: 0,
});
const isMounted = react_1.useRef(false);
const debounceResizer = react_1.useRef(helpers_1.debounce(({ rowIndex, columnIndex }) => gridRef.current.resetAfterIndices({ rowIndex, columnIndex }), timeout));
react_1.useEffect(() => {
isMounted.current = true;
}, []);
/* Update any styles, fonts if necessary */
react_1.useEffect(() => {
autoSizer.current.setFont(font);
}, [font]);
const getTextMetrics = (text) => {
return autoSizer.current.measureText(text);
};
const getColumnWidth = react_1.useCallback((columnIndex) => {
var _a;
const { rowStartIndex, rowStopIndex } = viewport;
const visibleRows = resizeStrategy === ResizeStrategy.full
? rowCount
: rowStopIndex || initialVisibleRows;
let start = resizeStrategy === ResizeStrategy.full ? 0 : rowStartIndex;
let maxWidth = minColumnWidth;
while (start < visibleRows) {
const value = (_a = getValue({
rowIndex: start,
columnIndex,
})) !== null && _a !== void 0 ? _a : null;
if (value !== null) {
const metrics = autoSizer.current.measureText(value);
if (metrics) {
const width = Math.ceil(metrics.width) + cellSpacing;
if (width > maxWidth)
maxWidth = width;
}
}
start++;
}
return maxWidth;
}, [viewport, getValue, initialVisibleRows]);
const handleResizeColumn = react_1.useCallback((columnIndex) => {
const width = getColumnWidth(columnIndex);
gridRef.current.resizeColumns([columnIndex]);
}, []);
const handleViewChange = react_1.useCallback((cells) => {
/* Update viewport cells */
setViewport(cells);
/* Check if viewport has changed */
if (resizeStrategy === ResizeStrategy.full ||
!resizeOnScroll ||
(cells.rowStartIndex === viewport.rowStartIndex &&
cells.columnStartIndex === viewport.columnStartIndex))
return;
if (gridRef.current) {
/* During first mount, column width is calculated. Do not re-calculate */
if (!isMounted.current)
return;
debounceResizer.current({
rowIndex: cells.rowStartIndex,
columnIndex: cells.columnStartIndex,
});
}
}, [resizeOnScroll, viewport, resizeStrategy]);
return {
columnWidth: autoResize ? getColumnWidth : undefined,
resizeColumn: handleResizeColumn,
onViewChange: handleViewChange,
getTextMetrics,
};
};
exports.default = useAutoSizer;
//# sourceMappingURL=useSizer.js.map