Skip to content

Commit

Permalink
feat(context-menu): update context-menu docs, details, styles
Browse files Browse the repository at this point in the history
  • Loading branch information
liujuping authored and JackLian committed Jan 11, 2024
1 parent 3e7d199 commit bb5d7dd
Show file tree
Hide file tree
Showing 10 changed files with 254 additions and 75 deletions.
62 changes: 62 additions & 0 deletions docs/docs/api/commonUI.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,70 @@ CommonUI API 是一个专为低代码引擎设计的组件 UI 库,使用它开
| condition | 显示条件函数<br/>Function to determine display condition | (nodes: IPublicModelNode[]) => boolean (optional) | |
| disabled | 禁用条件函数,可选<br/>Function to determine disabled condition, optional | (nodes: IPublicModelNode[]) => boolean (optional) | |

**ContextMenu 示例**

```typescript
const App = () => {
const menuItems: IPublicTypeContextMenuAction[] = [
{
name: 'a',
title: '选项 1',
action: () => console.log('选项 1 被点击'),
},
{
name: 'b',
title: '选项 2',
action: () => console.log('选项 2 被点击'),
},
];

const ContextMenu = ctx.commonUI.ContextMenu;

return (
<div>
<ContextMenu menus={menuItems}>
<div>右键点击这里</div>
</ContextMenu>
</div>
);
};

export default App;
```

**ContextMenu.create 示例**

```typescript
const App = () => {
const menuItems: IPublicTypeContextMenuAction[] = [
{
name: 'a',
title: '选项 1',
action: () => console.log('选项 1 被点击'),
},
{
name: 'b',
title: '选项 2',
action: () => console.log('选项 2 被点击'),
},
];

const ContextMenu = ctx.commonUI.ContextMenu;

return (
<div>
<div onClick={(e) => {
ContextMenu.create(menuItems, e);
}}>点击这里</div>
</div>
);
};

export default App;
```

### Balloon

详细文档: [Balloon Documentation](https://fusion.design/pc/component/balloon)

### Breadcrumb
Expand Down
46 changes: 46 additions & 0 deletions docs/docs/api/material.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,33 @@ material.modifyBuiltinComponentAction('remove', (action) => {
addContextMenuOption(action: IPublicTypeContextMenuAction): void;
```

示例

```typescript
import { IPublicEnumContextMenuType } from '@alilc/lowcode-types';

material.addContextMenuOption({
name: 'parentItem',
title: 'Parent Item',
condition: (nodes) => true,
items: [
{
name: 'childItem1',
title: 'Child Item 1',
action: (nodes) => console.log('Child Item 1 clicked', nodes),
condition: (nodes) => true
},
// 分割线
{
type: IPublicEnumContextMenuType.SEPARATOR
name: 'separator.1'
}
// 更多子菜单项...
]
});

```

#### removeContextMenuOption

删除特定右键菜单项
Expand All @@ -274,7 +301,26 @@ removeContextMenuOption(name: string): void;
adjustContextMenuLayout(fn: (actions: IPublicTypeContextMenuItem[]) => IPublicTypeContextMenuItem[]): void;
```

**示例**

通过 adjustContextMenuLayout 补充分割线

```typescript
material.adjustContextMenuLayout((actions: IPublicTypeContextMenuAction) => {
const names = ['a', 'b'];
const newActions = [];
actions.forEach(d => {
newActions.push(d);
if (names.include(d.name)) {
newActions.push({ type: 'separator' })
}
});
return newActions
})
```

### 物料元数据

#### getComponentMeta
获取指定名称的物料元数据

Expand Down
11 changes: 9 additions & 2 deletions packages/designer/src/context-menu-actions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IPublicTypeContextMenuAction, IPublicEnumContextMenuType, IPublicTypeContextMenuItem, IPublicApiMaterial } from '@alilc/lowcode-types';
import { IPublicTypeContextMenuAction, IPublicEnumContextMenuType, IPublicTypeContextMenuItem, IPublicApiMaterial, IPublicModelPluginContext } from '@alilc/lowcode-types';
import { IDesigner, INode } from './designer';
import { createContextMenu, parseContextMenuAsReactNode, parseContextMenuProperties, uniqueId } from '@alilc/lowcode-utils';
import { Menu } from '@alifd/next';
Expand Down Expand Up @@ -48,6 +48,7 @@ export class GlobalContextMenuActions {
event.preventDefault();

const actions: IPublicTypeContextMenuAction[] = [];
let contextMenu: ContextMenuActions = this.contextMenuActionsMap.values().next().value;
this.contextMenuActionsMap.forEach((contextMenu) => {
actions.push(...contextMenu.actions);
});
Expand All @@ -57,11 +58,13 @@ export class GlobalContextMenuActions {
const destroy = () => {
destroyFn?.();
};
const pluginContext: IPublicModelPluginContext = contextMenu.designer.editor.get('pluginContext') as IPublicModelPluginContext;

const menus: IPublicTypeContextMenuItem[] = parseContextMenuProperties(actions, {
nodes: [],
destroy,
event,
pluginContext,
});

if (!menus.length) {
Expand All @@ -73,6 +76,7 @@ export class GlobalContextMenuActions {
const menuNode = parseContextMenuAsReactNode(layoutMenu, {
destroy,
nodes: [],
pluginContext,
});

const target = event.target;
Expand Down Expand Up @@ -160,10 +164,13 @@ export class ContextMenuActions implements IContextMenuActions {
destroyFn?.();
};

const pluginContext: IPublicModelPluginContext = this.designer.editor.get('pluginContext') as IPublicModelPluginContext;

const menus: IPublicTypeContextMenuItem[] = parseContextMenuProperties(actions, {
nodes: nodes.map(d => designer.shellModelFactory.createNode(d)!),
destroy,
event,
pluginContext,
});

if (!menus.length) {
Expand All @@ -175,7 +182,7 @@ export class ContextMenuActions implements IContextMenuActions {
const menuNode = parseContextMenuAsReactNode(layoutMenu, {
destroy,
nodes: nodes.map(d => designer.shellModelFactory.createNode(d)!),
designer,
pluginContext,
});

destroyFn = createContextMenu(menuNode, {
Expand Down
4 changes: 2 additions & 2 deletions packages/engine/src/engine-core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,11 @@ const innerSetters = new InnerSetters();
const setters = new Setters(innerSetters);

const material = new Material(editor);
const commonUI = new CommonUI();
const commonUI = new CommonUI(editor);
editor.set('project', project);
editor.set('setters' as any, setters);
editor.set('material', material);
editor.set('innerHotkey', innerHotkey);
editor.set('commonUI' as any, commonUI);
const config = new Config(engineConfig);
const event = new Event(commonEvent, { prefix: 'common' });
const logger = new Logger({ level: 'warn', bizName: 'common' });
Expand All @@ -147,6 +146,7 @@ const pluginContextApiAssembler: ILowCodePluginContextApiAssembler = {
context.commonUI = commonUI;
context.registerLevel = IPublicEnumPluginRegisterLevel.Default;
context.isPluginRegisteredInWorkspace = false;
editor.set('pluginContext', context);
},
};

Expand Down
21 changes: 6 additions & 15 deletions packages/engine/src/inner-plugins/default-context-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,18 @@ import {
IPublicModelNode,
IPublicModelPluginContext,
IPublicTypeDragNodeDataObject,
IPublicTypeI18nData,
IPublicTypeNodeSchema,
} from '@alilc/lowcode-types';
import { isI18nData, isProjectSchema } from '@alilc/lowcode-utils';
import { isProjectSchema } from '@alilc/lowcode-utils';
import { Notification } from '@alifd/next';
import { intl, getLocale } from '../locale';
import { intl } from '../locale';

function getNodesSchema(nodes: IPublicModelNode[]) {
const componentsTree = nodes.map((node) => node?.exportSchema(IPublicEnumTransformStage.Clone));
const data = { type: 'nodeSchema', componentsMap: {}, componentsTree };
return data;
}

function getIntlStr(data: string | IPublicTypeI18nData) {
if (!isI18nData(data)) {
return data;
}

const locale = getLocale();
return data[locale] || data['zh-CN'] || data['zh_CN'] || data['en-US'] || data['en_US'] || '';
}

async function getClipboardText(): Promise<IPublicTypeNodeSchema[]> {
return new Promise((resolve, reject) => {
// 使用 Clipboard API 读取剪贴板内容
Expand Down Expand Up @@ -61,8 +51,9 @@ async function getClipboardText(): Promise<IPublicTypeNodeSchema[]> {
}

export const defaultContextMenu = (ctx: IPublicModelPluginContext) => {
const { material, canvas } = ctx;
const { material, canvas, common } = ctx;
const { clipboard } = canvas;
const { intl: utilsIntl } = common.utils;

return {
init() {
Expand Down Expand Up @@ -150,7 +141,7 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => {
});
if (canAddNodes.length === 0) {
Notification.open({
content: `${nodeSchema.map(d => getIntlStr(d.title || d.componentName)).join(',')}等组件无法放置到${getIntlStr(parent.title || parent.componentName as any)}内`,
content: `${nodeSchema.map(d => utilsIntl(d.title || d.componentName)).join(',')}等组件无法放置到${utilsIntl(parent.title || parent.componentName as any)}内`,
type: 'error',
});
return;
Expand Down Expand Up @@ -198,7 +189,7 @@ export const defaultContextMenu = (ctx: IPublicModelPluginContext) => {
});
if (canAddNodes.length === 0) {
Notification.open({
content: `${nodeSchema.map(d => getIntlStr(d.title || d.componentName)).join(',')}等组件无法放置到${getIntlStr(node.title || node.componentName as any)}内`,
content: `${nodeSchema.map(d => utilsIntl(d.title || d.componentName)).join(',')}等组件无法放置到${utilsIntl(node.title || node.componentName as any)}内`,
type: 'error',
});
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { IPublicApiCommonUI } from '@alilc/lowcode-types';
import { IPublicApiCommonUI, IPublicModelPluginContext, IPublicTypeContextMenuAction } from '@alilc/lowcode-types';
import {
IEditor,
Tip as InnerTip,
Title as InnerTitle,
} from '@alilc/lowcode-editor-core';
import { Balloon, Breadcrumb, Button, Card, Checkbox, DatePicker, Dialog, Dropdown, Form, Icon, Input, Loading, Message, Overlay, Pagination, Radio, Search, Select, SplitButton, Step, Switch, Tab, Table, Tree, TreeSelect, Upload, Divider } from '@alifd/next';
import { ContextMenu } from '../components/context-menu';
import { editorSymbol } from '../symbols';

export class CommonUI implements IPublicApiCommonUI {
[editorSymbol]: IEditor;

Balloon = Balloon;
Breadcrumb = Breadcrumb;
Button = Button;
Expand Down Expand Up @@ -35,13 +39,29 @@ export class CommonUI implements IPublicApiCommonUI {
Upload = Upload;
Divider = Divider;

constructor(editor: IEditor) {
this[editorSymbol] = editor;
}

get Tip() {
return InnerTip;
}
get Title() {
return InnerTitle;
}

get ContextMenu() {
return ContextMenu;
const editor = this[editorSymbol];
const innerContextMenu = (props: any) => {
const pluginContext: IPublicModelPluginContext = editor.get('pluginContext') as IPublicModelPluginContext;
return <ContextMenu {...props} pluginContext={pluginContext} />;
};

innerContextMenu.create = (menus: IPublicTypeContextMenuAction[], event: MouseEvent) => {
const pluginContext: IPublicModelPluginContext = editor.get('pluginContext') as IPublicModelPluginContext;
return ContextMenu.create(pluginContext, menus, event);
};

return innerContextMenu;
}
}
28 changes: 24 additions & 4 deletions packages/shell/src/components/context-menu.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { createContextMenu, parseContextMenuAsReactNode, parseContextMenuProperties } from '@alilc/lowcode-utils';
import { engineConfig } from '@alilc/lowcode-editor-core';
import { IPublicTypeContextMenuAction } from '@alilc/lowcode-types';
import { IPublicModelPluginContext, IPublicTypeContextMenuAction } from '@alilc/lowcode-types';
import React from 'react';

export function ContextMenu({ children, menus }: {
export function ContextMenu({ children, menus, pluginContext }: {
menus: IPublicTypeContextMenuAction[];
children: React.ReactElement[] | React.ReactElement;
pluginContext: IPublicModelPluginContext;
}): React.ReactElement<any, string | React.JSXElementConstructor<any>> {
if (!engineConfig.get('enableContextMenu')) {
return (
Expand All @@ -23,7 +24,10 @@ export function ContextMenu({ children, menus }: {
};
const children: React.ReactNode[] = parseContextMenuAsReactNode(parseContextMenuProperties(menus, {
destroy,
}));
pluginContext,
}), {
pluginContext,
});

if (!children?.length) {
return;
Expand All @@ -44,4 +48,20 @@ export function ContextMenu({ children, menus }: {
return (
<>{childrenWithContextMenu}</>
);
}
}

ContextMenu.create = (pluginContext: IPublicModelPluginContext, menus: IPublicTypeContextMenuAction[], event: MouseEvent) => {
const children: React.ReactNode[] = parseContextMenuAsReactNode(parseContextMenuProperties(menus, {
pluginContext,
}), {
pluginContext,
});

if (!children?.length) {
return;
}

return createContextMenu(children, {
event,
});
};
Loading

0 comments on commit bb5d7dd

Please sign in to comment.