feat: formula bar defined name input focus if has defined name (#6315)

Co-authored-by: r.sergeev <r.sergeev@yadro.com>
This commit is contained in:
Roman Sergeev
2025-12-17 15:02:21 +08:00
committed by GitHub
co-authored by r.sergeev
parent 24107e04e1
commit 5eef953855
@@ -15,13 +15,14 @@
*/
import type { Workbook, Worksheet } from '@univerjs/core';
import type { IDefinedNamesServiceParam } from '@univerjs/engine-formula';
import type { ChangeEvent, KeyboardEvent } from 'react';
import type { IScrollToCellCommandParams } from '../../commands/commands/set-scroll.command';
import { AbsoluteRefType, ICommandService, IUniverInstanceService, ThemeService, UniverInstanceType } from '@univerjs/core';
import { borderRightClassName, clsx, Dropdown } from '@univerjs/design';
import { deserializeRangeWithSheet, IDefinedNamesService, isReferenceString, LexerTreeBuilder, serializeRangeWithSheet } from '@univerjs/engine-formula';
import { MoreDownIcon } from '@univerjs/icons';
import { getPrimaryForRange, SetSelectionsOperation, SheetsSelectionsService } from '@univerjs/sheets';
import { getPrimaryForRange, SetSelectionsOperation, SetWorksheetShowCommand, SheetsSelectionsService } from '@univerjs/sheets';
import { useDependency } from '@univerjs/ui';
import { useEffect, useState } from 'react';
import { ScrollToCellCommand } from '../../commands/commands/set-scroll.command';
@@ -37,14 +38,71 @@ export function DefinedName({ disable }: { disable: boolean }) {
const selectionManagerService = useDependency(SheetsSelectionsService);
const lexerTreeBuilder = useDependency(LexerTreeBuilder);
const worksheet = univerInstanceService.getCurrentUnitOfType<Workbook>(UniverInstanceType.UNIVER_SHEET)!.getActiveSheet();
const unitId = worksheet?.getUnitId();
const subUnitId = worksheet?.getSheetId();
const workbook = univerInstanceService.getCurrentUnitOfType<Workbook>(UniverInstanceType.UNIVER_SHEET)!;
const unitId = workbook?.getUnitId();
const themeService = useDependency(ThemeService);
const getDefinedNameMap = () => {
const definedNameMap = definedNamesService.getDefinedNameMap(unitId);
if (definedNameMap) {
return Array.from(Object.values(definedNameMap));
}
return [];
};
const focusDefinedName = async (definedName: IDefinedNamesServiceParam) => {
// The worksheet may be hidden, so we need to show it first
const { formulaOrRefString, id } = definedName;
const worksheet = definedNamesService.getWorksheetByRef(unitId, formulaOrRefString);
if (!worksheet) {
return;
}
const isHidden = worksheet.isSheetHidden();
if (isHidden) {
await commandService.executeCommand(SetWorksheetShowCommand.id, { unitId, subUnitId: worksheet.getSheetId() });
}
definedNamesService.focusRange(unitId, id);
};
const focusSelection = (refString: string) => {
const worksheet = workbook.getActiveSheet();
const subUnitId = worksheet.getSheetId();
getSelections(worksheet, refString).then((selections) => {
if (!selections) return;
commandService.executeCommand(SetSelectionsOperation.id, {
unitId,
subUnitId,
selections,
});
commandService.executeCommand(
ScrollToCellCommand.id,
{ range: selections[0].range } as IScrollToCellCommandParams
);
});
};
const [definedNames, setDefinedNames] = useState<IDefinedNamesServiceParam[]>(getDefinedNameMap());
useEffect(() => {
const definedNamesSubscription = definedNamesService.update$.subscribe(() => {
setDefinedNames(getDefinedNameMap());
});
return () => {
definedNamesSubscription.unsubscribe();
};
}, []);
useEffect(() => {
const subscription = definedNamesService.currentRange$.subscribe(() => {
const selections = selectionManagerService.getCurrentSelections();
const worksheet = workbook.getActiveSheet();
const formulaOrRefs = selections?.map((selection) => {
return serializeRangeWithSheet(worksheet.getName(), selection.range);
})?.join(',');
@@ -73,27 +131,17 @@ export function DefinedName({ disable }: { disable: boolean }) {
// TODO: need implemented set defined name if value not referenceString
function confirm() {
if (inputValue === rangeString) return;
if (!isReferenceString(inputValue)) {
const definedName = definedNames.find((i) => i.name === inputValue);
if (definedName) {
setRangeString(inputValue);
focusDefinedName(definedName);
} else if (isReferenceString(inputValue)) {
setRangeString(inputValue);
focusSelection(inputValue);
} else {
resetValue();
return;
};
setRangeString(inputValue);
getSelections(worksheet, inputValue).then((selections) => {
if (!selections) return;
commandService.executeCommand(SetSelectionsOperation.id, {
unitId,
subUnitId,
selections,
});
commandService.executeCommand(
ScrollToCellCommand.id,
{ range: selections[0].range } as IScrollToCellCommandParams
);
});
}
}
function handleKeyDown(e: KeyboardEvent<HTMLInputElement>) {