Skip to content

Commit

Permalink
feat(extensions): todoList and TodoItem extension!
Browse files Browse the repository at this point in the history
Checkboxes lists with nested support

re #127
  • Loading branch information
iliyaZelenko committed Feb 19, 2020
1 parent da40d9c commit de0aa90
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 2 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ Available extensions (native tiptap extensions from `tiptap-extensions` package)
- `HardBreak`
- `HorizontalRule`
- `History`
- `TodoList` (use with the `TodoItem` extension)
- `TodoItem`

I can easily add more.

Expand Down
8 changes: 7 additions & 1 deletion demo/pages/Index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,17 @@ export default {
async created () {
const {
Heading, Bold, Italic, Strike, Underline, Code, CodeBlock, Paragraph, BulletList, OrderedList, ListItem,
Link, Blockquote, HardBreak, HorizontalRule, History, Image
Link, Blockquote, HardBreak, HorizontalRule, History, Image, TodoList, TodoItem
} = await MAIN_MODULE
this.extensions = [
MyCustomExtension,
TodoList,
[TodoItem, {
options: {
nested: true
}
}],
Code,
CodeBlock,
HorizontalRule,
Expand Down
14 changes: 14 additions & 0 deletions src/extensions/nativeExtensions/TodoList/TodoItem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// import { TodoItem as TodoItemOriginal } from 'tiptap-extensions'
import AbstractExtension from '~/extensions/AbstractExtension'
import ExtensionActionInterface from '~/extensions/actions/ExtensionActionInterface'
import TodoItemNode from '~/extensions/nativeExtensions/TodoList/TodoItemNode'

export default class TodoItem extends AbstractExtension {
constructor (options) {
super(options, TodoItemNode)
}

get availableActions (): ExtensionActionInterface[] {
return []
}
}
62 changes: 62 additions & 0 deletions src/extensions/nativeExtensions/TodoList/TodoItemNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// @ts-ignore
import { Node } from 'tiptap'
import { sinkListItem, splitToDefaultListItem, liftListItem } from 'tiptap-commands'
import TodoItemView from './TodoItemView.vue'

export default class TodoItem extends Node {
options

get name () {
return 'todo_item'
}

get defaultOptions () {
return {
nested: false
}
}

get view () {
return TodoItemView
}

get schema () {
return {
attrs: {
done: {
default: false
}
},
draggable: true,
content: this.options.nested ? '(paragraph|todo_list)+' : 'paragraph+',
toDOM: node => {
const { done } = node.attrs

return [
'li',
{
'data-type': this.name,
'data-done': done.toString()
},
['span', { class: 'todo-checkbox', contenteditable: 'false' }],
['div', { class: 'todo-content' }, 0]
]
},
parseDOM: [{
priority: 51,
tag: `[data-type="${this.name}"]`,
getAttrs: dom => ({
done: dom.getAttribute('data-done') === 'true'
})
}]
}
}

keys ({ type }) {
return {
Enter: splitToDefaultListItem(type),
Tab: this.options.nested ? sinkListItem(type) : () => {},
'Shift-Tab': liftListItem(type)
}
}
}
62 changes: 62 additions & 0 deletions src/extensions/nativeExtensions/TodoList/TodoItemView.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<template>
<li
:data-type="node.type.name"
:data-done="node.attrs.done.toString()"
class="tiptap-vuetify-todo-item-view"
data-drag-handle
>
<VCheckbox
:value="node.attrs.done"
class="mr-2 mt-3 pt-1"
hide-details
@input="onChange"
/>
<div
ref="content"
class="todo-content"
:contenteditable="view.editable.toString()"
/>
</li>
</template>

<script lang="ts">
import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator'
import { VCheckbox } from 'vuetify/lib'
@Component({
components: { VCheckbox }
})
export default class TodoItemView extends Vue {
@Prop({
type: Object,
required: true
})
node
@Prop({
type: Object,
required: true
})
view
@Prop({
type: Function,
required: true
})
updateAttrs: (...args: any) => any
onChange () {
console.log('onChange')
this.updateAttrs({
done: !this.node.attrs.done
})
}
}
</script>

<style lang="stylus">
.tiptap-vuetify-todo-item-view
display: flex
</style>
31 changes: 31 additions & 0 deletions src/extensions/nativeExtensions/TodoList/TodoList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { TodoList as TodoListOriginal } from 'tiptap-extensions'
import { VuetifyIconsGroups } from '~/configs/theme'
import VuetifyIcon from '~/extensions/nativeExtensions/icons/VuetifyIcon'
import I18nText from '~/i18n/I18nText'
import AbstractExtension from '~/extensions/AbstractExtension'
import ExtensionActionInterface from '~/extensions/actions/ExtensionActionInterface'
import ExtensionActionRenderBtn from '~/extensions/actions/renders/btn/ExtensionActionRenderBtn.ts'

export default class TodoList extends AbstractExtension {
constructor (options) {
super(options, TodoListOriginal)
}

get availableActions (): ExtensionActionInterface[] {
return [
{
render: new ExtensionActionRenderBtn({
tooltip: new I18nText('extensions.TodoList.buttons.todoList.tooltip'),
icons: {
[VuetifyIconsGroups.md]: new VuetifyIcon('check_box'),
[VuetifyIconsGroups.fa]: new VuetifyIcon('fas fa-tasks'),
[VuetifyIconsGroups.mdi]: new VuetifyIcon('mdi-format-list-checks'),
// mdiFormatListChecks
[VuetifyIconsGroups.mdiSvg]: new VuetifyIcon('M3,5H9V11H3V5M5,7V9H7V7H5M11,7H21V9H11V7M11,15H21V17H11V15M5,20L1.5,16.5L2.91,15.09L5,17.17L9.59,12.59L11,14L5,20Z')
},
nativeExtensionName: 'todo_list'
})
}
]
}
}
2 changes: 2 additions & 0 deletions src/extensions/nativeExtensions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,5 @@ export { default as HorizontalRule } from '~/extensions/nativeExtensions/Horizon
export { default as History } from '~/extensions/nativeExtensions/History'
export { default as Link } from '~/extensions/nativeExtensions/link/Link'
export { default as Image } from '~/extensions/nativeExtensions/image/Image'
export { default as TodoList } from '~/extensions/nativeExtensions/TodoList/TodoList'
export { default as TodoItem } from '~/extensions/nativeExtensions/TodoList/TodoItem'
7 changes: 7 additions & 0 deletions src/i18n/en/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,13 @@ export default {
apply: 'Apply'
}
}
},
TodoList: {
buttons: {
todoList: {
tooltip: 'To Do List'
}
}
}
}
}
2 changes: 1 addition & 1 deletion vue.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module.exports = {
// : '/',
outputDir: undefined,
assetsDir: undefined,
runtimeCompiler: undefined,
runtimeCompiler: true,
productionSourceMap: undefined,
parallel: undefined,

Expand Down

0 comments on commit de0aa90

Please sign in to comment.