@antv/s2-react
Version:
use S2 with react
123 lines • 5.32 kB
JavaScript
import { __awaiter } from "tslib";
import { S2Event, S2_PREFIX_CLS, customMerge, } from '@antv/s2';
import { isNil, pick } from 'lodash';
import React from 'react';
import { useSpreadSheetInstance } from '../../../../../context/SpreadSheetContext';
import { useS2Event } from '../../../../../hooks';
import { invokeComponent, } from '../../../../../utils/invokeComponent';
import './index.less';
function EditCellComponent(props) {
const { params, resolver } = props;
const s2 = useSpreadSheetInstance();
const { cell, onDataCellEditStart, onDataCellEditEnd, CustomComponent } = params;
const { left, top, width, height } = React.useMemo(() => {
var _a;
const rect = (_a = s2.getCanvasElement()) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
return {
left: window.scrollX + rect.left,
top: window.scrollY + rect.top,
width: rect.width,
height: rect.height,
};
}, [s2]);
const { x: cellLeft, y: cellTop, width: cellWidth, height: cellHeight, } = React.useMemo(() => {
const scroll = s2.facet.getScrollOffset();
const cellMeta = pick(cell === null || cell === void 0 ? void 0 : cell.getMeta(), ['x', 'y', 'width', 'height']);
if (isNil(cellMeta.x) || isNil(cellMeta.y)) {
return {
x: 0,
y: 0,
width: 0,
height: 0,
};
}
const sampleColNode = s2.facet.getColNodes()[0];
const sampleColNodeHeight = (sampleColNode === null || sampleColNode === void 0 ? void 0 : sampleColNode.height) || 0;
cellMeta.x -= scroll.scrollX || 0;
cellMeta.y -= (scroll.scrollY || 0) - sampleColNodeHeight;
return cellMeta;
}, [cell, s2]);
const [inputVal, setInputVal] = React.useState(() => cell.getFieldValue());
const inputRef = React.useRef(null);
const containerRef = React.useRef(null);
const onSave = () => __awaiter(this, void 0, void 0, function* () {
var _a;
const { rowIndex, valueField, id } = cell.getMeta();
const displayData = s2.dataSet.getDisplayDataSet();
displayData[rowIndex][valueField] = inputVal;
// 编辑后的值作为格式化后的结果, formatter 不再触发, 避免二次格式化
(_a = s2.dataSet.displayFormattedValueMap) === null || _a === void 0 ? void 0 : _a.set(id, inputVal);
yield s2.render();
const editedMeta = customMerge(cell.getMeta(), {
fieldValue: inputVal,
data: {
[valueField]: inputVal,
},
});
onDataCellEditEnd === null || onDataCellEditEnd === void 0 ? void 0 : onDataCellEditEnd(editedMeta, cell);
resolver(true);
});
const onKeyDown = (e) => {
if (e.key === 'Enter') {
e.preventDefault();
onSave();
}
};
// 让输入框聚焦时光标在文字的末尾
const onFocus = (e) => {
e.target.selectionStart = e.target.value.length;
e.target.selectionEnd = e.target.value.length;
};
const styleProps = React.useMemo(() => {
return {
left: cellLeft,
top: cellTop,
width: cellWidth,
height: cellHeight,
zIndex: 1000,
};
}, []);
const onChangeValue = React.useCallback((val) => {
setInputVal(val);
}, []);
const onChange = React.useCallback((e) => {
onChangeValue(e.target.value);
}, [onChangeValue]);
React.useEffect(() => {
onDataCellEditStart === null || onDataCellEditStart === void 0 ? void 0 : onDataCellEditStart(cell.getMeta(), cell);
setTimeout(() => {
var _a, _b;
// 防止触发表格全选
(_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.click();
// 开启 preventScroll, 防止页面有滚动条时触发滚动
(_b = inputRef.current) === null || _b === void 0 ? void 0 : _b.focus({ preventScroll: true });
});
}, []);
return (React.createElement("div", { ref: containerRef, style: {
zIndex: 500,
position: 'absolute',
overflow: 'hidden',
left,
top,
width,
height,
} }, CustomComponent ? (React.createElement(CustomComponent, { cell: cell, spreadsheet: s2, value: inputVal, style: styleProps, onChange: onChangeValue, onSave: onSave })) : (React.createElement("textarea", { required: true, style: styleProps, className: `${S2_PREFIX_CLS}-edit-cell`, value: inputVal, ref: inputRef, onChange: onChange, onBlur: onSave, onKeyDown: onKeyDown, onFocus: onFocus }))));
}
export const EditCell = React.memo((props) => {
const { CustomComponent } = props;
const s2 = useSpreadSheetInstance();
const onEditCell = React.useCallback((event) => {
invokeComponent({
component: EditCellComponent,
params: {
cell: s2.getCell(event.target),
CustomComponent,
},
s2,
});
}, [CustomComponent, s2]);
useS2Event(S2Event.DATA_CELL_DOUBLE_CLICK, onEditCell, s2);
return null;
});
EditCell.displayName = 'EditCell';
//# sourceMappingURL=index.js.map