trying to extend that editor
This commit is contained in:
parent
936ada94bd
commit
a33363eef0
4 changed files with 152 additions and 9 deletions
|
@ -1,15 +1,17 @@
|
|||
<template>
|
||||
<editor-menu-bar :editor="editor" v-slot="{ commands, isActive, focused }">
|
||||
<div class="menu-bar" :class="{ active: focused }">
|
||||
<button class="editor-button-bold" :class="{ active: isActive.bold() }" @click="commands.bold" />
|
||||
<button class="editor-button-italic" :class="{ active: isActive.italic() }" @click="commands.italic" />
|
||||
<button class="editor-button-bold" :class="{ active: active.bold }" @click="menuAction('bold', commands.bold, isActive)" />
|
||||
<button class="editor-button-italic" :class="{ active: active.italic }" @click="menuAction('italic', commands.italic, isActive)" />
|
||||
|
||||
<button class="editor-button-paragraph" :class="{ active: isActive.paragraph() }" @click="commands.paragraph" />
|
||||
<button class="editor-button-heading2" :class="{ active: isActive.heading({ level: 2 }) }" @click="commands.heading({ level: 2})" />
|
||||
<button class="editor-button-heading3" :class="{ active: isActive.heading({ level: 3 }) }" @click="commands.heading({ level: 3})" />
|
||||
<button class="editor-button-paragraph" :class="{ active: active.paragraph }" @click="menuAction('paragraph', commands.paragraph, isActive)" />
|
||||
<button class="editor-button-heading2" :class="{ active: active.heading2 }" @click="menuAction('heading2', commands.heading({ level: 2}), isActive)" />
|
||||
<button class="editor-button-heading3" :class="{ active: active.heading3 }" @click="menuAction('heading3', commands.heading({ level: 3}), isActive)" />
|
||||
|
||||
<button class="editor-button-bullet-list" :class="{ active: isActive.bullet_list() }" @click="commands.bullet_list" />
|
||||
<button class="editor-button-horizontal-rule" :class="{ active: isActive.horizontal_rule() }" @click="commands.horizontal_rule" />
|
||||
<button class="editor-button-bullet-list" :class="{ active: active.bullet_list }" @click="menuAction('bullet_list', commands.bullet_list, isActive)" />
|
||||
<button class="editor-button-horizontal-rule" :class="{ active: active.horizontal_rule }" @click="menuAction('horizontal_rule', commands.horizontal_rule, isActive)" />
|
||||
|
||||
<button class="editor-button-stat-block" :class="{ active: active.stat_block }" @click="menuAction('stat_block', commands.stat_block, isActive)" />
|
||||
</div>
|
||||
</editor-menu-bar>
|
||||
</template>
|
||||
|
@ -23,6 +25,26 @@ import { Editor, EditorMenuBar } from 'tiptap'
|
|||
})
|
||||
export default class DeckCardEditorMenu extends Vue {
|
||||
@Prop() public readonly editor!: Editor
|
||||
|
||||
private active: {[key: string]: boolean} = {
|
||||
bold: false,
|
||||
italic: false,
|
||||
|
||||
paragraph: false,
|
||||
heading2: false,
|
||||
heading3: false,
|
||||
|
||||
bulletList: false,
|
||||
horizontalLule: false
|
||||
}
|
||||
|
||||
private menuAction (name: string, command: () => void, isActive: {[key: string]: () => boolean}) {
|
||||
command()
|
||||
|
||||
Object.keys(this.active).forEach(action => {
|
||||
this.active[action] = isActive[action]()
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -63,6 +85,9 @@ export default class DeckCardEditorMenu extends Vue {
|
|||
font-size: 1.2rem;
|
||||
color: black;
|
||||
}
|
||||
.menu-bar > button.active {
|
||||
background-color: #FF0;
|
||||
}
|
||||
.editor-button-bold { background-image: url(../assets/zondicons/format-bold.svg); }
|
||||
.editor-button-italic { background-image: url(../assets/zondicons/format-italic.svg); }
|
||||
.editor-button-bullet-list { background-image: url(../assets/zondicons/list-bullet.svg); }
|
||||
|
@ -71,4 +96,6 @@ export default class DeckCardEditorMenu extends Vue {
|
|||
.editor-button-heading3:after { content: 'H3'; }
|
||||
.editor-button-paragraph:after { content: 'P'; }
|
||||
.editor-button-horizontal-rule:after { content: '—'; }
|
||||
|
||||
.editor-button-stat-block:after { content: 'ST'; }
|
||||
</style>
|
||||
|
|
|
@ -34,7 +34,20 @@
|
|||
import { Component, Prop, Vue } from 'vue-property-decorator'
|
||||
import { cardWHtoStyle, iconPath } from '@/lib'
|
||||
import { Editor, EditorContent } from 'tiptap'
|
||||
import { Heading, Bold, Italic, HorizontalRule, BulletList, ListItem, History } from 'tiptap-extensions'
|
||||
import {
|
||||
Heading,
|
||||
Bold,
|
||||
Italic,
|
||||
HorizontalRule,
|
||||
BulletList,
|
||||
ListItem,
|
||||
History,
|
||||
Table,
|
||||
TableCell,
|
||||
TableRow,
|
||||
TableHeader
|
||||
} from 'tiptap-extensions'
|
||||
import StatBlock from '@/editor/stat-block.js'
|
||||
import DeckCardEditorMenu from '@/components/deck-card-editor-menu.vue'
|
||||
|
||||
interface EditorContext {
|
||||
|
@ -51,7 +64,8 @@ const extensions = [
|
|||
new HorizontalRule(),
|
||||
new BulletList(),
|
||||
new ListItem(),
|
||||
new History()
|
||||
new History(),
|
||||
new StatBlock()
|
||||
]
|
||||
|
||||
@Component({
|
||||
|
|
53
src/editor/stat-block.js
Normal file
53
src/editor/stat-block.js
Normal file
|
@ -0,0 +1,53 @@
|
|||
import { Node } from 'tiptap'
|
||||
import { tableNodes, tableEditing, goToNextCell, deleteTable } from 'prosemirror-tables'
|
||||
import { createTable } from 'prosemirror-utils'
|
||||
import { TextSelection } from 'prosemirror-state'
|
||||
|
||||
export default class StatBlock extends Node {
|
||||
get name () {
|
||||
return 'stat_block'
|
||||
}
|
||||
|
||||
get defaultOptions () {
|
||||
return {
|
||||
resizable: false
|
||||
}
|
||||
}
|
||||
|
||||
get schema () {
|
||||
return {
|
||||
group: 'block',
|
||||
content: 'stat_column+',
|
||||
toDOM: () => ['ol', { 'data-type': this.name }, 0],
|
||||
parseDOM: [{
|
||||
priority: 51,
|
||||
tag: `[data-type="${this.name}"]`
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
commands ({ schema }) {
|
||||
return () => (state, dispatch) => {
|
||||
const offset = state.tr.selection.anchor + 1
|
||||
|
||||
const nodes = createTable(schema, 2, 6, true)
|
||||
const tr = state.tr.replaceSelectionWith(nodes).scrollIntoView()
|
||||
const resolvedPos = tr.doc.resolve(offset)
|
||||
|
||||
tr.setSelection(TextSelection.near(resolvedPos))
|
||||
|
||||
dispatch(tr)
|
||||
}
|
||||
}
|
||||
|
||||
keys () {
|
||||
return {
|
||||
Tab: goToNextCell(1),
|
||||
'Shift-Tab': goToNextCell(-1)
|
||||
}
|
||||
}
|
||||
|
||||
get plugins () {
|
||||
return [tableEditing()]
|
||||
}
|
||||
}
|
49
src/editor/stat-block.ts
Normal file
49
src/editor/stat-block.ts
Normal file
|
@ -0,0 +1,49 @@
|
|||
import { Node } from 'tiptap'
|
||||
import { tableEditing, goToNextCell, deleteTable } from 'prosemirror-tables'
|
||||
import { createTable } from 'prosemirror-utils'
|
||||
import { TextSelection } from 'prosemirror-state'
|
||||
import { TableNodes } from 'tiptap-extensions'
|
||||
|
||||
export default class StatBlock extends Node {
|
||||
public get name () {
|
||||
return 'stat_block'
|
||||
}
|
||||
|
||||
public get defaultOptions () {
|
||||
return {
|
||||
resizable: false
|
||||
}
|
||||
}
|
||||
|
||||
public get schema () {
|
||||
return TableNodes.table
|
||||
}
|
||||
|
||||
public commands ({ schema }) {
|
||||
return {
|
||||
createStatBlock: () => (state, dispatch) => {
|
||||
const offset = state.tr.selection.anchor + 1
|
||||
|
||||
const nodes = createTable(schema, 2, 6, true)
|
||||
const tr = state.tr.replaceSelectionWith(nodes).scrollIntoView()
|
||||
const resolvedPos = tr.doc.resolve(offset)
|
||||
|
||||
tr.setSelection(TextSelection.near(resolvedPos))
|
||||
|
||||
dispatch(tr)
|
||||
},
|
||||
deleteTable: () => deleteTable
|
||||
}
|
||||
}
|
||||
|
||||
public keys () {
|
||||
return {
|
||||
Tab: goToNextCell(1),
|
||||
'Shift-Tab': goToNextCell(-1)
|
||||
}
|
||||
}
|
||||
|
||||
public get plugins () {
|
||||
return [tableEditing()]
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue