diff --git a/packages/core/package.json b/packages/core/package.json index cf9c34e4c..0e4314653 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -15,6 +15,7 @@ "@types/clone-deep": "^4.0.1", "@types/prosemirror-dropcursor": "^1.0.0", "@types/prosemirror-gapcursor": "^1.0.1", + "@types/prosemirror-schema-list": "^1.0.1", "clone-deep": "^4.0.1", "collect.js": "^4.28.2", "deepmerge": "^4.2.2", @@ -24,6 +25,7 @@ "prosemirror-inputrules": "^1.1.2", "prosemirror-keymap": "^1.1.3", "prosemirror-model": "^1.9.1", + "prosemirror-schema-list": "^1.1.4", "prosemirror-state": "^1.3.3", "prosemirror-tables": "^1.1.1", "prosemirror-utils": "^0.9.6", diff --git a/packages/core/src/commands/index.ts b/packages/core/src/commands/index.ts index 797ec377f..755942860 100644 --- a/packages/core/src/commands/index.ts +++ b/packages/core/src/commands/index.ts @@ -4,12 +4,15 @@ export { default as deleteSelection } from './deleteSelection' export { default as focus } from './focus' export { default as insertHTML } from './insertHTML' export { default as insertText } from './insertText' +export { default as liftListItem } from './liftListItem' export { default as removeMark } from './removeMark' export { default as removeMarks } from './removeMarks' export { default as replaceWithNode } from './replaceWithNode' export { default as selectAll } from './selectAll' export { default as selectParentNode } from './selectParentNode' export { default as setContent } from './setContent' +export { default as sinkListItem } from './sinkListItem' +export { default as splitListItem } from './splitListItem' export { default as toggleMark } from './toggleMark' export { default as toggleNode } from './toggleNode' export { default as updateMark } from './updateMark' diff --git a/packages/core/src/commands/liftListItem.ts b/packages/core/src/commands/liftListItem.ts new file mode 100644 index 000000000..701521696 --- /dev/null +++ b/packages/core/src/commands/liftListItem.ts @@ -0,0 +1,20 @@ +import { Editor } from '../Editor' +import { liftListItem } from 'prosemirror-schema-list' +import { NodeType } from 'prosemirror-model' +import getNodeType from '../utils/getNodeType' + +type LiftListItem = (typeOrName: string | NodeType) => Editor + +declare module '../Editor' { + interface Editor { + liftListItem: LiftListItem, + } +} + +export default (next: Function, editor: Editor) => (typeOrName: string | NodeType) => { + const { view, state, schema } = editor + const type = getNodeType(typeOrName, schema) + + liftListItem(type)(state, view.dispatch) + next() +} diff --git a/packages/core/src/commands/sinkListItem.ts b/packages/core/src/commands/sinkListItem.ts new file mode 100644 index 000000000..d2cfa5fa7 --- /dev/null +++ b/packages/core/src/commands/sinkListItem.ts @@ -0,0 +1,20 @@ +import { Editor } from '../Editor' +import { sinkListItem } from 'prosemirror-schema-list' +import { NodeType } from 'prosemirror-model' +import getNodeType from '../utils/getNodeType' + +type SinkListItem = (typeOrName: string | NodeType) => Editor + +declare module '../Editor' { + interface Editor { + sinkListItem: SinkListItem, + } +} + +export default (next: Function, editor: Editor) => (typeOrName: string | NodeType) => { + const { view, state, schema } = editor + const type = getNodeType(typeOrName, schema) + + sinkListItem(type)(state, view.dispatch) + next() +} diff --git a/packages/core/src/commands/splitListItem.ts b/packages/core/src/commands/splitListItem.ts new file mode 100644 index 000000000..930eaec36 --- /dev/null +++ b/packages/core/src/commands/splitListItem.ts @@ -0,0 +1,20 @@ +import { Editor } from '../Editor' +import { splitListItem } from 'prosemirror-schema-list' +import { NodeType } from 'prosemirror-model' +import getNodeType from '../utils/getNodeType' + +type SplitListItem = (typeOrName: string | NodeType) => Editor + +declare module '../Editor' { + interface Editor { + splitListItem: SplitListItem, + } +} + +export default (next: Function, editor: Editor) => (typeOrName: string | NodeType) => { + const { view, state, schema } = editor + const type = getNodeType(typeOrName, schema) + + splitListItem(type)(state, view.dispatch) + next() +} diff --git a/packages/extension-bullet-list/index.ts b/packages/extension-bullet-list/index.ts new file mode 100644 index 000000000..79e4905b3 --- /dev/null +++ b/packages/extension-bullet-list/index.ts @@ -0,0 +1,32 @@ +import { Node } from '@tiptap/core' +import { wrappingInputRule } from 'prosemirror-inputrules' + +declare module '@tiptap/core/src/Editor' { + interface Editor { + bulletList(): Editor, + } +} + +export default new Node() + .name('bullet_list') + .schema(() => ({ + content: 'list_item+', + group: 'block', + parseDOM: [ + { tag: 'ul' }, + ], + toDOM: () => ['ul', 0], + })) + .commands(({ editor, type }) => ({ + [name]: next => attrs => { + // editor.toggleList(type, editor.schema.nodes.list_item) + next() + }, + })) + .keys(({ editor }) => ({ + 'Shift-Ctrl-8': () => editor.bulletList(), + })) + .inputRules(({ type }) => [ + wrappingInputRule(/^\s*([-+*])\s$/, type), + ]) + .create() diff --git a/packages/extension-bullet-list/package.json b/packages/extension-bullet-list/package.json new file mode 100644 index 000000000..3f449cfdd --- /dev/null +++ b/packages/extension-bullet-list/package.json @@ -0,0 +1,17 @@ +{ + "name": "@tiptap/extension-bullet-list", + "version": "1.0.0", + "source": "index.ts", + "main": "dist/tiptap-extension-bullet-list.js", + "umd:main": "dist/tiptap-extension-bullet-list.umd.js", + "module": "dist/tiptap-extension-bullet-list.mjs", + "unpkg": "dist/tiptap-extension-bullet-list.js", + "jsdelivr": "dist/tiptap-extension-bullet-list.js", + "files": [ + "src", + "dist" + ], + "peerDependencies": { + "@tiptap/core": "2.x" + } +} diff --git a/packages/extension-list-item/index.ts b/packages/extension-list-item/index.ts new file mode 100644 index 000000000..fa384d6e1 --- /dev/null +++ b/packages/extension-list-item/index.ts @@ -0,0 +1,19 @@ +import { Node } from '@tiptap/core' + +export default new Node() + .name('list_item') + .schema(() => ({ + content: 'paragraph block*', + defining: true, + draggable: false, + parseDOM: [ + { tag: 'li' }, + ], + toDOM: () => ['li', 0], + })) + .keys(({ editor, name }) => ({ + // Enter: () => editor.splitListItem(name), + // Tab: () => editor.sinkListItem(name), + // 'Shift-Tab': () => editor.liftListItem(name), + })) + .create() diff --git a/packages/extension-list-item/package.json b/packages/extension-list-item/package.json new file mode 100644 index 000000000..58bc113f9 --- /dev/null +++ b/packages/extension-list-item/package.json @@ -0,0 +1,17 @@ +{ + "name": "@tiptap/extension-list-item", + "version": "1.0.0", + "source": "index.ts", + "main": "dist/tiptap-extension-list-item.js", + "umd:main": "dist/tiptap-extension-list-item.umd.js", + "module": "dist/tiptap-extension-list-item.mjs", + "unpkg": "dist/tiptap-extension-list-item.js", + "jsdelivr": "dist/tiptap-extension-list-item.js", + "files": [ + "src", + "dist" + ], + "peerDependencies": { + "@tiptap/core": "2.x" + } +} diff --git a/packages/starter-kit/index.ts b/packages/starter-kit/index.ts index 487207c79..dce2e9b9a 100644 --- a/packages/starter-kit/index.ts +++ b/packages/starter-kit/index.ts @@ -12,6 +12,8 @@ import Strike from '@tiptap/extension-strike' import Underline from '@tiptap/extension-underline' import Blockquote from '@tiptap/extension-blockquote' import HorizontalRule from '@tiptap/extension-horizontal-rule' +import BulletList from '@tiptap/extension-bullet-list' +import ListItem from '@tiptap/extension-list-item' export default function defaultExtensions() { return [ @@ -29,5 +31,7 @@ export default function defaultExtensions() { Underline(), Blockquote(), HorizontalRule(), + BulletList(), + ListItem(), ] } \ No newline at end of file diff --git a/packages/vue-starter-kit/index.ts b/packages/vue-starter-kit/index.ts index 0c9dda1f1..0701952d9 100644 --- a/packages/vue-starter-kit/index.ts +++ b/packages/vue-starter-kit/index.ts @@ -14,6 +14,8 @@ import Strike from '@tiptap/extension-strike' import Underline from '@tiptap/extension-underline' import Blockquote from '@tiptap/extension-blockquote' import HorizontalRule from '@tiptap/extension-horizontal-rule' +import BulletList from '@tiptap/extension-bullet-list' +import ListItem from '@tiptap/extension-list-item' export function defaultExtensions() { return [ @@ -31,5 +33,7 @@ export function defaultExtensions() { Underline(), Blockquote(), HorizontalRule(), + BulletList(), + ListItem(), ] } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 9094c4927..33d32e17f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2397,6 +2397,15 @@ dependencies: "@types/orderedmap" "*" +"@types/prosemirror-schema-list@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/prosemirror-schema-list/-/prosemirror-schema-list-1.0.1.tgz#7f53e3c0326b1359755f3971b8c448d98b722f21" + integrity sha512-+iUYq+pj2wVHSThj0MjNDzkkGwq8aDQ6j0UJK8a0cNCL8v44Ftcx1noGPtBIEUJgitH960VnfBNoTWfQoQZfRA== + dependencies: + "@types/orderedmap" "*" + "@types/prosemirror-model" "*" + "@types/prosemirror-state" "*" + "@types/prosemirror-state@*", "@types/prosemirror-state@^1.2.5": version "1.2.5" resolved "https://registry.yarnpkg.com/@types/prosemirror-state/-/prosemirror-state-1.2.5.tgz#a91304e9aab6e71f868e23b3a1ae514a75033f8f" @@ -10862,6 +10871,14 @@ prosemirror-model@^1.0.0, prosemirror-model@^1.1.0, prosemirror-model@^1.11.0, p dependencies: orderedmap "^1.1.0" +prosemirror-schema-list@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/prosemirror-schema-list/-/prosemirror-schema-list-1.1.4.tgz#471f9caf2d2bed93641d2e490434c0d2d4330df1" + integrity sha512-pNTuZflacFOBlxrTcWSdWhjoB8BaucwfJVp/gJNxztOwaN3wQiC65axclXyplf6TKgXD/EkWfS/QAov3/Znadw== + dependencies: + prosemirror-model "^1.0.0" + prosemirror-transform "^1.0.0" + prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.3.1, prosemirror-state@^1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/prosemirror-state/-/prosemirror-state-1.3.3.tgz#b2862866b14dec2b3ae1ab18229f2bd337651a2c"