diff --git a/CHANGELOG.md b/CHANGELOG.md index 8714ed8e8050b0be8abbb98faf24cb445b361696..8e053620967ba09327e900c2fc4e395889d600dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ ## [Unreleased] +### Added + +- 添加富文本编辑器 + ## [0.0.24] - 2024-09-29 ### Added diff --git a/ibiz.config.ts b/ibiz.config.ts index 56e7040acfce1635e981877697b8596d1d251d09..8dca4ea034bc7bfa1a9ef7e93c6345ae0bf52d7c 100644 --- a/ibiz.config.ts +++ b/ibiz.config.ts @@ -40,6 +40,7 @@ export default defineConfig({ 'qx-util', 'pinia', 'cherry-markdown', + 'quill', '@ibiz-template/mob-theme', '@ibiz-template-package/vs-tree-ex', '@ibiz-template/core', diff --git a/package.json b/package.json index 980a80f866a25338dbbff5bd1c39665a5d434497..54af765d9fd665dad75e4b33a5150ec933f1c4ff 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "pinia": "^2.1.7", "qs": "^6.11.2", "qx-util": "^0.4.8", + "quill": "^2.0.2", "ramda": "^0.29.1", "rolldate": "^3.1.3", "vant": "^4.7.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bd8ebef8d7405bbae67a5cbd1b25f0d3491978d7..d8ddb316b52d1f0ecc808c552ec714f10908c29f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,7 +13,7 @@ dependencies: version: 0.7.35-alpha.1(axios@1.6.2)(lodash-es@4.17.21)(qs@6.11.2)(qx-util@0.4.8)(ramda@0.29.1) '@ibiz-template/mob-theme': specifier: ^0.2.13 - version: 0.2.13(@ibiz-template/core@0.7.35-alpha.1)(@ibiz/model-core@0.1.55)(async-validator@4.2.5)(dayjs@1.11.10)(echarts@5.4.3)(handlebars@4.7.8)(lodash-es@4.17.21)(mqtt@2.18.9)(path-browserify@1.0.1)(qs@6.11.2)(qx-util@0.4.8)(ramda@0.29.1) + version: 0.2.14(@ibiz-template/core@0.7.35-alpha.1)(@ibiz/model-core@0.1.55)(async-validator@4.2.5)(dayjs@1.11.10)(echarts@5.4.3)(handlebars@4.7.8)(lodash-es@4.17.21)(mqtt@2.18.9)(path-browserify@1.0.1)(qs@6.11.2)(qx-util@0.4.8)(ramda@0.29.1) '@ibiz-template/model-helper': specifier: 0.7.38-alpha.13 version: 0.7.38-alpha.13(@ibiz-template/runtime@0.7.38-alpha.13)(ramda@0.29.1) @@ -50,6 +50,9 @@ dependencies: qs: specifier: ^6.11.2 version: 6.11.2 + quill: + specifier: ^2.0.2 + version: 2.0.2 qx-util: specifier: ^0.4.8 version: 0.4.8 @@ -1164,7 +1167,7 @@ packages: dev: true /@ibiz-template/core@0.7.35-alpha.1(axios@1.6.2)(lodash-es@4.17.21)(qs@6.11.2)(qx-util@0.4.8)(ramda@0.29.1): - resolution: {integrity: sha512-EjFKX9vMkM61kfEQRG1cBy1bU9vAPFoPN2rDdqB2jzKdiEQXp6jtSSUZn6nJhWyZu18CiEHyAGFlZ3B50pm53A==} + resolution: {integrity: sha512-GVPvZLfrxPGnZtbp3FOoU6p8tO2r/0eMHUH4SaQrQJBNE3eSlpkEO2NjRE1CnHlSQO9C7C7PvlRTzgtBD0TiTA==} peerDependencies: axios: ^1.4.0 lodash-es: ^4.17.21 @@ -1182,8 +1185,8 @@ packages: ramda: 0.29.1 dev: false - /@ibiz-template/mob-theme@0.2.13(@ibiz-template/core@0.7.35-alpha.1)(@ibiz/model-core@0.1.55)(async-validator@4.2.5)(dayjs@1.11.10)(echarts@5.4.3)(handlebars@4.7.8)(lodash-es@4.17.21)(mqtt@2.18.9)(path-browserify@1.0.1)(qs@6.11.2)(qx-util@0.4.8)(ramda@0.29.1): - resolution: {integrity: sha512-B80HAxirLHkNF7QEwxRivFk9KarzaGhy9hIqvn8DU7V1yPNbnqVcCYycBoHyJu5riDxSul4db207CkaoOBjeSg==} + /@ibiz-template/mob-theme@0.2.14(@ibiz-template/core@0.7.35-alpha.1)(@ibiz/model-core@0.1.55)(async-validator@4.2.5)(dayjs@1.11.10)(echarts@5.4.3)(handlebars@4.7.8)(lodash-es@4.17.21)(mqtt@2.18.9)(path-browserify@1.0.1)(qs@6.11.2)(qx-util@0.4.8)(ramda@0.29.1): + resolution: {integrity: sha512-sywecC1JgL5yYkOhMm0snn4D/aSQ9lFHbuuWKpF6juiksbSKI3/WeSDOrzML5gxqXS6Mfj9dg+G0intkcQthvw==} dependencies: '@ibiz-template/runtime': 0.4.16(@ibiz-template/core@0.7.35-alpha.1)(@ibiz/model-core@0.1.55)(async-validator@4.2.5)(dayjs@1.11.10)(echarts@5.4.3)(handlebars@4.7.8)(lodash-es@4.17.21)(mqtt@2.18.9)(path-browserify@1.0.1)(qs@6.11.2)(qx-util@0.4.8)(ramda@0.29.1) transitivePeerDependencies: @@ -4156,7 +4159,6 @@ packages: /eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} - dev: true /execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} @@ -4280,7 +4282,6 @@ packages: /fast-diff@1.3.0: resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} - dev: true /fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} @@ -5822,7 +5823,10 @@ packages: /lodash.clonedeep@4.5.0: resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} - dev: true + + /lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + dev: false /lodash.isfunction@3.0.9: resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==} @@ -6498,6 +6502,10 @@ packages: engines: {node: '>=6'} dev: true + /parchment@3.0.0: + resolution: {integrity: sha512-HUrJFQ/StvgmXRcQ1ftY6VEZUq3jA2t9ncFN4F84J/vN0/FPpQF+8FKXb3l6fLces6q0uOHj6NJn+2xvZnxO6A==} + dev: false + /parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -6835,6 +6843,25 @@ packages: engines: {node: '>=10'} dev: true + /quill-delta@5.1.0: + resolution: {integrity: sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==} + engines: {node: '>= 12.0.0'} + dependencies: + fast-diff: 1.3.0 + lodash.clonedeep: 4.5.0 + lodash.isequal: 4.5.0 + dev: false + + /quill@2.0.2: + resolution: {integrity: sha512-QfazNrhMakEdRG57IoYFwffUIr04LWJxbS/ZkidRFXYCQt63c1gK6Z7IHUXMx/Vh25WgPBU42oBaNzQ0K1R/xw==} + engines: {npm: '>=8.2.3'} + dependencies: + eventemitter3: 5.0.1 + lodash-es: 4.17.21 + parchment: 3.0.0 + quill-delta: 5.1.0 + dev: false + /qx-util@0.4.8: resolution: {integrity: sha512-QSaMIyccyPEZZytdHDqadsFp06m36FBX9nkwUmfD15EZ7hibSj4yO9bLBKuVwCDKnMV2w0QL2qHDsLV5b5rY1Q==} dev: false diff --git a/src/editor/html/html-editor.controller.ts b/src/editor/html/html-editor.controller.ts new file mode 100644 index 0000000000000000000000000000000000000000..55e4f79a692840692205becf05817ff1f326ce30 --- /dev/null +++ b/src/editor/html/html-editor.controller.ts @@ -0,0 +1,114 @@ +import { EditorController, ScriptFactory } from '@ibiz-template/runtime'; +import { IHtml } from '@ibiz/model-core'; + +/** + * html框编辑器控制器 + * + * @export + * @class HtmlEditorController + * @extends {EditorController} + */ +export class HtmlEditorController extends EditorController { + /** + * 上传参数 + */ + public uploadParams?: IParams; + + /** + * 下载参数 + */ + public exportParams?: IParams; + + /** + * @description 是否显示工具栏 + * @type {boolean} + * @memberof HtmlEditorController + */ + public showToolbar: boolean = true; + + /** + * @description 值模式(暂时只支持html模式,text模式存在问题) + * @type {('text' | 'html')} + * @memberof HtmlEditorController + */ + public valueMode: 'text' | 'html' = 'html'; + + /** + * @description 图片模式 + * @type {('base64' | 'file')} + * @memberof HtmlEditorController + */ + public imageMode: 'base64' | 'file' = 'file'; + + /** + * @description quill配置 + * @type {IData} + * @memberof HtmlEditorController + */ + public modules: IData = { + toolbar: [ + [{ header: [1, 2, 3, 4, false] }], + ['bold', 'italic', 'underline', 'strike'], + ['link', 'image', 'code-block'], + ], + }; + + /** + * 初始化 + * + * @protected + * @return {*} {Promise} + * @memberof HtmlEditorController + */ + protected async onInit(): Promise { + await super.onInit(); + if (this.editorParams) { + const { + uploadParams, + exportParams, + SHOWTOOLBAR, + VALUEMODE, + IMAGEMODE, + MODULES, + } = this.editorParams; + + if (uploadParams) { + try { + this.uploadParams = JSON.parse(uploadParams); + } catch (error) { + ibiz.log.error( + `编辑器[${ibiz.log.error( + error, + )}]编辑器参数 uploadParams 非 json 格式`, + ); + } + } + if (exportParams) { + try { + this.exportParams = JSON.parse(exportParams); + } catch (error) { + ibiz.log.error( + `编辑器[${ibiz.log.error( + error, + )}]编辑器参数 exportParams 非 json 格式`, + ); + } + } + if (SHOWTOOLBAR) { + this.showToolbar = this.toBoolean(SHOWTOOLBAR); + } + if (VALUEMODE) { + this.valueMode = VALUEMODE.toLowerCase(); + } + if (IMAGEMODE) { + this.imageMode = IMAGEMODE.toLowerCase(); + } + if (MODULES) { + this.modules = ScriptFactory.execScriptFn( + { controller: this }, + MODULES, + ) as IData; + } + } + } +} diff --git a/src/editor/html/html-editor.provider.ts b/src/editor/html/html-editor.provider.ts new file mode 100644 index 0000000000000000000000000000000000000000..8baa9374ae3e640a5064486352dfa643067ea3b2 --- /dev/null +++ b/src/editor/html/html-editor.provider.ts @@ -0,0 +1,31 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { + IEditorContainerController, + IEditorProvider, +} from '@ibiz-template/runtime'; +import { IHtml } from '@ibiz/model-core'; +import { HtmlEditorController } from './html-editor.controller'; + +/** + * html框编辑器适配器 + * + * @author lxm + * @date 2022-09-19 22:09:03 + * @export + * @class HtmlEditorProvider + * @implements {EditorProvider} + */ +export class HtmlEditorProvider implements IEditorProvider { + formEditor: string = 'IBizQuill'; + + gridEditor: string = 'IBizQuill'; + + async createController( + editorModel: IHtml, + parentController: IEditorContainerController, + ): Promise { + const c = new HtmlEditorController(editorModel, parentController); + await c.init(); + return c; + } +} diff --git a/src/editor/html/index.ts b/src/editor/html/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..4ae95a9b9d02704d6bef2aef64f70c7bf188a97d --- /dev/null +++ b/src/editor/html/index.ts @@ -0,0 +1,2 @@ +export * from './html-editor.controller'; +export * from './html-editor.provider'; diff --git a/src/editor/html/quill-editor-preview/quill-editor-preview.scss b/src/editor/html/quill-editor-preview/quill-editor-preview.scss new file mode 100644 index 0000000000000000000000000000000000000000..42c679476236dc1fe586c45c5b2fe753a1a5f439 --- /dev/null +++ b/src/editor/html/quill-editor-preview/quill-editor-preview.scss @@ -0,0 +1,9 @@ +@include b(quill-preview) { + position: relative; + @include e(edit) { + position: absolute; + right: rem(15px); + top: rem(12px); + font-size: getCssVar(font-size, header-4); + } +} \ No newline at end of file diff --git a/src/editor/html/quill-editor-preview/quill-editor-preview.tsx b/src/editor/html/quill-editor-preview/quill-editor-preview.tsx new file mode 100644 index 0000000000000000000000000000000000000000..b2f2ea4bfa58c6bc08d4b622b6e3cb92734da3d7 --- /dev/null +++ b/src/editor/html/quill-editor-preview/quill-editor-preview.tsx @@ -0,0 +1,82 @@ +/* eslint-disable import/no-extraneous-dependencies */ +import { defineComponent, onMounted, ref } from 'vue'; +import { + getHtmlProps, + getEditorEmits, + useNamespace, +} from '@ibiz-template/vue3-util'; +import Quill from 'quill'; +import { HtmlEditorController } from '../html-editor.controller'; +import './quill-editor-preview.scss'; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const IBizQuillPreview: any = defineComponent({ + name: 'IBizQuillPreview', + props: getHtmlProps(), + emits: getEditorEmits(), + setup(props, { emit }) { + const ns = useNamespace('quill-preview'); + const c: HtmlEditorController = props.controller; + + const editorRef = ref(null); + + const lang = ibiz.i18n.getLang(); + + // 编辑器对象 + let quill: Quill | null = null; + + const init = () => { + if (!editorRef.value) { + return; + } + quill = new Quill(editorRef.value, { + theme: 'bubble', + modules: c.modules, + readOnly: true, + }); + if (c.valueMode === 'text') { + quill.setText(props.value); + } + }; + + onMounted(() => { + init(); + }); + + const handleClick = () => { + emit('edit'); + }; + + return { + ns, + lang, + editorRef, + handleClick, + }; + }, + render() { + return ( +
+
+ {this.controller.valueMode === 'html' ? ( +
+ ) : null} +
+ {!this.readOnly && !this.disable ? ( +
+ +
+ ) : null} +
+ ); + }, +}); + +export default IBizQuillPreview; diff --git a/src/editor/html/quill-editor/quill-editor.scss b/src/editor/html/quill-editor/quill-editor.scss new file mode 100644 index 0000000000000000000000000000000000000000..98312656c0003d7498ba785299e5887c3018cc8a --- /dev/null +++ b/src/editor/html/quill-editor/quill-editor.scss @@ -0,0 +1,87 @@ +@include b(quill) { + .van-action-sheet { + --van-action-sheet-max-height: 100%; + height: 100%; + border-radius: 0; + } + + .van-action-sheet__content { + position: relative; + .content { + display: flex; + height: 100%; + flex-direction: column; + } + .ql-toolbar { + padding: rem(8px) rem(50px); + } + .#{bem(quill, cancel)} { + position: absolute; + left: 0px; + top: 0; + padding: rem(8px) rem(12px); + line-height: rem(26px); + cursor: pointer; + } + .#{bem(quill, confirm)} { + position: absolute; + right: 0px; + top: 0; + padding: rem(8px) rem(12px); + line-height: rem(26px); + cursor: pointer; + } + } + // quill多语言特殊处理,后续补充多语言 + @include m(zh-cn) { + .ql-picker.ql-size { + .ql-picker-label::before, + .ql-picker-item::before { + content: '默认' + } + .ql-picker-label[data-value=small]::before, + .ql-picker-item[data-value=small]::before { + content: '小' + } + .ql-picker-label[data-value=large]::before, + .ql-picker-item[data-value=large]::before { + content: '大' + } + .ql-picker-label[data-value=huge]::before, + .ql-picker-item[data-value=huge]::before { + content: '超大' + } + } + + .ql-picker.ql-header { + .ql-picker-label::before, + .ql-picker-item::before { + content: '正文' + } + .ql-picker-label[data-value="1"]::before, + .ql-picker-item[data-value="1"]::before { + content: 'H 1'; + } + .ql-picker-label[data-value="2"]::before, + .ql-picker-item[data-value="2"]::before { + content: 'H 2'; + } + .ql-picker-label[data-value="3"]::before, + .ql-picker-item[data-value="3"]::before { + content: 'H 3'; + } + .ql-picker-label[data-value="4"]::before, + .ql-picker-item[data-value="4"]::before { + content: 'H 4'; + } + .ql-picker-label[data-value="5"]::before, + .ql-picker-item[data-value="5"]::before { + content: 'H 5'; + } + .ql-picker-label[data-value="6"]::before, + .ql-picker-item[data-value="6"]::before { + content: 'H 6'; + } + } + } +} \ No newline at end of file diff --git a/src/editor/html/quill-editor/quill-editor.tsx b/src/editor/html/quill-editor/quill-editor.tsx new file mode 100644 index 0000000000000000000000000000000000000000..b22f9ba72a34664fb29b042f054a8de7cf881732 --- /dev/null +++ b/src/editor/html/quill-editor/quill-editor.tsx @@ -0,0 +1,232 @@ +/* eslint-disable import/no-extraneous-dependencies */ +import { defineComponent, nextTick, Ref, ref, watch } from 'vue'; +import { + getHtmlProps, + getEditorEmits, + useNamespace, +} from '@ibiz-template/vue3-util'; +import 'quill/dist/quill.core.css'; +import 'quill/dist/quill.snow.css'; +import 'quill/dist/quill.bubble.css'; +import Quill from 'quill'; +import { Delta } from 'quill/core'; +import { base64ToBlob, CoreConst } from '@ibiz-template/core'; +import { getCookie } from 'qx-util'; +import { HtmlEditorController } from '../html-editor.controller'; +import './quill-editor.scss'; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const IBizQuill: any = defineComponent({ + name: 'IBizQuill', + props: getHtmlProps(), + emits: getEditorEmits(), + setup(props, { emit }) { + const ns = useNamespace('quill'); + const c: HtmlEditorController = props.controller; + + const editorRef = ref(null); + + const lang = ibiz.i18n.getLang(); + + // 编辑器对象 + let quill: Quill | null = null; + + // 请求头 + const headers: Ref = ref({ + Authorization: `Bearer ${getCookie(CoreConst.TOKEN)}`, + }); + + // 上传文件路径 + const uploadUrl: Ref = ref(''); + + // 下载文件路径 + const downloadUrl: Ref = ref(''); + + // 编辑状态 + const editing: Ref = ref(false); + + // 更新中 + const updating: Ref = ref(false); + + // 临时数据 + const tempValue: Ref = ref(''); + + const getImage = (delta: Delta) => { + const item = delta.ops.find(x => x.insert && (x.insert as IData).image); + if (item) { + return (item.insert as IData).image; + } + }; + + const getValue = () => { + if (c.valueMode === 'text') { + return quill!.getText(); + } + return quill!.getSemanticHTML(); + }; + + // 处理图片上传(文件模式) + const handleUpload = async (image: string) => { + const blob = base64ToBlob(image); + const file = await ibiz.util.file.fileUpload( + uploadUrl.value, + blob, + headers.value, + ); + const url = downloadUrl.value.replace('%fileId%', file.fileid); + const value = getValue(); + tempValue.value = value.replace(image, url); + }; + + const init = () => { + if (!editorRef.value) { + return; + } + const theme = c.showToolbar ? 'snow' : 'bubble'; + quill = new Quill(editorRef.value, { + theme, + modules: c.modules, + readOnly: props.disabled || props.readonly, + placeholder: c.placeHolder, + }); + quill.on('text-change', (delta, oldDelta, source) => { + if (source === 'user') { + const image = getImage(delta); + if (image && c.imageMode === 'file') { + handleUpload(image); + return; + } + tempValue.value = getValue(); + } + }); + if (c.valueMode === 'text') { + quill.setText(props.value); + } + }; + + watch( + () => [props.disable, props.readonly], + () => { + if (!quill) { + return; + } + if (props.disabled || props.readonly) { + quill.enable(false); + } else { + quill.enable(); + } + }, + { immediate: true }, + ); + + // data响应式变更基础路径 + watch( + () => props.data, + newVal => { + if (newVal) { + const urls = ibiz.util.file.calcFileUpDownUrl( + c.context, + c.params, + newVal, + c.editorParams, + ); + uploadUrl.value = urls.uploadUrl; + downloadUrl.value = urls.downloadUrl; + } + }, + { immediate: true, deep: true }, + ); + + watch( + () => props.value, + () => { + if (!quill) { + return; + } + tempValue.value = props.value; + if (c.valueMode === 'text') { + quill.setText(props.value); + } else { + updating.value = true; + nextTick(() => { + updating.value = false; + }); + } + }, + { immediate: true }, + ); + + // 展开编辑 + const handleEdit = () => { + if (!quill) { + init(); + } + }; + + // 取消编辑 + const handleCancel = () => { + editing.value = false; + }; + + // 确认编辑 + const handleConfirm = () => { + emit('change', tempValue.value); + editing.value = false; + }; + + return { + ns, + lang, + editing, + updating, + editorRef, + handleEdit, + handleCancel, + handleConfirm, + }; + }, + render() { + return ( +
+ {!this.updating && ( + { + this.editing = true; + }} + /> + )} + +
+
+ {ibiz.i18n.t('editor.common.cancel')} +
+
+ {this.controller.valueMode === 'html' ? ( +
+ ) : null} +
+
+ {ibiz.i18n.t('editor.common.confirm')} +
+
+
+
+ ); + }, +}); + +export default IBizQuill; diff --git a/src/editor/index.ts b/src/editor/index.ts index e53b05f254ad7f32a00222e7ec2b9252b8557cac..70f242e39b3de84c1622769a12c73267e4d970e3 100644 --- a/src/editor/index.ts +++ b/src/editor/index.ts @@ -32,6 +32,7 @@ import { DateRangeEditorProvider, IBizDateRangePicker } from './date-range'; import { IBizCascader, CascaderEditorProvider } from './cascader'; import { ColorPickerEditorProvider, IBizColorPicker } from './color-picker'; import { MarkDownEditorProvider } from './markdown'; +import { HtmlEditorProvider } from './html'; import { IBizDropdownList } from './dropdown-list/ibiz-dropdown-list/ibiz-dropdown-list'; export const IBizEditor = { @@ -69,6 +70,17 @@ export const IBizEditor = { ), ); + v.component( + 'IBizQuill', + defineAsyncComponent(() => import('./html/quill-editor/quill-editor')), + ); + v.component( + 'IBizQuillPreview', + defineAsyncComponent( + () => import('./html/quill-editor-preview/quill-editor-preview'), + ), + ); + // 标签 registerEditorProvider('SPAN', () => new SpanEditorProvider()); registerEditorProvider( @@ -119,6 +131,8 @@ export const IBizEditor = { registerEditorProvider('MOBRATING', () => new RateEditorProvider()); // 评分器 registerEditorProvider('MOBMARKDOWN', () => new MarkDownEditorProvider()); + // 富文本 + registerEditorProvider('MOBHTMLTEXT', () => new HtmlEditorProvider()); // 单选框列表 registerEditorProvider( @@ -262,6 +276,7 @@ export * from './date-picker'; export * from './date-range'; export * from './dropdown-list'; export * from './markdown'; +export * from './html'; export * from './number-range'; export * from './radio-button-list'; export * from './radio-button-list';