Add wysiwyg interface (#460)

* Install tinymce

* Add wysiwyg interface

* Mock window.matchMedia

* Fix wysiwyg not reading data on value change

* Render skeleton loader on top of wysiwyg

* Add hideLoader support to interfaces

* Sneak this little bugfix in unnoticed

It's now passing on the interface / options to the display rendering in render-template
This commit is contained in:
Rijk van Zanten
2020-04-23 14:01:27 -04:00
committed by GitHub
parent fc94de0067
commit 571412ff2c
18 changed files with 813 additions and 2 deletions

15
.jest/before-all.js Normal file
View File

@@ -0,0 +1,15 @@
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation(query => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // deprecated
removeListener: jest.fn(), // deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});

View File

@@ -5,6 +5,7 @@ module.exports = {
testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'],
coveragePathIgnorePatterns: ['<rootDir>/node_modules/', '<rootDir>/.jest/'],
transformIgnorePatterns: [`/node_modules/(?!${esModules})`],
setupFilesAfterEnv: ['<rootDir>/.jest/before-all.js'],
restoreMocks: true,
clearMocks: true,
resetMocks: true,

View File

@@ -19,6 +19,7 @@
"@directus/format-title": "^3.1.1",
"@popperjs/core": "^2.3.3",
"@sindresorhus/slugify": "^0.11.0",
"@tinymce/tinymce-vue": "^3.2.0",
"@types/debug": "^4.1.5",
"@types/lodash": "^4.14.150",
"@vue/composition-api": "^0.5.0",
@@ -34,6 +35,7 @@
"resize-observer": "^1.0.0",
"semver": "^7.3.2",
"stylelint-config-prettier": "^8.0.1",
"tinymce": "^5.2.2",
"vue": "^2.6.11",
"vue-i18n": "^8.17.3",
"vue-router": "^3.1.5",

View File

@@ -5,4 +5,5 @@ export type FormField = Partial<Field> & {
field: string;
name: string | TranslateResult;
hideLabel?: boolean;
hideLoader?: boolean;
};

View File

@@ -70,7 +70,7 @@
subdued: batchMode && batchActiveFields.includes(field.field) === false,
}"
>
<v-skeleton-loader v-if="loading" />
<v-skeleton-loader v-if="loading && field.hideLoader !== true" />
<component
:is="`interface-${field.interface}`"
v-bind="field.options"
@@ -226,6 +226,10 @@ export default defineComponent({
(field as FormField).hideLabel = true;
}
if (interfaceUsed?.hideLoader === true) {
(field as FormField).hideLoader = true;
}
return field;
});
@@ -349,6 +353,7 @@ export default defineComponent({
position: absolute;
top: 0;
left: 0;
z-index: 2;
width: 100%;
height: 100%;
}

View File

@@ -7,6 +7,7 @@ export default defineInterface(({ i18n }) => ({
icon: 'remove',
component: InterfaceDivider,
hideLabel: true,
hideLoader: true,
options: [
{
field: 'color',

View File

@@ -4,6 +4,7 @@ import InterfaceDivider from './divider/';
import InterfaceNumeric from './numeric/';
import InterfaceSlider from './slider/';
import InterfaceToggle from './toggle/';
import InterfaceWYSIWYG from './wysiwyg/';
export const interfaces = [
InterfaceTextInput,
@@ -12,6 +13,7 @@ export const interfaces = [
InterfaceSlider,
InterfaceDivider,
InterfaceToggle,
InterfaceWYSIWYG,
];
export default interfaces;

View File

@@ -9,6 +9,7 @@ export type InterfaceConfig = {
component: Component;
options: Partial<Field>[] | Component;
hideLabel?: boolean;
hideLoader?: boolean;
};
export type InterfaceContext = { i18n: VueI18n };

View File

@@ -0,0 +1,147 @@
function cssVar(name: string) {
return getComputedStyle(document.body).getPropertyValue(name);
}
export default function getEditorStyles(font: 'sans-serif' | 'serif' | 'monospace') {
return `
body {
color: ${cssVar('--foreground-normal')};
background-color: ${cssVar('--background-page')};
margin: 20px;
font-family: 'Roboto', sans-serif;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
-moz-osx-font-smoothing: grayscale;
}
h1 {
font-family: ${cssVar(`--font-${font}`)}, serif;
font-size: 44px;
line-height: 52px;
font-weight: 300;
margin-bottom: 0;
}
h2 {
font-size: 34px;
line-height: 38px;
font-weight: 600;
margin-top: 60px;
margin-bottom: 0;
}
h3 {
font-size: 26px;
line-height: 31px;
font-weight: 600;
margin-top: 40px;
margin-bottom: 0;
}
h4 {
font-size: 22px;
line-height: 28px;
font-weight: 600;
margin-top: 40px;
margin-bottom: 0;
}
h5 {
font-size: 18px;
line-height: 26px;
font-weight: 600;
margin-top: 40px;
margin-bottom: 0;
}
h6 {
font-size: 16px;
line-height: 24px;
font-weight: 600;
margin-top: 40px;
margin-bottom: 0;
}
p {
font-family: ${cssVar(`--font-${font}`)}, serif;
font-size: 16px;
line-height: 32px;
margin-top: 20px;
margin-bottom: 20px;
}
a {
color: #546e7a;
}
ul, ol {
font-family: ${cssVar(`--font-${font}`)}, serif;
font-size: 18px;
line-height: 34px;
margin: 24px 0;
}
ul ul,
ol ol,
ul ol,
ol ul {
margin: 0;
}
b, strong {
font-weight: 600;
}
code {
font-size: 18px;
line-height: 34px;
padding: 2px 4px;
font-family: ${cssVar('--family-monospace')}, monospace;
background-color: #eceff1;
border-radius: 3px;
overflow-wrap: break-word;
}
pre {
font-size: 18px;
line-height: 24px;
padding: 20px;
font-family: ${cssVar('--family-monospace')}, monospace;
background-color: #eceff1;
border-radius: 3px;
overflow: auto;
}
blockquote {
font-family: ${cssVar(`--font-${font}`)}, serif;
font-size: 18px;
line-height: 34px;
border-left: 2px solid #546e7a;
padding-left: 10px;
margin-left: -10px;
font-style: italic;
}
video,
iframe,
img {
max-width: 100 %;
border-radius: 3px;
height: auto;
}
hr {
border: 0;
margin-top: 52px;
margin-bottom: 56px;
text-align: center;
}
hr: after {
content: "...";
font-size: 28px;
letter-spacing: 16px;
line-height: 0;
}
table {
border-collapse: collapse;
}
table th,
table td {
border: 1px solid #cfd8dc;
padding: 0.4rem;
}
figure {
display: table;
margin: 1rem auto;
}
figure figcaption {
color: #999;
display: block;
margin-top: 0.25rem;
text-align: center;
}`;
}

View File

@@ -0,0 +1,120 @@
import InterfaceWYSIWYG from './wysiwyg.vue';
import { defineInterface } from '@/interfaces/define';
export default defineInterface(({ i18n }) => ({
id: 'wysiwyg',
name: i18n.t('wysiwyg'),
icon: 'format_quote',
component: InterfaceWYSIWYG,
options: [
{
field: 'toolbar',
name: i18n.t('toolbar'),
width: 'full',
interface: 'checkboxes',
default_value: [
'bold',
'italic',
'underline',
'removeformat',
'link',
'bullist',
'numlist',
'blockquote',
'h1',
'h2',
'h3',
'image',
'media',
'hr',
'code',
'fullscreen',
],
options: {
choices: {
aligncenter: i18n.t('wysiwyg_options.aligncenter'),
alignjustify: i18n.t('wysiwyg_options.alignjustify'),
alignleft: i18n.t('wysiwyg_options.alignleft'),
alignnone: i18n.t('wysiwyg_options.alignnone'),
alignright: i18n.t('wysiwyg_options.alignright'),
forecolor: i18n.t('wysiwyg_options.forecolor'),
backcolor: i18n.t('wysiwyg_options.backcolor'),
bold: i18n.t('wysiwyg_options.bold'),
italic: i18n.t('wysiwyg_options.italic'),
underline: i18n.t('wysiwyg_options.underline'),
strikethrough: i18n.t('wysiwyg_options.strikethrough'),
subscript: i18n.t('wysiwyg_options.subscript'),
superscript: i18n.t('wysiwyg_options.superscript'),
blockquote: i18n.t('wysiwyg_options.blockquote'),
bullist: i18n.t('wysiwyg_options.bullist'),
numlist: i18n.t('wysiwyg_options.numlist'),
hr: i18n.t('wysiwyg_options.hr'),
link: i18n.t('wysiwyg_options.link'),
unlink: i18n.t('wysiwyg_options.unlink'),
media: i18n.t('wysiwyg_options.media'),
image: i18n.t('wysiwyg_options.image'),
copy: i18n.t('wysiwyg_options.copy'),
cut: i18n.t('wysiwyg_options.cut'),
paste: i18n.t('wysiwyg_options.paste'),
h1: i18n.t('wysiwyg_options.h1'),
h2: i18n.t('wysiwyg_options.h2'),
h3: i18n.t('wysiwyg_options.h3'),
h4: i18n.t('wysiwyg_options.h4'),
h5: i18n.t('wysiwyg_options.h5'),
h6: i18n.t('wysiwyg_options.h6'),
fontselect: i18n.t('wysiwyg_options.fontselect'),
fontsizeselect: i18n.t('wysiwyg_options.fontsizeselect'),
indent: i18n.t('wysiwyg_options.indent'),
outdent: i18n.t('wysiwyg_options.outdent'),
undo: i18n.t('wysiwyg_options.undo'),
redo: i18n.t('wysiwyg_options.redo'),
remove: i18n.t('wysiwyg_options.remove'),
removeformat: i18n.t('wysiwyg_options.removeformat'),
selectall: i18n.t('wysiwyg_options.selectall'),
table: i18n.t('wysiwyg_options.table'),
visualaid: i18n.t('wysiwyg_options.visualaid'),
code: i18n.t('wysiwyg_options.code'),
fullscreen: i18n.t('wysiwyg_options.fullscreen'),
'ltr rtl': i18n.t('wysiwyg_options.directionality'),
},
},
},
{
field: 'font',
name: i18n.t('font'),
width: 'half',
interface: 'dropdown',
default_value: 'serif',
options: {
items: [
{ itemText: i18n.t('sans_serif'), itemValue: 'sans-serif' },
{ itemText: i18n.t('monospace'), itemValue: 'monospace' },
{ itemText: i18n.t('serif'), itemValue: 'serif' },
],
},
},
{
field: 'customFormats',
name: i18n.t('custom_formats'),
interface: 'code',
options: {
type: 'application/json',
template: {
title: 'My Custom Format',
inline: 'span',
classes: 'custom-wrapper',
styles: { color: '#00ff00', 'font-size': '20px' },
attributes: { title: 'My Custom Wrapper' },
},
},
},
{
field: 'tinymceOverrides',
name: i18n.t('tinymce_options_override'),
interface: 'code',
options: {
type: 'application/json',
},
},
],
}));

View File

@@ -0,0 +1,33 @@
# WYSIWYG
Rich Text editor based on TineMCE.
## Options
| Option | Description | Default |
|---------------------|--------------------------------------------------------------------------------------------------|--------------|
| `toolbar` | What toolbar options to show | _See below_ |
| `custom-formats` | What custom html blocks to show in the editor | `null` |
| `font` | Font to render the value in (`sans-serif`, `serif`, or `monospace`) | `serif` |
| `tinymce-overrides` | Override any of the [init options](https://www.tiny.cloud/docs/configure/integration-and-setup/) | `null` |
### Toolbar defaults
```
bold,
italic,
underline,
removeformat,
link,
bullist,
numlist,
blockquote,
h1,
h2,
h3,
image,
media,
hr,
code,
fullscreen
```

View File

@@ -0,0 +1,239 @@
/* stylelint-disable font-family-no-missing-generic-family-keyword */
.tox .tox-tbtn svg {
fill: var(--foreground-normal);
}
.tox-tbtn[aria-label='Bold'] .tox-icon svg {
display: none;
}
.tox-tbtn[aria-label='Bold'] .tox-icon::after {
display: inline-block;
margin-top: 4px;
color: var(--foreground-normal);
font-size: 24px;
font-family: 'Material Icons';
content: 'format_bold';
font-feature-settings: 'liga';
}
.tox-tbtn[aria-label='Italic'] .tox-icon svg {
display: none;
}
.tox-tbtn[aria-label='Italic'] .tox-icon::after {
display: inline-block;
margin-top: 4px;
color: var(--foreground-normal);
font-size: 24px;
font-family: 'Material Icons';
content: 'format_italic';
font-feature-settings: 'liga';
}
.tox-tbtn[aria-label='Underline'] .tox-icon svg {
display: none;
}
.tox-tbtn[aria-label='Underline'] .tox-icon::after {
display: inline-block;
margin-top: 4px;
color: var(--foreground-normal);
font-size: 24px;
font-family: 'Material Icons';
content: 'format_underlined';
font-feature-settings: 'liga';
}
.tox-tbtn[aria-label='Insert/edit link'] .tox-icon svg {
display: none;
}
.tox-tbtn[aria-label='Insert/edit link'] .tox-icon::after {
display: inline-block;
margin-top: 4px;
color: var(--foreground-normal);
font-size: 24px;
font-family: 'Material Icons';
content: 'insert_link';
font-feature-settings: 'liga';
}
.tox .tox-edit-area__iframe {
background-color: var(--background-page);
}
.tox-tinymce {
min-height: 300px;
color: var(--foreground-normal);
border: 2px solid var(--border-normal);
border-radius: var(--border-radius);
transition: var(--fast) var(--transition);
transition-property: color, border-color;
}
.tox-tinymce:hover {
border-color: var(--border-normal-alt);
}
.tox-tinymce:focus {
border-color: var(--primary);
}
.tox .tox-toolbar,
.tox .tox-toolbar__primary,
.tox .tox-toolbar__overflow {
background: url("data:image/svg+xml;charset=utf8,%3Csvg height='39px' viewBox='0 0 40 39px' width='40' xmlns='http://www.w3.org/2000/svg'%3E%3Crect x='0' y='37px' width='100' height='2' fill='%23cfd8dc'/%3E%3C/svg%3E")
left 0 top 0 var(--background-subdued);
}
body.dark .tox .tox-toolbar,
body.dark .tox .tox-toolbar__primary,
body.dark .tox .tox-toolbar__overflow {
background: url("data:image/svg+xml;charset=utf8,%3Csvg height='39px' viewBox='0 0 40 39px' width='40' xmlns='http://www.w3.org/2000/svg'%3E%3Crect x='0' y='37px' width='100' height='2' fill='%23455a64'/%3E%3C/svg%3E")
left 0 top 0 var(--background-subdued);
}
@media (prefers-color-scheme: dark) {
body.auto .tox .tox-toolbar,
body.auto .tox .tox-toolbar__primary,
body.auto .tox .tox-toolbar__overflow {
background: url("data:image/svg+xml;charset=utf8,%3Csvg height='39px' viewBox='0 0 40 39px' width='40' xmlns='http://www.w3.org/2000/svg'%3E%3Crect x='0' y='37px' width='100' height='2' fill='%23455a64'/%3E%3C/svg%3E")
left 0 top 0 var(--background-subdued);
}
}
.tox .tox-tbtn {
margin-right: 2px;
color: var(--foreground-normal);
}
.tox .tox-tbtn--enabled,
.tox .tox-tbtn--enabled:hover,
.tox .tox-tbtn:hover {
color: var(--foreground-normal);
background: var(--border-normal);
}
.mce-content-body {
margin: 20px;
}
/* Modal */
.tox .tox-dialog-wrap__backdrop {
background-color: rgba(0, 0, 0, 0.75);
}
.tox .tox-dialog {
color: var(--foreground-normal);
background-color: var(--background-page);
border: none;
box-shadow: none;
}
.tox .tox-dialog--width-lg {
max-width: 800px;
}
.tox .tox-dialog__header {
padding: 16px 24px 0 24px;
color: var(--foreground-normal);
background-color: var(--background-page);
}
.tox .tox-dialog__body-content {
padding: 24px 24px;
}
.tox .tox-dialog__footer {
padding: 0 24px 24px;
color: var(--foreground-normal);
background-color: var(--background-page);
border-top: none;
}
.tox .tox-textfield,
.tox .tox-toolbar-textfield,
.tox .tox-selectfield select,
.tox .tox-textarea {
padding: 12px;
color: var(--foreground-normal);
font-family: monospace;
background-color: var(--background-page);
border: 2px solid var(--border-normal);
border-radius: var(--border-radius);
transition: var(--fast) var(--transition);
}
.tox .tox-textfield:focus,
.tox .tox-selectfield select:focus,
.tox .tox-textarea:focus {
border-color: var(--foreground-subdued);
}
.tox .tox-button {
display: flex;
align-items: center;
justify-content: center;
min-width: 136px;
height: 44px;
padding: 0 20px 1px;
color: var(--white);
font-weight: 500;
font-size: 16px;
line-height: 19px;
background-color: var(--primary);
border: 2px solid var(--primary);
border: none;
border-color: var(--primary);
border-radius: var(--border-radius);
cursor: pointer;
-webkit-transition: var(--fast) var(--transition);
transition: var(--fast) var(--transition);
transition-property: border-color, background-color, color;
}
.tox .tox-button:hover:not(:disabled) {
background-color: var(--primary);
border-color: var(--primary);
}
.tox .tox-button--secondary {
color: var(--foreground-normal);
background-color: var(--background-normal);
border-color: var(--background-normal);
}
.tox .tox-button--secondary:hover:not(:disabled) {
color: var(--foreground-normal);
background-color: var(--background-normal);
border-color: var(--background-normal);
}
.tox .tox-button--naked {
min-width: auto;
height: auto;
color: var(--foreground-subdued);
background-color: transparent;
border-color: transparent;
}
.tox .tox-button--naked.tox-button--icon:hover:not(:disabled) {
color: var(--foreground-normal);
background-color: transparent;
border-color: transparent;
}
.tox .tox-form__group {
margin-top: 24px;
}
.tox .tox-label,
.tox .tox-toolbar-label {
margin-bottom: 10px;
color: var(--foreground-normal);
font-size: 14px;
}

View File

@@ -0,0 +1,36 @@
import { withKnobs, select } from '@storybook/addon-knobs';
import readme from './readme.md';
import withPadding from '../../../.storybook/decorators/with-padding';
import { defineComponent, ref } from '@vue/composition-api';
import RawValue from '../../../.storybook/raw-value.vue';
export default {
title: 'Interfaces / WYSIWYG',
decorators: [withKnobs, withPadding],
parameters: {
notes: readme,
},
};
export const basic = () =>
defineComponent({
components: { RawValue },
props: {
font: {
default: select('Font', ['sans-serif', 'serif', 'monospace'], 'serif'),
},
},
setup() {
const value = ref(false);
return { value };
},
template: `
<div>
<interface-wysiwyg
v-model="value"
:font="font"
/>
<raw-value>{{ value }}</raw-value>
</div>
`,
});

View File

@@ -0,0 +1,144 @@
<template>
<Editor ref="editorElement" :init="editorOptions" v-model="_value" />
</template>
<script lang="ts">
import { defineComponent, PropType, ref, computed, watch } from '@vue/composition-api';
import 'tinymce/tinymce';
import 'tinymce/themes/silver';
import 'tinymce/plugins/media/plugin';
import 'tinymce/plugins/table/plugin';
import 'tinymce/plugins/hr/plugin';
import 'tinymce/plugins/lists/plugin';
import 'tinymce/plugins/image/plugin';
import 'tinymce/plugins/imagetools/plugin';
import 'tinymce/plugins/link/plugin';
import 'tinymce/plugins/pagebreak/plugin';
import 'tinymce/plugins/code/plugin';
import 'tinymce/plugins/insertdatetime/plugin';
import 'tinymce/plugins/autoresize/plugin';
import 'tinymce/plugins/paste/plugin';
import 'tinymce/plugins/preview/plugin';
import 'tinymce/plugins/fullscreen/plugin';
import 'tinymce/plugins/directionality/plugin';
import Editor from '@tinymce/tinymce-vue';
import { debounce } from 'lodash';
import getEditorStyles from './get-editor-styles';
type CustomFormat = {
title: string;
inline: string;
classes: string;
styles: Record<string, string>;
attributes: Record<string, string>;
};
export default defineComponent({
components: { Editor },
props: {
value: {
type: String,
default: '',
},
toolbar: {
type: Array as PropType<string[]>,
default: () => [
'bold',
'italic',
'underline',
'removeformat',
'link',
'bullist',
'numlist',
'blockquote',
'h1',
'h2',
'h3',
'image',
'media',
'hr',
'code',
'fullscreen',
],
},
font: {
type: String as PropType<'sans-serif' | 'serif' | 'monospace'>,
default: 'serif',
},
customFormats: {
type: Array as PropType<CustomFormat[]>,
default: () => [],
},
tinymceOverrides: {
type: Object,
default: null,
},
disabled: {
type: Boolean,
default: false,
},
},
setup(props, { emit }) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const editorElement = ref<any>(null);
const _value = computed({
get() {
return props.value;
},
set(newValue: string) {
emit('input', newValue);
},
});
const editorOptions = computed(() => {
let styleFormats = null;
if (Array.isArray(props.customFormats) && props.customFormats.length > 0) {
styleFormats = props.customFormats;
}
let toolbarString = props.toolbar.join(' ');
if (styleFormats) {
toolbarString += ' styleselect';
}
return {
skin: false,
skin_url: false,
content_css: false,
content_style: getEditorStyles(props.font as 'sans-serif' | 'serif' | 'monospace'),
plugins:
'media table hr lists image link pagebreak code insertdatetime autoresize paste preview fullscreen directionality',
branding: false,
max_height: 1000,
elementpath: false,
statusbar: false,
menubar: false,
convert_urls: false,
readonly: props.disabled,
extended_valid_elements: 'audio[loop],source',
toolbar: toolbarString,
style_formats: styleFormats,
...(props.tinymceOverrides || {}),
};
});
return { editorElement, editorOptions, _value };
},
});
</script>
<style lang="scss" scoped>
.body {
padding: 20px;
}
@import '~tinymce/skins/ui/oxide/skin.css';
@import './tinymce-overrides.css';
</style>

View File

@@ -284,6 +284,56 @@
"icon_on": "Icon (On)",
"icon_off": "Icon (Off)",
"label": "Label",
"wysiwyg": "WYSIWYG",
"toolbar": "Toolbar",
"wysiwyg_options": {
"aligncenter": "Align Center",
"alignjustify": "Align Justify",
"alignleft": "Align Left",
"alignnone": "Align None",
"alignright": "Align Right",
"forecolor": "Foreground Color",
"backcolor": "Background Color",
"bold": "Bold",
"italic": "Italic",
"underline": "Underline",
"strikethrough": "Strikethrough",
"subscript": "Subscript",
"superscript": "Superscript",
"blockquote": "Blockquote",
"bullist": "Bullet List",
"numlist": "Numbered List",
"hr": "Horizontal Rule",
"link": "Add Link",
"unlink": "Remove Link",
"media": "Add Media",
"image": "Add Image",
"copy": "Copy",
"cut": "Cut",
"paste": "Paste",
"h1": "Heading 1",
"h2": "Heading 2",
"h3": "Heading 3",
"h4": "Heading 4",
"h5": "Heading 5",
"h6": "Heading 6",
"fontselect": "Select Font",
"fontsizeselect": "Select Font Size",
"indent": "Indent",
"outdent": "Outdent",
"undo": "Undo",
"redo": "Redo",
"remove": "Remove",
"removeformat": "Remove Format",
"selectall": "Select All",
"table": "Table",
"visualaid": "View invisible elements",
"code": "View Source",
"fullscreen": "Full Screen",
"directionality": "Directionality"
},
"custom_formats": "Custom Formats",
"tinymce_options_override": "TinyMCE Options Override",
"about_directus": "About Directus",
"activity_log": "Activity Log",

View File

@@ -52,7 +52,7 @@ export const useNotificationsStore = createStore({
}
return notification;
}
}
},
},
getters: {
lastFour(state) {

View File

@@ -6,6 +6,8 @@
:is="`display-${part.component}`"
:key="index"
:value="part.value"
:interface="part.interface"
:interface-options="part.interfaceOptions"
v-bind="part.options"
/>
<template v-else>{{ part }}</template>
@@ -74,6 +76,8 @@ export default defineComponent({
component: field.display,
options: field.display_options,
value: value,
interface: field.interface,
interfaceOptions: field.options,
};
})
);

View File

@@ -1852,6 +1852,11 @@
dependencies:
defer-to-connect "^1.0.1"
"@tinymce/tinymce-vue@^3.2.0":
version "3.2.0"
resolved "https://registry.yarnpkg.com/@tinymce/tinymce-vue/-/tinymce-vue-3.2.0.tgz#abadab7fd6e143688e756df779fc3b81e586427a"
integrity sha512-7mrexFcL23TdsHL35EHrhUN1HhRW5DbHeraai+idOqARhUhbATDxp4RBBUBGfuCjsEPnkNdu9+CcJl9xETSH/g==
"@types/babel__core@^7.1.0":
version "7.1.6"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.6.tgz#16ff42a5ae203c9af1c6e190ed1f30f83207b610"
@@ -14260,6 +14265,11 @@ tinycolor2@^1.4.1:
resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8"
integrity sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=
tinymce@^5.2.2:
version "5.2.2"
resolved "https://registry.yarnpkg.com/tinymce/-/tinymce-5.2.2.tgz#1ac77cce1565b54932b4e612d2fd9c07b687f238"
integrity sha512-G1KZOxHIrokeP/rhJuvwctmeAuHDAeH8AI1ubnVcdMZtmC6mUh3SfESqFJrFWoiF143OUMC61GkVhi920pIP0A==
tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"