replace Quill.js with tiptap (based on ProseMirror)
This commit is contained in:
@@ -1,12 +1,14 @@
|
||||
<template>
|
||||
<div class="ui-rte" :disabled="disabled">
|
||||
<div ref="editor" :id="id" class="pell" v-show="!raw"></div>
|
||||
<div class="pell-raw" v-show="raw">
|
||||
<div class="pell-actionbar">
|
||||
<button class="pell-button" title="Accept" type="button" @click="acceptHtml"><i class="fth-check"></i></button>
|
||||
<button class="pell-button" title="Cancel" type="button" @click="raw = false"><i class="fth-x"></i></button>
|
||||
</div>
|
||||
<pre class="pell-raw-content"></pre>
|
||||
<div ref="editor" :id="id">
|
||||
<editor-menu-bubble :editor="editor" :keep-in-bounds="true" v-slot="{ commands, isActive, menu }">
|
||||
<div class="ui-rte-controls theme-dark" :class="{ 'is-active': menu.isActive }" :style="`left: ${menu.left}px; bottom: ${menu.bottom}px;`">
|
||||
<button type="button" class="ui-rte-control" :class="{ 'is-active': isActive.bold() }" @click="commands.bold">B</button>
|
||||
<button type="button" class="ui-rte-control" :class="{ 'is-active': isActive.italic() }" @click="commands.italic">I</button>
|
||||
<button type="button" class="ui-rte-control" :class="{ 'is-active': isActive.code() }" @click="commands.code">C</button>
|
||||
</div>
|
||||
</editor-menu-bubble>
|
||||
<editor-content class="ui-rte-input" :editor="editor" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -14,11 +16,20 @@
|
||||
|
||||
<script>
|
||||
import Strings from 'zero/helpers/strings.js';
|
||||
import Pell from './rte.pell.dependency.js';
|
||||
import { debounce as _debounce } from 'underscore';
|
||||
import { Editor, EditorContent, EditorMenuBubble } from 'tiptap';
|
||||
import
|
||||
{
|
||||
Blockquote, BulletList, CodeBlock, HardBreak, Heading, ListItem, OrderedList, TodoItem, TodoList,
|
||||
Bold, Code, Italic, Link, Strike, Underline, History
|
||||
}
|
||||
from 'tiptap-extensions';
|
||||
|
||||
export default {
|
||||
name: 'uiRte',
|
||||
|
||||
components: { EditorContent, EditorMenuBubble },
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
@@ -31,218 +42,132 @@
|
||||
},
|
||||
|
||||
data: () => ({
|
||||
raw: false,
|
||||
editor: null,
|
||||
id: 'rte-' + Strings.guid(),
|
||||
id: 'quill-' + Strings.guid(),
|
||||
blocked: false,
|
||||
actions: [
|
||||
'bold',
|
||||
'underline',
|
||||
'italic',
|
||||
'strikethrough',
|
||||
'olist',
|
||||
'ulist',
|
||||
'line'
|
||||
]
|
||||
onDebouncedChange: null,
|
||||
editor: null
|
||||
}),
|
||||
|
||||
watch: {
|
||||
value()
|
||||
{
|
||||
this.setValue();
|
||||
this.init();
|
||||
}
|
||||
},
|
||||
|
||||
created()
|
||||
{
|
||||
this.actions.push({
|
||||
name: 'link',
|
||||
result: this.onLinkCreate
|
||||
});
|
||||
|
||||
this.actions.push({
|
||||
name: 'raw',
|
||||
icon: '<i class="fth-edit-2"></i>',
|
||||
title: 'Edit HTML',
|
||||
result: () =>
|
||||
{
|
||||
this.$el.querySelector('.pell-raw-content').innerText = this.value;
|
||||
this.raw = true;
|
||||
}
|
||||
});
|
||||
this.onDebouncedChange = _debounce(this.onChange, 350);
|
||||
},
|
||||
|
||||
mounted()
|
||||
{
|
||||
this.initialize();
|
||||
this.editor = new Editor({
|
||||
extensions: [
|
||||
new CodeBlock(),
|
||||
new HardBreak(),
|
||||
new Link(),
|
||||
new Bold(),
|
||||
new Code(),
|
||||
new Italic(),
|
||||
new Strike(),
|
||||
new Underline(),
|
||||
new History(),
|
||||
],
|
||||
onUpdate: ({ getHTML }) =>
|
||||
{
|
||||
this.onDebouncedChange(getHTML());
|
||||
},
|
||||
});
|
||||
|
||||
this.init();
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
initialize()
|
||||
init()
|
||||
{
|
||||
this.$el.querySelector('.pell-raw-content').contentEditable = true;
|
||||
|
||||
this.editor = Pell.init({
|
||||
element: this.$refs.editor,
|
||||
defaultParagraphSeparator: 'p',
|
||||
onChange: html =>
|
||||
{
|
||||
this.blocked = true;
|
||||
this.$emit('input', html);
|
||||
this.blocked = false;
|
||||
//setValue(html);
|
||||
},
|
||||
actions: this.actions
|
||||
});
|
||||
|
||||
this.editor.content.innerHTML = this.value;
|
||||
//this.setValue();
|
||||
this.editor.setContent(this.value);
|
||||
},
|
||||
|
||||
|
||||
setValue()
|
||||
onChange(content)
|
||||
{
|
||||
if (this.editor.content.innerHTML !== this.value)
|
||||
{
|
||||
this.editor.content.innerHTML = this.value;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
onLinkCreate()
|
||||
{
|
||||
|
||||
},
|
||||
|
||||
|
||||
acceptHtml()
|
||||
{
|
||||
var html = this.$el.querySelector('.pell-raw-content').innerText;
|
||||
this.editor.content.innerHTML = html;
|
||||
this.raw = false;
|
||||
// TODO this will automatically set the cursor to the end, not desired ;-)
|
||||
this.$emit('input', content);
|
||||
}
|
||||
},
|
||||
|
||||
beforeDestroy()
|
||||
{
|
||||
this.editor.destroy();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.ui-rte
|
||||
|
||||
.ui-rte-input
|
||||
{
|
||||
font-size: var(--font-size);
|
||||
height: auto;
|
||||
min-height: 42px;
|
||||
padding-top: 9px;
|
||||
|
||||
.pell,
|
||||
.pell-raw
|
||||
{
|
||||
background: var(--color-input);
|
||||
max-width: 800px;
|
||||
min-height: 42px;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
font-size: var(--font-size);
|
||||
display: inline-block;
|
||||
line-height: 1.5;
|
||||
color: var(--color-text);
|
||||
border-radius: var(--radius);
|
||||
border: 1px solid transparent;
|
||||
|
||||
&:focus-within
|
||||
{
|
||||
background: var(--color-input-focus-bg) !important;
|
||||
border: var(--color-input-focus-border);
|
||||
box-shadow: var(--color-input-focus-shadow);
|
||||
outline: none;
|
||||
|
||||
.pell-button:hover,
|
||||
.pell-button-selected
|
||||
{
|
||||
background: var(--color-box-nested);
|
||||
color: var(--color-text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pell, .pell-content, .pell-raw
|
||||
{
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.pell-content,
|
||||
.pell-raw-content
|
||||
{
|
||||
min-height: 60px;
|
||||
outline: none;
|
||||
overflow-y: auto;
|
||||
padding: 6px 12px 12px;
|
||||
max-height: 400px;
|
||||
}
|
||||
|
||||
pre.pell-raw-content
|
||||
p
|
||||
{
|
||||
margin: 0;
|
||||
background: none;
|
||||
border: none;
|
||||
word-wrap: normal;
|
||||
white-space: normal;
|
||||
font-family: Monaco,Menlo,Consolas,Courier New,monospace;
|
||||
font-size: var(--font-size);
|
||||
}
|
||||
|
||||
u-rte.-oneline .pell-content
|
||||
p + p
|
||||
{
|
||||
min-height: 46px;
|
||||
}
|
||||
|
||||
.pell-content
|
||||
{
|
||||
p
|
||||
{
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h3, h2
|
||||
{
|
||||
margin-bottom: .5em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.pell-content a, .pell-content a:hover, .pell-content a:visited, .pell-content a:focus
|
||||
{
|
||||
text-decoration: underline;
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.pell-actionbar
|
||||
{
|
||||
border-radius: var(--radius) var(--radius) 0 0;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.pell-button
|
||||
{
|
||||
background-color: transparent;
|
||||
cursor: pointer;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
text-align: center;
|
||||
border-radius: 5px;
|
||||
font-size: 14px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.pell-button + .pell-button
|
||||
{
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.pell-button:hover,
|
||||
.pell-button-selected
|
||||
{
|
||||
background: var(--color-box);
|
||||
color: var(--color-text);
|
||||
margin-top: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-rte-controls
|
||||
{
|
||||
position: absolute;
|
||||
display: flex;
|
||||
z-index: 20;
|
||||
background: var(--color-bg);
|
||||
border-radius: var(--radius);
|
||||
padding: 5px;
|
||||
margin-bottom: 8px;
|
||||
transform: translateX(-50%);
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s, visibility 0.2s;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.ui-rte-controls.is-active
|
||||
{
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.ui-rte-control
|
||||
{
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
color: var(--color-text);
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
margin-right: 4px;
|
||||
border-radius: var(--radius);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ui-rte-control:hover
|
||||
{
|
||||
background-color: var(--color-bg-shade-1);
|
||||
}
|
||||
|
||||
.ui-rte-control.is-active
|
||||
{
|
||||
background-color: var(--color-bg-shade-1);
|
||||
color: var(--color-text-dim);
|
||||
}
|
||||
</style>
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
input[type="text"], input[type="color"], input[type="date"], input[type="datetime"], input[type="email"], input[type="file"], input[type="month"], input[type="number"],
|
||||
input[type="password"], input[type="range"], input[type="search"], input[type="tel"], input[type="time"], input[type="url"], input[type="week"],
|
||||
textarea, .ui-native-select
|
||||
textarea, .ui-native-select, .ui-rte-input
|
||||
{
|
||||
@extend %font;
|
||||
background: var(--color-input);
|
||||
|
||||
@@ -14,7 +14,6 @@ import uiForm from './forms/form.vue';
|
||||
import uiInputList from './forms/input-list.vue';
|
||||
import uiProperty from './forms/property.vue';
|
||||
import uiRte from './forms/rte.vue';
|
||||
import uiQuill from './forms/quill.vue';
|
||||
import uiSearch from './forms/search.vue';
|
||||
import uiTags from './forms/tags.vue';
|
||||
import uiToggle from './forms/toggle.vue';
|
||||
@@ -78,7 +77,6 @@ export default {
|
||||
uiInputList,
|
||||
uiProperty,
|
||||
uiRte,
|
||||
uiQuill,
|
||||
uiSearch,
|
||||
uiTags,
|
||||
uiToggle,
|
||||
|
||||
@@ -1,19 +1,66 @@
|
||||
<template>
|
||||
<div class="ui-quill" :disabled="disabled">
|
||||
<div ref="editor" :id="id" v-show="!raw"></div>
|
||||
<div ref="editor" :id="id">
|
||||
<editor-menu-bubble :editor="editor" :keep-in-bounds="keepInBounds" v-slot="{ commands, isActive, menu }">
|
||||
<div class="menububble"
|
||||
:class="{ 'is-active': menu.isActive }"
|
||||
:style="`left: ${menu.left}px; bottom: ${menu.bottom}px;`">
|
||||
|
||||
<button type="button" class="menububble__button"
|
||||
:class="{ 'is-active': isActive.bold() }"
|
||||
@click="commands.bold">
|
||||
B
|
||||
</button>
|
||||
|
||||
<button type="button" class="menububble__button"
|
||||
:class="{ 'is-active': isActive.italic() }"
|
||||
@click="commands.italic">
|
||||
I
|
||||
</button>
|
||||
|
||||
<button type="button" class="menububble__button"
|
||||
:class="{ 'is-active': isActive.code() }"
|
||||
@click="commands.code">
|
||||
C
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</editor-menu-bubble>
|
||||
|
||||
<editor-content class="editor__content" :editor="editor" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import Strings from 'zero/helpers/strings.js';
|
||||
import Pell from './rte.pell.dependency.js';
|
||||
import Quill from 'quill';
|
||||
import 'quill/dist/quill.bubble.css';
|
||||
import { Editor, EditorContent, EditorMenuBubble } from 'tiptap'
|
||||
import
|
||||
{
|
||||
Blockquote,
|
||||
BulletList,
|
||||
CodeBlock,
|
||||
HardBreak,
|
||||
Heading,
|
||||
ListItem,
|
||||
OrderedList,
|
||||
TodoItem,
|
||||
TodoList,
|
||||
Bold,
|
||||
Code,
|
||||
Italic,
|
||||
Link,
|
||||
Strike,
|
||||
Underline,
|
||||
History,
|
||||
} from 'tiptap-extensions'
|
||||
|
||||
export default {
|
||||
name: 'uiQuill',
|
||||
|
||||
components: { EditorContent, EditorMenuBubble },
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
@@ -26,19 +73,31 @@
|
||||
},
|
||||
|
||||
data: () => ({
|
||||
raw: false,
|
||||
editor: null,
|
||||
id: 'quill-' + Strings.guid(),
|
||||
blocked: false
|
||||
blocked: false,
|
||||
keepInBounds: true,
|
||||
editor: new Editor({
|
||||
extensions: [
|
||||
new Blockquote(),
|
||||
new BulletList(),
|
||||
new CodeBlock(),
|
||||
new HardBreak(),
|
||||
new Heading({ levels: [1, 2, 3] }),
|
||||
new ListItem(),
|
||||
new OrderedList(),
|
||||
new TodoItem(),
|
||||
new TodoList(),
|
||||
new Link(),
|
||||
new Bold(),
|
||||
new Code(),
|
||||
new Italic(),
|
||||
new Strike(),
|
||||
new Underline(),
|
||||
new History(),
|
||||
],
|
||||
})
|
||||
}),
|
||||
|
||||
watch: {
|
||||
value()
|
||||
{
|
||||
this.setValue();
|
||||
}
|
||||
},
|
||||
|
||||
created()
|
||||
{
|
||||
|
||||
@@ -53,19 +112,7 @@
|
||||
|
||||
initialize()
|
||||
{
|
||||
this.quill = new Quill(this.$refs.editor, {
|
||||
theme: 'bubble',
|
||||
placeholder: 'Write something...',
|
||||
modules: {
|
||||
toolbar: [
|
||||
['bold', 'italic', 'underline', 'strike', 'code', 'link'],
|
||||
['clean']
|
||||
]
|
||||
},
|
||||
formats: ['bold','italic','underline','strike','code','link']
|
||||
});
|
||||
|
||||
this.$refs.editor.querySelector('.ql-tooltip').classList.add('theme-dark');
|
||||
|
||||
},
|
||||
|
||||
|
||||
@@ -86,94 +133,67 @@
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
beforeDestroy()
|
||||
{
|
||||
this.editor.destroy();
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.ui-quill
|
||||
{
|
||||
font-size: var(--font-size);
|
||||
.menububble {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
z-index: 20;
|
||||
background: black;
|
||||
border-radius: 5px;
|
||||
padding: 0.3rem;
|
||||
margin-bottom: 0.5rem;
|
||||
transform: translateX(-50%);
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s, visibility 0.2s;
|
||||
|
||||
&.is-active {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.ui-quill .ql-editor
|
||||
{
|
||||
line-height: 1.5;
|
||||
padding: 10px 12px 8px;
|
||||
&__button {
|
||||
display: inline-flex;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
color: white;
|
||||
padding: 0.2rem 0.5rem;
|
||||
margin-right: 0.2rem;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(white, 0.1);
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
background-color: rgba(white, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
.ui-quill .ql-editor.ql-blank::before
|
||||
{
|
||||
left: 12px;
|
||||
color: var(--color-input-placeholder);
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.ui-quill .ql-container
|
||||
{
|
||||
background: var(--color-input);
|
||||
max-width: 800px;
|
||||
min-height: 42px;
|
||||
&__form {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
font-size: var(--font-size);
|
||||
display: inline-block;
|
||||
line-height: 1.5;
|
||||
color: var(--color-text);
|
||||
border-radius: var(--radius);
|
||||
border: 1px solid transparent;
|
||||
font-family: var(--font);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.ui-quill .ql-container:focus, .ui-quill .ql-container:focus-within
|
||||
{
|
||||
background-color: var(--color-input-focus-bg);
|
||||
border: var(--color-input-focus-border);
|
||||
box-shadow: var(--color-input-focus-shadow);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.ui-quill .ql-tooltip
|
||||
{
|
||||
color: var(--color-text);
|
||||
background-color: var(--color-dropdown);
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
|
||||
.ui-quill .ql-toolbar
|
||||
{
|
||||
padding: 3px 6px;
|
||||
}
|
||||
|
||||
.ui-quill .ql-tooltip-arrow
|
||||
{
|
||||
border-bottom-color: var(--color-dropdown) !important;
|
||||
}
|
||||
|
||||
.ui-quill .ql-toolbar button
|
||||
{
|
||||
height: 36px;
|
||||
width: 36px;
|
||||
padding: 8px 10px;
|
||||
}
|
||||
|
||||
.ui-quill .ql-toolbar button svg
|
||||
{
|
||||
height: 85%;
|
||||
}
|
||||
|
||||
.ui-quill .ql-toolbar .ql-formats
|
||||
{
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.ui-quill .ql-bubble .ql-fill
|
||||
{
|
||||
fill: var(--color-text);
|
||||
}
|
||||
.ui-quill .ql-bubble .ql-stroke
|
||||
{
|
||||
stroke: var(--color-text);
|
||||
&__input {
|
||||
font: inherit;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,248 @@
|
||||
<template>
|
||||
<div class="ui-rte" :disabled="disabled">
|
||||
<div ref="editor" :id="id" class="pell" v-show="!raw"></div>
|
||||
<div class="pell-raw" v-show="raw">
|
||||
<div class="pell-actionbar">
|
||||
<button class="pell-button" title="Accept" type="button" @click="acceptHtml"><i class="fth-check"></i></button>
|
||||
<button class="pell-button" title="Cancel" type="button" @click="raw = false"><i class="fth-x"></i></button>
|
||||
</div>
|
||||
<pre class="pell-raw-content"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import Strings from 'zero/helpers/strings.js';
|
||||
import Pell from './rte.pell.dependency.js';
|
||||
|
||||
export default {
|
||||
name: 'uiRte',
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
},
|
||||
|
||||
data: () => ({
|
||||
raw: false,
|
||||
editor: null,
|
||||
id: 'rte-' + Strings.guid(),
|
||||
blocked: false,
|
||||
actions: [
|
||||
'bold',
|
||||
'underline',
|
||||
'italic',
|
||||
'strikethrough',
|
||||
'olist',
|
||||
'ulist',
|
||||
'line'
|
||||
]
|
||||
}),
|
||||
|
||||
watch: {
|
||||
value()
|
||||
{
|
||||
this.setValue();
|
||||
}
|
||||
},
|
||||
|
||||
created()
|
||||
{
|
||||
this.actions.push({
|
||||
name: 'link',
|
||||
result: this.onLinkCreate
|
||||
});
|
||||
|
||||
this.actions.push({
|
||||
name: 'raw',
|
||||
icon: '<i class="fth-edit-2"></i>',
|
||||
title: 'Edit HTML',
|
||||
result: () =>
|
||||
{
|
||||
this.$el.querySelector('.pell-raw-content').innerText = this.value;
|
||||
this.raw = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
mounted()
|
||||
{
|
||||
this.initialize();
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
initialize()
|
||||
{
|
||||
this.$el.querySelector('.pell-raw-content').contentEditable = true;
|
||||
|
||||
this.editor = Pell.init({
|
||||
element: this.$refs.editor,
|
||||
defaultParagraphSeparator: 'p',
|
||||
onChange: html =>
|
||||
{
|
||||
this.blocked = true;
|
||||
this.$emit('input', html);
|
||||
this.blocked = false;
|
||||
//setValue(html);
|
||||
},
|
||||
actions: this.actions
|
||||
});
|
||||
|
||||
this.editor.content.innerHTML = this.value;
|
||||
//this.setValue();
|
||||
},
|
||||
|
||||
|
||||
setValue()
|
||||
{
|
||||
if (this.editor.content.innerHTML !== this.value)
|
||||
{
|
||||
this.editor.content.innerHTML = this.value;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
onLinkCreate()
|
||||
{
|
||||
|
||||
},
|
||||
|
||||
|
||||
acceptHtml()
|
||||
{
|
||||
var html = this.$el.querySelector('.pell-raw-content').innerText;
|
||||
this.editor.content.innerHTML = html;
|
||||
this.raw = false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.ui-rte
|
||||
{
|
||||
font-size: var(--font-size);
|
||||
|
||||
.pell,
|
||||
.pell-raw
|
||||
{
|
||||
background: var(--color-input);
|
||||
max-width: 800px;
|
||||
min-height: 42px;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
font-size: var(--font-size);
|
||||
display: inline-block;
|
||||
line-height: 1.5;
|
||||
color: var(--color-text);
|
||||
border-radius: var(--radius);
|
||||
border: 1px solid transparent;
|
||||
|
||||
&:focus-within
|
||||
{
|
||||
background: var(--color-input-focus-bg) !important;
|
||||
border: var(--color-input-focus-border);
|
||||
box-shadow: var(--color-input-focus-shadow);
|
||||
outline: none;
|
||||
|
||||
.pell-button:hover,
|
||||
.pell-button-selected
|
||||
{
|
||||
background: var(--color-box-nested);
|
||||
color: var(--color-text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pell, .pell-content, .pell-raw
|
||||
{
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.pell-content,
|
||||
.pell-raw-content
|
||||
{
|
||||
min-height: 60px;
|
||||
outline: none;
|
||||
overflow-y: auto;
|
||||
padding: 6px 12px 12px;
|
||||
max-height: 400px;
|
||||
}
|
||||
|
||||
pre.pell-raw-content
|
||||
{
|
||||
margin: 0;
|
||||
background: none;
|
||||
border: none;
|
||||
word-wrap: normal;
|
||||
white-space: normal;
|
||||
font-family: Monaco,Menlo,Consolas,Courier New,monospace;
|
||||
font-size: var(--font-size);
|
||||
}
|
||||
|
||||
u-rte.-oneline .pell-content
|
||||
{
|
||||
min-height: 46px;
|
||||
}
|
||||
|
||||
.pell-content
|
||||
{
|
||||
p
|
||||
{
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h3, h2
|
||||
{
|
||||
margin-bottom: .5em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.pell-content a, .pell-content a:hover, .pell-content a:visited, .pell-content a:focus
|
||||
{
|
||||
text-decoration: underline;
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.pell-actionbar
|
||||
{
|
||||
border-radius: var(--radius) var(--radius) 0 0;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.pell-button
|
||||
{
|
||||
background-color: transparent;
|
||||
cursor: pointer;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
text-align: center;
|
||||
border-radius: 5px;
|
||||
font-size: 14px;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.pell-button + .pell-button
|
||||
{
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.pell-button:hover,
|
||||
.pell-button-selected
|
||||
{
|
||||
background: var(--color-box);
|
||||
color: var(--color-text);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -3,7 +3,6 @@ import Text from '../editor/fields/text.vue';
|
||||
import Currency from '../editor/fields/currency.vue';
|
||||
import Number from '../editor/fields/number.vue';
|
||||
import Rte from '../editor/fields/rte.vue';
|
||||
import QuillRte from '../editor/fields/quill.vue';
|
||||
import Select from '../editor/fields/select.vue';
|
||||
import Textarea from '../editor/fields/textarea.vue';
|
||||
import Toggle from '../editor/fields/toggle.vue';
|
||||
@@ -201,16 +200,6 @@ class EditorField
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render a rich-text editor (powered by Quill) field
|
||||
* @returns {EditorField}
|
||||
*/
|
||||
quill()
|
||||
{
|
||||
return this._setComponent(QuillRte);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {object} EditorSelectItem
|
||||
* @param {object} key - Key/Id of the item
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
<template>
|
||||
<ui-quill :value="value" @input="$emit('input', $event)" :disabled="disabled" />
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
config: Object
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -11,8 +11,9 @@
|
||||
"dayjs": "^1.8.26",
|
||||
"flatpickr": "^4.6.3",
|
||||
"qs": "^6.9.4",
|
||||
"quill": "^1.3.7",
|
||||
"sortablejs": "^1.10.2",
|
||||
"tiptap": "^1.30.0",
|
||||
"tiptap-extensions": "^1.33.2",
|
||||
"underscore": "^1.10.2",
|
||||
"vue": "^2.6.12",
|
||||
"vue-router": "^3.4.8"
|
||||
|
||||
Reference in New Issue
Block a user