Skip to content

Commit

Permalink
fix: 修复编辑表的输入框未回填格式化后的数据 close #2528
Browse files Browse the repository at this point in the history
  • Loading branch information
lijinke666 committed Feb 18, 2024
1 parent 9075896 commit fd737c7
Show file tree
Hide file tree
Showing 13 changed files with 96 additions and 78 deletions.
3 changes: 2 additions & 1 deletion packages/s2-core/src/cell/base-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import type { GuiIcon } from '../common/icons/gui-icon';
import { checkIsLinkField } from '../utils/interaction/link-field';
import type { Node } from '../facet/layout/node';
import type { ViewMeta } from '../common/interface/basic';
import { customMerge } from '../utils';

export abstract class BaseCell<T extends SimpleBBox> extends Group {
// cell's data meta info
Expand Down Expand Up @@ -113,7 +114,7 @@ export abstract class BaseCell<T extends SimpleBBox> extends Group {
}

public setMeta(viewMeta: T) {
this.meta = viewMeta;
this.meta = customMerge(this.meta, viewMeta);
}

public getIconStyle() {
Expand Down
4 changes: 2 additions & 2 deletions packages/s2-core/src/cell/data-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,8 @@ export class DataCell extends BaseCell<ViewMeta> {
}
}

public setMeta(viewMeta: ViewMeta) {
super.setMeta(viewMeta);
public setMeta(viewMeta: Partial<ViewMeta>) {
super.setMeta(viewMeta as ViewMeta);
this.initCell();
}

Expand Down
1 change: 0 additions & 1 deletion packages/s2-core/src/cell/table-data-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
getOrCreateResizeAreaGroupById,
getResizeAreaAttrs,
} from '../utils/interaction/resize';
import { checkIsLinkField } from '../utils/interaction/link-field';

export class TableDataCell extends DataCell {
protected getLinkFieldStyle() {
Expand Down
2 changes: 1 addition & 1 deletion packages/s2-react/playground/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export const pivotSheetDataCfgForCompactMode = customMerge(pivotSheetDataCfg, {
});

export const s2Options: SheetComponentOptions = {
debug: false,
debug: true,
width: 600,
height: 400,
frozenFirstRow: false,
Expand Down
1 change: 1 addition & 0 deletions packages/s2-react/playground/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,7 @@ function MainLayout() {
ref={s2Ref}
themeCfg={themeCfg}
onMounted={onSheetMounted}
onDataCellEditStart={logHandler('onDataCellEditStart')}
onDataCellEditEnd={logHandler('onDataCellEditEnd')}
/>
</TabPane>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
import type { Event as CanvasEvent } from '@antv/g-canvas';
import {
BaseCell,
S2Event,
SpreadSheet,
type DataType,
type S2CellType,
type TableDataCell,
type ViewMeta,
} from '@antv/s2';
import { Input } from 'antd';
import { merge, pick } from 'lodash';
import React, {
memo,
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import { pick } from 'lodash';
import React from 'react';
import { useS2Event } from '../../../../hooks';
import { useSpreadSheetRef } from '../../../../utils/SpreadSheetContext';
import {
Expand All @@ -34,9 +27,15 @@ export interface CustomProps {
cell: S2CellType;
}

type DateCellEdit = (meta: ViewMeta, cell: TableDataCell) => void;

type EditCellProps = {
/**
* @deprecated use `onDataCellEditEnd` instead.
*/
onChange?: (data: DataType[]) => void;
onDataCellEditEnd?: (meta: ViewMeta) => void;
onDataCellEditStart?: DateCellEdit;
onDataCellEditEnd?: DateCellEdit;
trigger?: number;
CustomComponent?: React.FunctionComponent<CustomProps>;
};
Expand All @@ -46,30 +45,32 @@ function EditCellComponent(
) {
const { params, resolver } = props;
const spreadsheet = useSpreadSheetRef();
const { event, onChange, onDataCellEditEnd, CustomComponent } = params;
const cell: BaseCell<ViewMeta> = event.target.cfg.parent;
const {
event,
onChange,
onDataCellEditStart,
onDataCellEditEnd,
CustomComponent,
} = params;

const { left, top, width, height } = useMemo(() => {
const rect = (
spreadsheet?.container.cfg.container as HTMLElement
).getBoundingClientRect();
const cell = spreadsheet.getCell<TableDataCell>(event.target);
const { left, top, width, height } = React.useMemo<Partial<DOMRect>>(() => {
const rect = spreadsheet.getCanvasElement()?.getBoundingClientRect();

const modified = {
return {
left: window.scrollX + rect.left,
top: window.scrollY + rect.top,
width: rect.width,
height: rect.height,
};

return modified;
}, [spreadsheet?.container.cfg.container]);
}, [spreadsheet]);

const {
x: cellLeft,
y: cellTop,
width: cellWidth,
height: cellHeight,
} = useMemo(() => {
} = React.useMemo(() => {
const scroll = spreadsheet.facet.getScrollOffset();
const cellMeta = pick(cell.getMeta(), ['x', 'y', 'width', 'height']);

Expand All @@ -81,45 +82,46 @@ function EditCellComponent(
return cellMeta;
}, [cell, spreadsheet]);

const [inputVal, setInputVal] = useState(cell.getMeta().fieldValue);
const inputRef = useRef<HTMLInputElement>(null);
const containerRef = useRef<HTMLDivElement>(null);
const [inputVal, setInputVal] = React.useState(() => {
return cell.getFieldValue();
});

useEffect(() => {
setTimeout(() => {
// 防止触发表格全选
containerRef.current?.click();
// 开启 preventScroll, 防止页面有滚动条时触发滚动
inputRef.current?.focus({ preventScroll: true });
});
}, []);
const inputRef = React.useRef<HTMLInputElement>(null);
const containerRef = React.useRef<HTMLDivElement>(null);

const onSave = () => {
const { rowIndex, valueField } = cell.getMeta();
const { rowIndex, valueField, fieldValue } = cell.getMeta();

cell.setMeta({
fieldValue: inputVal,
originalFieldValue: fieldValue,
data: {
[valueField]: inputVal,
},
});

const displayData = spreadsheet.dataSet.getDisplayDataSet();
displayData[rowIndex][valueField] = inputVal;
spreadsheet.render(true);

onDataCellEditEnd?.(
merge(cell.getMeta(), {
fieldValue: inputVal,
data: {
[valueField]: inputVal,
},
}),
);

onDataCellEditEnd?.(cell.getMeta(), cell);
onChange?.(displayData);
resolver(true);
};

const onKeyDown: React.KeyboardEventHandler<HTMLTextAreaElement> = (e) => {
if (e.keyCode === 13) {
if (e.key === 'Enter') {
e.preventDefault();
onSave();
}
};

// 让输入框聚焦时光标在文字的末尾
const onFocus: React.FocusEventHandler<HTMLTextAreaElement> = (e) => {
e.target.selectionStart = e.target.value.length;
e.target.selectionEnd = e.target.value.length;
};

const styleProps = React.useMemo<React.CSSProperties>(() => {
return {
left: cellLeft,
Expand All @@ -134,6 +136,16 @@ function EditCellComponent(
setInputVal(val);
};

React.useEffect(() => {
onDataCellEditStart?.(cell.getMeta(), cell);
setTimeout(() => {
// 防止触发表格全选
containerRef.current?.click();
// 开启 preventScroll, 防止页面有滚动条时触发滚动
inputRef.current?.focus({ preventScroll: true });
});
}, []);

return (
<div
ref={containerRef}
Expand Down Expand Up @@ -168,31 +180,26 @@ function EditCellComponent(
}}
onBlur={onSave}
onKeyDown={onKeyDown}
onFocus={onFocus}
/>
)}
</div>
);
}

export const EditCell: React.FC<EditCellProps> = memo(
({ onChange, onDataCellEditEnd, CustomComponent }) => {
const spreadsheet = useSpreadSheetRef();

const cb = useCallback(
(event: CanvasEvent) => {
invokeComponent(
EditCellComponent,
{ event, onChange, onDataCellEditEnd, CustomComponent },
spreadsheet,
);
},
[spreadsheet],
);
export const EditCell: React.FC<EditCellProps> = React.memo((props) => {
const spreadsheet = useSpreadSheetRef();

const cb = React.useCallback(
(event: CanvasEvent) => {
invokeComponent(EditCellComponent, { ...props, event }, spreadsheet);
},
[spreadsheet],
);

useS2Event(S2Event.DATA_CELL_DOUBLE_CLICK, cb, spreadsheet);
useS2Event(S2Event.DATA_CELL_DOUBLE_CLICK, cb, spreadsheet);

return null;
},
);
return null;
});

EditCell.displayName = 'EditCell';
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import React, { useCallback } from 'react';
import React from 'react';
import { BaseSheet } from '../base-sheet';
import type { SheetComponentsProps } from '../interface';
import { DragCopyPoint } from './drag-copy';
import { EditCell } from './edit-cell';

export const EditableSheet: React.FC<SheetComponentsProps> = React.memo(
(props) => {
const onChange = useCallback(() => {}, []);
return (
<BaseSheet {...props} sheetType={'table'}>
<EditCell
onChange={onChange}
onDataCellEditStart={props.onDataCellEditStart}
onDataCellEditEnd={props.onDataCellEditEnd}
/>
<DragCopyPoint />
Expand Down
4 changes: 3 additions & 1 deletion packages/s2-shared/src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import type {
S2RenderOptions,
SortParams,
SpreadSheet,
TableDataCell,
TargetCellInfo,
ThemeCfg,
TooltipContentType,
Expand Down Expand Up @@ -121,7 +122,8 @@ export interface BaseSheetComponentProps<
onDataCellTrendIconClick?: (meta: ViewMeta) => void;
onDataCellBrushSelection?: (brushRangeDataCells: DataCell[]) => void;
onDataCellSelectMove?: (metas: CellMeta[]) => void;
onDataCellEditEnd?: (meta: ViewMeta) => void;
onDataCellEditStart?: (meta: ViewMeta, cell: TableDataCell) => void;
onDataCellEditEnd?: (meta: ViewMeta, cell: TableDataCell) => void;

// ============== Corner Cell ====================
onCornerCellHover?: (data: TargetCellInfo) => void;
Expand Down
2 changes: 1 addition & 1 deletion s2-site/docs/api/basic-class/base-cell.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Function description: cell base class. [details](https://github.com/antvis/S2/bl
| parameter | illustrate | type |
| ---------------------- | -------------------------------------- | ----------------------------------------------------------------------- |
| getMeta | Get cell metadata | () => [ViewMeta](#viewmeta) |
| setMeta | Set cell metadata | (vieMeta: [ViewMeta](#viewmeta) ) => void |
| setMeta | Set cell metadata | (vieMeta: [Partial<ViewMeta>](#viewmeta) ) => void |
| getIconStyle | Get cell icon style | () => [IconTheme](/docs/api/general/S2Theme#icontheme) |
| getStyle | get cell style | () => [DefaultCellTheme](/docs/api/general/S2Theme#defaultcelltheme) |
| getTextAndIconPosition | Get the position of cell text and icon | (iconCount: `number` ) => [TextAndIconPosition](#textandiconposition) |
Expand Down
2 changes: 1 addition & 1 deletion s2-site/docs/api/basic-class/base-cell.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ cell.getActualText()
| 参数 | 说明 | 类型 |
| --- | --- | --- |
| getMeta | 获取单元格元数据 | () => [ViewMeta](#viewmeta) |
| setMeta | 设置单元格元数据 | (vieMeta: [ViewMeta](#viewmeta)) => void |
| setMeta | 设置单元格元数据 | (vieMeta: [Partial<ViewMeta>](#viewmeta)) => void |
| getIconStyle | 获取单元格图标样式 | () => [IconTheme](/docs/api/general/S2Theme#icontheme) |
| getStyle | 获取单元格样式 | () => [DefaultCellTheme](/docs/api/general/S2Theme#defaultcelltheme) |
| getTextAndIconPosition | 获取单元格文本和图标的位置 | (iconCount: `number`) => [TextAndIconPosition](#textandiconposition) |
Expand Down
3 changes: 2 additions & 1 deletion s2-site/docs/api/components/sheet-component.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ order: 0
| onDataCellTrendIconClick | 数值单元格的趋势图 icon 点击事件 | (meta: [ViewMeta](/docs/api/basic-class/node)) => void | | |
| onDataCellBrushSelection | 数值单元格刷选事件 | ( dataCells: [DataCell](/docs/api/basic-class/base-cell)[] ) => void | | |
| onDataCellSelectMove | 数值单元格键盘方向键移动事件 | (metas: CellMeta[]) => void | | |
| onDataCellEditEnd | 数值单元格编辑完成(暂只支持编辑表) | (meta: [ViewMeta](/docs/api/basic-class/node)) => void | | |
| onDataCellEditStart | 数值单元格编辑开始(暂只支持编辑表) | (meta: [ViewMeta](/docs/api/basic-class/node), cell: [S2CellType](/docs/api/basic-class/base-cell)) => void | | |
| onDataCellEditEnd | 数值单元格编辑完成(暂只支持编辑表) | (meta: [ViewMeta](/docs/api/basic-class/node), cell: [S2CellType](/docs/api/basic-class/base-cell)) => void | | |
| onCornerCellHover | 角头鼠标悬停事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | |
| onCornerCellClick | 角头鼠标单击事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | |
| onCornerCellDoubleClick | 角头鼠标双击事件 | (data: [TargetCellInfo](#targetcellinfo)) => void | | |
Expand Down
7 changes: 5 additions & 2 deletions s2-site/docs/manual/basic/analysis/editable-mode.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,11 @@ ReactDOM.render(
sheetType="editable" // 此处指定 sheetType 为 editable
dataCfg={s2DataCfg}
options={s2Options}
onDataCellEditEnd={(meta) => {
console.log('onDataCellEditEnd', meta);
onDataCellEditStart={(meta, cell) => {
console.log('onDataCellEditStart:', meta, cell);
}}
onDataCellEditEnd={(meta, cell) => {
console.log('onDataCellEditEnd:', meta, cell);
}}
/>,
document.getElementById('container')
Expand Down
9 changes: 7 additions & 2 deletions s2-site/examples/react-component/sheet/demo/editable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,20 @@ fetch('https://assets.antv.antgroup.com/s2/basic-table-mode.json')
frozenTrailingColCount: 1, // 列尾冻结数量
};

const onDataCellEditEnd = (meta) => {
console.log('onDataCellEditEnd', meta);
const onDataCellEditStart = (meta, cell) => {
console.log('onDataCellEditStart:', meta, cell);
};

const onDataCellEditEnd = (meta, cell) => {
console.log('onDataCellEditEnd:', meta, cell);
};

ReactDOM.render(
<SheetComponent
dataCfg={s2DataConfig}
options={s2Options}
sheetType="editable"
onDataCellEditStart={onDataCellEditStart}
onDataCellEditEnd={onDataCellEditEnd}
/>,
document.getElementById('container'),
Expand Down

0 comments on commit fd737c7

Please sign in to comment.