diff --git a/packages/sheets-formula-ui/src/views/formula-editor/hooks/useHighlight.ts b/packages/sheets-formula-ui/src/views/formula-editor/hooks/useHighlight.ts
index c1fd725cc3b..26d90e02b59 100644
--- a/packages/sheets-formula-ui/src/views/formula-editor/hooks/useHighlight.ts
+++ b/packages/sheets-formula-ui/src/views/formula-editor/hooks/useHighlight.ts
@@ -91,7 +91,7 @@ export function useSheetHighlight(isNeed: boolean, unitId: string, subUnitId: st
useEffect(() => {
const skeleton = sheetSkeletonManagerService?.getCurrentSkeleton();
- if (skeleton) {
+ if (skeleton && isNeed) {
const allControls = refSelectionsRenderService?.getSelectionControls() || [];
if (allControls.length === ranges.length) {
allControls.forEach((control, index) => {
@@ -103,11 +103,7 @@ export function useSheetHighlight(isNeed: boolean, unitId: string, subUnitId: st
refSelectionsService.setSelections(ranges);
}
}
- }, [ranges, sheetSkeletonManagerService]);
-
- useEffect(() => () => {
- refSelectionsService.setSelections([]);
- }, []);
+ }, [ranges, isNeed]);
}
export function useDocHight(editorId: string, sequenceNodes: (string | ISequenceNode)[]) {
diff --git a/packages/sheets-formula-ui/src/views/formula-editor/index.tsx b/packages/sheets-formula-ui/src/views/formula-editor/index.tsx
index a6364d0910d..59a56a52191 100644
--- a/packages/sheets-formula-ui/src/views/formula-editor/index.tsx
+++ b/packages/sheets-formula-ui/src/views/formula-editor/index.tsx
@@ -23,7 +23,6 @@ import { operatorToken } from '@univerjs/engine-formula';
import { EMBEDDING_FORMULA_EDITOR } from '@univerjs/sheets-ui';
import clsx from 'clsx';
import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
-import { useBlur } from '../range-selector/hooks/useBlur';
import { useFocus } from '../range-selector/hooks/useFocus';
import { useFormulaToken } from '../range-selector/hooks/useFormulaToken';
import { useLeftAndRightArrow } from '../range-selector/hooks/useLeftAndRightArrow';
@@ -100,16 +99,21 @@ export function FormulaEditor(props: IFormulaEditorProps) {
useVerify(isFocus, onVerify, formulaText);
const focus = useFocus(editor);
- useEffect(() => {
- const time = setTimeout(() => {
+ useLayoutEffect(() => {
+ // 在进行多个 input 切换的时候,失焦必须快于获得焦点.
+ if (_isFocus) {
+ const time = setTimeout(() => {
+ isFocusSet(_isFocus);
+ if (_isFocus) {
+ focus();
+ }
+ }, 30);
+ return () => {
+ clearTimeout(time);
+ };
+ } else {
isFocusSet(_isFocus);
- if (_isFocus) {
- focus();
- }
- }, 300);
- return () => {
- clearTimeout(time);
- };
+ }
}, [_isFocus, focus]);
const handleSelectionChange = (refString: string, offset: number) => {
@@ -128,7 +132,6 @@ export function FormulaEditor(props: IFormulaEditorProps) {
useRefactorEffect(isFocus, unitId);
useLeftAndRightArrow(isFocus, editor);
useSheetSelectionChange(isFocus, unitId, subUnitId, sequenceNodes, isSupportAcrossSheet, editor, handleSelectionChange);
- useBlur(editorId, isFocusSet);
useRefocus();
const { searchList, searchText, handlerFormulaReplace, reset: resetFormulaSearch } = useFormulaSearch(isFocus, sequenceNodes, editor);
@@ -188,12 +191,17 @@ export function FormulaEditor(props: IFormulaEditorProps) {
}
};
- const handleClick = () => {
- if (editor) {
+ const handleMouseUp = () => {
+ // 在进行多个 input 切换的时候,失焦必须快于获得焦点.
+ // 即使失焦是 mousedown 事件,
+ // 聚焦是 mouseup 事件,
+ // 但是 react 的 useEffect 无法保证顺序,无法确保失焦在聚焦之前.
+
+ setTimeout(() => {
isFocusSet(true);
onFocus();
focus();
- }
+ }, 30);
};
return (
@@ -207,7 +215,7 @@ export function FormulaEditor(props: IFormulaEditorProps) {
{errorText !== undefined ?
{errorText}
: null}
diff --git a/packages/sheets-formula-ui/src/views/range-selector/hooks/useBlur.ts b/packages/sheets-formula-ui/src/views/range-selector/hooks/useBlur.ts
deleted file mode 100644
index 7483b73c7f0..00000000000
--- a/packages/sheets-formula-ui/src/views/range-selector/hooks/useBlur.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Copyright 2023-present DreamNum Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import { useDependency } from '@univerjs/core';
-import { IEditorService } from '@univerjs/docs-ui';
-import { useEffect } from 'react';
-
-export const useBlur = (editorId: string, isFocusSet: (v: boolean) => void) => {
- const editorService = useDependency(IEditorService);
- useEffect(() => {
- const handleBlur = (_focusEditorId?: string) => {
- const focusEditorId = _focusEditorId || editorService.getFocusEditor()?.getEditorId();
- if (focusEditorId && editorId !== focusEditorId) {
- isFocusSet(false);
- }
- };
- const d = editorService.focus$.subscribe(() => handleBlur());
- const d2 = editorService.focusStyle$.subscribe((e) => handleBlur(e!));
- return () => {
- d.unsubscribe();
- d2.unsubscribe();
- };
- }, [editorService, editorId]);
-};
diff --git a/packages/sheets-formula-ui/src/views/range-selector/hooks/useHighlight.ts b/packages/sheets-formula-ui/src/views/range-selector/hooks/useHighlight.ts
index 739a0ac2606..c0912eaf733 100644
--- a/packages/sheets-formula-ui/src/views/range-selector/hooks/useHighlight.ts
+++ b/packages/sheets-formula-ui/src/views/range-selector/hooks/useHighlight.ts
@@ -90,7 +90,7 @@ export function useSheetHighlight(isNeed: boolean, unitId: string, subUnitId: st
useEffect(() => {
const skeleton = sheetSkeletonManagerService?.getCurrentSkeleton();
- if (skeleton) {
+ if (skeleton && isNeed) {
const allControls = refSelectionsRenderService?.getSelectionControls() || [];
if (allControls.length === ranges.length) {
allControls.forEach((control, index) => {
@@ -102,11 +102,7 @@ export function useSheetHighlight(isNeed: boolean, unitId: string, subUnitId: st
refSelectionsService.setSelections(ranges);
}
}
- }, [ranges, sheetSkeletonManagerService]);
-
- useEffect(() => () => {
- refSelectionsService.setSelections([]);
- }, []);
+ }, [ranges, isNeed]);
}
export function useDocHight(editorId: string, sequenceNodes: (string | ISequenceNode)[]) {
diff --git a/packages/sheets-formula-ui/src/views/range-selector/hooks/useRefactorEffect.ts b/packages/sheets-formula-ui/src/views/range-selector/hooks/useRefactorEffect.ts
index 425442a0abf..5c1cb9ba8a3 100644
--- a/packages/sheets-formula-ui/src/views/range-selector/hooks/useRefactorEffect.ts
+++ b/packages/sheets-formula-ui/src/views/range-selector/hooks/useRefactorEffect.ts
@@ -17,7 +17,7 @@
import type { Workbook } from '@univerjs/core';
import { EDITOR_ACTIVATED, IContextService, IUniverInstanceService, UniverInstanceType, useDependency } from '@univerjs/core';
import { IRenderManagerService } from '@univerjs/engine-render';
-import { DISABLE_NORMAL_SELECTIONS, SheetsSelectionsService } from '@univerjs/sheets';
+import { DISABLE_NORMAL_SELECTIONS, IRefSelectionsService, SheetsSelectionsService } from '@univerjs/sheets';
import { IContextMenuService } from '@univerjs/ui';
import { useEffect, useLayoutEffect } from 'react';
@@ -29,19 +29,20 @@ export const useRefactorEffect = (isNeed: boolean, unitId: string) => {
const contextService = useDependency(IContextService);
const sheetsSelectionsService = useDependency(SheetsSelectionsService);
const contextMenuService = useDependency(IContextMenuService);
+ const refSelectionsService = useDependency(IRefSelectionsService);
const render = renderManagerService.getRenderById(unitId);
const refSelectionsRenderService = render?.with(RefSelectionsRenderService);
- useEffect(() => {
+ useLayoutEffect(() => {
if (isNeed) {
const d1 = refSelectionsRenderService?.enableSelectionChanging();
contextService.setContextValue(DISABLE_NORMAL_SELECTIONS, true);
contextService.setContextValue(EDITOR_ACTIVATED, true);
return () => {
- d1?.dispose();
- contextService.setContextValue(DISABLE_NORMAL_SELECTIONS, false);
contextService.setContextValue(EDITOR_ACTIVATED, false);
+ contextService.setContextValue(DISABLE_NORMAL_SELECTIONS, false);
+ d1?.dispose();
};
}
}, [isNeed]);
@@ -53,6 +54,7 @@ export const useRefactorEffect = (isNeed: boolean, unitId: string) => {
const sheet = workbook?.getActiveSheet();
const selections = [...sheetsSelectionsService.getCurrentSelections()];
return () => {
+ refSelectionsService.clear();
const workbook = univerInstanceService.getCurrentUnitForType
(UniverInstanceType.UNIVER_SHEET);
const currentSheet = workbook?.getActiveSheet();
if (currentSheet && currentSheet === sheet) {
diff --git a/packages/sheets-formula-ui/src/views/range-selector/index.tsx b/packages/sheets-formula-ui/src/views/range-selector/index.tsx
index 3254bf0cd1f..9a54bf43614 100644
--- a/packages/sheets-formula-ui/src/views/range-selector/index.tsx
+++ b/packages/sheets-formula-ui/src/views/range-selector/index.tsx
@@ -31,7 +31,6 @@ import cl from 'clsx';
import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
import { filter } from 'rxjs';
import { RefSelectionsRenderService } from '../../services/render-services/ref-selections.render-service';
-import { useBlur } from './hooks/useBlur';
import { useEditorInput } from './hooks/useEditorInput';
import { useFocus } from './hooks/useFocus';
@@ -185,16 +184,22 @@ export function RangeSelector(props: IRangeSelectorProps) {
const focus = useFocus(editor);
- useEffect(() => {
- const time = setTimeout(() => {
+ useLayoutEffect(() => {
+ // 如果是失去焦点的话,需要立刻执行
+ // 在进行多个 input 切换的时候,失焦必须立刻执行.
+ if (_isFocus) {
+ const time = setTimeout(() => {
+ isFocusSet(_isFocus);
+ if (_isFocus) {
+ focus();
+ }
+ }, 30);
+ return () => {
+ clearTimeout(time);
+ };
+ } else {
isFocusSet(_isFocus);
- if (_isFocus) {
- focus();
- }
- }, 300);
- return () => {
- clearTimeout(time);
- };
+ }
}, [_isFocus, focus]);
const { checkScrollBar } = useResize(editor);
@@ -231,8 +236,6 @@ export function RangeSelector(props: IRangeSelectorProps) {
useVerify(!rangeDialogVisible && isFocus, onVerify, sequenceNodes);
- useBlur(editorId, isFocusSet);
-
useLeftAndRightArrow(!rangeDialogVisible && isFocus, editor);
useRefocus();
@@ -309,9 +312,15 @@ export function RangeSelector(props: IRangeSelectorProps) {
}, []);
const handleClick = () => {
- onFocus();
- focus();
- isFocusSet(true);
+ // 在进行多个 input 切换的时候,失焦必须快于获得焦点.
+ // 即使失焦是 mousedown 事件,
+ // 聚焦是 mouseup 事件,
+ // 但是 react 的 useEffect 无法保证顺序,无法确保失焦在聚焦之前.
+ setTimeout(() => {
+ onFocus();
+ focus();
+ isFocusSet(true);
+ }, 30);
};
return (