max-length + options for RTE
This commit is contained in:
@@ -41,6 +41,7 @@
|
||||
import { debounce as _debounce } from 'underscore';
|
||||
import { Editor, EditorContent, EditorMenuBubble } from 'tiptap';
|
||||
import EditorMenuBar from './rte.menubar.js';
|
||||
import { MaxSize } from 'zero/config/rte.extensions.js';
|
||||
import { Placeholder } from 'tiptap-extensions';
|
||||
import createConfig from 'zero/config/rte.config.js';
|
||||
|
||||
@@ -58,6 +59,10 @@
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
maxLength: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: null
|
||||
@@ -139,6 +144,11 @@
|
||||
}));
|
||||
}
|
||||
|
||||
if (this.maxLength > 0)
|
||||
{
|
||||
this.extensions.push(new MaxSize({ maxSize: this.maxLength }));
|
||||
}
|
||||
|
||||
this.editor = new Editor({
|
||||
editable: !this.disabled,
|
||||
extensions: this.extensions,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
import { Node } from 'tiptap';
|
||||
import { Node, Extension, Plugin } from 'tiptap';
|
||||
import { chainCommands, exitCode } from 'prosemirror-commands';
|
||||
|
||||
export class HardBreak extends Node
|
||||
@@ -33,4 +33,41 @@ export class HardBreak extends Node
|
||||
'Enter': command
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class MaxSize extends Extension
|
||||
{
|
||||
get name()
|
||||
{
|
||||
return 'maxSize'
|
||||
}
|
||||
|
||||
get defaultOptions()
|
||||
{
|
||||
return {
|
||||
maxSize: null
|
||||
}
|
||||
}
|
||||
|
||||
get plugins()
|
||||
{
|
||||
return [
|
||||
new Plugin({
|
||||
appendTransaction: (transactions, oldState, newState) =>
|
||||
{
|
||||
const max = this.options.maxSize;
|
||||
const oldLength = oldState.doc.content.size;
|
||||
const newLength = newState.doc.content.size;
|
||||
|
||||
if (max && newLength > max && newLength > oldLength)
|
||||
{
|
||||
let newTr = newState.tr;
|
||||
newTr.insertText('', max + 1, newLength);
|
||||
return newTr;
|
||||
}
|
||||
}
|
||||
})
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<ui-rte :value="value" @input="$emit('input', $event)" :disabled="disabled" />
|
||||
<ui-rte :value="value" @input="$emit('input', $event)" :disabled="disabled" v-bind="{ maxLength, placeholder, setup }" />
|
||||
</template>
|
||||
|
||||
|
||||
@@ -14,6 +14,18 @@
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
maxLength: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
setup: {
|
||||
type: Function,
|
||||
default: () => { }
|
||||
},
|
||||
config: Object
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,11 +187,15 @@ class EditorField
|
||||
|
||||
/**
|
||||
* Render a rich-text editor field
|
||||
* @param {object} [options] - Custom options
|
||||
* @param {number} [options.maxLength=null] - Maximum characters
|
||||
* @param {string} [options.placeholder=null] - Placeholder text (can be a translation) or function
|
||||
* @param {function} [options.setup=value] - Called on RTE setup
|
||||
* @returns {EditorField}
|
||||
*/
|
||||
rte()
|
||||
rte(options)
|
||||
{
|
||||
return this._setComponent(() => import('../editor/fields/rte.vue'));
|
||||
return this._setComponent(() => import('../editor/fields/rte.vue'), { ...options });
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user