mirror of
https://github.com/dream-num/univer.git
synced 2026-09-01 15:29:43 +08:00
feat(*): improve styles in sheets-ui (#4704)
This commit is contained in:
@@ -13,6 +13,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
@@ -131,6 +131,9 @@ const config: StorybookConfig = {
|
||||
dynamicImport: true,
|
||||
},
|
||||
transform: {
|
||||
react: {
|
||||
runtime: 'automatic',
|
||||
},
|
||||
legacyDecorator: true,
|
||||
decoratorMetadata: true,
|
||||
},
|
||||
|
||||
@@ -36,7 +36,6 @@ import {
|
||||
LocaleType,
|
||||
LocalUndoRedoService,
|
||||
PermissionService,
|
||||
RediContext,
|
||||
ResourceManagerService,
|
||||
ThemeService,
|
||||
UniverInstanceService,
|
||||
@@ -44,7 +43,7 @@ import {
|
||||
import { ConfigProvider, defaultTheme, greenTheme, themeInstance } from '@univerjs/design';
|
||||
import enUS from '@univerjs/design/locale/en-US';
|
||||
import zhCN from '@univerjs/design/locale/zh-CN';
|
||||
import { DesktopLocalStorageService } from '@univerjs/ui';
|
||||
import { DesktopLocalStorageService, RediContext } from '@univerjs/ui';
|
||||
import React, { useMemo } from 'react';
|
||||
|
||||
import './global.css';
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"@storybook/addon-interactions": "^8.5.8",
|
||||
"@storybook/addon-links": "^8.5.8",
|
||||
"@storybook/addon-styling-webpack": "^1.0.1",
|
||||
"@storybook/addon-webpack5-compiler-swc": "^1.0.5",
|
||||
"@storybook/addon-webpack5-compiler-swc": "^2.1.0",
|
||||
"@storybook/blocks": "^8.5.8",
|
||||
"@storybook/icons": "^1.3.2",
|
||||
"@storybook/react": "^8.5.8",
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
{
|
||||
"extends": "@univerjs-infra/shared/tsconfigs/base",
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"jsx": "react",
|
||||
"lib": ["ESNext", "dom", "dom.iterable"],
|
||||
"useDefineForClassFields": false,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
|
||||
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 77 KiB |
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 77 KiB |
@@ -34,6 +34,7 @@
|
||||
"@univerjs/engine-formula": "workspace:*",
|
||||
"@univerjs/engine-render": "workspace:*",
|
||||
"@univerjs/find-replace": "workspace:*",
|
||||
"@univerjs/icons": "0.2.20",
|
||||
"@univerjs/mockdata": "workspace:*",
|
||||
"@univerjs/rpc": "workspace:*",
|
||||
"@univerjs/rpc-node": "workspace:*",
|
||||
@@ -84,7 +85,7 @@
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"cross-env": "^7.0.3",
|
||||
"detect-port": "^2.1.0",
|
||||
"esbuild": "^0.24.2",
|
||||
"esbuild": "^0.25.0",
|
||||
"esbuild-plugin-clean": "^1.0.1",
|
||||
"esbuild-plugin-copy": "^2.1.1",
|
||||
"esbuild-plugin-vue3": "^0.4.2",
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* 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;
|
||||
},
|
||||
};
|
||||
+9
-18
@@ -14,23 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { RefObject } from 'react';
|
||||
import { createContext, useContext } from 'react';
|
||||
import type { IAccessor, ICommand } from '@univerjs/core';
|
||||
import { CommandType } from '@univerjs/core';
|
||||
|
||||
interface IDropdownContextType {
|
||||
show: boolean;
|
||||
updateShow: (value: boolean) => void;
|
||||
disabled: boolean;
|
||||
overlayRef: RefObject<HTMLDivElement>;
|
||||
triggerRef: RefObject<HTMLElement>;
|
||||
}
|
||||
|
||||
export const DropdownContext = createContext<IDropdownContextType | null>(null);
|
||||
|
||||
export const useDropdown = () => {
|
||||
const context = useContext(DropdownContext);
|
||||
if (!context) {
|
||||
throw new Error('useDropdown must be used within a DropdownProvider');
|
||||
}
|
||||
return context;
|
||||
export const SingleButtonOperation: ICommand = {
|
||||
id: 'custom-menu.operation.single-button',
|
||||
type: CommandType.OPERATION,
|
||||
handler: async (_accessor: IAccessor) => {
|
||||
// alert('Single button operation')
|
||||
return true;
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* 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, RibbonStartGroup } 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({
|
||||
[RibbonStartGroup.OTHERS]: {
|
||||
[SingleButtonOperation.id]: {
|
||||
order: 10,
|
||||
menuItemFactory: CustomMenuItemSingleButtonFactory,
|
||||
},
|
||||
[CUSTOM_MENU_DROPDOWN_LIST_OPERATION_ID]: {
|
||||
order: 11,
|
||||
menuItemFactory: CustomMenuItemDropdownListMainButtonFactory,
|
||||
[DropdownListFirstItemOperation.id]: {
|
||||
order: 0,
|
||||
menuItemFactory: CustomMenuItemDropdownListFirstItemFactory,
|
||||
},
|
||||
[DropdownListSecondItemOperation.id]: {
|
||||
order: 1,
|
||||
menuItemFactory: CustomMenuItemDropdownListSecondItemFactory,
|
||||
},
|
||||
...largeDropdownList,
|
||||
},
|
||||
},
|
||||
[ContextMenuPosition.MAIN_AREA]: {
|
||||
[ContextMenuGroup.OTHERS]: {
|
||||
[SingleButtonOperation.id]: {
|
||||
order: 12,
|
||||
menuItemFactory: CustomMenuItemSingleButtonFactory,
|
||||
},
|
||||
[CUSTOM_MENU_DROPDOWN_LIST_OPERATION_ID]: {
|
||||
order: 9,
|
||||
menuItemFactory: CustomMenuItemDropdownListMainButtonFactory,
|
||||
[DropdownListFirstItemOperation.id]: {
|
||||
order: 0,
|
||||
menuItemFactory: CustomMenuItemDropdownListFirstItemFactory,
|
||||
},
|
||||
[DropdownListSecondItemOperation.id]: {
|
||||
order: 1,
|
||||
menuItemFactory: CustomMenuItemDropdownListSecondItemFactory,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* 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',
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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',
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* 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';
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 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',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* 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: '项目二',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* 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(
|
||||
@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],
|
||||
]);
|
||||
}
|
||||
}
|
||||
+71
-69
@@ -43,9 +43,10 @@ import { UniverSheetsUIPlugin } from '@univerjs/sheets-ui';
|
||||
import { UniverSheetsZenEditorPlugin } from '@univerjs/sheets-zen-editor';
|
||||
import { UniverThreadCommentUIPlugin } from '@univerjs/thread-comment-ui';
|
||||
import { UniverUIPlugin } from '@univerjs/ui';
|
||||
|
||||
import { enUS, faIR, frFR, ruRU, viVN, zhCN, zhTW } from '../locales';
|
||||
|
||||
import { UniverSheetsCustomMenuPlugin } from './custom-menu';
|
||||
|
||||
import '@univerjs/sheets/facade';
|
||||
import '@univerjs/ui/facade';
|
||||
import '@univerjs/docs-ui/facade';
|
||||
@@ -127,6 +128,7 @@ function createNewInstance() {
|
||||
univer.registerPlugin(UniverSheetsThreadCommentPlugin);
|
||||
univer.registerPlugin(UniverSheetsThreadCommentUIPlugin);
|
||||
univer.registerPlugin(UniverSheetsBindingSourcePlugin);
|
||||
univer.registerPlugin(UniverSheetsCustomMenuPlugin);
|
||||
|
||||
// If we are running in e2e platform, we should immediately register the debugger plugin.
|
||||
if (IS_E2E) {
|
||||
@@ -182,7 +184,7 @@ declare global {
|
||||
function initEvent() {
|
||||
const logService = window.univer!.__getInjector().get(ILogService);
|
||||
|
||||
// Workbook Events
|
||||
// Workbook Events
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.WorkbookCreated, (params) => {
|
||||
logService.log('===WorkbookCreated', params);
|
||||
});
|
||||
@@ -191,132 +193,132 @@ function initEvent() {
|
||||
logService.log('===WorkbookDisposed', params);
|
||||
});
|
||||
|
||||
// Sheet Lifecycle Events
|
||||
// checked
|
||||
// Sheet Lifecycle Events
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.BeforeSheetCreate, (params) => {
|
||||
logService.log('===BeforeSheetCreate', params);
|
||||
});
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.SheetCreated, (params) => {
|
||||
logService.log('===SheetCreated', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.BeforeSheetDelete, (params) => {
|
||||
logService.log('===BeforeSheetDelete', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.SheetDeleted, (params) => {
|
||||
logService.log('===SheetDeleted', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.BeforeSheetMove, (params) => {
|
||||
logService.log('===BeforeSheetMove', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.SheetMoved, (params) => {
|
||||
logService.log('===SheetMoved', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.BeforeSheetNameChange, (params) => {
|
||||
logService.log('===BeforeSheetNameChange', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.SheetNameChanged, (params) => {
|
||||
logService.log('===SheetNameChanged', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.BeforeSheetHideChange, (params) => {
|
||||
logService.log('===BeforeSheetHideChange', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.SheetHideChanged, (params) => {
|
||||
logService.log('===SheetHideChanged', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.CellClicked, (params) => {
|
||||
logService.log('===CellClicked', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.CellHover, (params) => {
|
||||
logService.log('===CellHover', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.CellPointerDown, (params) => {
|
||||
logService.log('===CellPointerDown', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.CellPointerUp, (params) => {
|
||||
logService.log('===CellPointerUp', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.CellPointerMove, (params) => {
|
||||
logService.log('===CellPointerMove', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.SelectionChanged, (params) => {
|
||||
logService.log('===SelectionChanged', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.SelectionMoveStart, (params) => {
|
||||
logService.log('===SelectionMoveStart', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.SelectionMoveEnd, (params) => {
|
||||
logService.log('===SelectionMoveEnd', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.SelectionMoving, (params) => {
|
||||
logService.log('===SelectionMoving', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.BeforeSheetEditStart, (params) => {
|
||||
logService.log('===BeforeSheetEditStart', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.SheetEditStarted, (params) => {
|
||||
logService.log('===SheetEditStarted', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.SheetEditChanging, (params) => {
|
||||
logService.log('===SheetEditChanging', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.BeforeSheetEditEnd, (params) => {
|
||||
logService.log('===BeforeSheetEditEnd', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.SheetEditEnded, (params) => {
|
||||
logService.log('===SheetEditEnded', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.SheetValueChanged, (params) => {
|
||||
logService.log('===SheetValueChanged', params);
|
||||
});
|
||||
|
||||
// Clipboard Events
|
||||
// Clipboard Events
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.BeforeClipboardChange, (params) => {
|
||||
logService.log('===BeforeClipboardChange', params);
|
||||
});
|
||||
@@ -333,72 +335,72 @@ function initEvent() {
|
||||
logService.log('===ClipboardPasted', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.BeforeGridlineEnableChange, (params) => {
|
||||
logService.log('===BeforeGridlineEnableChange', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.BeforeGridlineColorChange, (params) => {
|
||||
logService.log('===BeforeGridlineColorChange', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.GridlineChanged, (params) => {
|
||||
logService.log('===GridlineChanged', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.BeforeSheetZoomChange, (params) => {
|
||||
logService.log('===BeforeSheetZoomChange', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.SheetZoomChanged, (params) => {
|
||||
logService.log('===SheetZoomChanged', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.Scroll, (params) => {
|
||||
logService.log('===Scroll', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.SheetSkeletonChanged, (params) => {
|
||||
logService.log('===SheetSkeletonChanged', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.BeforeSheetDataValidationAdd, (params) => {
|
||||
logService.log('===BeforeSheetDataValidationAdd', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.SheetDataValidationChanged, (params) => {
|
||||
logService.log('===SheetDataValidationChanged', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.SheetDataValidatorStatusChanged, (params) => {
|
||||
logService.log('===SheetDataValidatorStatusChanged', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.SheetBeforeRangeFilter, (params) => {
|
||||
logService.log('===SheetBeforeRangeFilter', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.SheetRangeFiltered, (params) => {
|
||||
logService.log('===SheetRangeFiltered', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.SheetBeforeRangeSort, (params) => {
|
||||
logService.log('===SheetBeforeRangeSort', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.SheetRangeSorted, (params) => {
|
||||
logService.log('===SheetRangeSorted', params);
|
||||
});
|
||||
@@ -411,7 +413,7 @@ function initEvent() {
|
||||
logService.log('===SheetRangeFilterCleared', params);
|
||||
});
|
||||
|
||||
// Image Events
|
||||
// Image Events
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.BeforeOverGridImageInsert, (params) => {
|
||||
logService.log('===BeforeOverGridImageInsert', params);
|
||||
});
|
||||
@@ -444,102 +446,102 @@ function initEvent() {
|
||||
logService.log('===OverGridImageSelected', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.BeforeCommentAdd, (params) => {
|
||||
logService.log('===BeforeCommentAdd', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.CommentAdded, (params) => {
|
||||
logService.log('===CommentAdded', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.BeforeCommentUpdate, (params) => {
|
||||
logService.log('===BeforeCommentUpdate', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.CommentUpdated, (params) => {
|
||||
logService.log('===CommentUpdated', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.BeforeCommentDeleted, (params) => {
|
||||
logService.log('===BeforeCommentDeleted', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.CommentDeleted, (params) => {
|
||||
logService.log('===CommentDeleted', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.BeforeCommentResolve, (params) => {
|
||||
logService.log('===BeforeCommentResolve', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.CommentResolved, (params) => {
|
||||
logService.log('===CommentResolved', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.RowHeaderClick, (params) => {
|
||||
logService.log('===RowHeaderClick', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.RowHeaderHover, (params) => {
|
||||
logService.log('===RowHeaderHover', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.RowHeaderPointerDown, (params) => {
|
||||
logService.log('===RowHeaderPointerDown', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.RowHeaderPointerUp, (params) => {
|
||||
logService.log('===RowHeaderPointerUp', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.ColumnHeaderClick, (params) => {
|
||||
logService.log('===ColumnHeaderClick', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.ColumnHeaderHover, (params) => {
|
||||
logService.log('===ColumnHeaderHover', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.ColumnHeaderPointerDown, (params) => {
|
||||
logService.log('===ColumnHeaderPointerDown', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.ColumnHeaderPointerUp, (params) => {
|
||||
logService.log('===ColumnHeaderPointerUp', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.BeforeSheetLinkAdd, (params) => {
|
||||
logService.log('===BeforeSheetLinkAdd', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.BeforeSheetLinkUpdate, (params) => {
|
||||
logService.log('===BeforeSheetLinkUpdate', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.BeforeSheetLinkCancel, (params) => {
|
||||
logService.log('===BeforeSheetLinkCancel', params);
|
||||
});
|
||||
|
||||
// Drag and Drop Events
|
||||
// Drag and Drop Events
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.DragOver, (params) => {
|
||||
logService.log('===DragOver', params);
|
||||
});
|
||||
@@ -548,17 +550,17 @@ function initEvent() {
|
||||
logService.log('===Drop', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.CrosshairHighlightColorChanged, (params) => {
|
||||
logService.log('===CrosshairHighlightColorChanged', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.CrosshairHighlightEnabledChanged, (params) => {
|
||||
logService.log('===CrosshairHighlightEnabledChanged', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.BeforeSheetEditStart, (params) => {
|
||||
const { row, column } = params;
|
||||
if (row === 0 && column === 0) {
|
||||
@@ -566,12 +568,12 @@ function initEvent() {
|
||||
}
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.ActiveSheetChanged, (params) => {
|
||||
logService.log('===active sheet changed', params);
|
||||
});
|
||||
|
||||
// checked
|
||||
// checked
|
||||
window.univerAPI?.addEvent(window.univerAPI.Event.SheetEditChanging, (params) => {
|
||||
logService.log('===SheetEditChanging', params);
|
||||
});
|
||||
|
||||
+5
-5
@@ -19,7 +19,7 @@
|
||||
"url": "https://github.com/dream-num/univer/issues"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18 || <=22",
|
||||
"node": ">=20 || <=22",
|
||||
"pnpm": ">=10"
|
||||
},
|
||||
"scripts": {
|
||||
@@ -47,18 +47,18 @@
|
||||
"@antfu/eslint-config": "4.3.0",
|
||||
"@commitlint/cli": "^19.7.1",
|
||||
"@commitlint/config-conventional": "^19.7.1",
|
||||
"@eslint-react/eslint-plugin": "^1.26.2",
|
||||
"@eslint-react/eslint-plugin": "^1.27.0",
|
||||
"@playwright/test": "^1.50.1",
|
||||
"@release-it-plugins/workspaces": "^4.2.0",
|
||||
"@release-it/conventional-changelog": "^9.0.4",
|
||||
"@storybook/react": "8.5.8",
|
||||
"@types/node": "^22.13.4",
|
||||
"@types/node": "^22.13.5",
|
||||
"@types/react": "^19.0.10",
|
||||
"@types/react-dom": "^19.0.4",
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"@univerjs/design": "workspace:*",
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"eslint": "9.20.1",
|
||||
"eslint": "9.21.0",
|
||||
"eslint-plugin-format": "^1.0.1",
|
||||
"eslint-plugin-header": "^3.1.1",
|
||||
"eslint-plugin-jsdoc": "^50.6.3",
|
||||
@@ -73,7 +73,7 @@
|
||||
"react-dom": "19.0.0",
|
||||
"release-it": "^17.11.0",
|
||||
"serve": "^14.2.4",
|
||||
"tsx": "^4.19.2",
|
||||
"tsx": "^4.19.3",
|
||||
"turbo": "^2.4.2",
|
||||
"typescript": "^5.7.3",
|
||||
"vitest": "^3.0.6"
|
||||
|
||||
@@ -16,10 +16,9 @@
|
||||
|
||||
import type { ITextWatermarkConfig } from '@univerjs/engine-render';
|
||||
import { LocaleService } from '@univerjs/core';
|
||||
import { Checkbox, ColorPicker, DropdownLegacy, Input, InputNumber, Select } from '@univerjs/design';
|
||||
import { Checkbox, clsx, ColorPicker, Dropdown, Input, InputNumber, Select } from '@univerjs/design';
|
||||
import { BoldSingle, FontColor, ItalicSingle } from '@univerjs/icons';
|
||||
import { useDependency } from '@univerjs/ui';
|
||||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
import styles from './index.module.less';
|
||||
|
||||
@@ -38,73 +37,77 @@ export const WatermarkTextSetting: React.FC<IWatermarkTextSettingProps> = (props
|
||||
<div className={styles.watermarkTextSetting}>
|
||||
<div className={styles.watermarkTextSettingHeader}>{localeService.t('univer-watermark.style')}</div>
|
||||
|
||||
<div className={styles.watermarkTextSettingFontContent}>
|
||||
<div className="univer-mb-4 univer-grid univer-gap-1">
|
||||
<div>{localeService.t('univer-watermark.content')}</div>
|
||||
<Input
|
||||
value={config.content}
|
||||
onChange={(val) => onChange({ ...config, content: val })}
|
||||
className={styles.watermarkInputContent}
|
||||
placeholder={localeService.t('univer-watermark.textPlaceholder')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles.watermarkTextSettingFontStyle}>
|
||||
<div className={styles.watermarkTextSettingFontStylePart}>
|
||||
<div>
|
||||
<div className={clsx(styles.watermarkTextSettingFontStyle, 'univer-grid univer-gap-4')}>
|
||||
<div className={clsx(styles.watermarkTextSettingFontStylePart, 'univer-flex univer-gap-2')}>
|
||||
<div className="univer-grid univer-gap-1">
|
||||
<div>{localeService.t('univer-watermark.fontSize')}</div>
|
||||
<InputNumber
|
||||
className="univer-box-border univer-h-7"
|
||||
value={config.fontSize}
|
||||
max={72}
|
||||
min={12}
|
||||
onChange={(val) => {
|
||||
if (val != null) {
|
||||
onChange({ ...config, fontSize: Number.parseInt(val.toString()) });
|
||||
}
|
||||
}}
|
||||
max={72}
|
||||
min={12}
|
||||
className={styles.watermarkInput}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div style={{ margin: '0 8px' }}>
|
||||
<div className="univer-grid univer-gap-1">
|
||||
<div>{localeService.t('univer-watermark.direction')}</div>
|
||||
<Select
|
||||
className="univer-box-border univer-h-7"
|
||||
value={config.direction}
|
||||
onChange={(v) => onChange({ ...config, direction: v as 'ltr' | 'rtl' })}
|
||||
options={[
|
||||
{ label: localeService.t('univer-watermark.ltr'), value: 'ltr' },
|
||||
{ label: localeService.t('univer-watermark.rtl'), value: 'rtl' },
|
||||
]}
|
||||
onChange={(v) => onChange({ ...config, direction: v as 'ltr' | 'rtl' })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="univer-grid univer-gap-1">
|
||||
<div>{localeService.t('univer-watermark.opacity')}</div>
|
||||
<InputNumber
|
||||
className="univer-box-border univer-h-7"
|
||||
max={1}
|
||||
min={0}
|
||||
step={0.05}
|
||||
value={config.opacity}
|
||||
onChange={(val) => {
|
||||
if (val != null) {
|
||||
onChange({ ...config, opacity: Number.parseFloat(val.toString()) });
|
||||
}
|
||||
}}
|
||||
max={1}
|
||||
min={0}
|
||||
step={0.05}
|
||||
className={styles.watermarkInput}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.watermarkTextSettingFontStylePart}>
|
||||
<div
|
||||
className={clsx(styles.watermarkTextSettingFontStylePart, `
|
||||
univer-flex univer-justify-around univer-gap-4
|
||||
`)}
|
||||
>
|
||||
<div className={styles.watermarkIconWrapper}>
|
||||
<DropdownLegacy
|
||||
<Dropdown
|
||||
overlay={(
|
||||
<div className={styles.watermarkColorPickerWrapper}>
|
||||
<div className="univer-rounded-lg univer-p-4">
|
||||
<ColorPicker value={config.color} onChange={(val) => onChange({ ...config, color: val })} />
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
<FontColor className={styles.watermarkIcon} extend={{ colorChannel1: config.color ?? 'rgb(var(--primary-color))' }} />
|
||||
</DropdownLegacy>
|
||||
</Dropdown>
|
||||
</div>
|
||||
<div className={clsx(styles.watermarkIconWrapper, { [styles.watermarkIconWrapperSelect]: config.bold })} onClick={() => { onChange({ ...config, bold: !config.bold }); }}>
|
||||
<BoldSingle className={styles.watermarkIcon} />
|
||||
@@ -115,94 +118,94 @@ export const WatermarkTextSetting: React.FC<IWatermarkTextSettingProps> = (props
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Layout */}
|
||||
<div className={styles.watermarkTextSettingHeader}>{localeService.t('univer-watermark.layout')}</div>
|
||||
|
||||
<div className={styles.watermarkTextSettingLayout}>
|
||||
|
||||
<div className={styles.watermarkTextSettingFontStylePart}>
|
||||
<div className={styles.watermarkTextSettingLayoutFontWrapper}>
|
||||
<div className="univer-grid univer-gap-2 univer-text-center">
|
||||
<div className="univer-flex univer-gap-2">
|
||||
<div className="univer-grid univer-flex-1 univer-gap-1">
|
||||
<div>{localeService.t('univer-watermark.rotate')}</div>
|
||||
<InputNumber
|
||||
className="univer-box-border univer-h-7"
|
||||
value={config.rotate}
|
||||
max={360}
|
||||
min={-360}
|
||||
onChange={(val) => {
|
||||
if (val != null) {
|
||||
onChange({ ...config, rotate: Number.parseInt(val.toString()) });
|
||||
}
|
||||
}}
|
||||
max={360}
|
||||
min={-360}
|
||||
className={styles.watermarkInput}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.watermarkTextSettingLayoutFontWrapper}>
|
||||
<div className="univer-grid univer-flex-1 univer-gap-1">
|
||||
<div>{localeService.t('univer-watermark.repeat')}</div>
|
||||
<Checkbox
|
||||
className="univer-justify-center univer-self-baseline"
|
||||
checked={config.repeat}
|
||||
onChange={(val) => onChange({ ...config, repeat: val as boolean })}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.watermarkTextSettingFontStylePart}>
|
||||
<div className={styles.watermarkTextSettingLayoutFontWrapper}>
|
||||
<div className="univer-flex univer-gap-2">
|
||||
<div className="univer-grid univer-gap-1">
|
||||
<div>{localeService.t('univer-watermark.spacingX')}</div>
|
||||
<InputNumber
|
||||
className="univer-box-border univer-h-7"
|
||||
value={config.spacingX}
|
||||
min={0}
|
||||
onChange={(val) => {
|
||||
if (val != null) {
|
||||
onChange({ ...config, spacingX: Number.parseInt(val.toString()) });
|
||||
}
|
||||
}}
|
||||
min={0}
|
||||
className={styles.watermarkInput}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles.watermarkTextSettingLayoutFontWrapper}>
|
||||
<div className="univer-grid univer-gap-1">
|
||||
<div>{localeService.t('univer-watermark.spacingY')}</div>
|
||||
<InputNumber
|
||||
className="univer-box-border univer-h-7"
|
||||
value={config.spacingY}
|
||||
min={0}
|
||||
onChange={(val) => {
|
||||
if (val != null) {
|
||||
onChange({ ...config, spacingY: Number.parseInt(val.toString()) });
|
||||
}
|
||||
}}
|
||||
min={0}
|
||||
className={styles.watermarkInput}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.watermarkTextSettingFontStylePart}>
|
||||
|
||||
<div className={styles.watermarkTextSettingLayoutFontWrapper}>
|
||||
<div className="univer-flex univer-gap-2">
|
||||
<div className="univer-grid univer-gap-1">
|
||||
<div>{localeService.t('univer-watermark.startX')}</div>
|
||||
<InputNumber
|
||||
className="univer-box-border univer-h-7"
|
||||
value={config.x}
|
||||
min={0}
|
||||
onChange={(val) => {
|
||||
if (val != null) {
|
||||
onChange({ ...config, x: Number.parseInt(val.toString()) });
|
||||
}
|
||||
}}
|
||||
min={0}
|
||||
className={styles.watermarkInput}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles.watermarkTextSettingLayoutFontWrapper}>
|
||||
<div>{localeService.t('univer-watermark.startY')}</div>
|
||||
<InputNumber
|
||||
className="univer-box-border univer-h-7"
|
||||
value={config.y}
|
||||
min={0}
|
||||
onChange={(val) => {
|
||||
if (val != null) {
|
||||
onChange({ ...config, y: Number.parseInt(val.toString()) });
|
||||
}
|
||||
}}
|
||||
min={0}
|
||||
className={styles.watermarkInput}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -46,49 +46,12 @@
|
||||
color: rgb(var(--text-color-secondary));
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
&-font {
|
||||
&-content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
&-style-part {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 16px;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-layout {
|
||||
&-font-wrapper {
|
||||
width: calc(50% - 8px);
|
||||
align-self: flex-start;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-image-setting {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&-input {
|
||||
height: 28px;
|
||||
box-sizing: border-box;
|
||||
|
||||
&-content {
|
||||
width: 220px;
|
||||
}
|
||||
}
|
||||
|
||||
&-icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
@@ -117,11 +80,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-color-picker-wrapper {
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
border: 1px solid rgb(var(--grey-100));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,13 +15,10 @@
|
||||
*/
|
||||
|
||||
import type { IProjectNode } from '../../services/unit-grid/unit-grid.service';
|
||||
import { DropdownLegacy, Tooltip } from '@univerjs/design';
|
||||
import { clsx, Dropdown, Tooltip } from '@univerjs/design';
|
||||
import { CheckMarkSingle, FullscreenSingle, IncreaseSingle, ZoomReduceSingle } from '@univerjs/icons';
|
||||
import { ISidebarService, useDependency } from '@univerjs/ui';
|
||||
import {
|
||||
useReactFlow,
|
||||
} from '@xyflow/react';
|
||||
import clsx from 'clsx';
|
||||
import { useReactFlow } from '@xyflow/react';
|
||||
import React, { useCallback, useEffect, useLayoutEffect } from 'react';
|
||||
import { IUnitGridService } from '../../services/unit-grid/unit-grid.service';
|
||||
import { UniDiv } from '../uni-toolbar/UniFloatToolbar';
|
||||
@@ -127,10 +124,9 @@ export const UniControls = ({ zoom, onItemClick }: { zoom: number; onItemClick?:
|
||||
<UniControlButton tooltips="Zoom in" onClick={onZoomInHandler}>
|
||||
<IncreaseSingle />
|
||||
</UniControlButton>
|
||||
<DropdownLegacy
|
||||
placement="topLeft"
|
||||
<Dropdown
|
||||
overlay={(
|
||||
<div className={styles.sliderShortcuts}>
|
||||
<div className={clsx(styles.sliderShortcuts, 'univer-rounded-lg univer-p-4')}>
|
||||
{shortcuts?.map((item) => (
|
||||
<a
|
||||
key={item}
|
||||
@@ -157,7 +153,7 @@ export const UniControls = ({ zoom, onItemClick }: { zoom: number; onItemClick?:
|
||||
{zoomPercent}
|
||||
%
|
||||
</a>
|
||||
</DropdownLegacy>
|
||||
</Dropdown>
|
||||
<UniControlButton tooltips="Zoom out" onClick={onZoomOutHandler}>
|
||||
<ZoomReduceSingle />
|
||||
</UniControlButton>
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
"fast-diff": "1.3.0",
|
||||
"kdbush": "^4.0.2",
|
||||
"lodash-es": "^4.17.21",
|
||||
"nanoid": "5.0.9",
|
||||
"nanoid": "5.1.0",
|
||||
"numeral": "^2.0.6",
|
||||
"numfmt": "^2.5.2",
|
||||
"ot-json1": "^1.0.2",
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { LocaleType } from '../types/enum/locale-type';
|
||||
import { version } from '../../package.json';
|
||||
import type { IWorkbookData } from './typedef';
|
||||
import pkg from '../../package.json';
|
||||
import { LocaleType } from '../types/enum/locale-type';
|
||||
|
||||
export function getEmptySnapshot(
|
||||
unitID = '',
|
||||
@@ -27,7 +27,7 @@ export function getEmptySnapshot(
|
||||
id: unitID,
|
||||
sheetOrder: [],
|
||||
name,
|
||||
appVersion: version,
|
||||
appVersion: pkg.version,
|
||||
locale,
|
||||
styles: {},
|
||||
sheets: {},
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
"react-dom": ">=16.9.0 || >=17 || >=18 || >=19"
|
||||
},
|
||||
"dependencies": {
|
||||
"@radix-ui/react-popover": "^1.1.6",
|
||||
"@rc-component/color-picker": "^2.0.1",
|
||||
"@rc-component/trigger": "^2.2.6",
|
||||
"@univerjs/icons": "^0.2.20",
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
import type { Meta } from '@storybook/react';
|
||||
import React from 'react';
|
||||
|
||||
import { Avatar } from './Avatar';
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
import type { Meta } from '@storybook/react';
|
||||
import React from 'react';
|
||||
|
||||
import { Button } from './Button';
|
||||
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
|
||||
import { ChevronSortSingle } from '@univerjs/icons';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { DropdownOverlay } from '../dropdown/DropdownOverlay';
|
||||
import { DropdownProvider } from '../dropdown/DropdownProvider';
|
||||
import { DropdownTrigger } from '../dropdown/DropdownTrigger';
|
||||
import { Dropdown } from '../dropdown';
|
||||
import { hexToHsv, hslToHsv, hsvToHex, hsvToHsl, hsvToRgb, rgbToHsv } from './color-conversion';
|
||||
|
||||
interface IColorInputProps {
|
||||
@@ -310,6 +308,7 @@ function AlphaInput({ alpha, onChange }: IAlphaInputProps) {
|
||||
|
||||
export function ColorInput({ hsv, alpha, showAlpha, onChangeColor, onChangeAlpha }: IColorInputProps) {
|
||||
const [format, setFormat] = useState<ColorFormat>('hex');
|
||||
const [formatPanelVisible, setFormatPanelVisible] = useState(false);
|
||||
|
||||
function renderInput(format: ColorFormat) {
|
||||
switch (format) {
|
||||
@@ -324,6 +323,11 @@ export function ColorInput({ hsv, alpha, showAlpha, onChangeColor, onChangeAlpha
|
||||
}
|
||||
}
|
||||
|
||||
function handleSelectFormat(format: ColorFormat) {
|
||||
setFormatPanelVisible(false);
|
||||
setFormat(format);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`
|
||||
@@ -335,36 +339,39 @@ export function ColorInput({ hsv, alpha, showAlpha, onChangeColor, onChangeAlpha
|
||||
dark:[&_input]:univer-border-gray-600 dark:[&_input]:univer-text-white
|
||||
`}
|
||||
>
|
||||
<DropdownProvider>
|
||||
<DropdownTrigger>
|
||||
<a
|
||||
className={`
|
||||
univer-box-border univer-flex univer-h-8 univer-flex-1 univer-cursor-pointer
|
||||
univer-items-center univer-justify-between univer-gap-1 univer-rounded univer-border
|
||||
univer-border-solid univer-border-gray-200 univer-px-1.5 univer-text-sm univer-text-gray-700
|
||||
dark:univer-border-gray-600 dark:univer-text-white
|
||||
`}
|
||||
>
|
||||
<span>{format.toUpperCase()}</span>
|
||||
<ChevronSortSingle className="univer-size-5 univer-text-gray-400" />
|
||||
</a>
|
||||
</DropdownTrigger>
|
||||
<DropdownOverlay>
|
||||
<Dropdown
|
||||
align="start"
|
||||
overlay={(
|
||||
<div
|
||||
className={`
|
||||
univer-grid univer-w-16
|
||||
univer-grid univer-w-32
|
||||
[&>a]:univer-cursor-pointer [&>a]:univer-px-2 [&>a]:univer-py-1 [&>a]:univer-text-sm
|
||||
dark:univer-text-white
|
||||
focus-visible:univer-outline-none
|
||||
`}
|
||||
>
|
||||
<a onClick={() => setFormat('hex')}>HEX</a>
|
||||
<a onClick={() => setFormat('hsl')}>HSL</a>
|
||||
<a onClick={() => setFormat('rgb')}>RGB</a>
|
||||
<a onClick={() => handleSelectFormat('hex')}>HEX</a>
|
||||
<a onClick={() => handleSelectFormat('hsl')}>HSL</a>
|
||||
<a onClick={() => handleSelectFormat('rgb')}>RGB</a>
|
||||
</div>
|
||||
</DropdownOverlay>
|
||||
</DropdownProvider>
|
||||
)}
|
||||
open={formatPanelVisible}
|
||||
onOpenChange={setFormatPanelVisible}
|
||||
>
|
||||
<a
|
||||
className={`
|
||||
univer-box-border univer-flex univer-h-8 univer-w-32 univer-cursor-pointer univer-items-center
|
||||
univer-justify-between univer-gap-1 univer-rounded univer-border univer-border-solid
|
||||
univer-border-gray-200 univer-px-1.5 univer-text-sm univer-text-gray-700
|
||||
dark:univer-border-gray-600 dark:univer-text-white
|
||||
`}
|
||||
>
|
||||
<span>{format.toUpperCase()}</span>
|
||||
<ChevronSortSingle className="univer-size-5 univer-text-gray-400" />
|
||||
</a>
|
||||
</Dropdown>
|
||||
|
||||
<div className="univer-relative univer-flex univer-gap-2">
|
||||
<div className="univer-relative univer-flex univer-flex-1 univer-gap-2">
|
||||
{renderInput(format)}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ export default meta;
|
||||
|
||||
export const Playground = {
|
||||
render() {
|
||||
const [value, setValue] = useState('rgba(100,150,200,0.8)');
|
||||
const [value, setValue] = useState('#FF0000');
|
||||
const [format] = useState<'hex' | 'rgb' | 'hsl'>('rgb');
|
||||
|
||||
return (
|
||||
|
||||
+36
-18
@@ -53,12 +53,18 @@ exports[`ColorPicker > should render correctly 1`] = `
|
||||
"
|
||||
>
|
||||
<a
|
||||
aria-controls="radix-:r0:"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="dialog"
|
||||
class="
|
||||
univer-box-border univer-flex univer-h-8 univer-flex-1 univer-cursor-pointer
|
||||
univer-items-center univer-justify-between univer-gap-1 univer-rounded univer-border
|
||||
univer-border-solid univer-border-gray-200 univer-px-1.5 univer-text-sm univer-text-gray-700
|
||||
dark:univer-border-gray-600 dark:univer-text-white
|
||||
"
|
||||
univer-box-border univer-flex univer-h-8 univer-w-32 univer-cursor-pointer univer-items-center
|
||||
univer-justify-between univer-gap-1 univer-rounded univer-border univer-border-solid
|
||||
univer-border-gray-200 univer-px-1.5 univer-text-sm univer-text-gray-700
|
||||
dark:univer-border-gray-600 dark:univer-text-white
|
||||
"
|
||||
data-slot="popover-trigger"
|
||||
data-state="closed"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
HEX
|
||||
@@ -79,7 +85,7 @@ exports[`ColorPicker > should render correctly 1`] = `
|
||||
</svg>
|
||||
</a>
|
||||
<div
|
||||
class="univer-relative univer-flex univer-gap-2"
|
||||
class="univer-relative univer-flex univer-flex-1 univer-gap-2"
|
||||
>
|
||||
<input
|
||||
class="
|
||||
@@ -429,12 +435,18 @@ exports[`ColorPicker > should render with showAlpha 1`] = `
|
||||
"
|
||||
>
|
||||
<a
|
||||
aria-controls="radix-:r2:"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="dialog"
|
||||
class="
|
||||
univer-box-border univer-flex univer-h-8 univer-flex-1 univer-cursor-pointer
|
||||
univer-items-center univer-justify-between univer-gap-1 univer-rounded univer-border
|
||||
univer-border-solid univer-border-gray-200 univer-px-1.5 univer-text-sm univer-text-gray-700
|
||||
dark:univer-border-gray-600 dark:univer-text-white
|
||||
"
|
||||
univer-box-border univer-flex univer-h-8 univer-w-32 univer-cursor-pointer univer-items-center
|
||||
univer-justify-between univer-gap-1 univer-rounded univer-border univer-border-solid
|
||||
univer-border-gray-200 univer-px-1.5 univer-text-sm univer-text-gray-700
|
||||
dark:univer-border-gray-600 dark:univer-text-white
|
||||
"
|
||||
data-slot="popover-trigger"
|
||||
data-state="closed"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
HEX
|
||||
@@ -455,7 +467,7 @@ exports[`ColorPicker > should render with showAlpha 1`] = `
|
||||
</svg>
|
||||
</a>
|
||||
<div
|
||||
class="univer-relative univer-flex univer-gap-2"
|
||||
class="univer-relative univer-flex univer-flex-1 univer-gap-2"
|
||||
>
|
||||
<input
|
||||
class="
|
||||
@@ -801,12 +813,18 @@ exports[`ColorPicker > should render with value 1`] = `
|
||||
"
|
||||
>
|
||||
<a
|
||||
aria-controls="radix-:r1:"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="dialog"
|
||||
class="
|
||||
univer-box-border univer-flex univer-h-8 univer-flex-1 univer-cursor-pointer
|
||||
univer-items-center univer-justify-between univer-gap-1 univer-rounded univer-border
|
||||
univer-border-solid univer-border-gray-200 univer-px-1.5 univer-text-sm univer-text-gray-700
|
||||
dark:univer-border-gray-600 dark:univer-text-white
|
||||
"
|
||||
univer-box-border univer-flex univer-h-8 univer-w-32 univer-cursor-pointer univer-items-center
|
||||
univer-justify-between univer-gap-1 univer-rounded univer-border univer-border-solid
|
||||
univer-border-gray-200 univer-px-1.5 univer-text-sm univer-text-gray-700
|
||||
dark:univer-border-gray-600 dark:univer-text-white
|
||||
"
|
||||
data-slot="popover-trigger"
|
||||
data-state="closed"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
HEX
|
||||
@@ -827,7 +845,7 @@ exports[`ColorPicker > should render with value 1`] = `
|
||||
</svg>
|
||||
</a>
|
||||
<div
|
||||
class="univer-relative univer-flex univer-gap-2"
|
||||
class="univer-relative univer-flex univer-flex-1 univer-gap-2"
|
||||
>
|
||||
<input
|
||||
class="
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import React from 'react';
|
||||
|
||||
import { defaultTheme, greenTheme } from '../../themes';
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
import type { Meta } from '@storybook/react';
|
||||
import React from 'react';
|
||||
|
||||
import { Button } from '../button/Button';
|
||||
import { DropdownLegacy } from './DropdownLegacy';
|
||||
|
||||
@@ -79,6 +79,7 @@ export interface IDropdownLegacyProps {
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export function DropdownLegacy(props: IDropdownLegacyProps) {
|
||||
const {
|
||||
className,
|
||||
|
||||
@@ -15,15 +15,12 @@
|
||||
*/
|
||||
|
||||
import type { Meta } from '@storybook/react';
|
||||
import React from 'react';
|
||||
|
||||
import { DropdownOverlay } from './DropdownOverlay';
|
||||
import { DropdownProvider } from './DropdownProvider';
|
||||
import { DropdownTrigger } from './DropdownTrigger';
|
||||
import { Dropdown } from './Dropdown';
|
||||
|
||||
const meta: Meta<typeof DropdownProvider> = {
|
||||
const meta: Meta<typeof Dropdown> = {
|
||||
title: 'Components / Dropdown',
|
||||
component: DropdownProvider,
|
||||
component: Dropdown,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
@@ -36,31 +33,29 @@ export const Playground = {
|
||||
render() {
|
||||
return (
|
||||
<div className="univer-relative">
|
||||
<DropdownProvider>
|
||||
<DropdownTrigger>
|
||||
<a className="univer-cursor-pointer univer-border univer-rounded-lg univer-border-gray-200 univer-px-4 univer-py-2 univer-border-solid hover:univer-bg-gray-100 univer-transition-all">
|
||||
Click me
|
||||
</a>
|
||||
</DropdownTrigger>
|
||||
<DropdownOverlay>
|
||||
<Dropdown
|
||||
overlay={(
|
||||
<div className="univer-text-blue-500">
|
||||
Hello Univer
|
||||
<DropdownProvider>
|
||||
<DropdownTrigger>
|
||||
<a>Nested Dropdown</a>
|
||||
</DropdownTrigger>
|
||||
<DropdownOverlay>
|
||||
<Dropdown
|
||||
overlay={(
|
||||
<div className="univer-text-cyan-700">
|
||||
<div>Nested Content</div>
|
||||
<div>Nested Content</div>
|
||||
<div>Nested Content</div>
|
||||
<div>Nested Content</div>
|
||||
</div>
|
||||
</DropdownOverlay>
|
||||
</DropdownProvider>
|
||||
)}
|
||||
>
|
||||
<a>Nested Popover</a>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</DropdownOverlay>
|
||||
</DropdownProvider>
|
||||
)}
|
||||
>
|
||||
<a className="univer-cursor-pointer univer-border univer-rounded-lg univer-border-gray-200 univer-px-4 univer-py-2 univer-border-solid hover:univer-bg-gray-100 univer-transition-all">
|
||||
Click me
|
||||
</a>
|
||||
</Dropdown>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* 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 { Content } from '@radix-ui/react-popover';
|
||||
import type { ComponentProps, ReactNode } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { PopoverContent, PopoverPrimitive, PopoverTrigger } from './Popover';
|
||||
|
||||
interface IDropdownProps {
|
||||
children: ReactNode;
|
||||
overlay: ReactNode;
|
||||
disabled?: boolean;
|
||||
open?: boolean;
|
||||
onOpenChange?: (open: boolean) => void;
|
||||
}
|
||||
|
||||
export function Dropdown(props: IDropdownProps & ComponentProps<typeof Content>) {
|
||||
const {
|
||||
children,
|
||||
overlay,
|
||||
disabled,
|
||||
open: controlledOpen,
|
||||
onOpenChange: controlledOnOpenChange,
|
||||
...restProps
|
||||
} = props;
|
||||
|
||||
const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
|
||||
|
||||
const isControlled = controlledOpen !== undefined;
|
||||
const open = isControlled ? controlledOpen : uncontrolledOpen;
|
||||
|
||||
function handleChangeOpen(newOpen: boolean) {
|
||||
if (disabled) return;
|
||||
|
||||
if (!isControlled) {
|
||||
setUncontrolledOpen(newOpen);
|
||||
}
|
||||
|
||||
controlledOnOpenChange?.(newOpen);
|
||||
}
|
||||
|
||||
return (
|
||||
<PopoverPrimitive open={open} onOpenChange={handleChangeOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
{children}
|
||||
</PopoverTrigger>
|
||||
<PopoverContent {...restProps}>
|
||||
{overlay}
|
||||
</PopoverContent>
|
||||
</PopoverPrimitive>
|
||||
);
|
||||
}
|
||||
@@ -1,109 +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 canUseDom from 'rc-util/lib/Dom/canUseDom';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { clsx } from '../../helper/clsx';
|
||||
import { useDropdown } from './DropdownContext';
|
||||
|
||||
export interface IDropdownOverlayProps {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
offset?: {
|
||||
x?: number;
|
||||
y?: number;
|
||||
};
|
||||
anchor?: {
|
||||
x: 'left' | 'right';
|
||||
y: 'top' | 'bottom';
|
||||
};
|
||||
}
|
||||
|
||||
export function DropdownOverlay({ children, className, offset, anchor: anchorPos = { x: 'left', y: 'bottom' } }: IDropdownOverlayProps) {
|
||||
if (!canUseDom) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { show, updateShow, overlayRef, triggerRef } = useDropdown();
|
||||
const [mounted, setMounted] = useState(false);
|
||||
const [position, setPosition] = useState({ top: 0, left: 0 });
|
||||
|
||||
useEffect(() => {
|
||||
if (show && triggerRef.current && overlayRef.current) {
|
||||
const triggerRect = triggerRef.current.getBoundingClientRect();
|
||||
const overlayRect = overlayRef.current.getBoundingClientRect();
|
||||
const viewportWidth = document.documentElement.clientWidth;
|
||||
const viewportHeight = document.documentElement.clientHeight;
|
||||
|
||||
let top = triggerRect[anchorPos.y] + window.scrollY;
|
||||
let left = triggerRect[anchorPos.x] + window.scrollX;
|
||||
|
||||
if (top + overlayRect.height > viewportHeight + window.scrollY) {
|
||||
top = triggerRect.top - overlayRect.height + window.scrollY;
|
||||
}
|
||||
|
||||
if (left + overlayRect.width > viewportWidth + window.scrollX) {
|
||||
left = triggerRect.right - overlayRect.width + window.scrollX;
|
||||
}
|
||||
|
||||
top = Math.max(top, window.scrollY);
|
||||
left = Math.max(left, window.scrollX);
|
||||
|
||||
setPosition({
|
||||
top: top + (offset?.y ?? 0),
|
||||
left: left + (offset?.x ?? 0),
|
||||
});
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setMounted(true);
|
||||
});
|
||||
}
|
||||
}, [show, offset?.x, offset?.y, overlayRef, triggerRef]);
|
||||
|
||||
const hideAfterClick = useCallback((e: React.MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
updateShow(false);
|
||||
}, []);
|
||||
|
||||
if (!show) return null;
|
||||
|
||||
return createPortal(
|
||||
<div
|
||||
ref={overlayRef}
|
||||
className={clsx(
|
||||
`
|
||||
univer-fixed univer-z-[1071] univer-overflow-hidden univer-rounded-md univer-border univer-bg-white
|
||||
univer-opacity-0 univer-shadow-md
|
||||
dark:univer-bg-gray-700
|
||||
`,
|
||||
{
|
||||
'univer-opacity-100 univer-animate-in univer-slide-in-from-top-2': mounted,
|
||||
},
|
||||
className
|
||||
)}
|
||||
style={{
|
||||
top: position.top,
|
||||
left: position.left,
|
||||
}}
|
||||
onClick={hideAfterClick}
|
||||
onPointerUpCapture={(e) => e.stopPropagation()}
|
||||
>
|
||||
{children}
|
||||
</div>,
|
||||
document.body
|
||||
);
|
||||
}
|
||||
@@ -1,73 +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 { ReactNode } from 'react';
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { DropdownContext } from './DropdownContext';
|
||||
|
||||
interface IDropdownProviderProps {
|
||||
visible?: boolean;
|
||||
children: ReactNode;
|
||||
disabled?: boolean;
|
||||
onVisibleChange?: (visible: boolean) => void;
|
||||
}
|
||||
|
||||
export function DropdownProvider({ visible, children, disabled = false, onVisibleChange }: IDropdownProviderProps) {
|
||||
const triggerRef = useRef<HTMLDivElement>(null!);
|
||||
const overlayRef = useRef<HTMLDivElement>(null!);
|
||||
|
||||
const [internalShow, setInternalShow] = useState(false);
|
||||
const isControlled = visible !== undefined;
|
||||
const show = isControlled ? visible : internalShow;
|
||||
|
||||
const updateShow = useCallback((newShow: boolean) => {
|
||||
if (disabled) return;
|
||||
|
||||
if (!isControlled) {
|
||||
setInternalShow(newShow);
|
||||
}
|
||||
onVisibleChange?.(newShow);
|
||||
}, [disabled, isControlled, onVisibleChange]);
|
||||
|
||||
useEffect(() => {
|
||||
// If the Dropdown is not visible, we do not add event listeners to boost performance.
|
||||
if (!show) return;
|
||||
|
||||
const handleClickOutside = (event: MouseEvent) => {
|
||||
const target = event.target as Node;
|
||||
|
||||
if (!triggerRef.current?.contains(target) && !overlayRef.current?.contains(target)) {
|
||||
// As this function listens to mousedown event, while the Button components listens to
|
||||
// click event, we can anticapte this event callback will be triggered first.
|
||||
// If we hide the Dropdown in a synchronous way, the button's callback will never be triggered.
|
||||
// TODO: @jikkai: This is a temp fix. A more appropriate fix would be detecting if the target is
|
||||
// in a nested dropdown.
|
||||
updateShow(false);
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('pointerup', handleClickOutside);
|
||||
return () => window.removeEventListener('pointerup', handleClickOutside);
|
||||
}, [show, updateShow]);
|
||||
|
||||
const contextValue = useMemo(() => ({ show, updateShow, disabled, triggerRef, overlayRef }), [show, disabled]);
|
||||
|
||||
return (
|
||||
<DropdownContext.Provider value={contextValue}>
|
||||
{children}
|
||||
</DropdownContext.Provider>
|
||||
);
|
||||
}
|
||||
@@ -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 type { ReactElement } from 'react';
|
||||
import { cloneElement, isValidElement } from 'react';
|
||||
import { useDropdown } from './DropdownContext';
|
||||
|
||||
interface IDropdownTriggerProps {
|
||||
children: ReactElement;
|
||||
}
|
||||
|
||||
export function DropdownTrigger({ children }: IDropdownTriggerProps) {
|
||||
const { show, updateShow, triggerRef } = useDropdown();
|
||||
|
||||
if (!isValidElement(children)) {
|
||||
throw new Error('DropdownTrigger children must be a valid React element');
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react/no-clone-element
|
||||
return cloneElement(children, {
|
||||
ref: triggerRef,
|
||||
onClick: (e: React.MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
updateShow(!show);
|
||||
// eslint-disable-next-line ts/no-explicit-any
|
||||
(children.props as React.HTMLProps<HTMLElement>)?.onClick?.(e as any);
|
||||
},
|
||||
// eslint-disable-next-line ts/no-explicit-any
|
||||
} as any);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* 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 { ComponentProps } from 'react';
|
||||
import { Anchor, Content, Portal, Root, Trigger } from '@radix-ui/react-popover';
|
||||
import { clsx } from '../../helper/clsx';
|
||||
|
||||
function PopoverPrimitive({
|
||||
...props
|
||||
}: ComponentProps<typeof Root>) {
|
||||
return <Root data-slot="popover" {...props} />;
|
||||
}
|
||||
|
||||
function PopoverTrigger({
|
||||
...props
|
||||
}: ComponentProps<typeof Trigger>) {
|
||||
return <Trigger data-slot="popover-trigger" {...props} />;
|
||||
}
|
||||
|
||||
function PopoverContent({
|
||||
className,
|
||||
align = 'center',
|
||||
sideOffset = 4,
|
||||
...props
|
||||
}: ComponentProps<typeof Content>) {
|
||||
return (
|
||||
<Portal>
|
||||
<Content
|
||||
data-slot="popover-content"
|
||||
align={align}
|
||||
sideOffset={sideOffset}
|
||||
className={clsx(
|
||||
`
|
||||
univer-z-[1080] univer-rounded-md univer-border univer-border-solid univer-bg-white
|
||||
univer-text-gray-900 univer-shadow-md univer-outline-hidden univer-border-gray-200
|
||||
data-[side=bottom]:univer-slide-in-from-top-2
|
||||
data-[side=left]:univer-slide-in-from-right-2
|
||||
data-[side=right]:univer-slide-in-from-left-2
|
||||
data-[side=top]:univer-slide-in-from-bottom-2
|
||||
data-[state=closed]:univer-animate-out data-[state=closed]:univer-fade-out-0
|
||||
data-[state=closed]:univer-zoom-out-95
|
||||
data-[state=open]:univer-animate-in data-[state=open]:univer-fade-in-0
|
||||
data-[state=open]:univer-zoom-in-95
|
||||
`,
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</Portal>
|
||||
);
|
||||
}
|
||||
|
||||
function PopoverAnchor({
|
||||
...props
|
||||
}: ComponentProps<typeof Anchor>) {
|
||||
return <Anchor data-slot="popover-anchor" {...props} />;
|
||||
}
|
||||
|
||||
export { PopoverAnchor, PopoverContent, PopoverPrimitive, PopoverTrigger };
|
||||
@@ -14,6 +14,4 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { DropdownOverlay, type IDropdownOverlayProps } from './DropdownOverlay';
|
||||
export { DropdownProvider } from './DropdownProvider';
|
||||
export { DropdownTrigger } from './DropdownTrigger';
|
||||
export { Dropdown } from './Dropdown';
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
import type { Meta } from '@storybook/react';
|
||||
import React from 'react';
|
||||
|
||||
import { Input } from '../input';
|
||||
import { Select } from '../select';
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
import type { Meta } from '@storybook/react';
|
||||
import React from 'react';
|
||||
|
||||
import { Button } from '../button/Button';
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
import type { Meta } from '@storybook/react';
|
||||
import React from 'react';
|
||||
|
||||
import { InputNumber } from './InputNumber';
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
import type { Meta } from '@storybook/react';
|
||||
import React from 'react';
|
||||
|
||||
import { Input } from './Input';
|
||||
|
||||
|
||||
@@ -108,17 +108,15 @@ export const Input = ({
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleClear}
|
||||
className={clsx(
|
||||
'univer-absolute univer-right-2 univer-rounded-full univer-p-1',
|
||||
`
|
||||
univer-text-gray-400
|
||||
hover:univer-text-gray-500
|
||||
`,
|
||||
'univer-transition-colors univer-duration-200',
|
||||
'focus:univer-outline-none focus:univer-ring-2 focus:univer-ring-blue-500/20'
|
||||
)}
|
||||
className={`
|
||||
univer-absolute univer-right-2 univer-flex univer-items-center univer-rounded-full
|
||||
univer-border-none univer-bg-transparent univer-p-1 univer-text-gray-400 univer-transition-colors
|
||||
univer-duration-200
|
||||
focus:univer-outline-none
|
||||
hover:univer-text-gray-500
|
||||
`}
|
||||
>
|
||||
<CloseSingle className="univer-h-4 univer-w-4" />
|
||||
<CloseSingle className="univer-size-4" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
import type { Meta } from '@storybook/react';
|
||||
import React from 'react';
|
||||
|
||||
import { Pager } from '../pager';
|
||||
import { InputWithSlot } from './InputWithSlot';
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
import type { MenuItemGroupProps, MenuItemProps, MenuProps, MenuRef, SubMenuProps } from 'rc-menu';
|
||||
import RcMenu, { MenuItem as RcMenuItem, MenuItemGroup as RcMenuItemGroup, SubMenu as RcSubMenu } from 'rc-menu';
|
||||
import React, { useContext } from 'react';
|
||||
|
||||
import { clsx } from '../../helper/clsx';
|
||||
import { ConfigContext } from '../config-provider/ConfigProvider';
|
||||
import styles from './index.module.less';
|
||||
|
||||
export const Menu = React.forwardRef<MenuRef, MenuProps>((props, ref) => {
|
||||
const { mountContainer } = useContext(ConfigContext);
|
||||
return mountContainer && React.cloneElement(<RcMenu ref={ref} prefixCls={styles.menu} getPopupContainer={() => mountContainer} />, {
|
||||
return mountContainer && React.cloneElement(<RcMenu ref={ref} prefixCls={clsx(styles.menu, props.className)} getPopupContainer={() => mountContainer} />, {
|
||||
...props,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
list-style: none;
|
||||
|
||||
background-color: rgb(var(--bg-color-secondary));
|
||||
border: 1px solid rgb(var(--border-color));
|
||||
border-radius: var(--border-radius-lg);
|
||||
outline: none;
|
||||
box-shadow: var(--box-shadow-base);
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
import type { Meta } from '@storybook/react';
|
||||
import React from 'react';
|
||||
|
||||
import { Button } from '../button/Button';
|
||||
import { message, Messager, MessageType } from './Message';
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
import type { Meta } from '@storybook/react';
|
||||
import React from 'react';
|
||||
|
||||
import { Radio } from './Radio';
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import React from 'react';
|
||||
|
||||
import { Scrollbar } from './Scrollbar';
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import type { Meta } from '@storybook/react';
|
||||
import { Segmented } from './Segmented';
|
||||
|
||||
@@ -33,10 +32,11 @@ export const SegmentedBasic = {
|
||||
render() {
|
||||
return (
|
||||
<div style={{ width: 280 }}>
|
||||
<Segmented options={[
|
||||
{ label: 'By Values', value: 'Values' },
|
||||
{ label: 'By Conditions', value: 'Conditions' },
|
||||
]}
|
||||
<Segmented
|
||||
options={[
|
||||
{ label: 'By Values', value: 'Values' },
|
||||
{ label: 'By Conditions', value: 'Conditions' },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,89 +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 { fireEvent, render, screen } from '@testing-library/react';
|
||||
import React, { useState } from 'react';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { Slider } from '../Slider';
|
||||
|
||||
describe('Slider', () => {
|
||||
it('renders correctly', () => {
|
||||
const { container } = render(<Slider min={0} max={100} value={90} />);
|
||||
expect(container);
|
||||
});
|
||||
|
||||
it('renders correctly with resetPoint', () => {
|
||||
let value = 90;
|
||||
|
||||
function handleChange(point: number) {
|
||||
value = point;
|
||||
}
|
||||
|
||||
const { container } = render(<Slider value={value} resetPoint={30} onChange={handleChange} />);
|
||||
|
||||
fireEvent.click(container.querySelector('[role=button]')!);
|
||||
|
||||
expect(value).toBe(30);
|
||||
});
|
||||
|
||||
it('renders correctly with steps', () => {
|
||||
let result = 10;
|
||||
function Demo() {
|
||||
const [value, setValue] = useState(result);
|
||||
|
||||
function handleChange(point: number) {
|
||||
setValue(point);
|
||||
result = point;
|
||||
}
|
||||
|
||||
return <Slider max={20} value={value} onChange={handleChange} />;
|
||||
}
|
||||
|
||||
const { container } = render(<Demo />);
|
||||
|
||||
const [prev, next] = container.querySelectorAll('button');
|
||||
|
||||
fireEvent.click(prev);
|
||||
fireEvent.click(prev);
|
||||
fireEvent.click(next);
|
||||
fireEvent.click(next);
|
||||
fireEvent.click(next);
|
||||
|
||||
expect(result).toBe(20);
|
||||
});
|
||||
|
||||
it('renders correctly with shortcuts', () => {
|
||||
let result = 10;
|
||||
function Demo() {
|
||||
const [value, setValue] = useState(result);
|
||||
|
||||
function handleChange(point: number) {
|
||||
setValue(point);
|
||||
result = point;
|
||||
}
|
||||
|
||||
return <Slider value={value} shortcuts={[10, 50]} onChange={handleChange} />;
|
||||
}
|
||||
|
||||
const { container } = render(<Demo />);
|
||||
|
||||
fireEvent.click(screen.getByText('10%'));
|
||||
fireEvent.click(screen.getByText('50%'));
|
||||
|
||||
expect(result).toBe(50);
|
||||
});
|
||||
});
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
import type { Meta } from '@storybook/react';
|
||||
import React from 'react';
|
||||
|
||||
import { Button } from '../button/Button';
|
||||
import { Tooltip } from './Tooltip';
|
||||
|
||||
@@ -27,7 +27,7 @@ export { Confirm, type IConfirmProps } from './components/confirm';
|
||||
export { DatePanel, DatePicker, type IDatePanelProps, type IDatePickerProps } from './components/date-picker';
|
||||
export { Dialog, type IDialogProps } from './components/dialog';
|
||||
export { DropdownLegacy, type IDropdownLegacyProps } from './components/dropdown-legacy';
|
||||
export { DropdownOverlay, DropdownProvider, DropdownTrigger, type IDropdownOverlayProps } from './components/dropdown';
|
||||
export { Dropdown } from './components/dropdown';
|
||||
export { FormDualColumnLayout, FormLayout, type IFormDualColumnLayoutProps, type IFormLayoutProps } from './components/form-layout';
|
||||
export { type IInputProps, type IInputWithSlotProps, Input, InputWithSlot } from './components/input';
|
||||
export { type IInputNumberProps, InputNumber } from './components/input-number';
|
||||
@@ -41,7 +41,6 @@ export { type IScrollbarProps, Scrollbar } from './components/scrollbar';
|
||||
export { type ISelectProps, Select } from './components/select';
|
||||
export { type ISelectListProps, SelectList } from './components/select-list';
|
||||
export { type ISegmentedProps, Segmented } from './components/segmented';
|
||||
export { type ISliderProps, Slider } from './components/slider';
|
||||
export { type ITooltipProps, Tooltip } from './components/tooltip';
|
||||
export { filterLeafNode, findNodePathFromTree, findSubTreeFromPath, type ITreeNodeProps, type ITreeProps, mergeTreeSelected, Tree, TreeSelectionMode } from './components/tree';
|
||||
export { Switch } from './components/switch';
|
||||
|
||||
@@ -24,9 +24,6 @@ const locale: ILocale = {
|
||||
cancel: 'cancel',
|
||||
confirm: 'ok',
|
||||
},
|
||||
Slider: {
|
||||
resetTo: 'Reset to',
|
||||
},
|
||||
Picker: {
|
||||
...dajsEnUS,
|
||||
...PickerEnUs,
|
||||
|
||||
@@ -24,9 +24,6 @@ const locale: ILocale = {
|
||||
cancel: 'لغو',
|
||||
confirm: 'باشه',
|
||||
},
|
||||
Slider: {
|
||||
resetTo: 'بازنشانی به',
|
||||
},
|
||||
Picker: {
|
||||
...dajsEnUS,
|
||||
...PickerEnUs,
|
||||
|
||||
@@ -24,9 +24,6 @@ const locale: ILocale = {
|
||||
cancel: 'annuler',
|
||||
confirm: 'ok',
|
||||
},
|
||||
Slider: {
|
||||
resetTo: 'Réinitialiser à',
|
||||
},
|
||||
Picker: {
|
||||
...dajsFrFR,
|
||||
...PickerFrFR,
|
||||
|
||||
@@ -19,7 +19,6 @@ import type PickerZhCN from 'rc-picker/lib/locale/zh_CN';
|
||||
export interface ILocale {
|
||||
design: {
|
||||
Confirm: Record<string, any>;
|
||||
Slider: Record<string, any>;
|
||||
Picker: typeof PickerZhCN;
|
||||
CascaderList: Record<string, any>;
|
||||
Select: Record<string, any>;
|
||||
|
||||
@@ -24,9 +24,6 @@ const locale: ILocale = {
|
||||
cancel: 'отмена',
|
||||
confirm: 'ок',
|
||||
},
|
||||
Slider: {
|
||||
resetTo: 'Сбросить до',
|
||||
},
|
||||
Picker: {
|
||||
...dajsRuRU,
|
||||
...PickerRuRU,
|
||||
|
||||
@@ -24,9 +24,6 @@ const locale: ILocale = {
|
||||
cancel: 'Hủy bỏ',
|
||||
confirm: 'Xác nhận',
|
||||
},
|
||||
Slider: {
|
||||
resetTo: 'Khôi phục đến',
|
||||
},
|
||||
Picker: {
|
||||
...dajsViVN,
|
||||
...PickerViVN,
|
||||
|
||||
@@ -24,9 +24,6 @@ const locale: ILocale = {
|
||||
cancel: '取消',
|
||||
confirm: '确定',
|
||||
},
|
||||
Slider: {
|
||||
resetTo: '恢复至',
|
||||
},
|
||||
Picker: {
|
||||
...dajsZhCN,
|
||||
...PickerZhCN,
|
||||
|
||||
@@ -24,9 +24,6 @@ const locale: ILocale = {
|
||||
cancel: '取消',
|
||||
confirm: '確定',
|
||||
},
|
||||
Slider: {
|
||||
resetTo: '恢復至',
|
||||
},
|
||||
Picker: {
|
||||
...dajsZhTw,
|
||||
...PickerZhTw,
|
||||
|
||||
@@ -15,14 +15,9 @@
|
||||
*/
|
||||
|
||||
import type { DocumentDataModel } from '@univerjs/core';
|
||||
import {
|
||||
ICommandService,
|
||||
IUniverInstanceService,
|
||||
UniverInstanceType,
|
||||
} from '@univerjs/core';
|
||||
import { Slider } from '@univerjs/design';
|
||||
import { useDependency, useObservable } from '@univerjs/ui';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { ICommandService, IUniverInstanceService, UniverInstanceType } from '@univerjs/core';
|
||||
import { Slider, useDependency, useObservable } from '@univerjs/ui';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { SetDocZoomRatioOperation } from '../../commands/operations/set-doc-zoom-ratio.operation';
|
||||
|
||||
const ZOOM_MAP = [50, 80, 100, 130, 150, 170, 200, 400];
|
||||
|
||||
@@ -16,10 +16,9 @@
|
||||
|
||||
import type { IDrawingSearch } from '@univerjs/core';
|
||||
import { ICommandService, LocaleService } from '@univerjs/core';
|
||||
import { DropdownLegacy } from '@univerjs/design';
|
||||
import { clsx, Dropdown } from '@univerjs/design';
|
||||
import { Autofill, MoreDownSingle } from '@univerjs/icons';
|
||||
import { useDependency } from '@univerjs/ui';
|
||||
import clsx from 'clsx';
|
||||
import React, { useState } from 'react';
|
||||
import styles from './index.module.less';
|
||||
|
||||
@@ -80,11 +79,14 @@ export const ImagePopupMenu: React.FC<IImagePopupMenuProps> = (props: IImagePopu
|
||||
onMouseEnter={handleMouseEnter}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
>
|
||||
<DropdownLegacy
|
||||
placement="bottomLeft"
|
||||
trigger={['click']}
|
||||
<Dropdown
|
||||
align="start"
|
||||
overlay={(
|
||||
<ul className={styles.imagePopupMenu}>
|
||||
<ul
|
||||
className={clsx(styles.imagePopupMenu, `
|
||||
univer-box-border univer-p-2 univer-text-sm univer-theme
|
||||
`)}
|
||||
>
|
||||
{availableMenu.map((item) => (
|
||||
<li
|
||||
key={item.index}
|
||||
@@ -96,8 +98,8 @@ export const ImagePopupMenu: React.FC<IImagePopupMenuProps> = (props: IImagePopu
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
visible={visible}
|
||||
onVisibleChange={onVisibleChange}
|
||||
open={visible}
|
||||
onOpenChange={onVisibleChange}
|
||||
>
|
||||
<div
|
||||
className={clsx(styles.btnContainer, {
|
||||
@@ -110,7 +112,7 @@ export const ImagePopupMenu: React.FC<IImagePopupMenuProps> = (props: IImagePopu
|
||||
/>
|
||||
{showMore && <MoreDownSingle style={{ color: '#CCCCCC', fontSize: '8px', marginLeft: '8px' }} />}
|
||||
</div>
|
||||
</DropdownLegacy>
|
||||
</Dropdown>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -9,13 +9,6 @@
|
||||
margin-bottom: 0;
|
||||
padding: var(--padding-sm);
|
||||
|
||||
font-size: var(--font-size-base);
|
||||
|
||||
background-color: rgb(var(--bg-color-secondary));
|
||||
border: 1px solid rgb(var(--border-color));
|
||||
border-radius: var(--border-radius-lg);
|
||||
box-shadow: var(--box-shadow-lg);
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
@@ -31,7 +24,6 @@
|
||||
box-sizing: border-box;
|
||||
height: 28px;
|
||||
|
||||
font-size: var(--font-size-base);
|
||||
font-style: normal;
|
||||
line-height: 20px; /* 153.846% */
|
||||
text-align: left;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import { ColorKit } from '@univerjs/core';
|
||||
import { DropdownLegacy, ColorPicker as OriginColorPicker } from '@univerjs/design';
|
||||
import { Dropdown, ColorPicker as OriginColorPicker } from '@univerjs/design';
|
||||
import { MoreDownSingle } from '@univerjs/icons';
|
||||
import { ComponentManager, useDependency } from '@univerjs/ui';
|
||||
import React, { useMemo } from 'react';
|
||||
@@ -40,26 +40,23 @@ export const ColorPicker = (props: IColorPickerProps) => {
|
||||
|
||||
return Icon && (!disable
|
||||
? (
|
||||
<DropdownLegacy
|
||||
<Dropdown
|
||||
overlay={(
|
||||
<div className={`
|
||||
${styles.cfColorPicker}
|
||||
`}
|
||||
>
|
||||
<div className="univer-rounded-lg univer-p-4">
|
||||
<OriginColorPicker value={color} onChange={onChange} />
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
<span className={`
|
||||
${styles.cfColorPickerIcon}
|
||||
${className}
|
||||
`}
|
||||
<span
|
||||
className={`
|
||||
${styles.cfColorPickerIcon}
|
||||
${className}
|
||||
`}
|
||||
>
|
||||
<Icon extend={{ colorChannel1: colorKit.isValid ? color : 'rgb(var(--primary-color))' }} />
|
||||
{isNeedDropdownIcon && <MoreDownSingle className={styles.iconDropdown} />}
|
||||
</span>
|
||||
|
||||
</DropdownLegacy>
|
||||
</Dropdown>
|
||||
)
|
||||
: <Icon className={className} extend={{ colorChannel1: colorKit.isValid ? color : 'rgb(var(--primary-color))' }} />);
|
||||
};
|
||||
|
||||
+20
-16
@@ -18,7 +18,7 @@ import type { Workbook } from '@univerjs/core';
|
||||
import type { IColorScale, IConditionalFormattingRuleConfig } from '@univerjs/sheets-conditional-formatting';
|
||||
import type { IStyleEditorProps } from './type';
|
||||
import { IUniverInstanceService, LocaleService, UniverInstanceType } from '@univerjs/core';
|
||||
import { InputNumber, Select } from '@univerjs/design';
|
||||
import { clsx, InputNumber, Select } from '@univerjs/design';
|
||||
import { CFRuleType, CFValueType, createDefaultValueByValueType } from '@univerjs/sheets-conditional-formatting';
|
||||
import { FormulaEditor } from '@univerjs/sheets-formula-ui';
|
||||
import { useDependency, useSidebarClick } from '@univerjs/ui';
|
||||
@@ -222,17 +222,19 @@ export const ColorScaleStyleEditor = (props: IStyleEditorProps) => {
|
||||
return (
|
||||
<div>
|
||||
<div className={stylesBase.title}>{localeService.t('sheet.cf.panel.styleRule')}</div>
|
||||
<div className={`
|
||||
${styles.cfPreviewWrap}
|
||||
`}
|
||||
<div
|
||||
className={`
|
||||
${styles.cfPreviewWrap}
|
||||
`}
|
||||
>
|
||||
<Preview rule={getResult({ minType, medianType, maxType, minValue, medianValue, maxValue, minColor, medianColor, maxColor }) as IConditionalFormattingRuleConfig} />
|
||||
</div>
|
||||
<div className={stylesBase.label}>{localeService.t('sheet.cf.valueType.min')}</div>
|
||||
<div className={`
|
||||
${stylesBase.labelContainer}
|
||||
${stylesBase.mTSm}
|
||||
`}
|
||||
<div
|
||||
className={clsx(`
|
||||
${stylesBase.labelContainer}
|
||||
${stylesBase.mTSm}
|
||||
`, 'univer-box-border univer-h-7')}
|
||||
>
|
||||
<Select
|
||||
style={{ flexShrink: 0 }}
|
||||
@@ -267,10 +269,11 @@ export const ColorScaleStyleEditor = (props: IStyleEditorProps) => {
|
||||
/>
|
||||
</div>
|
||||
<div className={stylesBase.label}>{localeService.t('sheet.cf.panel.medianValue')}</div>
|
||||
<div className={`
|
||||
${stylesBase.labelContainer}
|
||||
${stylesBase.mTSm}
|
||||
`}
|
||||
<div
|
||||
className={clsx(`
|
||||
${stylesBase.labelContainer}
|
||||
${stylesBase.mTSm}
|
||||
`, 'univer-box-border univer-h-7')}
|
||||
>
|
||||
<Select
|
||||
style={{ flexShrink: 0 }}
|
||||
@@ -309,10 +312,11 @@ export const ColorScaleStyleEditor = (props: IStyleEditorProps) => {
|
||||
|
||||
</div>
|
||||
<div className={stylesBase.label}>{localeService.t('sheet.cf.valueType.max')}</div>
|
||||
<div className={`
|
||||
${stylesBase.labelContainer}
|
||||
${stylesBase.mTSm}
|
||||
`}
|
||||
<div
|
||||
className={clsx(`
|
||||
${stylesBase.labelContainer}
|
||||
${stylesBase.mTSm}
|
||||
`, 'univer-box-border univer-h-7')}
|
||||
>
|
||||
<Select
|
||||
style={{ flexShrink: 0 }}
|
||||
|
||||
+22
-16
@@ -19,7 +19,7 @@ import type { IIconSet, IIconType } from '@univerjs/sheets-conditional-formattin
|
||||
import type { IStyleEditorProps } from './type';
|
||||
|
||||
import { get, IUniverInstanceService, LocaleService, set, Tools, UniverInstanceType } from '@univerjs/core';
|
||||
import { Checkbox, DropdownLegacy, InputNumber, Select } from '@univerjs/design';
|
||||
import { Checkbox, clsx, Dropdown, InputNumber, Select } from '@univerjs/design';
|
||||
import { MoreDownSingle, SlashSingle } from '@univerjs/icons';
|
||||
import {
|
||||
CFNumberOperator,
|
||||
@@ -285,12 +285,18 @@ const IconSetRuleEdit = (props: {
|
||||
${styles.width45}
|
||||
`}
|
||||
>
|
||||
<DropdownLegacy overlay={<IconItemList onClick={handleIconClick} iconId={item.iconId} iconType={item.iconType} />}>
|
||||
<div className={styles.dropdownIcon}>
|
||||
<Dropdown
|
||||
overlay={(
|
||||
<div className="univer-rounded-lg univer-p-4">
|
||||
<IconItemList onClick={handleIconClick} iconId={item.iconId} iconType={item.iconType} />
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
<div className={clsx(styles.dropdownIcon, 'univer-box-border univer-h-7')}>
|
||||
{icon ? <img src={icon} className={styles.icon} /> : <SlashSingle className={styles.icon} />}
|
||||
<MoreDownSingle />
|
||||
</div>
|
||||
</DropdownLegacy>
|
||||
</Dropdown>
|
||||
|
||||
</div>
|
||||
{!isEnd
|
||||
@@ -560,24 +566,24 @@ export const IconSet = (props: IStyleEditorProps<unknown, IIconSet>) => {
|
||||
${stylesBase.mTSm}
|
||||
`}
|
||||
>
|
||||
<DropdownLegacy
|
||||
placement="bottomLeft"
|
||||
<Dropdown
|
||||
overlay={(
|
||||
<IconGroupList
|
||||
ref={(el) => {
|
||||
!iconGroupListEl && el && setIconGroupListEl(el);
|
||||
}}
|
||||
iconType={currentIconType}
|
||||
onClick={handleClickIconList}
|
||||
/>
|
||||
<div className="univer-rounded-lg univer-p-4">
|
||||
<IconGroupList
|
||||
ref={(el) => {
|
||||
!iconGroupListEl && el && setIconGroupListEl(el);
|
||||
}}
|
||||
iconType={currentIconType}
|
||||
onClick={handleClickIconList}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
<div className={styles.dropdownIcon} style={{ width: 'unset' }}>
|
||||
<div className={clsx(styles.dropdownIcon, 'univer-box-border univer-h-7 univer-w-auto')}>
|
||||
{previewIcon}
|
||||
<MoreDownSingle />
|
||||
</div>
|
||||
{/* <div>{previewIcon}</div> */}
|
||||
</DropdownLegacy>
|
||||
</Dropdown>
|
||||
</div>
|
||||
<div
|
||||
className={`
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@univerjs-infra/shared": "workspace:*",
|
||||
"@univerjs/icons-svg": "^0.2.15",
|
||||
"@univerjs/icons-svg": "^0.2.20",
|
||||
"rxjs": "^7.8.1",
|
||||
"typescript": "^5.7.3",
|
||||
"vite": "^6.1.1",
|
||||
|
||||
+3
-3
@@ -156,7 +156,7 @@ export function SelectFunction(props: ISelectFunctionProps) {
|
||||
onKeyDown={handleSelectListKeyDown}
|
||||
value={searchText}
|
||||
onChange={handleSearchInputChange}
|
||||
size="large"
|
||||
size="small"
|
||||
allowClear
|
||||
/>
|
||||
</div>
|
||||
@@ -200,9 +200,9 @@ export function SelectFunction(props: ISelectFunctionProps) {
|
||||
/>
|
||||
|
||||
{functionInfo.functionParameter &&
|
||||
functionInfo.functionParameter.map((item: IFunctionParam, i: number) => (
|
||||
functionInfo.functionParameter.map((item: IFunctionParam) => (
|
||||
<FunctionParams
|
||||
key={i}
|
||||
key={item.name}
|
||||
title={item.name}
|
||||
value={`${item.require ? required : optional} ${item.detail}`}
|
||||
/>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import type { IBorderInfo } from '@univerjs/sheets';
|
||||
import type { IBorderPanelProps } from './interface';
|
||||
import { BorderStyleTypes } from '@univerjs/core';
|
||||
import { ColorPicker, DropdownLegacy, Menu, MenuItem } from '@univerjs/design';
|
||||
import { ColorPicker, Dropdown, Menu, MenuItem } from '@univerjs/design';
|
||||
import { MoreDownSingle, PaintBucket } from '@univerjs/icons';
|
||||
import { BorderStyleManagerService } from '@univerjs/sheets';
|
||||
import { ComponentManager, useDependency } from '@univerjs/ui';
|
||||
@@ -121,14 +121,11 @@ export function BorderPanel(props: IBorderPanelProps) {
|
||||
|
||||
<div className={styles.uiPluginSheetsBorderPanelStyles}>
|
||||
<div>
|
||||
<DropdownLegacy
|
||||
align={{
|
||||
offset: [0, 18],
|
||||
}}
|
||||
<Dropdown
|
||||
overlay={(
|
||||
<section className={styles.uiPluginSheetsBorderPanelBoard} onClick={stopPropagation}>
|
||||
<div className="univer-rounded-lg univer-p-4" onClick={stopPropagation}>
|
||||
<ColorPicker onChange={(value) => handleClick(value, 'color')} />
|
||||
</section>
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
<a className={styles.uiPluginSheetsBorderPanelButton} onClick={stopPropagation}>
|
||||
@@ -137,16 +134,13 @@ export function BorderPanel(props: IBorderPanelProps) {
|
||||
<MoreDownSingle />
|
||||
</span>
|
||||
</a>
|
||||
</DropdownLegacy>
|
||||
</Dropdown>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<DropdownLegacy
|
||||
align={{
|
||||
offset: [0, 18],
|
||||
}}
|
||||
<Dropdown
|
||||
overlay={(
|
||||
<section onClick={stopPropagation}>
|
||||
<section className="univer-rounded-lg univer-p-4" onClick={stopPropagation}>
|
||||
<Menu>
|
||||
{BORDER_SIZE_CHILDREN.map((item) => (
|
||||
<MenuItem
|
||||
@@ -167,7 +161,7 @@ export function BorderPanel(props: IBorderPanelProps) {
|
||||
<MoreDownSingle />
|
||||
</span>
|
||||
</a>
|
||||
</DropdownLegacy>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -41,16 +41,6 @@
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
&-board {
|
||||
box-sizing: border-box;
|
||||
padding: var(--padding-base);
|
||||
|
||||
background-color: rgb(var(--bg-color-secondary));
|
||||
border: 1px solid rgb(var(--border-color));
|
||||
border-radius: var(--border-radius-lg);
|
||||
box-shadow: var(--box-shadow-base);
|
||||
}
|
||||
|
||||
&-button {
|
||||
cursor: pointer;
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import { DOCS_COMPONENT_MAIN_LAYER_INDEX, VIEWPORT_KEY } from '@univerjs/docs-ui
|
||||
import { convertTextRotation, fixLineWidthByScale, IRenderManagerService, Rect, ScrollBar } from '@univerjs/engine-render';
|
||||
import { ILayoutService } from '@univerjs/ui';
|
||||
import { getEditorObject } from '../../basics/editor/get-editor-object';
|
||||
import styles from '../../views/sheet-container/index.module.less';
|
||||
import { SHEET_FOOTER_BAR_HEIGHT } from '../../views/sheet-container/SheetContainer';
|
||||
import { IEditorBridgeService } from '../editor-bridge.service';
|
||||
import { SheetSkeletonManagerService } from '../sheet-skeleton-manager.service';
|
||||
import { ICellEditorManagerService } from './cell-editor-manager.service';
|
||||
@@ -217,7 +217,7 @@ export class SheetCellEditorResizeService extends Disposable implements IRenderM
|
||||
const clientHeight =
|
||||
document.body.clientHeight -
|
||||
startY -
|
||||
Number.parseFloat(styles.sheetFooterBarHeight) -
|
||||
SHEET_FOOTER_BAR_HEIGHT -
|
||||
canvasOffset.top -
|
||||
EDITOR_BORDER_SIZE * 2;
|
||||
|
||||
|
||||
@@ -17,15 +17,14 @@
|
||||
import type { IDiscreteRange } from '../../controllers/utils/range-tools';
|
||||
import type { IPasteHookKeyType } from '../../services/clipboard/type';
|
||||
import { ICommandService, IUniverInstanceService, LocaleService } from '@univerjs/core';
|
||||
import { DropdownOverlay, DropdownProvider, DropdownTrigger } from '@univerjs/design';
|
||||
import { clsx, Dropdown } from '@univerjs/design';
|
||||
import { convertTransformToOffsetX, convertTransformToOffsetY, IRenderManagerService } from '@univerjs/engine-render';
|
||||
import { CheckMarkSingle, MoreDownSingle, PasteSpecial } from '@univerjs/icons';
|
||||
import { useDependency, useObservable } from '@univerjs/ui';
|
||||
import clsx from 'clsx';
|
||||
import { useState } from 'react';
|
||||
import { SheetOptionalPasteCommand } from '../../commands/commands/clipboard.command';
|
||||
import { useActiveWorkbook } from '../../components/hook';
|
||||
import { SheetClipboardController } from '../../controllers/clipboard/clipboard.controller';
|
||||
// import { SheetClipboardController } from '../../controllers/clipboard/clipboard.controller';
|
||||
import { getSheetObject } from '../../controllers/utils/component-tools';
|
||||
import { ISheetClipboardService, PREDEFINED_HOOK_NAME } from '../../services/clipboard/clipboard.service';
|
||||
import { ISheetSelectionRenderService } from '../../services/selection/base-selection-render.service';
|
||||
@@ -112,7 +111,7 @@ const useMenuPosition = (range?: IDiscreteRange) => {
|
||||
export const ClipboardPopupMenu = () => {
|
||||
const clipboardService = useDependency(ISheetClipboardService);
|
||||
const showMenu = useObservable(clipboardService.showMenu$, false);
|
||||
const clipboardController = useDependency(SheetClipboardController);
|
||||
// const clipboardController = useDependency(SheetClipboardController);
|
||||
const pasteOptionsCache = useObservable(clipboardService.pasteOptionsCache$, null);
|
||||
const localeService = useDependency(LocaleService);
|
||||
const commandService = useDependency(ICommandService);
|
||||
@@ -120,7 +119,7 @@ export const ClipboardPopupMenu = () => {
|
||||
const [menuHovered, setMenuHovered] = useState(false);
|
||||
const [menuVisible, setMenuVisible] = useState(false);
|
||||
|
||||
const version = useObservable(clipboardController.refreshOptionalPaste$, Math.random());
|
||||
// const version = useObservable(clipboardController.refreshOptionalPaste$, Math.random());
|
||||
|
||||
const range = pasteOptionsCache?.target.pastedRange;
|
||||
|
||||
@@ -133,6 +132,7 @@ export const ClipboardPopupMenu = () => {
|
||||
const iconVisible = menuHovered || menuVisible;
|
||||
|
||||
const handleClick = (type: string) => {
|
||||
setMenuVisible(false);
|
||||
commandService.executeCommand(SheetOptionalPasteCommand.id, { type });
|
||||
};
|
||||
|
||||
@@ -146,52 +146,58 @@ export const ClipboardPopupMenu = () => {
|
||||
onMouseEnter={() => setMenuHovered(true)}
|
||||
onMouseLeave={() => setMenuHovered(false)}
|
||||
>
|
||||
<DropdownProvider
|
||||
visible={menuVisible}
|
||||
onVisibleChange={(visible) => {
|
||||
setMenuVisible(visible);
|
||||
}}
|
||||
>
|
||||
<DropdownTrigger>
|
||||
<Dropdown
|
||||
overlay={(
|
||||
<div
|
||||
className={styles.sheetPasteOptionsIconWrapper}
|
||||
onClick={() => {
|
||||
setMenuVisible(!menuVisible);
|
||||
}}
|
||||
className={clsx(styles.sheetPasteOptionsMenu, `
|
||||
univer-border univer-border-solid univer-border-gray-200 univer-opacity-100
|
||||
`)}
|
||||
>
|
||||
<PasteSpecial
|
||||
style={{ color: '#35322B' }}
|
||||
extend={{ colorChannel1: 'rgb(var(--green-700))' }}
|
||||
/>
|
||||
{iconVisible && <MoreDownSingle />}
|
||||
<ul>
|
||||
{SheetPasteOptions.map((item) => {
|
||||
const itemType = PREDEFINED_HOOK_NAME[item.value as IPasteHookKeyType];
|
||||
const selected = pasteOptionsCache?.pasteType === itemType;
|
||||
return (
|
||||
<li
|
||||
key={item.value}
|
||||
className={clsx(styles.sheetPasteOptionsMenuItem, 'hover:univer-bg-neutral-100')}
|
||||
onClick={() => handleClick(item.value)}
|
||||
>
|
||||
<span>
|
||||
{selected && (
|
||||
<CheckMarkSingle className={styles.sheetPasteOptionsMenuItemIcon} style={{ color: 'rgb(var(--green-700, #409f11))' }} />
|
||||
)}
|
||||
</span>
|
||||
<div
|
||||
className={clsx(styles.sheetPasteOptionsMenuItemTitle, `
|
||||
univer-text-gray-700
|
||||
`)}
|
||||
>
|
||||
{localeService.t(item.label)}
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</DropdownTrigger>
|
||||
<DropdownOverlay className={clsx(styles.sheetPasteOptionsMenu, `
|
||||
univer-border univer-border-solid univer-border-gray-200 univer-opacity-100
|
||||
`)}
|
||||
)}
|
||||
open={menuVisible}
|
||||
onOpenChange={setMenuVisible}
|
||||
>
|
||||
|
||||
<div
|
||||
className={styles.sheetPasteOptionsIconWrapper}
|
||||
onClick={() => {
|
||||
setMenuVisible(!menuVisible);
|
||||
}}
|
||||
>
|
||||
<ul>
|
||||
{SheetPasteOptions.map((item) => {
|
||||
const itemType = PREDEFINED_HOOK_NAME[item.value as IPasteHookKeyType];
|
||||
const selected = pasteOptionsCache?.pasteType === itemType;
|
||||
return (
|
||||
<li
|
||||
key={item.value}
|
||||
onClick={() => handleClick(item.value)}
|
||||
className={clsx(styles.sheetPasteOptionsMenuItem, 'hover:univer-bg-neutral-100')}
|
||||
>
|
||||
<span>
|
||||
{selected && (
|
||||
<CheckMarkSingle className={styles.sheetPasteOptionsMenuItemIcon} style={{ color: 'rgb(var(--green-700, #409f11))' }} />
|
||||
)}
|
||||
</span>
|
||||
<div className={clsx(styles.sheetPasteOptionsMenuItemTitle, 'univer-text-gray-700')}>{localeService.t(item.label)}</div>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</DropdownOverlay>
|
||||
</DropdownProvider>
|
||||
<PasteSpecial
|
||||
style={{ color: '#35322B' }}
|
||||
extend={{ colorChannel1: 'rgb(var(--green-700))' }}
|
||||
/>
|
||||
{iconVisible && <MoreDownSingle />}
|
||||
</div>
|
||||
</Dropdown>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -21,10 +21,9 @@ import {
|
||||
IUniverInstanceService,
|
||||
UniverInstanceType,
|
||||
} from '@univerjs/core';
|
||||
import { Slider } from '@univerjs/design';
|
||||
import { SetWorksheetActiveOperation } from '@univerjs/sheets';
|
||||
import { useDependency, useObservable } from '@univerjs/ui';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { Slider, useDependency, useObservable } from '@univerjs/ui';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import { SetZoomRatioCommand } from '../../commands/commands/set-zoom-ratio.command';
|
||||
import { SetZoomRatioOperation } from '../../commands/operations/set-zoom-ratio.operation';
|
||||
|
||||
@@ -14,8 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { DropdownOverlay, DropdownProvider, DropdownTrigger } from '@univerjs/design';
|
||||
|
||||
import { Dropdown } from '@univerjs/design';
|
||||
import { IDefinedNamesService } from '@univerjs/engine-formula';
|
||||
import { MoreDownSingle } from '@univerjs/icons';
|
||||
import { useDependency } from '@univerjs/ui';
|
||||
@@ -45,11 +44,16 @@ export function DefinedName({ disable }: { disable: boolean }) {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.definedName}>
|
||||
<div
|
||||
className={`
|
||||
univer-relative univer-box-border univer-flex univer-h-full univer-w-24 univer-border-r-gray-200
|
||||
univer-py-1.5 univer-transition-all
|
||||
`}
|
||||
>
|
||||
<input
|
||||
className={clsx(`
|
||||
univer-absolute univer-box-border univer-h-full univer-w-full univer-appearance-none
|
||||
univer-border-none univer-px-1.5
|
||||
univer-box-border univer-h-full univer-w-full univer-appearance-none univer-border-0 univer-border-r
|
||||
univer-border-r-gray-200 univer-px-1.5
|
||||
focus:univer-outline-none
|
||||
`, {
|
||||
[styles.defineNameInputDisable]: disable,
|
||||
@@ -59,27 +63,26 @@ export function DefinedName({ disable }: { disable: boolean }) {
|
||||
onChange={handleChangeSelection}
|
||||
/>
|
||||
|
||||
<DropdownProvider>
|
||||
<DropdownTrigger>
|
||||
<a
|
||||
className={clsx(`
|
||||
univer-absolute univer-right-0 univer-flex univer-h-full univer-cursor-pointer
|
||||
univer-items-center univer-justify-center univer-px-1 univer-transition-colors
|
||||
univer-duration-200
|
||||
hover:univer-bg-gray-100
|
||||
`,
|
||||
{
|
||||
'univer-cursor-not-allowed univer-text-gray-300 hover:univer-bg-transparent': disable,
|
||||
})}
|
||||
>
|
||||
<MoreDownSingle />
|
||||
</a>
|
||||
</DropdownTrigger>
|
||||
|
||||
<DropdownOverlay className="univer-z-[1001]" offset={{ x: -75, y: 2 }}>
|
||||
<DefinedNameOverlay />
|
||||
</DropdownOverlay>
|
||||
</DropdownProvider>
|
||||
<Dropdown
|
||||
overlay={(
|
||||
<div className="univer-z-[1001]">
|
||||
<DefinedNameOverlay />
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
<a
|
||||
className={clsx(`
|
||||
univer-absolute univer-right-0 univer-top-0 univer-flex univer-h-full univer-cursor-pointer
|
||||
univer-items-center univer-justify-center univer-px-1 univer-transition-colors univer-duration-200
|
||||
hover:univer-bg-gray-100
|
||||
`,
|
||||
{
|
||||
'univer-cursor-not-allowed univer-text-gray-300 hover:univer-bg-transparent': disable,
|
||||
})}
|
||||
>
|
||||
<MoreDownSingle />
|
||||
</a>
|
||||
</Dropdown>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
.defined-name {
|
||||
display: flex;
|
||||
|
||||
position: relative;
|
||||
|
||||
transition: height 0.15s;
|
||||
|
||||
border-right: 1px solid rgb(var(--border-color));
|
||||
|
||||
height: 100%;
|
||||
|
||||
width: 100px;
|
||||
|
||||
box-sizing: border-box;
|
||||
|
||||
&-overlay {
|
||||
position: relative;
|
||||
width: 300px;
|
||||
|
||||
@@ -160,12 +160,14 @@ export function FormulaBar(props: IProps) {
|
||||
}, [editorBridgeService.currentEditCellState$]);
|
||||
|
||||
useEffect(() => {
|
||||
if (ref.current) {
|
||||
const handleResize = () => {
|
||||
const editorRect = ref.current!.getBoundingClientRect();
|
||||
formulaEditorManagerService.setPosition(editorRect);
|
||||
};
|
||||
const handleResize = () => {
|
||||
if (!ref.current) return;
|
||||
|
||||
const editorRect = ref.current.getBoundingClientRect();
|
||||
formulaEditorManagerService.setPosition(editorRect);
|
||||
};
|
||||
|
||||
if (ref.current) {
|
||||
handleResize();
|
||||
const a = new ResizeObserver(handleResize);
|
||||
|
||||
|
||||
@@ -16,11 +16,10 @@
|
||||
|
||||
import type { ICommandInfo, IExecutionOptions } from '@univerjs/core';
|
||||
import { ICommandService, IUniverInstanceService, LocaleService, toDisposable } from '@univerjs/core';
|
||||
import { DropdownLegacy } from '@univerjs/design';
|
||||
import { clsx, Dropdown } from '@univerjs/design';
|
||||
import { convertTransformToOffsetX, convertTransformToOffsetY, IRenderManagerService } from '@univerjs/engine-render';
|
||||
import { Autofill, CheckMarkSingle, MoreDownSingle } from '@univerjs/icons';
|
||||
import { useDependency } from '@univerjs/ui';
|
||||
import clsx from 'clsx';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { RefillCommand } from '../../commands/commands/refill.command';
|
||||
import { SetScrollOperation } from '../../commands/operations/scroll.operation';
|
||||
@@ -186,16 +185,20 @@ export const AutoFillPopupMenu: React.FC<{}> = () => {
|
||||
onMouseLeave={handleMouseLeave}
|
||||
style={{ left: `${relativeX + 2}px`, top: `${relativeY + 2}px`, position: 'absolute' }}
|
||||
>
|
||||
<DropdownLegacy
|
||||
placement="bottomLeft"
|
||||
trigger={['click']}
|
||||
<Dropdown
|
||||
align="start"
|
||||
overlay={(
|
||||
<ul className={styles.autoFillPopupMenu}>
|
||||
<ul
|
||||
className={`
|
||||
univer-rounded-lg univer-p-2 univer-theme univer-m-0 univer-box-border univer-grid
|
||||
univer-list-none univer-gap-1
|
||||
`}
|
||||
>
|
||||
{availableMenu.map((item) => (
|
||||
<li
|
||||
key={item.index}
|
||||
onClick={() => handleClick(item)}
|
||||
className={styles.autoFillPopupMenuItem}
|
||||
onClick={() => handleClick(item)}
|
||||
>
|
||||
<span className={styles.autoFillPopupMenuItemIcon}>
|
||||
{item.value === selected && (
|
||||
@@ -207,8 +210,8 @@ export const AutoFillPopupMenu: React.FC<{}> = () => {
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
visible={visible}
|
||||
onVisibleChange={onVisibleChange}
|
||||
open={visible}
|
||||
onOpenChange={onVisibleChange}
|
||||
>
|
||||
<div
|
||||
className={clsx(styles.btnContainer, {
|
||||
@@ -221,7 +224,7 @@ export const AutoFillPopupMenu: React.FC<{}> = () => {
|
||||
/>
|
||||
{showMore && <MoreDownSingle style={{ color: '#CCCCCC', fontSize: '8px', marginLeft: '8px' }} />}
|
||||
</div>
|
||||
</DropdownLegacy>
|
||||
</Dropdown>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -7,31 +7,9 @@
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
@item-padding-left: 36px;
|
||||
@auto-fill-popup-menu-min-width: 128px;
|
||||
@item-padding-left: 24px;
|
||||
|
||||
.auto-fill-popup-menu {
|
||||
display: grid;
|
||||
gap: var(--margin-xxs);
|
||||
align-items: center;
|
||||
|
||||
box-sizing: border-box;
|
||||
min-width: @auto-fill-popup-menu-min-width;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
padding: var(--padding-sm);
|
||||
|
||||
font-size: var(--font-size-base);
|
||||
|
||||
background-color: rgb(var(--bg-color-secondary));
|
||||
border: 1px solid rgb(var(--border-color));
|
||||
border-radius: var(--border-radius-lg);
|
||||
box-shadow: var(--box-shadow-lg);
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
&-item {
|
||||
cursor: pointer;
|
||||
|
||||
@@ -41,7 +19,6 @@
|
||||
align-items: center;
|
||||
|
||||
box-sizing: border-box;
|
||||
width: 134px;
|
||||
height: 28px;
|
||||
padding: var(--padding-xs) 0 var(--padding-xs) @item-padding-left;
|
||||
|
||||
|
||||
@@ -16,10 +16,11 @@
|
||||
|
||||
import type { IScrollState } from './sheet-bar-tabs/utils/slide-tab-bar';
|
||||
import { ICommandService, IPermissionService } from '@univerjs/core';
|
||||
import { clsx } from '@univerjs/design';
|
||||
import { IncreaseSingle, MoreSingle } from '@univerjs/icons';
|
||||
import { InsertSheetCommand, WorkbookCreateSheetPermission, WorkbookEditablePermission } from '@univerjs/sheets';
|
||||
import { useDependency, useObservable } from '@univerjs/ui';
|
||||
|
||||
import { useDependency, useObservable } from '@univerjs/ui';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useActiveWorkbook } from '../../components/hook';
|
||||
import { ISheetBarService } from '../../services/sheet-bar/sheet-bar.service';
|
||||
@@ -77,7 +78,7 @@ export const SheetBar = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.sheetBar}>
|
||||
<div className={clsx(styles.sheetBar, 'univer-relative univer-flex univer-h-full univer-flex-1')}>
|
||||
<div className={styles.sheetBarOptions}>
|
||||
{/* Add sheet button */}
|
||||
<SheetBarButton onClick={addSheet} disabled={!(workbookCreateSheetPermission?.value && workbookEditablePermission?.value)}>
|
||||
@@ -92,10 +93,11 @@ export const SheetBar = () => {
|
||||
|
||||
{/* Scroll arrows */}
|
||||
{(!leftScrollState || !rightScrollState) && (
|
||||
<div className={`
|
||||
${styles.sheetBarOptions}
|
||||
${styles.sheetBarOptionsDivider}
|
||||
`}
|
||||
<div
|
||||
className={`
|
||||
${styles.sheetBarOptions}
|
||||
${styles.sheetBarOptionsDivider}
|
||||
`}
|
||||
>
|
||||
<SheetBarButton disabled={leftScrollState} onClick={handleScrollLeft}>
|
||||
<MoreSingle style={{ transform: 'rotateZ(180deg)' }} />
|
||||
|
||||
@@ -4,17 +4,8 @@
|
||||
@margin-right: -4px;
|
||||
|
||||
.sheet-bar {
|
||||
position: relative;
|
||||
|
||||
display: flex;
|
||||
flex: 1 1 0px;
|
||||
flex-direction: row;
|
||||
|
||||
min-width: calc(100% - @zoom-slider-width - @status-bar-max-width);
|
||||
max-width: calc(100% - @zoom-slider-width);
|
||||
height: 100%;
|
||||
|
||||
background-color: rgb(var(--bg-color-secondary));
|
||||
|
||||
&-options {
|
||||
display: flex;
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
@import '../../sheet-container/index.module.less';
|
||||
|
||||
@padding-left-right: 24px;
|
||||
@line-height: 20px;
|
||||
|
||||
.sheet-bar-menu {
|
||||
max-height: calc(100vh - @sheet-footer-bar-height);
|
||||
max-height: calc(100vh - 36px);
|
||||
display: grid;
|
||||
gap: var(--margin-xxs);
|
||||
align-items: center;
|
||||
|
||||
@@ -17,8 +17,7 @@
|
||||
import type { Workbook } from '@univerjs/core';
|
||||
import { IUniverInstanceService, UniverInstanceType } from '@univerjs/core';
|
||||
import { ContextMenuPosition, IMenuManagerService, ToolbarItem, useDependency, useObservable } from '@univerjs/ui';
|
||||
import React, { useMemo } from 'react';
|
||||
|
||||
import { useMemo } from 'react';
|
||||
import { useActiveWorkbook } from '../../components/hook';
|
||||
import { CountBar } from '../count-bar/CountBar';
|
||||
import { EditorContainer } from '../editor-container/EditorContainer';
|
||||
@@ -26,7 +25,8 @@ import { FormulaBar } from '../formula-bar/FormulaBar';
|
||||
import { OperateContainer } from '../operate-container/OperateContainer';
|
||||
import { SheetBar } from '../sheet-bar/SheetBar';
|
||||
import { StatusBar } from '../status-bar/StatusBar';
|
||||
import styles from './index.module.less';
|
||||
|
||||
export const SHEET_FOOTER_BAR_HEIGHT = 36;
|
||||
|
||||
export function RenderSheetFooter() {
|
||||
const menuManagerService = useDependency(IMenuManagerService);
|
||||
@@ -37,20 +37,33 @@ export function RenderSheetFooter() {
|
||||
const footerMenus = menuManagerService.getMenuByPositionKey(ContextMenuPosition.FOOTER_MENU);
|
||||
|
||||
return (
|
||||
<section className={styles.sheetContainer} data-range-selector>
|
||||
<section
|
||||
className={`
|
||||
univer-box-border univer-flex univer-items-center univer-justify-between univer-bg-white univer-px-5
|
||||
univer-text-gray-900
|
||||
dark:univer-bg-gray-900 dark:univer-text-gray-200
|
||||
`}
|
||||
style={{
|
||||
height: SHEET_FOOTER_BAR_HEIGHT,
|
||||
}}
|
||||
data-range-selector
|
||||
>
|
||||
<SheetBar />
|
||||
<StatusBar />
|
||||
{footerMenus.map((item) => item.children?.map((child) => (
|
||||
child?.item && (
|
||||
<ToolbarItem
|
||||
key={child.key}
|
||||
align={{
|
||||
offset: [-32, 18],
|
||||
}}
|
||||
{...child.item}
|
||||
/>
|
||||
)
|
||||
)))}
|
||||
|
||||
{footerMenus.length && (
|
||||
<div className="univer-mr-2 univer-flex univer-gap-2">
|
||||
{footerMenus.map((item) => item.children?.map((child) => (
|
||||
child?.item && (
|
||||
<ToolbarItem
|
||||
key={child.key}
|
||||
{...child.item}
|
||||
/>
|
||||
)
|
||||
)))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<CountBar />
|
||||
</section>
|
||||
);
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
@sheet-footer-bar-height: 36px;
|
||||
|
||||
:export {
|
||||
--sheet-footer-bar-height: unit(@sheet-footer-bar-height);
|
||||
}
|
||||
|
||||
.sheet-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
box-sizing: border-box;
|
||||
height: @sheet-footer-bar-height;
|
||||
padding: 0 var(--padding-xl);
|
||||
|
||||
background-color: rgb(var(--bg-color-secondary));
|
||||
|
||||
> span:not(:last-of-type) {
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
@@ -190,7 +190,7 @@ export const StatusBar = () => {
|
||||
[styles.singleMode]: isSingle,
|
||||
})}
|
||||
>
|
||||
<div className={clsx(styles.statisticList)}>{renderContent}</div>
|
||||
<div className="univer-flex">{renderContent}</div>
|
||||
<div className={styles.statusBarDiv} />
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -18,14 +18,6 @@
|
||||
}
|
||||
|
||||
.statistic {
|
||||
&-list {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
&-list-column {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&-list-column &-item {
|
||||
font-size: 12px;
|
||||
line-height: 140%;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import type { IDrawingSearch } from '@univerjs/core';
|
||||
import { ICommandService, LocaleService } from '@univerjs/core';
|
||||
import { DropdownLegacy } from '@univerjs/design';
|
||||
import { Dropdown } from '@univerjs/design';
|
||||
import { Autofill, MoreDownSingle } from '@univerjs/icons';
|
||||
import { useDependency } from '@univerjs/ui';
|
||||
import clsx from 'clsx';
|
||||
@@ -80,11 +80,14 @@ export const SlideImagePopupMenu: React.FC<IImagePopupMenuProps> = (props: IImag
|
||||
onMouseEnter={handleMouseEnter}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
>
|
||||
<DropdownLegacy
|
||||
placement="bottomLeft"
|
||||
trigger={['click']}
|
||||
<Dropdown
|
||||
align="start"
|
||||
overlay={(
|
||||
<ul className={styles.imagePopupMenu}>
|
||||
<ul
|
||||
className={clsx(styles.imagePopupMenu, `
|
||||
univer-box-border univer-p-2 univer-text-sm univer-theme
|
||||
`)}
|
||||
>
|
||||
{availableMenu.map((item) => (
|
||||
<li
|
||||
key={item.index}
|
||||
@@ -96,8 +99,8 @@ export const SlideImagePopupMenu: React.FC<IImagePopupMenuProps> = (props: IImag
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
visible={visible}
|
||||
onVisibleChange={onVisibleChange}
|
||||
open={visible}
|
||||
onOpenChange={onVisibleChange}
|
||||
>
|
||||
<div
|
||||
className={clsx(styles.btnContainer, {
|
||||
@@ -110,7 +113,7 @@ export const SlideImagePopupMenu: React.FC<IImagePopupMenuProps> = (props: IImag
|
||||
/>
|
||||
{showMore && <MoreDownSingle style={{ color: '#CCCCCC', fontSize: '8px', marginLeft: '8px' }} />}
|
||||
</div>
|
||||
</DropdownLegacy>
|
||||
</Dropdown>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -18,7 +18,7 @@ import type { Nullable } from '@univerjs/core';
|
||||
|
||||
import type { Rect } from '@univerjs/engine-render';
|
||||
import { ICommandService, LocaleService } from '@univerjs/core';
|
||||
import { ColorPicker, DropdownLegacy } from '@univerjs/design';
|
||||
import { ColorPicker, Dropdown } from '@univerjs/design';
|
||||
import { MoreDownSingle, PaintBucket } from '@univerjs/icons';
|
||||
import { useDependency } from '@univerjs/ui';
|
||||
import clsx from 'clsx';
|
||||
@@ -93,17 +93,14 @@ export default function ArrangePanel(props: IProps) {
|
||||
</div>
|
||||
<div className={styles.imageCommonPanelRow}>
|
||||
<div className={clsx(styles.imageCommonPanelColumn, styles.imageCommonPanelSpan2)}>
|
||||
<DropdownLegacy
|
||||
align={{
|
||||
offset: [0, 18],
|
||||
}}
|
||||
<Dropdown
|
||||
overlay={(
|
||||
<section className={styles.slidePanelColorPicker}>
|
||||
<div className="univer-rounded-lg univer-p-4">
|
||||
<ColorPicker
|
||||
value="#fff"
|
||||
onChange={handleChangeColor}
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
<a className={styles.uiPluginSheetsBorderPanelButton}>
|
||||
@@ -112,7 +109,7 @@ export default function ArrangePanel(props: IProps) {
|
||||
<MoreDownSingle />
|
||||
</span>
|
||||
</a>
|
||||
</DropdownLegacy>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -18,7 +18,7 @@ import type { IUser, UniverInstanceType } from '@univerjs/core';
|
||||
import type { IAddCommentCommandParams, IThreadComment, IUpdateCommentCommandParams } from '@univerjs/thread-comment';
|
||||
import type { IThreadCommentEditorInstance } from '../thread-comment-editor';
|
||||
import { generateRandomId, ICommandService, LocaleService, UserManagerService } from '@univerjs/core';
|
||||
import { DropdownLegacy, Menu, MenuItem, Tooltip } from '@univerjs/design';
|
||||
import { Dropdown, Tooltip } from '@univerjs/design';
|
||||
import { DeleteSingle, MoreHorizontalSingle, ReplyToCommentSingle, ResolvedSingle, SolveSingle } from '@univerjs/icons';
|
||||
import { AddCommentCommand, DeleteCommentCommand, DeleteCommentTreeCommand, getDT, ResolveCommentCommand, ThreadCommentModel, UpdateCommentCommand } from '@univerjs/thread-comment';
|
||||
import { useDependency, useObservable } from '@univerjs/ui';
|
||||
@@ -118,18 +118,40 @@ const ThreadCommentItem = (props: IThreadCommentItemProps) => {
|
||||
)}
|
||||
{isCommentBySelf && !isMock && !resolved
|
||||
? (
|
||||
<DropdownLegacy
|
||||
<Dropdown
|
||||
overlay={(
|
||||
<Menu>
|
||||
<MenuItem key="edit" onClick={() => onEditingChange?.(true)}>{localeService.t('threadCommentUI.item.edit')}</MenuItem>
|
||||
<MenuItem key="delete" onClick={handleDeleteItem}>{localeService.t('threadCommentUI.item.delete')}</MenuItem>
|
||||
</Menu>
|
||||
<div className="univer-rounded-lg univer-p-4 univer-theme">
|
||||
<ul
|
||||
className={`
|
||||
univer-m-0 univer-grid univer-list-none univer-gap-2 univer-p-0
|
||||
univer-text-sm
|
||||
[&_a]:univer-cursor-pointer [&_a]:univer-rounded [&_a]:univer-p-1
|
||||
`}
|
||||
>
|
||||
<li>
|
||||
<a
|
||||
className="hover:univer-bg-gray-200"
|
||||
onClick={() => onEditingChange?.(true)}
|
||||
>
|
||||
{localeService.t('threadCommentUI.item.edit')}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
className="hover:univer-bg-gray-200"
|
||||
onClick={handleDeleteItem}
|
||||
>
|
||||
{localeService.t('threadCommentUI.item.delete')}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
<div className={styles.threadCommentIcon}>
|
||||
<MoreHorizontalSingle />
|
||||
</div>
|
||||
</DropdownLegacy>
|
||||
</Dropdown>
|
||||
)
|
||||
: null}
|
||||
</div>
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import canUseDom from 'rc-util/lib/Dom/canUseDom';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import type { Nullable } from '@univerjs/core';
|
||||
import { resizeObserverCtor } from '@univerjs/design';
|
||||
|
||||
import canUseDom from 'rc-util/lib/Dom/canUseDom';
|
||||
import { useEffect } from 'react';
|
||||
import { useEvent } from './event';
|
||||
/**
|
||||
* These hooks are used for browser layout
|
||||
@@ -40,12 +40,12 @@ export function useScrollYOverContainer(element: Nullable<HTMLElement>, containe
|
||||
|
||||
const elStyle = element.style;
|
||||
const elRect = element.getBoundingClientRect();
|
||||
const { y } = elRect;
|
||||
const { y, height } = elRect;
|
||||
const containerRect = container.getBoundingClientRect();
|
||||
|
||||
const scrolled = element.scrollHeight > elRect.height;
|
||||
const scrolled = element.scrollHeight > height;
|
||||
|
||||
const isOverViewport = y < 0 || (y + elRect.height > containerRect.height);
|
||||
const isOverViewport = y < 0 || (y + height > containerRect.height);
|
||||
|
||||
if (!isOverViewport && !scrolled) {
|
||||
elStyle.overflowY = '';
|
||||
@@ -54,7 +54,7 @@ export function useScrollYOverContainer(element: Nullable<HTMLElement>, containe
|
||||
}
|
||||
|
||||
if (isOverViewport) {
|
||||
elStyle.overflowY = 'scroll';
|
||||
elStyle.overflowY = 'auto';
|
||||
elStyle.maxHeight = y < 0 ? `${element.scrollHeight + y}px` : `${containerRect.height - y}px`;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -18,3 +18,4 @@ export * from './custom-label';
|
||||
export * from './font-family';
|
||||
export * from './font-size';
|
||||
export { useScrollYOverContainer } from './hooks/layout';
|
||||
export { type ISliderProps, Slider } from './slider';
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type {
|
||||
MenuRef } from '@univerjs/design';
|
||||
import type {
|
||||
IDisplayMenuItem,
|
||||
IMenuButtonItem,
|
||||
@@ -186,9 +188,15 @@ export const Menu = (props: IBaseMenuProps) => {
|
||||
|
||||
useScrollYOverContainer(overViewport === 'scroll' ? menuEl : null, layoutService.rootContainerElement);
|
||||
|
||||
function handleSetMenuEl(ref: MenuRef | null) {
|
||||
if (ref) {
|
||||
setMenuEl(ref.list);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<DesignMenu
|
||||
ref={(ref) => ref?.list && setMenuEl(ref.list)}
|
||||
ref={handleSetMenuEl}
|
||||
selectable={false}
|
||||
>
|
||||
<MenuOptionsWrapper {...restProps} />
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
import type { Meta } from '@storybook/react';
|
||||
import { Button } from '@univerjs/design';
|
||||
import React from 'react';
|
||||
|
||||
import { Notification, notification } from './Notification';
|
||||
|
||||
|
||||
+43
-39
@@ -14,16 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { LocaleService } from '@univerjs/core';
|
||||
import { Button, clsx, Dropdown, Tooltip } from '@univerjs/design';
|
||||
import { CheckMarkSingle, IncreaseSingle, ReduceSingle } from '@univerjs/icons';
|
||||
import clsx from 'clsx';
|
||||
import React, { useContext, useMemo, useRef } from 'react';
|
||||
|
||||
import { Button } from '../button/Button';
|
||||
import { ConfigContext } from '../config-provider/ConfigProvider';
|
||||
import { DropdownOverlay } from '../dropdown/DropdownOverlay';
|
||||
import { DropdownProvider } from '../dropdown/DropdownProvider';
|
||||
import { DropdownTrigger } from '../dropdown/DropdownTrigger';
|
||||
import { Tooltip } from '../tooltip/Tooltip';
|
||||
import { useDependency } from '@wendellhu/redi/react-bindings';
|
||||
import React, { useMemo, useRef, useState } from 'react';
|
||||
import styles from './index.module.less';
|
||||
|
||||
export interface ISliderProps {
|
||||
@@ -65,11 +60,12 @@ export interface ISliderProps {
|
||||
* Slider Component
|
||||
*/
|
||||
export function Slider(props: ISliderProps) {
|
||||
const localeService = useDependency(LocaleService);
|
||||
|
||||
const { value, min = 0, max = 400, disabled = false, resetPoint = 100, shortcuts, onChange } = props;
|
||||
|
||||
const sliderInnerRailRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const { locale } = useContext(ConfigContext);
|
||||
const [zoomListVisible, setZoomListVisible] = useState(false);
|
||||
|
||||
function handleReset() {
|
||||
if (disabled) return;
|
||||
@@ -147,6 +143,13 @@ export function Slider(props: ISliderProps) {
|
||||
window.addEventListener('pointerout', onMouseOut);
|
||||
}
|
||||
|
||||
function handleSelectZoomLevel(value: number) {
|
||||
if (disabled) return;
|
||||
|
||||
setZoomListVisible(false);
|
||||
onChange && onChange(value);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(styles.slider, {
|
||||
@@ -159,13 +162,13 @@ export function Slider(props: ISliderProps) {
|
||||
|
||||
<div className={styles.sliderRail}>
|
||||
<div ref={sliderInnerRailRef} role="track" className={styles.sliderInnerRail}>
|
||||
<Tooltip title={`${locale?.Slider.resetTo} ${resetPoint}%`} placement="top" asChild>
|
||||
<Tooltip title={`${localeService.t('zoom-slider.resetTo')} ${resetPoint}%`} placement="top" asChild>
|
||||
<a
|
||||
key="reset-button"
|
||||
className={`
|
||||
univer-cursor-pointer univer-absolute univer-left-1/2 univer-top-1/2
|
||||
-univer-translate-x-1/2 -univer-translate-y-1/2 univer-box-border univer-w-0.5
|
||||
univer-h-0.5 univer-bg-white univer-rounded-full univer-block
|
||||
univer-absolute univer-left-1/2 univer-top-1/2 univer-box-border univer-block univer-h-0.5
|
||||
univer-w-0.5 -univer-translate-x-1/2 -univer-translate-y-1/2 univer-cursor-pointer
|
||||
univer-rounded-full univer-bg-white
|
||||
`}
|
||||
role="button"
|
||||
onClick={handleReset}
|
||||
@@ -187,44 +190,32 @@ export function Slider(props: ISliderProps) {
|
||||
<IncreaseSingle />
|
||||
</Button>
|
||||
|
||||
<DropdownProvider>
|
||||
<DropdownTrigger>
|
||||
<a
|
||||
className={`
|
||||
univer-text-gray-800 univer-h-7 univer-text-sm univer-flex univer-items-center
|
||||
univer-cursor-pointer univer-rounded univer-transition-all univer-w-[55px]
|
||||
univer-justify-center
|
||||
hover:univer-bg-gray-100
|
||||
`}
|
||||
>
|
||||
{value}
|
||||
%
|
||||
</a>
|
||||
</DropdownTrigger>
|
||||
<DropdownOverlay offset={{ y: -20 }}>
|
||||
<Dropdown
|
||||
align="end"
|
||||
overlay={(
|
||||
<div
|
||||
className={`
|
||||
univer-gap-1 univer-items-center univer-w-32 univer-p-2 univer-text-sm univer-text-gray-800
|
||||
univer-box-border univer-grid
|
||||
univer-box-border univer-grid univer-w-32 univer-items-center univer-gap-1 univer-p-2
|
||||
univer-text-sm univer-text-gray-800
|
||||
`}
|
||||
>
|
||||
{shortcuts?.map((item) => (
|
||||
<a
|
||||
key={item}
|
||||
className={clsx(`
|
||||
univer-cursor-pointer univer-rounded-md univer-transition-colors univer-duration-200
|
||||
univer-px-2 univer-py-1 univer-relative univer-text-center
|
||||
univer-relative univer-cursor-pointer univer-rounded-md univer-px-2 univer-py-1
|
||||
univer-text-center univer-transition-colors univer-duration-200
|
||||
hover:univer-bg-gray-100
|
||||
`, {
|
||||
'univer-bg-gray-100': item === value,
|
||||
})}
|
||||
onClick={() => onChange && onChange(item)}
|
||||
onClick={() => handleSelectZoomLevel(item)}
|
||||
>
|
||||
{item === value && (
|
||||
<span
|
||||
className={`
|
||||
univer-text-green-500 univer-absolute univer-left-2 univer-top-0 univer-h-full
|
||||
univer-items-center univer-flex
|
||||
univer-absolute univer-left-2 univer-top-0 univer-flex univer-h-full
|
||||
univer-items-center univer-text-green-500
|
||||
`}
|
||||
>
|
||||
<CheckMarkSingle />
|
||||
@@ -237,8 +228,21 @@ export function Slider(props: ISliderProps) {
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</DropdownOverlay>
|
||||
</DropdownProvider>
|
||||
)}
|
||||
open={zoomListVisible}
|
||||
onOpenChange={setZoomListVisible}
|
||||
>
|
||||
<a
|
||||
className={`
|
||||
univer-flex univer-h-7 univer-w-[55px] univer-cursor-pointer univer-items-center
|
||||
univer-justify-center univer-rounded univer-text-sm univer-text-gray-800 univer-transition-all
|
||||
hover:univer-bg-gray-100
|
||||
`}
|
||||
>
|
||||
{value}
|
||||
%
|
||||
</a>
|
||||
</Dropdown>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user