import * as React from 'react'; import { IStoreState, ID, IColDimensions, IRowDimensions } from '../index.data'; import { connect } from 'unistore/react'; import { getCellType, getCell, getCellDimensions, getPresentCell, getActivedCell, } from '../store/selectors'; import { getEditor } from '../cellTypes'; import styles from './index.less'; import { IEditor } from '../cellTypes/index.data'; import classnames from 'classnames'; import { FSM_IGNORE } from '../constants'; import { Store } from 'unistore'; import { FormulaEditor } from '../cellTypes'; import * as R from 'rambda'; import RuntimeContext from '../RuntimeContext'; import equals from 'fast-deep-equal'; import FakeEditor from '../cellTypes/base/FakeEditor'; import { fsmPred } from '../StateMachine/helper'; interface Props { id: ID; loadableRowFlags: boolean[]; loadableColumnFlags: boolean[]; isActiving: boolean; colDimensions: IColDimensions; rowDimensions: IRowDimensions; // 指示当前正在滚动, 只有滚动完成后, 重算colDimensions/rowDimensions后, 才能显示Editor readyDimensions: boolean; } class PresentCell extends React.Component { ref = React.createRef(); static contextType = RuntimeContext; context!: React.ContextType; forceShowFormulaEditor: boolean = false; constructor(props: Props) { super(props); this.handleSubmit = this.handleSubmit.bind(this); this.handleChange = this.handleChange.bind(this); this.openFormulaEditor = this.openFormulaEditor.bind(this); } setCellValue(id: ID, value: any) { this.context!.commands.setCellData({ id, value }); } setCellData(id: ID, data: any) { this.context!.commands.setCellData({ id, ...data }); } handleChange(v: any) {} handleSubmit(v: any) { if ((this.getEditor() as any) === FormulaEditor) { // 全部改用 SetCellData this.setCellData(this.props.id, v); } else { this.setCellData(this.props.id, { value: v, error: null }); } if (getActivedCell(this.context!.store.getState()) === this.props.id) { // 如果当前还在编辑状态, 则退出 ( 此条件不可忽略, 否则会导致死循环 ) this.handleExitEditing(); } } getEditor() { const state = this.context!.store.getState(); const cellType = getCellType(state, this.props.id); const cell = getCell(state, this.props.id)!; return state.usage === 'editor' && !cell.locked ? this.forceShowFormulaEditor ? FormulaEditor : !R.isNil(cell.formula) && !cell.formulaDisabled ? FormulaEditor : getEditor(cellType)! : FakeEditor; } openFormulaEditor() { this.forceShowFormulaEditor = true; if (fsmPred.isEditing(this.context!.store.getState().mode)) { // 若已在editing横式下按下=号, 则如果直接发送editing事件, state不会有变化, 公式编辑器不会显示出来 this.forceUpdate(); // this.context!.patchState({ isActiving: true }); // bug: 未同步状态机 } else { this.context!.fsmService.send({ type: 'EDITING' }); // ok } } handleExitEditing = () => { this.forceShowFormulaEditor = false; this.context!.fsmService.send({ type: 'SELECT.CELL', selectedCell: this.props.id }); }; shouldComponentUpdate(nextProps: any, nextState: any) { return !equals(this.props, nextProps) || !equals(this.state, nextState); } render() { const { id, isActiving, readyDimensions } = this.props; const getState = this.context!.store.getState; const state = getState(); const cell = getCell(state, id)!; // 在undo时, 有时会不同步 if (!cell) return null; const Editor: any = this.getEditor(); const dim = getCellDimensions(state, id); const newStyle = { ...cell.style, left: dim.offsetLeft, top: dim.offsetTop, width: dim.offsetWidth + 1, height: dim.offsetHeight + 1, opacity: isActiving && !readyDimensions ? 1 : 0, pointerEvents: isActiving ? 'all' : ('none' as any), }; // 如果已经被折叠或被滚走, 则不显示 if (newStyle.width <= 1 || newStyle.height <= 1) { newStyle.top = -100000; } return Editor ? (
) : null; } } export default PresentCell;