Skip to content

feat(md): Markdown MD 编辑器支持自定义配置工具栏 #1862 #1874

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 3, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions packages/devui-vue/devui/editor-md/src/components/toolbar.tsx
Original file line number Diff line number Diff line change
@@ -6,20 +6,20 @@ import './toolbar.scss';
export default defineComponent({
name: 'DMdToolbar',
setup() {
const { toolbars, toolbarConfig } = useToolbar();

const { toolbars, toolbarConfig, customToolbars } = useToolbar();
const tempToolbars = { ...toolbars, ...customToolbars?.value };
return () => (
<div class="md-toolbar-container">
{toolbarConfig.value.map((item, index) =>
Array.isArray(item) ? (
<>
{item.map((key, idx) => (
<ToolbarItem config={toolbars[key]} key={`${index}-${idx}`} />
<ToolbarItem config={tempToolbars[key]} key={`${index}-${idx}`} />
))}
<span class="md-toolbar-span"></span>
</>
) : (
<ToolbarItem config={toolbars[item]} key={index} />
<ToolbarItem config={tempToolbars[item]} key={index} />
)
)}
</div>
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ import { inject } from 'vue';
import { EditorMdInjectionKey, IEditorMdInjection } from '../editor-md-types';

export function useToolbar() {
const { toolbars, toolbarConfig } = inject(EditorMdInjectionKey) as IEditorMdInjection;
const { toolbars, toolbarConfig, customToolbars } = inject(EditorMdInjectionKey) as IEditorMdInjection;

return { toolbars, toolbarConfig };
return { toolbars, toolbarConfig, customToolbars };
}
Original file line number Diff line number Diff line change
@@ -414,8 +414,10 @@ export function useEditorMd(props: EditorMdProps, ctx: SetupContext) {
renderRef,
containerRef,
toolbars,
toolbarConfig,
previewHtmlList,
isHintShow,
customToolbars,
getEditorIns,
onPaste,
previewContentChange,
1 change: 1 addition & 0 deletions packages/devui-vue/devui/editor-md/src/editor-md-types.ts
Original file line number Diff line number Diff line change
@@ -136,6 +136,7 @@ export interface IEditorMdInjection {
showFullscreen: Ref<boolean>;
toolbars: Record<string, IToolbarItemConfig>;
toolbarConfig: Ref<ToolbarConfigProp>;
customToolbars: Ref<Record<string, IToolbarItemConfig> | undefined> | undefined;
getEditorIns: () => any;
t: (name: string) => string;
}
2 changes: 2 additions & 0 deletions packages/devui-vue/devui/editor-md/src/editor-md.tsx
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@ export default defineComponent({
const {
mode,
toolbarConfig,
customToolbars,
editorContainerHeight,
hidePreviewView,
placeholder,
@@ -66,6 +67,7 @@ export default defineComponent({
showFullscreen,
toolbars,
toolbarConfig,
customToolbars,
getEditorIns,
t: locale,
});
2 changes: 1 addition & 1 deletion packages/devui-vue/devui/editor-md/src/utils.ts
Original file line number Diff line number Diff line change
@@ -84,5 +84,5 @@ export function locale(key: string): string {
loading: '正在加载中...',
pasting: '您粘贴内容较多, 正在努力加载中,请耐心等待...',
};
return localeMap[key];
return localeMap[key] || key;
}
81 changes: 80 additions & 1 deletion packages/devui-vue/docs/components/editor-md/index.md
Original file line number Diff line number Diff line change
@@ -88,6 +88,64 @@ export default defineComponent({
});
</script>
```
:::

### 自定义工具栏

:::demo 自定义编辑器的工具栏

```vue
<template>
<d-editor-md v-model="content" :toolbar-config="toolbarConfig" :custom-toolbars="customToolbars"></d-editor-md>
</template>

<script>
import { defineComponent, ref } from 'vue';

export default defineComponent({
setup() {
const content = ref('');
const toolbarConfig = ['add',
['undo', 'redo'],
['h1', 'h2', 'bold', 'italic', 'strike', 'underline', 'color', 'font'],
['ul', 'ol', 'checklist', 'code', 'link', 'image', 'table'],
'fullscreen',
];
const customToolbars = {
add: {
id: 'add',
name: '新增',
exitName: '新增',
type: 'button',
icon: `<span>+</span>`,
shortKey: 'ALT+K',
handler: () => {
console.log('自定义工具点击事件');
},
},
undo: {
id: 'undo',
name: '撤销',
exitName: '撤销',
type: 'button',
icon: `<svg width="16px" height="14px" viewBox="0 0 16 14">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g fill="#293040">
<path d="M11,5 C13.7614237,5 16,7.23857625 16,10 C16,12.7614237 13.7614237,15 11,15 L7,15 L7,14 L11,14 C13.209139,14 15,12.209139 15,10 C15,7.790861 13.209139,6 11,6 L5,6 L5,10 L0,5.5 L5,1 L5,5 L11,5 Z" id="路径"></path>
</g>
</g>
</svg>`,
shortKey: 'Ctrl+M',
handler: () => {
console.log('覆盖原有工具栏功能事件');
},
}
};
return { content, toolbarConfig, customToolbars };
},
});
</script>
```

:::

@@ -629,7 +687,9 @@ Bob-->>John: Jolly good!
| placeholder | `string` | '' | 编辑器无内容是的提示信息 |
| fullscreen-z-index | `number` | 10 | 编辑器全屏状态的 z-index |
| image-upload-to-server | `boolean` | false | 是否打开图片自定义上传开关(打开后将将监听图片的复制,toolbar 图片功能上传,传出事件回调) |
|editor-container-height|`number`|--|可选,编辑器内容区高度||
| editor-container-height| `number`|--|可选,编辑器内容区高度 ||
| toolbar-config | `Array(string)` |`[['undo', 'redo'],['h1', 'h2', 'bold', 'italic', 'strike', 'underline', 'color', 'font'],['ul', 'ol', 'checklist', 'code', 'link', 'image', 'table'],'fullscreen']`|展示在toolbar工具栏处的按钮,用[]包起来的表示是同一组,不同组的会有线隔开。也可以自定义,自定义时需要配置参数custom-toolbars ||
| custom-toolbars | {[IToolbarItemConfig](#itoolbaritemconfig)} |--|配置toolbar-config中对应按钮的具体设置 [自定义工具栏](#自定义工具栏) | |

### EditorMd 事件

@@ -696,3 +756,22 @@ export interface HintConfig {
[key: string]: HintConfigItem; // key为触发提示前缀配置
}
```


### IToolbarItemConfig
```ts
export interface IToolbarItemConfig {
id: string;
name?: string;
exitName?: string;
type?: 'button' | 'dropDown';
icon?: string;
exitIcon?: string;
template?: any;
component?: any;
shortKey?: string;
params?: { [key: string]: any };
handler?(editor?: any, params?: any): void;
}
const toolbars = Record<string, IToolbarItemConfig>
```