All extensions are listed below.
import {
BaseKit,
Blockquote,
Bold,
BulletList,
Clear,
CodeBlock,
Color,
FontFamily,
FontSize,
Fullscreen,
Heading,
Highlight,
History,
HorizontalRule,
Image,
Indent,
Italic,
Link,
OrderedList,
Strike,
Table,
TextAlign,
Underline,
Video
} from 'olotap';
In the following example, we will explain how to create an emoji extension for your Olotap editor. If you want to see full code example you can reach our demo repo from here.
├── olotap-demo
├── node-modules
├── public
├── src
│ ├── components
│ │ ├── EmojiActionButton.vue
│ ├── extensions
│ │ ├── emoji.js
│ ├── i18n
│ │ ├── locales
│ │ │ ├── en.js
│ │ │ ├── tr.js
│ ├── index.js
│ ├── plugins
│ │ ├── index.js
│ │ ├── vuetify.js
First let's create a our emoji.js in your extensions/ folder.
import { Node } from '@tiptap/core';
import EmojiActionButton from '../components/EmojiActionButton.vue';
import { Context } from "olotap";
export const Emoji = Node.create({
name: 'emoji',
addOptions() {
const { state } = Context.useContext(); // olotap store for i18n and others ...
return {
...this.parent?.(),
button: ({ editor }) => ({
component: EmojiActionButton,
componentProps: {
editor,
action: (emoji) => {
if (typeof emoji === 'string') editor.chain().focus().insertContent(emoji).run();
},
isActive: () => editor.isActive('emoji') || false,
icon: 'mdi-emoticon-outline',
tooltip: state.t('editor.emoji.tooltip')
}
})
};
}
});
export default Emoji;
At the second step you need to create your button component called EmojiActionButton.vue in your components/ folder. This component will open a menu with the help of vuetify v-menu when the emoji button is pressed and allow you to choose one of the available emoji lists.
<template>
<action-button
:icon="icon"
:tooltip="tooltip"
:disabled="disabled"
:is-active="isActive"
>
<v-menu
v-model="menu"
:nudge-left="50"
:nudge-top="42"
:close-on-content-click="false"
transition="scale-transition"
activator="parent"
>
<v-list>
<v-sheet class="d-flex flex-wrap justify-between ma-1" fluid :max-width="230">
<template v-for="emoji in getEmojiList" :key="emoji">
<v-btn flat elevation="0" icon density="compact" @click="addEmoji(emoji)">
{{ emoji }}
</v-btn>
</template>
</v-sheet>
</v-list>
</v-menu>
</action-button>
</template>
<script>
import { ActionButton } from "olotap";
export default {
components: {
ActionButton,
},
props: {
editor: {
type: Object,
required: true
},
icon: {
type: String,
default: undefined
},
tooltip: {
type: String,
default: undefined
},
disabled: {
type: Boolean,
default: false
},
action: {
type: Function,
default: undefined
},
isActive: {
type: Function,
default: undefined
}
},
data() {
return {
menu: false,
emojiList: [
"😀", "😁", "😂", "🤣", "😃", "😄", "😅", "😆", "😉", "😊",
"😎", "😍", "😘", "😗", "😙", "😚", "🤗", "🤩", "🤔", "🤨",
"😐", "😑", "😶", "🙄", "😏", "😣", "😥", "😮", "🤐", "😯",
"😪", "😫", "🥱", "😴", "😌", "🤤", "😛", "😜", "😝", "🤪"
],
};
},
computed: {
getEmojiList() {
return this.emojiList;
}
},
methods: {
addEmoji(emoji) {
if (this.action) {
this.action(emoji);
}
}
}
};
</script>
Go to i18n/locales/en.js and add a translation for the tooltip that will be shown when the emoji button hovers. Below the example we added translation for emoji.tooltip key.
{
"locale": {
"en": "English",
"tr": "Türkçe"
},
"editor": {
"placeholder": "Enter you content here...",
"video": {
"tooltip": "Video",
},
"emoji": {
"tooltip": "Emoji"
}
}
}
Now let's look at how to include the emoji extension in your application. Import the emoji file and add it to the extension list as follows.
import i18n from "@/i18n";
import "olotap/classic-editor.css";
import { OlotapEditor, defaultBubbleList, Context } from "olotap";
import Emoji from '@/extensions/emoji';
export default {
name: 'App',
components: {
OlotapEditor
},
data() {
return {
lang: "en",
model: {
contentJson: null,
contentHtml: null
},
errorMessages: [],
markdownTheme: "default",
editorKey: "editor_",
extensions: [],
};
},
created() {
this.model.contentJson = defaultContentJson;
this.created = false;
this.createExtensions();
this.created = true;
},
watch: {
lang(val) {
i18n.global.locale.value = val;
this.createExtensions(); // re create extension for new locale
}
},
computed: {
isFullscreen() {
return Context.useContext().state.isFullscreen;
},
getEditorKey() {
return "olotap_" + i18n.global.locale.value;
}
},
methods: {
createExtensions() {
const {
BaseKit,
History,
Video,
Table,
Blockquote,
HorizontalRule,
CodeBlock,
// Fullscreen,
} = this.$extensions;
this.extensions = [
BaseKit.configure({
placeholder: {
placeholder: this.$t("editor.placeholder")
},
bubble: {
// default config
list: {
image: [ 'float-left', 'float-none', 'float-right', 'divider', 'image-size-small', 'image-size-medium', 'image-size-large', 'divider', 'textAlign', 'divider', 'image', 'image-aspect-ratio', 'remove'],
text: ['bold', 'italic', 'underline', 'strike', 'divider', 'color', 'highlight', 'textAlign', 'divider', 'link'],
video: ['video', 'video-size-small', 'video-size-medium', 'video-size-large', 'remove'],
codeBlock: ['paste-code', 'change-language', 'copy-code', 'remove'],
horizontalRule: ['remove'],
blockquote: ['remove'],
},
defaultBubbleList: editor => {
// You can customize the bubble menu here
const defaultBubble = defaultBubbleList(editor)
return defaultBubble; // default customize bubble list
}
}
}),
History.configure({ divider: true }),
Video,
Table.configure({ divider: true }),
Blockquote,
HorizontalRule,
CodeBlock,
Emoji
// Fullscreen,
];
},
onChange(val) {
// console.error(val)
},
}
};
If everything went well, your emoji button should look like this in the editor.