mirror of
https://github.com/dream-num/univer.git
synced 2026-10-02 04:24:34 +08:00
fix(sheets-ui): improve percentage cell editing (#7557)
This commit is contained in:
@@ -319,6 +319,8 @@ export interface IFontRenderExtension {
|
||||
export interface ICellDataForSheetInterceptor extends ICellData {
|
||||
interceptorStyle?: Nullable<IStyleData>;
|
||||
isInArrayFormulaRange?: Nullable<boolean>;
|
||||
/** Marks intercepted cell data prepared for percentage editing. */
|
||||
isPercentFormat?: boolean;
|
||||
markers?: ICellMarks;
|
||||
customRender?: Nullable<ICellCustomRender[]>;
|
||||
interceptorAutoHeight?: () => number | undefined;
|
||||
|
||||
@@ -174,6 +174,46 @@ describe('test editor', () => {
|
||||
// The currency format needs to be entered in the editor with real values, not with currency symbols
|
||||
expect(result!.v).toEqual('100.1234567%');
|
||||
expect(result!.t).toEqual(2);
|
||||
expect(result!.isPercentFormat).toBe(true);
|
||||
});
|
||||
|
||||
describe('after edit with percent', () => {
|
||||
function setPercentFormat() {
|
||||
const params: ISetNumfmtMutationParams = {
|
||||
unitId,
|
||||
subUnitId,
|
||||
values: {
|
||||
1: {
|
||||
ranges: [{ startRow: 10, endRow: 10, startColumn: 0, endColumn: 0 }],
|
||||
},
|
||||
},
|
||||
refMap: {
|
||||
1: {
|
||||
pattern: '0.00%',
|
||||
},
|
||||
},
|
||||
};
|
||||
commandService.syncExecuteCommand(SetNumfmtMutation.id, params);
|
||||
}
|
||||
|
||||
it.each([
|
||||
['35%', 0.35],
|
||||
['0.35%', 0.0035],
|
||||
])('stores edited percent text %s as %s', (content, expected) => {
|
||||
setPercentFormat();
|
||||
const sheetInterceptorService = testBed.get(SheetInterceptorService);
|
||||
const result = sheetInterceptorService.writeCellInterceptor
|
||||
.fetchThroughInterceptors(AFTER_CELL_EDIT)({ v: content, t: CellValueType.NUMBER }, {
|
||||
workbook,
|
||||
worksheet,
|
||||
unitId,
|
||||
subUnitId,
|
||||
row: 10,
|
||||
col: 0,
|
||||
});
|
||||
|
||||
expect(result?.v).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('after edit with data', () => {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { ICellData, IDocumentBody, IRange, Nullable, Workbook } from '@univerjs/core';
|
||||
import type { ICellData, ICellDataForSheetInterceptor, IDocumentBody, IRange, Nullable, Workbook } from '@univerjs/core';
|
||||
import type {
|
||||
INumfmtItemWithCache,
|
||||
IRemoveNumfmtMutationParams,
|
||||
@@ -133,9 +133,10 @@ export class NumfmtEditorController extends Disposable {
|
||||
* If the editor also display '100.12%', will lose precision when before edit.
|
||||
*/
|
||||
case 'percent': {
|
||||
const cell: Nullable<ICellData> = { ...context.worksheet.getCellRaw(row, col) };
|
||||
const cell: Nullable<ICellDataForSheetInterceptor> = { ...context.worksheet.getCellRaw(row, col) };
|
||||
if (cell?.t === CellValueType.NUMBER && isRealNum(cell.v)) {
|
||||
cell.v = `${stripErrorMargin(Number(cell.v) * 100)}%`;
|
||||
cell.isPercentFormat = true;
|
||||
}
|
||||
return next && next(cell);
|
||||
}
|
||||
|
||||
+142
-3
@@ -24,6 +24,7 @@ import {
|
||||
LocaleType,
|
||||
UniverInstanceType,
|
||||
} from '@univerjs/core';
|
||||
import { InsertTextCommand } from '@univerjs/docs';
|
||||
import { MoveCursorOperation, MoveSelectionOperation, SetDocInputStyleCommand, VIEWPORT_KEY } from '@univerjs/docs-ui';
|
||||
import { LexerTreeBuilder } from '@univerjs/engine-formula';
|
||||
import { DeviceInputEventType } from '@univerjs/engine-render';
|
||||
@@ -69,7 +70,7 @@ describe('emptyBody', () => {
|
||||
});
|
||||
});
|
||||
|
||||
function createController() {
|
||||
function createController(initialDataStream = 'new value\r\n', isPercentFormat = false, isInArrayFormulaRange = false) {
|
||||
const worksheet = {
|
||||
getSheetId: vi.fn(() => 'sheet-1'),
|
||||
getCellRaw: vi.fn(() => ({ v: 'old' })),
|
||||
@@ -83,11 +84,11 @@ function createController() {
|
||||
getStyles: vi.fn(() => styles),
|
||||
};
|
||||
let normalSnapshot = {
|
||||
body: { dataStream: 'new value\r\n', paragraphs: [{ startIndex: 9, paragraphId: 'normal-para' }] },
|
||||
body: { dataStream: initialDataStream, paragraphs: [{ startIndex: 9, paragraphId: 'normal-para' }] },
|
||||
documentStyle: {},
|
||||
};
|
||||
let formulaSnapshot = {
|
||||
body: { dataStream: 'new value\r\n', paragraphs: [{ startIndex: 9, paragraphId: 'formula-para' }] },
|
||||
body: { dataStream: initialDataStream, paragraphs: [{ startIndex: 9, paragraphId: 'formula-para' }] },
|
||||
documentStyle: {},
|
||||
};
|
||||
const docModel = {
|
||||
@@ -144,6 +145,8 @@ function createController() {
|
||||
row: 2,
|
||||
column: 3,
|
||||
documentLayoutObject: { documentModel },
|
||||
isInArrayFormulaRange,
|
||||
isPercentFormat,
|
||||
})),
|
||||
getEditLocation: vi.fn(() => ({
|
||||
unitId: 'unit-1',
|
||||
@@ -151,8 +154,12 @@ function createController() {
|
||||
row: 2,
|
||||
column: 3,
|
||||
documentLayoutObject: { documentModel },
|
||||
isInArrayFormulaRange,
|
||||
isPercentFormat,
|
||||
})),
|
||||
getCurrentEditorId: vi.fn(() => DOCS_NORMAL_EDITOR_UNIT_ID_KEY),
|
||||
isVisible: vi.fn(() => ({ visible: true, eventType: DeviceInputEventType.Keyboard, unitId: 'unit-1' })),
|
||||
getEditorDirty: vi.fn(() => false),
|
||||
isForceKeepVisible: vi.fn(() => false),
|
||||
disableForceKeepVisible: vi.fn(),
|
||||
refreshEditCellPosition: vi.fn(),
|
||||
@@ -348,6 +355,138 @@ describe('EditingRenderController business methods', () => {
|
||||
expect(controller._editorBridgeService.changeEditorDirty).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it.each(['3', '35', '0.35', '35%'])('preserves the percent suffix when input starts with a digit: %s', (initialValue) => {
|
||||
const { controller, getFormulaSnapshot, getNormalSnapshot } = createController('25%\r\n', true);
|
||||
|
||||
controller._handleEditorVisible({
|
||||
visible: true,
|
||||
eventType: DeviceInputEventType.Keyboard,
|
||||
keycode: KeyCode.Digit3,
|
||||
initialValue,
|
||||
unitId: 'unit-1',
|
||||
});
|
||||
|
||||
expect(getNormalSnapshot().body.dataStream).toBe('25%\r\n');
|
||||
expect(getFormulaSnapshot().body.dataStream).toBe('25%\r\n');
|
||||
expect(controller._textSelectionManagerService.replaceDocRanges).toHaveBeenCalledWith(
|
||||
[{ startOffset: 0, endOffset: 2, collapsed: false }],
|
||||
{
|
||||
unitId: DOCS_NORMAL_EDITOR_UNIT_ID_KEY,
|
||||
subUnitId: DOCS_NORMAL_EDITOR_UNIT_ID_KEY,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it.each(['$30', '=1', 'text', '+', '-', '.', ','])('replaces percent content when input does not start with a digit: %s', (initialValue) => {
|
||||
const { controller, getNormalSnapshot } = createController('25%\r\n', true);
|
||||
|
||||
controller._handleEditorVisible({
|
||||
visible: true,
|
||||
eventType: DeviceInputEventType.Keyboard,
|
||||
keycode: KeyCode.Digit3,
|
||||
initialValue,
|
||||
unitId: 'unit-1',
|
||||
});
|
||||
|
||||
expect(getNormalSnapshot().body.dataStream).toBe('\r\n');
|
||||
});
|
||||
|
||||
it.each([KeyCode.BACKSPACE, KeyCode.DELETE])('keeps full-clear behavior for keycode %s', (keycode) => {
|
||||
const { controller, getNormalSnapshot } = createController('25%\r\n', true);
|
||||
|
||||
controller._handleEditorVisible({
|
||||
visible: true,
|
||||
eventType: DeviceInputEventType.Keyboard,
|
||||
keycode,
|
||||
unitId: 'unit-1',
|
||||
});
|
||||
|
||||
expect(getNormalSnapshot().body.dataStream).toBe('\r\n');
|
||||
});
|
||||
|
||||
it('keeps full-clear behavior for array formula cells', () => {
|
||||
const { controller, getNormalSnapshot } = createController('25%\r\n', true, true);
|
||||
|
||||
controller._handleEditorVisible({
|
||||
visible: true,
|
||||
eventType: DeviceInputEventType.Keyboard,
|
||||
keycode: KeyCode.Digit3,
|
||||
initialValue: '3',
|
||||
unitId: 'unit-1',
|
||||
});
|
||||
|
||||
expect(getNormalSnapshot().body.dataStream).toBe('\r\n');
|
||||
});
|
||||
|
||||
it.each([
|
||||
['F2', { eventType: DeviceInputEventType.Keyboard, keycode: KeyCode.F2 }],
|
||||
['double-click', { eventType: DeviceInputEventType.Dblclick }],
|
||||
])('places the caret before the percent suffix for %s editing', (_name, input) => {
|
||||
const { controller } = createController('25%\r\n', true);
|
||||
const selection = { startOffset: 2, endOffset: 2, collapsed: true };
|
||||
|
||||
controller._handleEditorVisible({
|
||||
visible: true,
|
||||
unitId: 'unit-1',
|
||||
...input,
|
||||
});
|
||||
|
||||
expect(controller._textSelectionManagerService.replaceDocRanges).toHaveBeenLastCalledWith(
|
||||
[selection],
|
||||
{
|
||||
unitId: DOCS_NORMAL_EDITOR_UNIT_ID_KEY,
|
||||
subUnitId: DOCS_NORMAL_EDITOR_UNIT_ID_KEY,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('overtypes a preserved percent suffix on subsequent percent input', () => {
|
||||
const { controller } = createController('0.35%\r\n', true);
|
||||
const beforeCommandListeners: Array<(command: { id: string; params: unknown }) => void> = [];
|
||||
controller._commandService.beforeCommandExecuted = vi.fn((listener) => {
|
||||
beforeCommandListeners.push(listener);
|
||||
return { dispose: vi.fn() };
|
||||
});
|
||||
controller._commandService.onCommandExecuted = vi.fn(() => ({ dispose: vi.fn() }));
|
||||
controller._commandExecutedListener({ add: vi.fn() });
|
||||
const params = {
|
||||
unitId: DOCS_NORMAL_EDITOR_UNIT_ID_KEY,
|
||||
body: { dataStream: '%' },
|
||||
range: { startOffset: 4, endOffset: 4, collapsed: true },
|
||||
};
|
||||
|
||||
expect(beforeCommandListeners).toHaveLength(1);
|
||||
beforeCommandListeners[0]({ id: InsertTextCommand.id, params });
|
||||
|
||||
expect(params.range).toEqual({ startOffset: 4, endOffset: 5, collapsed: false });
|
||||
});
|
||||
|
||||
it('overtypes the original percent value on initial digit input', () => {
|
||||
const { controller } = createController('25%\r\n', true);
|
||||
const beforeCommandListeners: Array<(command: { id: string; params: unknown }) => void> = [];
|
||||
controller._editorBridgeService.isVisible.mockReturnValue({
|
||||
visible: true,
|
||||
eventType: DeviceInputEventType.Keyboard,
|
||||
initialValue: '3',
|
||||
unitId: 'unit-1',
|
||||
});
|
||||
controller._commandService.beforeCommandExecuted = vi.fn((listener) => {
|
||||
beforeCommandListeners.push(listener);
|
||||
return { dispose: vi.fn() };
|
||||
});
|
||||
controller._commandService.onCommandExecuted = vi.fn(() => ({ dispose: vi.fn() }));
|
||||
controller._commandExecutedListener({ add: vi.fn() });
|
||||
const params = {
|
||||
unitId: DOCS_NORMAL_EDITOR_UNIT_ID_KEY,
|
||||
body: { dataStream: '3' },
|
||||
range: { startOffset: 0, endOffset: 0, collapsed: true },
|
||||
};
|
||||
|
||||
beforeCommandListeners[0]({ id: InsertTextCommand.id, params });
|
||||
|
||||
expect(params.range).toEqual({ startOffset: 0, endOffset: 2, collapsed: false });
|
||||
});
|
||||
|
||||
it('syncs the active sheet editor selection instead of the host document selection on focus', () => {
|
||||
const { controller, workbook } = createController();
|
||||
const focus$ = new Subject<boolean>();
|
||||
|
||||
@@ -26,18 +26,19 @@ import type {
|
||||
IDocumentStyle,
|
||||
IMutationInfo,
|
||||
IStyleData,
|
||||
ITextRange,
|
||||
Nullable,
|
||||
Styles,
|
||||
Workbook,
|
||||
} from '@univerjs/core';
|
||||
import type { IRichTextEditingMutationParams } from '@univerjs/docs';
|
||||
import type { IInsertTextCommandParams, IRichTextEditingMutationParams } from '@univerjs/docs';
|
||||
import type {
|
||||
ISetRangeValuesCommandParams,
|
||||
ISetWorksheetActivateCommandParams,
|
||||
MutationsAffectRange,
|
||||
} from '@univerjs/sheets';
|
||||
import type { IUniverSheetsUIConfig } from '../../config/config';
|
||||
import type { IEditorBridgeServiceVisibleParam } from '../../services/editor-bridge.service';
|
||||
import type { ICellEditorState, IEditorBridgeServiceVisibleParam } from '../../services/editor-bridge.service';
|
||||
import {
|
||||
CellValueType,
|
||||
createParagraphId,
|
||||
@@ -66,7 +67,7 @@ import {
|
||||
UniverInstanceType,
|
||||
WrapStrategy,
|
||||
} from '@univerjs/core';
|
||||
import { DocSelectionManagerService, DocSkeletonManagerService, RichTextEditingMutation } from '@univerjs/docs';
|
||||
import { DocSelectionManagerService, DocSkeletonManagerService, InsertTextCommand, RichTextEditingMutation } from '@univerjs/docs';
|
||||
import {
|
||||
DocSelectionRenderService,
|
||||
IEditorService,
|
||||
@@ -118,6 +119,45 @@ import { isRangeSelector } from './utils/is-range-selector';
|
||||
|
||||
const HIDDEN_EDITOR_POSITION = -1000;
|
||||
|
||||
function getPercentOffset(editCellState: ICellEditorState, dataStream: string | undefined): Nullable<number> {
|
||||
if (!editCellState.isPercentFormat || editCellState.isInArrayFormulaRange) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const percentSuffix = `%${DEFAULT_EMPTY_DOCUMENT_VALUE}`;
|
||||
return dataStream?.endsWith(percentSuffix) ? dataStream.length - percentSuffix.length : null;
|
||||
}
|
||||
|
||||
function getPercentEditorSelection(
|
||||
editCellState: ICellEditorState,
|
||||
visibleParam: IEditorBridgeServiceVisibleParam,
|
||||
dataStream: string | undefined
|
||||
): Nullable<ITextRange> {
|
||||
const percentOffset = getPercentOffset(editCellState, dataStream);
|
||||
if (percentOffset == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { eventType, initialValue, keycode } = visibleParam;
|
||||
if (
|
||||
eventType === DeviceInputEventType.Dblclick ||
|
||||
(eventType === DeviceInputEventType.Keyboard && keycode === KeyCode.F2)
|
||||
) {
|
||||
return { startOffset: percentOffset, endOffset: percentOffset, collapsed: true };
|
||||
}
|
||||
|
||||
if (
|
||||
eventType !== DeviceInputEventType.Keyboard ||
|
||||
keycode === KeyCode.BACKSPACE ||
|
||||
keycode === KeyCode.DELETE ||
|
||||
!/^\d/.test(initialValue ?? '')
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return { startOffset: 0, endOffset: percentOffset, collapsed: false };
|
||||
}
|
||||
|
||||
enum CursorChange {
|
||||
InitialState,
|
||||
StartEditor,
|
||||
@@ -375,6 +415,48 @@ export class EditingRenderController extends Disposable {
|
||||
* Listen to document edits to refresh the size of the sheet editor, not for normal editor.
|
||||
*/
|
||||
private _commandExecutedListener(d: DisposableCollection) {
|
||||
d.add(this._commandService.beforeCommandExecuted((command: ICommandInfo) => {
|
||||
if (command.id !== InsertTextCommand.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
const params = command.params as IInsertTextCommandParams;
|
||||
const visibleParam = this._editorBridgeService.isVisible();
|
||||
const editCellState = this._editorBridgeService.getEditLocation();
|
||||
if (params.unitId !== DOCS_NORMAL_EDITOR_UNIT_ID_KEY || !visibleParam.visible || editCellState == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dataStream = this._getDocumentDataModel()?.getBody()?.dataStream;
|
||||
if (dataStream == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const percentOffset = getPercentOffset(editCellState, dataStream);
|
||||
// The input event captures its range before the editor opens, so the first digit still carries a stale range.
|
||||
if (
|
||||
percentOffset != null &&
|
||||
!this._editorBridgeService.getEditorDirty() &&
|
||||
visibleParam.eventType === DeviceInputEventType.Keyboard &&
|
||||
/^\d/.test(visibleParam.initialValue ?? '') &&
|
||||
/^\d/.test(params.body.dataStream)
|
||||
) {
|
||||
params.range = { startOffset: 0, endOffset: percentOffset, collapsed: false };
|
||||
return;
|
||||
}
|
||||
|
||||
// Overtype the preserved suffix so entering `35%` does not produce `35%%`.
|
||||
if (
|
||||
percentOffset != null &&
|
||||
params.body.dataStream === '%' &&
|
||||
params.range.collapsed &&
|
||||
params.range.startOffset === percentOffset &&
|
||||
params.range.endOffset === percentOffset
|
||||
) {
|
||||
params.range = { ...params.range, endOffset: percentOffset + 1, collapsed: false };
|
||||
}
|
||||
}));
|
||||
|
||||
d.add(this._commandService.onCommandExecuted((command: ICommandInfo) => {
|
||||
if (command.id === RichTextEditingMutation.id) {
|
||||
const params = command.params as IRichTextEditingMutationParams;
|
||||
@@ -498,6 +580,16 @@ export class EditingRenderController extends Disposable {
|
||||
}
|
||||
);
|
||||
};
|
||||
const replaceSelection = (selection: ITextRange) => {
|
||||
this._textSelectionManagerService.replaceDocRanges(
|
||||
[selection],
|
||||
{
|
||||
unitId: DOCS_NORMAL_EDITOR_UNIT_ID_KEY,
|
||||
subUnitId: DOCS_NORMAL_EDITOR_UNIT_ID_KEY,
|
||||
}
|
||||
);
|
||||
};
|
||||
const percentSelection = getPercentEditorSelection(editCellState, param, documentDataModel.getBody()?.dataStream);
|
||||
const cellImage = isCellImage(documentDataModel.getSnapshot());
|
||||
this._submitEmptyCellImageEdit = cellImage && eventType === DeviceInputEventType.Keyboard && keycode === KeyCode.BACKSPACE;
|
||||
|
||||
@@ -513,34 +605,46 @@ export class EditingRenderController extends Disposable {
|
||||
},
|
||||
]);
|
||||
const endOffset = (documentDataModel.getBody()?.dataStream.length ?? 2) - 2;
|
||||
this._textSelectionManagerService.replaceDocRanges(
|
||||
[{
|
||||
startOffset: endOffset,
|
||||
endOffset,
|
||||
}],
|
||||
{
|
||||
unitId: DOCS_NORMAL_EDITOR_UNIT_ID_KEY,
|
||||
subUnitId: DOCS_NORMAL_EDITOR_UNIT_ID_KEY,
|
||||
}
|
||||
);
|
||||
if (percentSelection) {
|
||||
replaceSelection(percentSelection);
|
||||
} else {
|
||||
this._textSelectionManagerService.replaceDocRanges(
|
||||
[{
|
||||
startOffset: endOffset,
|
||||
endOffset,
|
||||
}],
|
||||
{
|
||||
unitId: DOCS_NORMAL_EDITOR_UNIT_ID_KEY,
|
||||
subUnitId: DOCS_NORMAL_EDITOR_UNIT_ID_KEY,
|
||||
}
|
||||
);
|
||||
}
|
||||
} else if (
|
||||
// clear and edit
|
||||
eventType === DeviceInputEventType.Keyboard ||
|
||||
(eventType === DeviceInputEventType.Dblclick && isInArrayFormulaRange)
|
||||
) {
|
||||
clearAndEdit();
|
||||
if (percentSelection) {
|
||||
replaceSelection(percentSelection);
|
||||
} else {
|
||||
clearAndEdit();
|
||||
}
|
||||
} else if (eventType === DeviceInputEventType.Dblclick) {
|
||||
if (this._contextService.getContextValue(FOCUSING_EDITOR_INPUT_FORMULA)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const cursor = documentDataModel.getBody()!.dataStream.length - 2 || 0;
|
||||
this._textSelectionManagerService.replaceDocRanges([
|
||||
{
|
||||
startOffset: cursor,
|
||||
endOffset: cursor,
|
||||
},
|
||||
]);
|
||||
if (percentSelection) {
|
||||
replaceSelection(percentSelection);
|
||||
} else {
|
||||
this._textSelectionManagerService.replaceDocRanges([
|
||||
{
|
||||
startOffset: cursor,
|
||||
endOffset: cursor,
|
||||
},
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
this._renderManagerService.getRenderUnitById(unitId)?.scene.resetCursor();
|
||||
|
||||
@@ -282,7 +282,7 @@ describe('EditorBridgeService', () => {
|
||||
getSheetId: () => 'sheet-1',
|
||||
getFreeze: () => null,
|
||||
getCellRaw: vi.fn(() => ({ v: '=SUM(A1:A2)' })),
|
||||
getCell: vi.fn(() => ({ isInArrayFormulaRange: true })),
|
||||
getCell: vi.fn(() => ({ isInArrayFormulaRange: true, isPercentFormat: true })),
|
||||
getCellDocumentModelWithFormula: vi.fn(() => ({ documentModel })),
|
||||
getBlankCellDocumentModel: vi.fn(() => ({ documentModel })),
|
||||
};
|
||||
@@ -310,6 +310,7 @@ describe('EditorBridgeService', () => {
|
||||
row: 1,
|
||||
column: 2,
|
||||
editorUnitId: DOCS_NORMAL_EDITOR_UNIT_ID_KEY,
|
||||
isPercentFormat: true,
|
||||
}));
|
||||
expect(service.getEditCellLayout()).toEqual(expect.objectContaining({
|
||||
scaleX: 2,
|
||||
|
||||
@@ -74,6 +74,7 @@ export interface ICellEditorState {
|
||||
documentLayoutObject: IDocumentLayoutObject;
|
||||
editorUnitId: string;
|
||||
isInArrayFormulaRange?: Nullable<boolean>;
|
||||
isPercentFormat?: boolean;
|
||||
}
|
||||
|
||||
export interface ICellEditorLayout {
|
||||
@@ -423,6 +424,7 @@ export class EditorBridgeService extends Disposable implements IEditorBridgeServ
|
||||
documentLayoutObject,
|
||||
editorUnitId: this._editorUnitId,
|
||||
isInArrayFormulaRange: cell?.isInArrayFormulaRange,
|
||||
isPercentFormat: cell?.isPercentFormat,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user