fix suggestions example

This commit is contained in:
Philipp Kühn
2018-10-23 23:16:51 +02:00
parent e66debc823
commit a84e71cc2a

View File

@@ -1,19 +1,9 @@
<template> <template>
<div> <div>
<editor class="editor" :extensions="extensions" ref="editor"> <div class="editor">
<div class="editor__content" slot="content" slot-scope="props"> <editor-content class="editor__content" :editor="editor" />
<h2> </div>
Suggestions
</h2>
<p>
Sometimes it's useful to <strong>mention</strong> someone. That's a feature we're very used to. Under the hood this technique can also be used for other features likes <strong>hashtags</strong> and <strong>commands</strong> lets call it <em>suggestions</em>.
</p>
<p>
This is an example how to mention some users like <span data-mention-id="1">Philipp Kühn</span> or <span data-mention-id="2">Hans Pagel</span>. Try to type <code>@</code> and a popup (rendered with tippy.js) will appear. You can navigate with arrow keys through a list of suggestions.
</p>
</div>
</editor>
<div class="suggestion-list" v-show="showSuggestions" ref="suggestions"> <div class="suggestion-list" v-show="showSuggestions" ref="suggestions">
<template v-if="hasResults"> <template v-if="hasResults">
@@ -38,8 +28,7 @@
<script> <script>
import Fuse from 'fuse.js' import Fuse from 'fuse.js'
import tippy from 'tippy.js' import tippy from 'tippy.js'
import Icon from 'Components/Icon' import { Editor, EditorContent } from 'tiptap'
import { Editor } from 'tiptap'
import { import {
HardBreakNode, HardBreakNode,
HeadingNode, HeadingNode,
@@ -52,92 +41,104 @@ import {
export default { export default {
components: { components: {
Editor, EditorContent,
Icon,
}, },
data() { data() {
return { return {
extensions: [ editor: new Editor({
new HardBreakNode(), extensions: [
new HeadingNode({ maxLevel: 3 }), new HardBreakNode(),
new MentionNode({ new HeadingNode({ maxLevel: 3 }),
// a list of all suggested items new MentionNode({
items: [ // a list of all suggested items
{ id: 1, name: 'Philipp Kühn' }, items: [
{ id: 2, name: 'Hans Pagel' }, { id: 1, name: 'Philipp Kühn' },
{ id: 3, name: 'Kris Siepert' }, { id: 2, name: 'Hans Pagel' },
{ id: 4, name: 'Justin Schueler' }, { id: 3, name: 'Kris Siepert' },
], { id: 4, name: 'Justin Schueler' },
// is called when a suggestion starts ],
onEnter: ({ items, query, range, command, virtualNode }) => { // is called when a suggestion starts
this.query = query onEnter: ({ items, query, range, command, virtualNode }) => {
this.filteredUsers = items this.query = query
this.suggestionRange = range this.filteredUsers = items
this.renderPopup(virtualNode) this.suggestionRange = range
// we save the command for inserting a selected mention this.renderPopup(virtualNode)
// this allows us to call it inside of our custom popup // we save the command for inserting a selected mention
// via keyboard navigation and on click // this allows us to call it inside of our custom popup
this.insertMention = command // via keyboard navigation and on click
}, this.insertMention = command
// is called when a suggestion has changed },
onChange: ({ items, query, range, virtualNode }) => { // is called when a suggestion has changed
this.query = query onChange: ({ items, query, range, virtualNode }) => {
this.filteredUsers = items this.query = query
this.suggestionRange = range this.filteredUsers = items
this.navigatedUserIndex = 0 this.suggestionRange = range
this.renderPopup(virtualNode) this.navigatedUserIndex = 0
}, this.renderPopup(virtualNode)
// is called when a suggestion is cancelled },
onExit: () => { // is called when a suggestion is cancelled
// reset all saved values onExit: () => {
this.query = null // reset all saved values
this.filteredUsers = [] this.query = null
this.suggestionRange = null this.filteredUsers = []
this.navigatedUserIndex = 0 this.suggestionRange = null
this.destroyPopup() this.navigatedUserIndex = 0
}, this.destroyPopup()
// is called on every keyDown event while a suggestion is active },
onKeyDown: ({ event }) => { // is called on every keyDown event while a suggestion is active
// pressing up arrow onKeyDown: ({ event }) => {
if (event.keyCode === 38) { // pressing up arrow
this.upHandler() if (event.keyCode === 38) {
return true this.upHandler()
} return true
// pressing down arrow }
if (event.keyCode === 40) { // pressing down arrow
this.downHandler() if (event.keyCode === 40) {
return true this.downHandler()
} return true
// pressing enter }
if (event.keyCode === 13) { // pressing enter
this.enterHandler() if (event.keyCode === 13) {
return true this.enterHandler()
} return true
}
return false return false
}, },
// is called when a suggestion has changed // is called when a suggestion has changed
// this function is optional because there is basic filtering built-in // this function is optional because there is basic filtering built-in
// you can overwrite it if you prefer your own filtering // you can overwrite it if you prefer your own filtering
// in this example we use fuse.js with support for fuzzy search // in this example we use fuse.js with support for fuzzy search
onFilter: (items, query) => { onFilter: (items, query) => {
if (!query) { if (!query) {
return items return items
} }
const fuse = new Fuse(items, { const fuse = new Fuse(items, {
threshold: 0.2, threshold: 0.2,
keys: ['name'], keys: ['name'],
}) })
return fuse.search(query) return fuse.search(query)
}, },
}), }),
new CodeMark(), new CodeMark(),
new BoldMark(), new BoldMark(),
new ItalicMark(), new ItalicMark(),
], ],
content: `
<h2>
Suggestions
</h2>
<p>
Sometimes it's useful to <strong>mention</strong> someone. That's a feature we're very used to. Under the hood this technique can also be used for other features likes <strong>hashtags</strong> and <strong>commands</strong> lets call it <em>suggestions</em>.
</p>
<p>
This is an example how to mention some users like <span data-mention-id="1">Philipp Kühn</span> or <span data-mention-id="2">Hans Pagel</span>. Try to type <code>@</code> and a popup (rendered with tippy.js) will appear. You can navigate with arrow keys through a list of suggestions.
</p>
`,
}),
query: null, query: null,
suggestionRange: null, suggestionRange: null,
filteredUsers: [], filteredUsers: [],
@@ -190,7 +191,7 @@ export default {
label: user.name, label: user.name,
}, },
}) })
this.$refs.editor.focus() this.editor.focus()
}, },
// renders a popup with suggestions // renders a popup with suggestions