diff --git a/docs/src/demos/Extensions/Blockquote/index.spec.js b/docs/src/demos/Extensions/Blockquote/index.spec.js new file mode 100644 index 00000000..53b3c8df --- /dev/null +++ b/docs/src/demos/Extensions/Blockquote/index.spec.js @@ -0,0 +1,48 @@ +context('/api/extensions/blockquote', () => { + beforeEach(() => { + cy.visit('/api/extensions/blockquote') + + cy.get('.ProseMirror').window().then(window => { + const { editor } = window + editor.setContent('
Example Text
') + editor.focus().selectAll() + }) + }) + + describe('blockquote', () => { + it('the button should make the selected line a blockquote', () => { + cy.get('.demo__preview button:first').click({ force: true }) + cy.get('.ProseMirror').contains('blockquote', 'Example Text') + }) + + it('the button should toggle the blockquote', () => { + cy.get('.demo__preview button:first').click({ force: true }) + cy.get('.ProseMirror').contains('blockquote', 'Example Text') + cy.get('.demo__preview button:first').click({ force: true }) + cy.get('.ProseMirror blockquote').should('not.exist') + }) + + it('the keyboard shortcut should make the selected line a blockquote', () => { + cy.get('.ProseMirror').type('{meta}{shift}9', {force: true}) + cy.get('.ProseMirror').contains('blockquote', 'Example Text') + }) + + it('the keyboard shortcut should toggle the blockquote', () => { + cy.get('.ProseMirror').type('{meta}{shift}9', {force: true}) + cy.get('.ProseMirror').contains('blockquote', 'Example Text') + cy.get('.ProseMirror').type('{meta}{shift}9', {force: true}) + cy.get('.ProseMirror blockquote').should('not.exist') + }) + + it('should make a blockquote form markdown shortcuts', () => { + cy.get('.ProseMirror').window().then(window => { + const { editor } = window + editor.clearContent() + + cy.get('.ProseMirror') + .type('> Quote', {force: true}) + .contains('blockquote', 'Quote') + }) + }) + }) +}) \ No newline at end of file diff --git a/docs/src/demos/Extensions/Blockquote/index.vue b/docs/src/demos/Extensions/Blockquote/index.vue new file mode 100644 index 00000000..1eb70053 --- /dev/null +++ b/docs/src/demos/Extensions/Blockquote/index.vue @@ -0,0 +1,53 @@ + +` HTML tag in the editor. +The Blockquote extension enables you to use the `` HTML tag in the editor. This is great – you might have guessed – to use quotes in the editor. + +Type `> ` on the beginning of a new line and it will be magically transformed to a blockquote. ## Options | Option | Type | Default | Description | @@ -12,49 +14,11 @@ The Blockquote extension enables you to use the `` HTML tag in the e | blockquote | — | Wrap content in a blockquote. | ## Keybindings -* `Control` + `→` +* Windows & Linux: `Control` + `Shift` + `9` +* macOS: `Command` + `Shift` + `9` + +## Source Code +[packages/extension-blockquote/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-blockquote/) ## Usage -```markup - --- - - -``` \ No newline at end of file +- - - -- diff --git a/docs/src/links.yaml b/docs/src/links.yaml index 46114d00..d06918fa 100644 --- a/docs/src/links.yaml +++ b/docs/src/links.yaml @@ -115,7 +115,6 @@ items: - title: Blockquote link: /api/extensions/blockquote - draft: true - title: Bold link: /api/extensions/bold - title: BulletList diff --git a/packages/extension-blockquote/index.ts b/packages/extension-blockquote/index.ts new file mode 100644 index 00000000..848c226d --- /dev/null +++ b/packages/extension-blockquote/index.ts @@ -0,0 +1,38 @@ +import { Node } from '@tiptap/core' +import { textblockTypeInputRule } from 'prosemirror-inputrules' + +declare module '@tiptap/core/src/Editor' { + interface Editor { + blockquote(): Editor, + } +} + +export const inputRegex = /^\s*>\s$/gm + +export default new Node() + .name('blockquote') + .schema(() => ({ + content: 'inline*', + group: 'block', + defining: true, + draggable: false, + parseDOM: [ + { tag: 'blockquote' }, + ], + toDOM: () => ['blockquote', 0], + })) + .commands(({ editor, name }) => ({ + [name]: next => attrs => { + editor.toggleNode(name, 'paragraph', attrs) + next() + }, + })) + .keys(({ editor }) => ({ + 'Shift-Mod-9': () => editor.blockquote(), + })) + .inputRules(({ type }) => [ + textblockTypeInputRule(inputRegex, type), + ]) + .create() + + diff --git a/packages/extension-blockquote/package.json b/packages/extension-blockquote/package.json new file mode 100644 index 00000000..12654f78 --- /dev/null +++ b/packages/extension-blockquote/package.json @@ -0,0 +1,17 @@ +{ + "name": "@tiptap/extension-blockquote", + "version": "1.0.0", + "source": "index.ts", + "main": "dist/tiptap-extension-blockquote.js", + "umd:main": "dist/tiptap-extension-blockquote.umd.js", + "module": "dist/tiptap-extension-blockquote.mjs", + "unpkg": "dist/tiptap-extension-blockquote.js", + "jsdelivr": "dist/tiptap-extension-blockquote.js", + "files": [ + "src", + "dist" + ], + "peerDependencies": { + "@tiptap/core": "2.x" + } +}