mirror of
https://github.com/dream-num/univer.git
synced 2026-10-29 18:06:28 +08:00
feat: add simple mode for Ribbon (#5243)
This commit is contained in:
@@ -1,36 +0,0 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 type { IAccessor, ICommand } from '@univerjs/core';
|
||||
import { CommandType } from '@univerjs/core';
|
||||
|
||||
export const DropdownListFirstItemOperation: ICommand = {
|
||||
id: 'custom-menu.operation.dropdown-list-first-item',
|
||||
type: CommandType.OPERATION,
|
||||
handler: async (_accessor: IAccessor) => {
|
||||
// alert('Dropdown list first item operation')
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
export const DropdownListSecondItemOperation: ICommand = {
|
||||
id: 'custom-menu.operation.dropdown-list-second-item',
|
||||
type: CommandType.OPERATION,
|
||||
handler: async (_accessor: IAccessor) => {
|
||||
// alert('Dropdown list second item operation')
|
||||
return true;
|
||||
},
|
||||
};
|
||||
@@ -1,27 +0,0 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 type { IAccessor, ICommand } from '@univerjs/core';
|
||||
import { CommandType } from '@univerjs/core';
|
||||
|
||||
export const SingleButtonOperation: ICommand = {
|
||||
id: 'custom-menu.operation.single-button',
|
||||
type: CommandType.OPERATION,
|
||||
handler: async (_accessor: IAccessor) => {
|
||||
// alert('Single button operation')
|
||||
return true;
|
||||
},
|
||||
};
|
||||
@@ -1,118 +0,0 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 { Disposable, ICommandService, Inject, Injector } from '@univerjs/core';
|
||||
import { AiSingle, BarChartSingle, CommentSingle } from '@univerjs/icons';
|
||||
import { ComponentManager, ContextMenuGroup, ContextMenuPosition, IMenuManagerService, MenuItemType, RibbonOthersGroup } from '@univerjs/ui';
|
||||
import { DropdownListFirstItemOperation, DropdownListSecondItemOperation } from '../commands/operations/dropdown-list.operation';
|
||||
import { SingleButtonOperation } from '../commands/operations/single-button.operation';
|
||||
import { CUSTOM_MENU_DROPDOWN_LIST_OPERATION_ID, CustomMenuItemDropdownListFirstItemFactory, CustomMenuItemDropdownListMainButtonFactory, CustomMenuItemDropdownListSecondItemFactory } from './menu/dropdown-list.menu';
|
||||
import { CustomMenuItemSingleButtonFactory } from './menu/single-button.menu';
|
||||
|
||||
export class CustomMenuController extends Disposable {
|
||||
constructor(
|
||||
@Inject(Injector) private readonly _injector: Injector,
|
||||
@ICommandService private readonly _commandService: ICommandService,
|
||||
@IMenuManagerService private readonly _menuManagerService: IMenuManagerService,
|
||||
@Inject(ComponentManager) private readonly _componentManager: ComponentManager
|
||||
) {
|
||||
super();
|
||||
|
||||
this._initCommands();
|
||||
this._registerComponents();
|
||||
this._initMenus();
|
||||
}
|
||||
|
||||
/**
|
||||
* register commands
|
||||
*/
|
||||
private _initCommands(): void {
|
||||
[
|
||||
SingleButtonOperation,
|
||||
DropdownListFirstItemOperation,
|
||||
DropdownListSecondItemOperation,
|
||||
].forEach((c) => {
|
||||
this.disposeWithMe(this._commandService.registerCommand(c));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* register icon components
|
||||
*/
|
||||
private _registerComponents(): void {
|
||||
this.disposeWithMe(this._componentManager.register('ButtonIcon', AiSingle));
|
||||
this.disposeWithMe(this._componentManager.register('ItemIcon', BarChartSingle));
|
||||
this.disposeWithMe(this._componentManager.register('MainButtonIcon', CommentSingle));
|
||||
}
|
||||
|
||||
/**
|
||||
* register menu items
|
||||
*/
|
||||
private _initMenus(): void {
|
||||
const largeDropdownList = Array.from({ length: 15 }, (_, i) => ({
|
||||
order: 20 + i,
|
||||
menuItemFactory: () => {
|
||||
return {
|
||||
id: `${DropdownListSecondItemOperation.id}-${i}`,
|
||||
type: MenuItemType.BUTTON,
|
||||
title: 'customMenu.itemTwo',
|
||||
icon: 'ItemIcon',
|
||||
};
|
||||
},
|
||||
}));
|
||||
this._menuManagerService.mergeMenu({
|
||||
[RibbonOthersGroup.OTHERS]: {
|
||||
[SingleButtonOperation.id]: {
|
||||
order: 9999,
|
||||
menuItemFactory: CustomMenuItemSingleButtonFactory,
|
||||
},
|
||||
[CUSTOM_MENU_DROPDOWN_LIST_OPERATION_ID]: {
|
||||
order: 9998.5,
|
||||
menuItemFactory: CustomMenuItemDropdownListMainButtonFactory,
|
||||
[DropdownListFirstItemOperation.id]: {
|
||||
order: 0,
|
||||
menuItemFactory: CustomMenuItemDropdownListFirstItemFactory,
|
||||
},
|
||||
[DropdownListSecondItemOperation.id]: {
|
||||
order: 1,
|
||||
menuItemFactory: CustomMenuItemDropdownListSecondItemFactory,
|
||||
},
|
||||
...largeDropdownList,
|
||||
},
|
||||
},
|
||||
[ContextMenuPosition.MAIN_AREA]: {
|
||||
[ContextMenuGroup.OTHERS]: {
|
||||
[SingleButtonOperation.id]: {
|
||||
order: 9999,
|
||||
menuItemFactory: CustomMenuItemSingleButtonFactory,
|
||||
},
|
||||
[CUSTOM_MENU_DROPDOWN_LIST_OPERATION_ID]: {
|
||||
order: 9998,
|
||||
menuItemFactory: CustomMenuItemDropdownListMainButtonFactory,
|
||||
[DropdownListFirstItemOperation.id]: {
|
||||
order: 0,
|
||||
menuItemFactory: CustomMenuItemDropdownListFirstItemFactory,
|
||||
},
|
||||
[DropdownListSecondItemOperation.id]: {
|
||||
order: 1,
|
||||
menuItemFactory: CustomMenuItemDropdownListSecondItemFactory,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 type { IMenuButtonItem, IMenuSelectorItem } from '@univerjs/ui';
|
||||
import { MenuItemType } from '@univerjs/ui';
|
||||
import { DropdownListFirstItemOperation, DropdownListSecondItemOperation } from '../../commands/operations/dropdown-list.operation';
|
||||
|
||||
export const CUSTOM_MENU_DROPDOWN_LIST_OPERATION_ID = 'custom-menu.operation.dropdown-list';
|
||||
|
||||
export function CustomMenuItemDropdownListMainButtonFactory(): IMenuSelectorItem<string> {
|
||||
return {
|
||||
// When type is MenuItemType.SUBITEMS, this factory serves as a container for the drop-down list, and you can set any unique id
|
||||
id: CUSTOM_MENU_DROPDOWN_LIST_OPERATION_ID,
|
||||
// The type of the menu item, in this case, it is a subitems
|
||||
type: MenuItemType.SUBITEMS,
|
||||
icon: 'MainButtonIcon',
|
||||
tooltip: 'customMenu.dropdownList',
|
||||
title: 'customMenu.dropdown',
|
||||
};
|
||||
}
|
||||
|
||||
export function CustomMenuItemDropdownListFirstItemFactory(): IMenuButtonItem<string> {
|
||||
return {
|
||||
id: DropdownListFirstItemOperation.id,
|
||||
type: MenuItemType.BUTTON,
|
||||
title: 'customMenu.itemOne',
|
||||
icon: 'ItemIcon',
|
||||
};
|
||||
}
|
||||
|
||||
export function CustomMenuItemDropdownListSecondItemFactory(): IMenuButtonItem<string> {
|
||||
return {
|
||||
id: DropdownListSecondItemOperation.id,
|
||||
type: MenuItemType.BUTTON,
|
||||
title: 'customMenu.itemTwo',
|
||||
icon: 'ItemIcon',
|
||||
};
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 type { IMenuButtonItem } from '@univerjs/ui';
|
||||
import { MenuItemType } from '@univerjs/ui';
|
||||
import { SingleButtonOperation } from '../../commands/operations/single-button.operation';
|
||||
|
||||
export function CustomMenuItemSingleButtonFactory(): IMenuButtonItem<string> {
|
||||
return {
|
||||
// Bind the command id, clicking the button will trigger this command
|
||||
id: SingleButtonOperation.id,
|
||||
// The type of the menu item, in this case, it is a button
|
||||
type: MenuItemType.BUTTON,
|
||||
// The icon of the button, which needs to be registered in ComponentManager
|
||||
icon: 'ButtonIcon',
|
||||
// The tooltip of the button. Prioritize matching internationalization. If no match is found, the original string will be displayed
|
||||
tooltip: 'customMenu.singleButton',
|
||||
// The title of the button. Prioritize matching internationalization. If no match is found, the original string will be displayed
|
||||
title: 'customMenu.button',
|
||||
};
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export { UniverSheetsCustomMenuPlugin } from './plugin';
|
||||
@@ -1,26 +0,0 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export default {
|
||||
customMenu: {
|
||||
button: 'Button',
|
||||
singleButton: 'Single button',
|
||||
dropdown: 'Dropdown',
|
||||
dropdownList: 'Dropdown list',
|
||||
itemOne: 'Item 1',
|
||||
itemTwo: 'Item 2',
|
||||
},
|
||||
};
|
||||
@@ -1,26 +0,0 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export default {
|
||||
customMenu: {
|
||||
button: '按钮',
|
||||
singleButton: '单个按钮',
|
||||
dropdown: '下拉',
|
||||
dropdownList: '下拉列表',
|
||||
itemOne: '项目一',
|
||||
itemTwo: '项目二',
|
||||
},
|
||||
};
|
||||
@@ -1,53 +0,0 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 type { Dependency } from '@univerjs/core';
|
||||
import { Inject, Injector, LocaleService, Plugin, touchDependencies, UniverInstanceType } from '@univerjs/core';
|
||||
import { CustomMenuController } from './controllers/custom-menu.controller';
|
||||
import enUS from './locale/en-US';
|
||||
import zhCN from './locale/zh-CN';
|
||||
|
||||
const SHEET_CUSTOM_MENU_PLUGIN = 'SHEET_CUSTOM_MENU_PLUGIN';
|
||||
|
||||
export class UniverSheetsCustomMenuPlugin extends Plugin {
|
||||
static override type = UniverInstanceType.UNIVER_SHEET;
|
||||
static override pluginName = SHEET_CUSTOM_MENU_PLUGIN;
|
||||
|
||||
constructor(
|
||||
_config = {},
|
||||
@Inject(Injector) protected readonly _injector: Injector,
|
||||
@Inject(LocaleService) private readonly _localeService: LocaleService
|
||||
) {
|
||||
super();
|
||||
|
||||
this._localeService.load({
|
||||
enUS,
|
||||
zhCN,
|
||||
});
|
||||
}
|
||||
|
||||
override onStarting(): void {
|
||||
([
|
||||
[CustomMenuController],
|
||||
] as Dependency[]).forEach((d) => this._injector.add(d));
|
||||
}
|
||||
|
||||
override onRendered(): void {
|
||||
touchDependencies(this._injector, [
|
||||
[CustomMenuController],
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,6 @@ import { UniverSheetsUIPlugin } from '@univerjs/sheets-ui';
|
||||
import { UniverSheetsZenEditorPlugin } from '@univerjs/sheets-zen-editor';
|
||||
import { UniverUIPlugin } from '@univerjs/ui';
|
||||
import { enUS, faIR, frFR, ruRU, viVN, zhCN, zhTW } from '../locales';
|
||||
import { UniverSheetsCustomMenuPlugin } from './custom-menu';
|
||||
import ImportCSVButtonPlugin from './custom-plugin/import-csv-button';
|
||||
|
||||
import '@univerjs/sheets/facade';
|
||||
@@ -105,6 +104,7 @@ function createNewInstance() {
|
||||
univer.registerPlugin(UniverRenderEnginePlugin);
|
||||
univer.registerPlugin(UniverUIPlugin, {
|
||||
container: 'app',
|
||||
// ribbonType: 'simple',
|
||||
});
|
||||
univer.registerPlugin(UniverDocsUIPlugin);
|
||||
|
||||
@@ -126,7 +126,6 @@ function createNewInstance() {
|
||||
univer.registerPlugin(UniverSheetsSortPlugin);
|
||||
univer.registerPlugin(UniverSheetsHyperLinkPlugin);
|
||||
univer.registerPlugin(UniverSheetsThreadCommentPlugin);
|
||||
univer.registerPlugin(UniverSheetsCustomMenuPlugin);
|
||||
|
||||
univer.registerPlugin(UniverSheetsTablePlugin);
|
||||
univer.registerPlugin(UniverNetworkPlugin);
|
||||
|
||||
@@ -48,7 +48,9 @@ export class DebuggerController extends Disposable {
|
||||
const configs = this._configService.getConfig<IUniverDebuggerConfig>(DEBUGGER_PLUGIN_CONFIG_KEY);
|
||||
|
||||
if (configs?.fab) {
|
||||
this._uiPartsService.registerComponent(BuiltInUIPart.GLOBAL, () => connectInjector(Fab, this._injector));
|
||||
this.disposeWithMe(
|
||||
this._uiPartsService.registerComponent(BuiltInUIPart.GLOBAL, () => connectInjector(Fab, this._injector))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 { Disposable, ICommandService } from '@univerjs/core';
|
||||
import { IMenuManagerService } from '@univerjs/ui';
|
||||
import { menuSchema, SwitchUnitOperation } from './multi-units.menu';
|
||||
|
||||
/**
|
||||
* This controller helps to debug multi units inside a single Univer
|
||||
* instance.
|
||||
*/
|
||||
export class MultiUnitsController extends Disposable {
|
||||
constructor(
|
||||
@ICommandService private readonly _commandService: ICommandService,
|
||||
@IMenuManagerService private readonly _menuManagerService: IMenuManagerService
|
||||
) {
|
||||
super();
|
||||
|
||||
this._initializeCommand();
|
||||
this._initializeMenu();
|
||||
}
|
||||
|
||||
private _initializeCommand(): void {
|
||||
this.disposeWithMe(this._commandService.registerCommand(SwitchUnitOperation));
|
||||
}
|
||||
|
||||
private _initializeMenu(): void {
|
||||
this._menuManagerService.mergeMenu(menuSchema);
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 type { IAccessor, IOperation, Workbook } from '@univerjs/core';
|
||||
import type { IMenuSelectorItem, IValueOption, MenuSchemaType } from '@univerjs/ui';
|
||||
import { CommandType, IUniverInstanceService, UniverInstanceType } from '@univerjs/core';
|
||||
import { MenuItemType, RibbonOthersGroup } from '@univerjs/ui';
|
||||
import { merge, Observable, shareReplay } from 'rxjs';
|
||||
|
||||
export const SwitchUnitOperation: IOperation<{ value: string }> = {
|
||||
id: 'debugger.operation.switch-unit',
|
||||
type: CommandType.OPERATION,
|
||||
handler: (accessor, params) => {
|
||||
const univerInstanceService = accessor.get(IUniverInstanceService);
|
||||
if (!univerInstanceService.getUnit(params.value)) return false;
|
||||
univerInstanceService.setCurrentUnitForType(params.value);
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
function SwitchUnitMenuFactory(accessor: IAccessor): IMenuSelectorItem {
|
||||
const instanceService = accessor.get(IUniverInstanceService);
|
||||
const selections$ = new Observable<Array<IValueOption>>((observer) => {
|
||||
function emit() {
|
||||
const sheets = instanceService.getAllUnitsForType<Workbook>(UniverInstanceType.UNIVER_SHEET);
|
||||
const options = sheets.map((sheet) => ({ label: sheet.getName() || sheet.getUnitId(), value: sheet.getUnitId() }));
|
||||
observer.next(options);
|
||||
}
|
||||
|
||||
merge(instanceService.unitAdded$, instanceService.unitDisposed$).subscribe(() => emit());
|
||||
emit();
|
||||
}).pipe(shareReplay(1));
|
||||
|
||||
return {
|
||||
id: SwitchUnitOperation.id,
|
||||
title: 'Switch Unit', // TODO: i18n,
|
||||
type: MenuItemType.SELECTOR,
|
||||
selections: selections$,
|
||||
};
|
||||
}
|
||||
|
||||
export const menuSchema: MenuSchemaType = {
|
||||
[RibbonOthersGroup.OTHERS]: {
|
||||
[SwitchUnitOperation.id]: {
|
||||
order: 999,
|
||||
menuItemFactory: SwitchUnitMenuFactory,
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -20,7 +20,6 @@ import { IConfigService, Inject, Injector, merge, Plugin, registerDependencies,
|
||||
import { DEBUGGER_PLUGIN_CONFIG_KEY, defaultPluginConfig } from './controllers/config.schema';
|
||||
import { DebuggerController } from './controllers/debugger.controller';
|
||||
import { E2EController } from './controllers/e2e/e2e.controller';
|
||||
import { MultiUnitsController } from './controllers/multi-units/multi-units.controller';
|
||||
import { PerformanceMonitorController } from './controllers/performance-monitor.controller';
|
||||
import { UniverWatermarkMenuController } from './controllers/watermark.menu.controller';
|
||||
|
||||
@@ -51,7 +50,6 @@ export class UniverDebuggerPlugin extends Plugin {
|
||||
override onStarting(): void {
|
||||
const dependencies: Dependency[] = [
|
||||
[DebuggerController],
|
||||
[MultiUnitsController],
|
||||
[E2EController],
|
||||
[UniverWatermarkMenuController],
|
||||
];
|
||||
@@ -70,7 +68,6 @@ export class UniverDebuggerPlugin extends Plugin {
|
||||
override onReady(): void {
|
||||
touchDependencies(this._injector, [
|
||||
[DebuggerController],
|
||||
[MultiUnitsController],
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ import { useNotification } from './use-notification';
|
||||
import { useSidebar } from './use-sidebar';
|
||||
import { useSnapshot } from './use-snapshot';
|
||||
import { useTheme } from './use-theme';
|
||||
import { useUnits } from './use-units';
|
||||
import { useUser } from './use-user';
|
||||
import { useWatermark } from './use-watermark';
|
||||
|
||||
@@ -40,6 +41,8 @@ export function Fab() {
|
||||
const univerInstanceService = useDependency(IUniverInstanceService);
|
||||
const unitType = univerInstanceService.getFocusedUnit()?.type;
|
||||
|
||||
if (!unitType) return null;
|
||||
|
||||
const items: IDropdownMenuProps['items'] = [
|
||||
useLocale(),
|
||||
useDarkMode(),
|
||||
@@ -53,6 +56,7 @@ export function Fab() {
|
||||
{ type: 'separator' },
|
||||
unitType === UniverInstanceType.UNIVER_SHEET && useFloatingDom(),
|
||||
unitType === UniverInstanceType.UNIVER_SHEET && useCellContent(),
|
||||
unitType === UniverInstanceType.UNIVER_SHEET && useUnits(),
|
||||
useSnapshot(),
|
||||
useEditable(),
|
||||
useUser(),
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { IUniverInstanceService, UniverInstanceType } from '@univerjs/core';
|
||||
import { IUniverInstanceService } from '@univerjs/core';
|
||||
import { useDependency } from '@univerjs/ui';
|
||||
|
||||
const menu = [
|
||||
@@ -26,10 +26,6 @@ const menu = [
|
||||
label: 'Dispose current unit',
|
||||
value: 'unit',
|
||||
},
|
||||
{
|
||||
label: 'Create another sheet',
|
||||
value: 'create',
|
||||
},
|
||||
];
|
||||
|
||||
export function useDispose() {
|
||||
@@ -45,8 +41,6 @@ export function useDispose() {
|
||||
if (!focused) return false;
|
||||
|
||||
return univerInstanceService.disposeUnit(focused.getUnitId());
|
||||
} else if (value === 'create') {
|
||||
univerInstanceService.createUnit(UniverInstanceType.UNIVER_SHEET, {});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Copyright 2023-present DreamNum Co., Ltd.
|
||||
*
|
||||
* 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 type { Workbook } from '@univerjs/core';
|
||||
import { IUniverInstanceService, UniverInstanceType } from '@univerjs/core';
|
||||
import { useDependency, useObservable } from '@univerjs/ui';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
const defaultMenu = [
|
||||
{
|
||||
label: 'Create another sheet',
|
||||
value: 'create',
|
||||
},
|
||||
];
|
||||
|
||||
export function useUnits() {
|
||||
const univerInstanceService = useDependency(IUniverInstanceService);
|
||||
const [menu, setMenu] = useState<{ label: string; value: string }[]>([...defaultMenu]);
|
||||
const unitAdded = useObservable(univerInstanceService.unitAdded$);
|
||||
const unitDisposed = useObservable(univerInstanceService.unitDisposed$);
|
||||
|
||||
useEffect(() => {
|
||||
const sheets = univerInstanceService.getAllUnitsForType<Workbook>(UniverInstanceType.UNIVER_SHEET);
|
||||
const options = sheets.map((sheet) => ({
|
||||
label: sheet.getName() || sheet.getUnitId(),
|
||||
value: sheet.getUnitId(),
|
||||
}));
|
||||
|
||||
setMenu([
|
||||
...defaultMenu,
|
||||
...(options as any[]),
|
||||
]);
|
||||
}, [unitAdded, unitDisposed]);
|
||||
|
||||
const onSelect = (value: string) => {
|
||||
if (value === 'create') {
|
||||
univerInstanceService.createUnit(UniverInstanceType.UNIVER_SHEET, {});
|
||||
} else {
|
||||
if (!univerInstanceService.getUnit(value)) return false;
|
||||
univerInstanceService.setCurrentUnitForType(value);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
type: 'subItem' as const,
|
||||
children: '🪸 Units',
|
||||
options: menu.map((item) => ({
|
||||
type: 'item' as const,
|
||||
children: item.label,
|
||||
onSelect: () => onSelect(item.value),
|
||||
})),
|
||||
};
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
import { createIdentifier } from '@univerjs/core';
|
||||
|
||||
export type RibbonType = 'default' | 'simple';
|
||||
|
||||
export interface IWorkbenchOptions {
|
||||
container?: string | HTMLElement;
|
||||
|
||||
@@ -29,6 +31,8 @@ export interface IWorkbenchOptions {
|
||||
*/
|
||||
toolbar?: boolean;
|
||||
|
||||
ribbonType?: RibbonType;
|
||||
|
||||
/**
|
||||
* If Univer should make the footer bar visible.
|
||||
*/
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import type { ComponentType } from 'react';
|
||||
import type { Observable } from 'rxjs';
|
||||
import type { RibbonType } from '../../../controllers/ui/ui.controller';
|
||||
import type { IMenuSchema } from '../../../services/menu/menu-manager.service';
|
||||
import { LocaleService, throttle } from '@univerjs/core';
|
||||
import { borderBottomClassName, borderClassName, clsx, divideXClassName, Dropdown, HoverCard } from '@univerjs/design';
|
||||
@@ -30,6 +31,7 @@ import { ToolbarButton } from './ToolbarButton';
|
||||
import { ToolbarItem } from './ToolbarItem';
|
||||
|
||||
interface IRibbonProps {
|
||||
ribbonType: RibbonType;
|
||||
headerMenuComponents?: Set<ComponentType>;
|
||||
headerMenu?: boolean;
|
||||
}
|
||||
@@ -44,7 +46,7 @@ const iconMap = {
|
||||
};
|
||||
|
||||
export function Ribbon(props: IRibbonProps) {
|
||||
const { headerMenuComponents, headerMenu = true } = props;
|
||||
const { ribbonType, headerMenuComponents, headerMenu = true } = props;
|
||||
|
||||
const menuManagerService = useDependency(IMenuManagerService);
|
||||
const localeService = useDependency(LocaleService);
|
||||
@@ -64,8 +66,9 @@ export function Ribbon(props: IRibbonProps) {
|
||||
const toolbarItemRefs = useRef<Record<string, {
|
||||
el: HTMLSpanElement;
|
||||
key: string;
|
||||
groupOrder: number;
|
||||
order: number;
|
||||
groupOrder: number;
|
||||
itemOrder: number;
|
||||
}>>({});
|
||||
|
||||
const [ribbon, setRibbon] = useState<IMenuSchema[]>([]);
|
||||
@@ -156,7 +159,18 @@ export function Ribbon(props: IRibbonProps) {
|
||||
}
|
||||
}
|
||||
|
||||
setRibbon(newRibbon);
|
||||
if (ribbonType === 'simple') {
|
||||
const simpleRibbon: IMenuSchema[] = [{ key: RibbonPosition.START, children: [], order: 0 }];
|
||||
newRibbon.forEach((group) => {
|
||||
group.children?.forEach((item) => {
|
||||
simpleRibbon[0].children?.push(item);
|
||||
});
|
||||
});
|
||||
|
||||
setRibbon(simpleRibbon);
|
||||
} else {
|
||||
setRibbon(newRibbon);
|
||||
}
|
||||
})
|
||||
.unsubscribe();
|
||||
}, [menuChangedTimes]);
|
||||
@@ -201,10 +215,7 @@ export function Ribbon(props: IRibbonProps) {
|
||||
const { width: avaliableWidth } = entry.contentRect;
|
||||
const toolbarItems = Object.values(toolbarItemRefs.current);
|
||||
const sortedToolbarItems = toolbarItems.sort((a, b) => {
|
||||
if (a.groupOrder === b.groupOrder) {
|
||||
return a.order - b.order;
|
||||
}
|
||||
return a.groupOrder - b.groupOrder;
|
||||
return a.order - b.order || a.groupOrder - b.groupOrder || a.itemOrder - b.itemOrder;
|
||||
});
|
||||
|
||||
const newCollapsedIds: string[] = [];
|
||||
@@ -229,7 +240,7 @@ export function Ribbon(props: IRibbonProps) {
|
||||
setFakeToolbarVisible(false);
|
||||
});
|
||||
}
|
||||
}, 300));
|
||||
}, 100));
|
||||
|
||||
observer.observe(containerRef.current);
|
||||
|
||||
@@ -249,7 +260,7 @@ export function Ribbon(props: IRibbonProps) {
|
||||
univer-flex univer-h-10 univer-min-w-min univer-items-center univer-px-3 univer-opacity-0
|
||||
`, borderBottomClassName)}
|
||||
>
|
||||
{activeGroup.allGroups.map((groupItem) => (groupItem.children?.length || groupItem.item) && (
|
||||
{activeGroup.allGroups.map((groupItem, index) => (groupItem.children?.length || groupItem.item) && (
|
||||
<Fragment key={groupItem.key}>
|
||||
<div className="univer-grid univer-grid-flow-col univer-gap-2 univer-px-2">
|
||||
{groupItem.children && groupItem.children?.map((child) => (
|
||||
@@ -262,8 +273,9 @@ export function Ribbon(props: IRibbonProps) {
|
||||
toolbarItemRefs.current[child.key] = {
|
||||
el: ref.el,
|
||||
key: child.key,
|
||||
order: index,
|
||||
groupOrder: groupItem.order,
|
||||
order: child.order,
|
||||
itemOrder: child.order,
|
||||
};
|
||||
}
|
||||
}}
|
||||
@@ -298,7 +310,10 @@ export function Ribbon(props: IRibbonProps) {
|
||||
<div
|
||||
className={clsx(`
|
||||
univer-box-border univer-grid univer-h-10 univer-grid-flow-col univer-items-center univer-px-3
|
||||
`, 'univer-grid-cols-[auto,1fr]', borderBottomClassName)}
|
||||
`, {
|
||||
'univer-grid-cols-[auto,1fr]': ribbon.length > 1,
|
||||
'univer-grid-cols-none': ribbon.length === 1,
|
||||
}, borderBottomClassName)}
|
||||
>
|
||||
{/* <search className="univer-mr-1 univer-w-20">
|
||||
<Input />
|
||||
@@ -317,6 +332,7 @@ export function Ribbon(props: IRibbonProps) {
|
||||
return (
|
||||
<a
|
||||
key={group.key}
|
||||
data-u-comp="ribbon-group-btn"
|
||||
className={`
|
||||
univer-box-border univer-flex univer-cursor-pointer univer-items-center
|
||||
univer-gap-2.5 univer-rounded-lg univer-px-2 univer-py-1.5
|
||||
@@ -377,7 +393,11 @@ export function Ribbon(props: IRibbonProps) {
|
||||
</HoverCard>
|
||||
)}
|
||||
|
||||
<div ref={containerRef} className={clsx('univer-flex univer-overflow-hidden', divideXClassName)}>
|
||||
<div
|
||||
data-u-comp="ribbon-toolbar"
|
||||
ref={containerRef}
|
||||
className={clsx('univer-flex univer-overflow-hidden', divideXClassName)}
|
||||
>
|
||||
{activeGroup.visibleGroups.map((groupItem) => (groupItem.children?.length || groupItem.item) && (
|
||||
<Fragment key={groupItem.key}>
|
||||
<div className="univer-grid univer-grid-flow-col univer-gap-2 univer-px-2">
|
||||
@@ -390,7 +410,7 @@ export function Ribbon(props: IRibbonProps) {
|
||||
|
||||
{/* More functions dropdown */}
|
||||
{collapsedIds.length > 0 && (
|
||||
<div className="univer-pl-2">
|
||||
<div data-u-comp="ribbon-toolbar-more" className="univer-pl-2">
|
||||
<Dropdown
|
||||
collisionPadding={{ right: 12 }}
|
||||
overlay={(
|
||||
|
||||
@@ -50,6 +50,7 @@ export function DesktopWorkbenchContent(props: IUniverWorkbenchProps) {
|
||||
footer = true,
|
||||
headerMenu = true,
|
||||
contextMenu = true,
|
||||
ribbonType = 'default',
|
||||
mountContainer,
|
||||
onRendered,
|
||||
} = props;
|
||||
@@ -161,6 +162,7 @@ export function DesktopWorkbenchContent(props: IUniverWorkbenchProps) {
|
||||
key="toolbar"
|
||||
components={toolbarComponents}
|
||||
sharedProps={{
|
||||
ribbonType,
|
||||
headerMenuComponents,
|
||||
headerMenu,
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user