@visactor/react-vtable
Version:
The react version of VTable
91 lines (85 loc) • 5.45 kB
JavaScript
import React, { isValidElement, useCallback, useContext, useLayoutEffect, useRef } from "react";
import RootTableContext from "../../context/table";
import { Group } from "@visactor/vtable/es/vrender";
import { reconcilor, createReconcilerContainer } from "./reconciler";
export const CustomLayout = (props, ref) => {
const {componentId: componentId, children: children} = props;
if (!isValidElement(children)) return null;
const context = useContext(RootTableContext), {table: table, onError: onError} = context, isHeaderCustomLayout = "header-custom-layout" === children.props.role, container = useRef(new Map), reportReconcilerError = useCallback(((type, error) => {
var _a;
if (!onError) return;
if (error instanceof Error) {
const wrapped = new Error(`[react-vtable custom-layout:${type}] ${error.message}`);
return wrapped.stack = error.stack, void onError(wrapped);
}
const message = "string" == typeof error ? error : null !== (_a = null == error ? void 0 : error.message) && void 0 !== _a ? _a : String(error);
onError(new Error(`[react-vtable custom-layout:${type}] ${message}`));
}), [ onError ]), createGraphic = useCallback((args => {
var _a, _b;
const key = `${null !== (_a = args.originCol) && void 0 !== _a ? _a : args.col}-${null !== (_b = args.originRow) && void 0 !== _b ? _b : args.row}${args.forComputation ? "-forComputation" : ""}`;
let group;
if (container.current.has(key)) {
const currentContainer = container.current.get(key);
reconcilorUpdateContainer(children, currentContainer, args), group = currentContainer.containerInfo;
} else {
group = new Group({});
const currentContainer = createReconcilerContainer(group, "custom", reportReconcilerError);
container.current.set(key, currentContainer), reconcilorUpdateContainer(children, currentContainer, args);
}
return {
rootContainer: group,
renderDefault: !!children.props.renderDefault
};
}), [ children, reportReconcilerError ]), removeContainer = useCallback(((col, row) => {
const key = `${col}-${row}`;
if (container.current.has(key)) {
const currentContainer = container.current.get(key);
reconcilor.updateContainer(null, currentContainer, null), currentContainer.containerInfo.delete(),
container.current.delete(key);
}
}), []), removeAllContainer = useCallback((() => {
container.current.forEach(((value, key) => {
const currentContainer = value;
reconcilor.updateContainer(null, currentContainer, null), currentContainer.containerInfo.delete();
})), container.current.clear();
}), []);
return useLayoutEffect((() => () => {}), []), useLayoutEffect((() => {
var _a, _b, _c, _d, _e, _f;
null == table || table.checkReactCustomLayout(), null === (_a = null == table ? void 0 : table.reactCustomLayout) || void 0 === _a || _a.setReactRemoveAllGraphic(componentId, removeAllContainer, isHeaderCustomLayout),
table && !(null === (_b = table.reactCustomLayout) || void 0 === _b ? void 0 : _b.hasReactCreateGraphic(componentId, isHeaderCustomLayout)) ? (null === (_c = table.reactCustomLayout) || void 0 === _c || _c.setReactCreateGraphic(componentId, createGraphic, isHeaderCustomLayout),
null === (_d = table.reactCustomLayout) || void 0 === _d || _d.setReactRemoveGraphic(componentId, removeContainer, isHeaderCustomLayout),
null === (_e = table.reactCustomLayout) || void 0 === _e || _e.updateCustomCell(componentId, isHeaderCustomLayout)) : table && (null === (_f = table.reactCustomLayout) || void 0 === _f || _f.setReactCreateGraphic(componentId, createGraphic, isHeaderCustomLayout),
container.current.forEach(((value, key) => {
const [col, row] = key.split("-").map(Number), {width: width, height: height} = getCellRect(col, row, table), currentContainer = value, args = {
col: col,
row: row,
dataValue: table.getCellOriginValue(col, row),
value: table.getCellValue(col, row),
rect: {
left: 0,
top: 0,
right: width,
bottom: height,
width: width,
height: height
},
table: table
};
currentContainer.containerInfo;
reconcilorUpdateContainer(children, currentContainer, args), table.scenegraph.updateNextFrame();
})));
})), null;
};
function reconcilorUpdateContainer(children, currentContainer, args) {
const element = React.cloneElement(children, Object.assign({}, args)), updateContainerSync = reconcilor.updateContainerSync;
if ("function" != typeof updateContainerSync) reconcilor.updateContainer(element, currentContainer, null); else {
updateContainerSync(element, currentContainer, null);
const flushSyncWork = reconcilor.flushSyncWork;
"function" == typeof flushSyncWork && flushSyncWork();
}
}
function getCellRect(col, row, table) {
const range = table.getCellRange(col, row);
return table.getCellsRect(range.start.col, range.start.row, range.end.col, range.end.row);
}
//# sourceMappingURL=custom-layout.js.map