diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e827dd9d..6ffb9036 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -54,7 +54,7 @@ jobs: with: status: ${{ job.status }} steps: ${{ toJson(steps) }} - channel: '#tiptap-next' + channel: '#tiptap-notifications' if: failure() test: @@ -107,52 +107,52 @@ jobs: with: status: ${{ job.status }} steps: ${{ toJson(steps) }} - channel: '#tiptap-next' + channel: '#tiptap-notifications' if: failure() - build: - runs-on: ubuntu-latest + # build: + # runs-on: ubuntu-latest - needs: lint + # needs: lint - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + # env: + # SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - strategy: - matrix: - node-version: [14] + # strategy: + # matrix: + # node-version: [14] - steps: + # steps: - - uses: actions/checkout@v2.3.3 + # - uses: actions/checkout@v2.3.3 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2.1.2 - with: - node-version: ${{ matrix.node-version }} + # - name: Use Node.js ${{ matrix.node-version }} + # uses: actions/setup-node@v2.1.2 + # with: + # node-version: ${{ matrix.node-version }} - - name: Load cached dependencies - uses: actions/cache@v2 - id: cache - with: - path: | - **/node_modules - /home/runner/.cache/Cypress - key: ${{ runner.os }}-node-${{ matrix.node-version }}-${{ hashFiles('**/yarn.lock') }} + # - name: Load cached dependencies + # uses: actions/cache@v2 + # id: cache + # with: + # path: | + # **/node_modules + # /home/runner/.cache/Cypress + # key: ${{ runner.os }}-node-${{ matrix.node-version }}-${{ hashFiles('**/yarn.lock') }} - - name: Install dependencies - id: install-dependencies - if: steps.cache.outputs.cache-hit != 'true' - run: yarn install + # - name: Install dependencies + # id: install-dependencies + # if: steps.cache.outputs.cache-hit != 'true' + # run: yarn install - - name: Build packages dependencies - id: build-packages - run: yarn build:packages + # - name: Build packages dependencies + # id: build-packages + # run: yarn build:packages - - name: Send Slack notifications - uses: act10ns/slack@v1 - with: - status: ${{ job.status }} - steps: ${{ toJson(steps) }} - channel: '#tiptap-next' - if: failure() + # - name: Send Slack notifications + # uses: act10ns/slack@v1 + # with: + # status: ${{ job.status }} + # steps: ${{ toJson(steps) }} + # channel: '#tiptap-notifications' + # if: failure() diff --git a/docs/gridsome.client.js b/docs/gridsome.client.js index 65d2f3f2..6c5bcc17 100644 --- a/docs/gridsome.client.js +++ b/docs/gridsome.client.js @@ -1,5 +1,13 @@ export default function (Vue, options, context) { + Vue.mixin({ + data() { + return { + cwd: options.cwd, + } + }, + }) + context.router.afterEach(to => { if (to.hash) { setTimeout(() => { diff --git a/docs/gridsome.server.js b/docs/gridsome.server.js index 24b1b86b..214db742 100644 --- a/docs/gridsome.server.js +++ b/docs/gridsome.server.js @@ -52,6 +52,10 @@ const globby = require('globby') module.exports = function (api) { + api.setClientOptions({ + cwd: process.cwd(), + }) + api.loadSource(({ addCollection }) => { const appCollection = addCollection({ typeName: 'Package' }) diff --git a/docs/src/demos/Api/Schema/GenerateHtml/index.vue b/docs/src/demos/Api/Schema/GenerateHTML/index.vue similarity index 81% rename from docs/src/demos/Api/Schema/GenerateHtml/index.vue rename to docs/src/demos/Api/Schema/GenerateHTML/index.vue index 5673dcd2..b0a6eda4 100644 --- a/docs/src/demos/Api/Schema/GenerateHtml/index.vue +++ b/docs/src/demos/Api/Schema/GenerateHTML/index.vue @@ -1,9 +1,9 @@ - {{ html }} + {{ html }} diff --git a/docs/src/demos/Examples/Formatting/index.vue b/docs/src/demos/Examples/Formatting/index.vue new file mode 100644 index 00000000..ce9c2a99 --- /dev/null +++ b/docs/src/demos/Examples/Formatting/index.vue @@ -0,0 +1,118 @@ + + + + + bold + + + italic + + + h1 + + + h2 + + + h3 + + + paragraph + + + left + + + center + + + right + + + justify + + + + + + + diff --git a/docs/src/demos/Examples/Links/index.vue b/docs/src/demos/Examples/Links/index.vue index e3240fc7..0bdfe621 100644 --- a/docs/src/demos/Examples/Links/index.vue +++ b/docs/src/demos/Examples/Links/index.vue @@ -11,13 +11,19 @@ + + diff --git a/docs/src/demos/Extensions/Focus/index.spec.js b/docs/src/demos/Extensions/Focus/index.spec.js new file mode 100644 index 00000000..029eb69e --- /dev/null +++ b/docs/src/demos/Extensions/Focus/index.spec.js @@ -0,0 +1,9 @@ +context('/examples/focus', () => { + before(() => { + cy.visit('/examples/focus') + }) + + it('should have class', () => { + cy.get('.ProseMirror p:first').should('have.class', 'has-focus') + }) +}) diff --git a/docs/src/demos/Extensions/Focus/index.vue b/docs/src/demos/Extensions/Focus/index.vue new file mode 100644 index 00000000..b4c7f0f3 --- /dev/null +++ b/docs/src/demos/Extensions/Focus/index.vue @@ -0,0 +1,59 @@ + + + + + + + + + diff --git a/docs/src/demos/Extensions/Gapcursor/index.spec.js b/docs/src/demos/Extensions/Gapcursor/index.spec.js new file mode 100644 index 00000000..3adf87fd --- /dev/null +++ b/docs/src/demos/Extensions/Gapcursor/index.spec.js @@ -0,0 +1,5 @@ +context('/examples/gapcursor', () => { + before(() => { + cy.visit('/examples/gapcursor') + }) +}) diff --git a/docs/src/demos/Extensions/Gapcursor/index.vue b/docs/src/demos/Extensions/Gapcursor/index.vue new file mode 100644 index 00000000..11d5bc99 --- /dev/null +++ b/docs/src/demos/Extensions/Gapcursor/index.vue @@ -0,0 +1,78 @@ + + + + + + + + + diff --git a/docs/src/demos/Extensions/ListItem/index.spec.js b/docs/src/demos/Extensions/ListItem/index.spec.js deleted file mode 100644 index 798b7b97..00000000 --- a/docs/src/demos/Extensions/ListItem/index.spec.js +++ /dev/null @@ -1,5 +0,0 @@ -context('/api/extensions/list-item', () => { - before(() => { - cy.visit('/api/extensions/list-item') - }) -}) diff --git a/docs/src/demos/Extensions/TextAlign/index.spec.js b/docs/src/demos/Extensions/TextAlign/index.spec.js index a9d851de..125c4571 100644 --- a/docs/src/demos/Extensions/TextAlign/index.spec.js +++ b/docs/src/demos/Extensions/TextAlign/index.spec.js @@ -1,6 +1,6 @@ -context('/api/extensions/text', () => { +context('/api/nodes/text', () => { before(() => { - cy.visit('/api/extensions/text') + cy.visit('/api/nodes/text') }) beforeEach(() => { diff --git a/docs/src/demos/Extensions/TextAlign/index.vue b/docs/src/demos/Extensions/TextAlign/index.vue index 58af3f46..08ec6d50 100644 --- a/docs/src/demos/Extensions/TextAlign/index.vue +++ b/docs/src/demos/Extensions/TextAlign/index.vue @@ -9,6 +9,9 @@ right + + set default + diff --git a/docs/src/demos/Extensions/Bold/index.spec.js b/docs/src/demos/Marks/Bold/index.spec.js similarity index 97% rename from docs/src/demos/Extensions/Bold/index.spec.js rename to docs/src/demos/Marks/Bold/index.spec.js index dbdbba45..d7d56680 100644 --- a/docs/src/demos/Extensions/Bold/index.spec.js +++ b/docs/src/demos/Marks/Bold/index.spec.js @@ -1,6 +1,6 @@ -context('/api/extensions/bold', () => { +context('/api/marks/bold', () => { before(() => { - cy.visit('/api/extensions/bold') + cy.visit('/api/marks/bold') }) beforeEach(() => { diff --git a/docs/src/demos/Extensions/Bold/index.vue b/docs/src/demos/Marks/Bold/index.vue similarity index 100% rename from docs/src/demos/Extensions/Bold/index.vue rename to docs/src/demos/Marks/Bold/index.vue diff --git a/docs/src/demos/Extensions/Code/index.spec.js b/docs/src/demos/Marks/Code/index.spec.js similarity index 94% rename from docs/src/demos/Extensions/Code/index.spec.js rename to docs/src/demos/Marks/Code/index.spec.js index 2111e436..91e0fdd4 100644 --- a/docs/src/demos/Extensions/Code/index.spec.js +++ b/docs/src/demos/Marks/Code/index.spec.js @@ -1,6 +1,6 @@ -context('/api/extensions/code', () => { +context('/api/marks/code', () => { before(() => { - cy.visit('/api/extensions/code') + cy.visit('/api/marks/code') }) beforeEach(() => { diff --git a/docs/src/demos/Extensions/Code/index.vue b/docs/src/demos/Marks/Code/index.vue similarity index 100% rename from docs/src/demos/Extensions/Code/index.vue rename to docs/src/demos/Marks/Code/index.vue diff --git a/docs/src/demos/Extensions/Italic/index.spec.js b/docs/src/demos/Marks/Italic/index.spec.js similarity index 96% rename from docs/src/demos/Extensions/Italic/index.spec.js rename to docs/src/demos/Marks/Italic/index.spec.js index 16d26c3f..1035bc9c 100644 --- a/docs/src/demos/Extensions/Italic/index.spec.js +++ b/docs/src/demos/Marks/Italic/index.spec.js @@ -1,6 +1,6 @@ -context('/api/extensions/italic', () => { +context('/api/marks/italic', () => { before(() => { - cy.visit('/api/extensions/italic') + cy.visit('/api/marks/italic') }) beforeEach(() => { diff --git a/docs/src/demos/Extensions/Italic/index.vue b/docs/src/demos/Marks/Italic/index.vue similarity index 100% rename from docs/src/demos/Extensions/Italic/index.vue rename to docs/src/demos/Marks/Italic/index.vue diff --git a/docs/src/demos/Extensions/Link/index.spec.js b/docs/src/demos/Marks/Link/index.spec.js similarity index 96% rename from docs/src/demos/Extensions/Link/index.spec.js rename to docs/src/demos/Marks/Link/index.spec.js index 6f7f89c1..73457961 100644 --- a/docs/src/demos/Extensions/Link/index.spec.js +++ b/docs/src/demos/Marks/Link/index.spec.js @@ -1,6 +1,6 @@ -context('/api/extensions/link', () => { +context('/api/marks/link', () => { before(() => { - cy.visit('/api/extensions/link') + cy.visit('/api/marks/link') }) beforeEach(() => { diff --git a/docs/src/demos/Extensions/Link/index.vue b/docs/src/demos/Marks/Link/index.vue similarity index 100% rename from docs/src/demos/Extensions/Link/index.vue rename to docs/src/demos/Marks/Link/index.vue diff --git a/docs/src/demos/Extensions/Strike/index.spec.js b/docs/src/demos/Marks/Strike/index.spec.js similarity index 96% rename from docs/src/demos/Extensions/Strike/index.spec.js rename to docs/src/demos/Marks/Strike/index.spec.js index f43f91d6..98f40014 100644 --- a/docs/src/demos/Extensions/Strike/index.spec.js +++ b/docs/src/demos/Marks/Strike/index.spec.js @@ -1,6 +1,6 @@ -context('/api/extensions/strike', () => { +context('/api/marks/strike', () => { before(() => { - cy.visit('/api/extensions/strike') + cy.visit('/api/marks/strike') }) beforeEach(() => { diff --git a/docs/src/demos/Extensions/Strike/index.vue b/docs/src/demos/Marks/Strike/index.vue similarity index 100% rename from docs/src/demos/Extensions/Strike/index.vue rename to docs/src/demos/Marks/Strike/index.vue diff --git a/docs/src/demos/Extensions/Underline/index.spec.js b/docs/src/demos/Marks/Underline/index.spec.js similarity index 95% rename from docs/src/demos/Extensions/Underline/index.spec.js rename to docs/src/demos/Marks/Underline/index.spec.js index 3d7664e7..bb1d5193 100644 --- a/docs/src/demos/Extensions/Underline/index.spec.js +++ b/docs/src/demos/Marks/Underline/index.spec.js @@ -1,6 +1,6 @@ -context('/api/extensions/underline', () => { +context('/api/marks/underline', () => { before(() => { - cy.visit('/api/extensions/underline') + cy.visit('/api/marks/underline') }) beforeEach(() => { diff --git a/docs/src/demos/Extensions/Underline/index.vue b/docs/src/demos/Marks/Underline/index.vue similarity index 100% rename from docs/src/demos/Extensions/Underline/index.vue rename to docs/src/demos/Marks/Underline/index.vue diff --git a/docs/src/demos/Extensions/Blockquote/index.spec.js b/docs/src/demos/Nodes/Blockquote/index.spec.js similarity index 96% rename from docs/src/demos/Extensions/Blockquote/index.spec.js rename to docs/src/demos/Nodes/Blockquote/index.spec.js index d6e0cc7d..e4318e0e 100644 --- a/docs/src/demos/Extensions/Blockquote/index.spec.js +++ b/docs/src/demos/Nodes/Blockquote/index.spec.js @@ -1,6 +1,6 @@ -context('/api/extensions/blockquote', () => { +context('/api/nodes/blockquote', () => { before(() => { - cy.visit('/api/extensions/blockquote') + cy.visit('/api/nodes/blockquote') }) beforeEach(() => { diff --git a/docs/src/demos/Extensions/Blockquote/index.vue b/docs/src/demos/Nodes/Blockquote/index.vue similarity index 100% rename from docs/src/demos/Extensions/Blockquote/index.vue rename to docs/src/demos/Nodes/Blockquote/index.vue diff --git a/docs/src/demos/Extensions/BulletList/index.spec.js b/docs/src/demos/Nodes/BulletList/index.spec.js similarity index 97% rename from docs/src/demos/Extensions/BulletList/index.spec.js rename to docs/src/demos/Nodes/BulletList/index.spec.js index 28f9a815..4d699aec 100644 --- a/docs/src/demos/Extensions/BulletList/index.spec.js +++ b/docs/src/demos/Nodes/BulletList/index.spec.js @@ -1,6 +1,6 @@ -context('/api/extensions/bullet-list', () => { +context('/api/nodes/bullet-list', () => { before(() => { - cy.visit('/api/extensions/bullet-list') + cy.visit('/api/nodes/bullet-list') }) beforeEach(() => { diff --git a/docs/src/demos/Extensions/BulletList/index.vue b/docs/src/demos/Nodes/BulletList/index.vue similarity index 94% rename from docs/src/demos/Extensions/BulletList/index.vue rename to docs/src/demos/Nodes/BulletList/index.vue index cdc34101..70491f71 100644 --- a/docs/src/demos/Extensions/BulletList/index.vue +++ b/docs/src/demos/Nodes/BulletList/index.vue @@ -1,6 +1,6 @@ - + bullet list diff --git a/docs/src/demos/Extensions/CodeBlock/index.spec.js b/docs/src/demos/Nodes/CodeBlock/index.spec.js similarity index 97% rename from docs/src/demos/Extensions/CodeBlock/index.spec.js rename to docs/src/demos/Nodes/CodeBlock/index.spec.js index 18b6bb18..aa2dd17c 100644 --- a/docs/src/demos/Extensions/CodeBlock/index.spec.js +++ b/docs/src/demos/Nodes/CodeBlock/index.spec.js @@ -1,6 +1,6 @@ -context('/api/extensions/code-block', () => { +context('/api/nodes/code-block', () => { before(() => { - cy.visit('/api/extensions/code-block') + cy.visit('/api/nodes/code-block') }) beforeEach(() => { diff --git a/docs/src/demos/Extensions/CodeBlock/index.vue b/docs/src/demos/Nodes/CodeBlock/index.vue similarity index 100% rename from docs/src/demos/Extensions/CodeBlock/index.vue rename to docs/src/demos/Nodes/CodeBlock/index.vue diff --git a/docs/src/demos/Extensions/Document/index.spec.js b/docs/src/demos/Nodes/Document/index.spec.js similarity index 84% rename from docs/src/demos/Extensions/Document/index.spec.js rename to docs/src/demos/Nodes/Document/index.spec.js index 0231d33c..59529eed 100644 --- a/docs/src/demos/Extensions/Document/index.spec.js +++ b/docs/src/demos/Nodes/Document/index.spec.js @@ -1,6 +1,6 @@ -context('/api/extensions/document', () => { +context('/api/nodes/document', () => { before(() => { - cy.visit('/api/extensions/document') + cy.visit('/api/nodes/document') }) beforeEach(() => { diff --git a/docs/src/demos/Extensions/Document/index.vue b/docs/src/demos/Nodes/Document/index.vue similarity index 100% rename from docs/src/demos/Extensions/Document/index.vue rename to docs/src/demos/Nodes/Document/index.vue diff --git a/docs/src/demos/Extensions/HardBreak/index.spec.js b/docs/src/demos/Nodes/HardBreak/index.spec.js similarity index 94% rename from docs/src/demos/Extensions/HardBreak/index.spec.js rename to docs/src/demos/Nodes/HardBreak/index.spec.js index 00586450..86d516fd 100644 --- a/docs/src/demos/Extensions/HardBreak/index.spec.js +++ b/docs/src/demos/Nodes/HardBreak/index.spec.js @@ -1,6 +1,6 @@ -context('/api/extensions/hard-break', () => { +context('/api/nodes/hard-break', () => { before(() => { - cy.visit('/api/extensions/hard-break') + cy.visit('/api/nodes/hard-break') }) beforeEach(() => { diff --git a/docs/src/demos/Extensions/HardBreak/index.vue b/docs/src/demos/Nodes/HardBreak/index.vue similarity index 100% rename from docs/src/demos/Extensions/HardBreak/index.vue rename to docs/src/demos/Nodes/HardBreak/index.vue diff --git a/docs/src/demos/Extensions/Heading/index.spec.js b/docs/src/demos/Nodes/Heading/index.spec.js similarity index 96% rename from docs/src/demos/Extensions/Heading/index.spec.js rename to docs/src/demos/Nodes/Heading/index.spec.js index 2543c17e..70e5dcef 100644 --- a/docs/src/demos/Extensions/Heading/index.spec.js +++ b/docs/src/demos/Nodes/Heading/index.spec.js @@ -1,6 +1,6 @@ -context('/api/extensions/heading', () => { +context('/api/nodes/heading', () => { before(() => { - cy.visit('/api/extensions/heading') + cy.visit('/api/nodes/heading') }) beforeEach(() => { diff --git a/docs/src/demos/Extensions/Heading/index.vue b/docs/src/demos/Nodes/Heading/index.vue similarity index 100% rename from docs/src/demos/Extensions/Heading/index.vue rename to docs/src/demos/Nodes/Heading/index.vue diff --git a/docs/src/demos/Extensions/HorizontalRule/index.spec.js b/docs/src/demos/Nodes/HorizontalRule/index.spec.js similarity index 94% rename from docs/src/demos/Extensions/HorizontalRule/index.spec.js rename to docs/src/demos/Nodes/HorizontalRule/index.spec.js index 30e962be..77442db8 100644 --- a/docs/src/demos/Extensions/HorizontalRule/index.spec.js +++ b/docs/src/demos/Nodes/HorizontalRule/index.spec.js @@ -1,6 +1,6 @@ -context('/api/extensions/horizontal-rule', () => { +context('/api/nodes/horizontal-rule', () => { before(() => { - cy.visit('/api/extensions/horizontal-rule') + cy.visit('/api/nodes/horizontal-rule') }) beforeEach(() => { diff --git a/docs/src/demos/Extensions/HorizontalRule/index.vue b/docs/src/demos/Nodes/HorizontalRule/index.vue similarity index 100% rename from docs/src/demos/Extensions/HorizontalRule/index.vue rename to docs/src/demos/Nodes/HorizontalRule/index.vue diff --git a/docs/src/demos/Nodes/Image/index.spec.js b/docs/src/demos/Nodes/Image/index.spec.js new file mode 100644 index 00000000..5740e17c --- /dev/null +++ b/docs/src/demos/Nodes/Image/index.spec.js @@ -0,0 +1,27 @@ +context('/api/nodes/image', () => { + before(() => { + cy.visit('/api/nodes/image') + }) + + beforeEach(() => { + cy.get('.ProseMirror').then(([{ editor }]) => { + editor.setContent('Example Text') + editor.selectAll() + }) + }) + + it('should add an img tag with the correct URL', () => { + cy.window().then(win => { + cy.stub(win, 'prompt').returns('foobar.png') + + cy.get('.demo__preview button:first') + .click() + + cy.window().its('prompt').should('be.called') + + cy.get('.ProseMirror') + .find('img') + .should('have.attr', 'src', 'foobar.png') + }) + }) +}) diff --git a/docs/src/demos/Extensions/Image/index.vue b/docs/src/demos/Nodes/Image/index.vue similarity index 59% rename from docs/src/demos/Extensions/Image/index.vue rename to docs/src/demos/Nodes/Image/index.vue index 52615a3b..a101cda5 100644 --- a/docs/src/demos/Extensions/Image/index.vue +++ b/docs/src/demos/Nodes/Image/index.vue @@ -1,5 +1,8 @@ + + image + @@ -11,6 +14,7 @@ import Document from '@tiptap/extension-document' import Paragraph from '@tiptap/extension-paragraph' import Text from '@tiptap/extension-text' import Image from '@tiptap/extension-image' +import Dropcursor from '@tiptap/extension-dropcursor' export default { components: { @@ -23,6 +27,14 @@ export default { } }, + methods: { + addImage() { + const url = window.prompt('URL') + + this.editor.chain().focus().image({ src: url }).run() + }, + }, + mounted() { this.editor = new Editor({ extensions: [ @@ -30,10 +42,12 @@ export default { Paragraph(), Text(), Image(), + Dropcursor(), ], content: ` - This is basic example of implementing images. Try to drop new images here. Reordering also works. - + This is a basic example of implementing images. Drag to re-order. + + `, }) }, diff --git a/docs/src/demos/Nodes/ListItem/index.spec.js b/docs/src/demos/Nodes/ListItem/index.spec.js new file mode 100644 index 00000000..f8b0c6be --- /dev/null +++ b/docs/src/demos/Nodes/ListItem/index.spec.js @@ -0,0 +1,5 @@ +context('/api/nodes/list-item', () => { + before(() => { + cy.visit('/api/nodes/list-item') + }) +}) diff --git a/docs/src/demos/Extensions/ListItem/index.vue b/docs/src/demos/Nodes/ListItem/index.vue similarity index 93% rename from docs/src/demos/Extensions/ListItem/index.vue rename to docs/src/demos/Nodes/ListItem/index.vue index 142c64ff..86137256 100644 --- a/docs/src/demos/Extensions/ListItem/index.vue +++ b/docs/src/demos/Nodes/ListItem/index.vue @@ -1,9 +1,9 @@ - + bullet list - + ordered list diff --git a/docs/src/demos/Extensions/OrderedList/index.spec.js b/docs/src/demos/Nodes/OrderedList/index.spec.js similarity index 96% rename from docs/src/demos/Extensions/OrderedList/index.spec.js rename to docs/src/demos/Nodes/OrderedList/index.spec.js index acab83cc..72c8ceec 100644 --- a/docs/src/demos/Extensions/OrderedList/index.spec.js +++ b/docs/src/demos/Nodes/OrderedList/index.spec.js @@ -1,6 +1,6 @@ -context('/api/extensions/ordered-list', () => { +context('/api/nodes/ordered-list', () => { before(() => { - cy.visit('/api/extensions/ordered-list') + cy.visit('/api/nodes/ordered-list') }) beforeEach(() => { diff --git a/docs/src/demos/Extensions/OrderedList/index.vue b/docs/src/demos/Nodes/OrderedList/index.vue similarity index 95% rename from docs/src/demos/Extensions/OrderedList/index.vue rename to docs/src/demos/Nodes/OrderedList/index.vue index 6703c4ec..0677b451 100644 --- a/docs/src/demos/Extensions/OrderedList/index.vue +++ b/docs/src/demos/Nodes/OrderedList/index.vue @@ -1,6 +1,6 @@ - + ordered list diff --git a/docs/src/demos/Extensions/Paragraph/index.spec.js b/docs/src/demos/Nodes/Paragraph/index.spec.js similarity index 94% rename from docs/src/demos/Extensions/Paragraph/index.spec.js rename to docs/src/demos/Nodes/Paragraph/index.spec.js index 359cfbcf..fd539594 100644 --- a/docs/src/demos/Extensions/Paragraph/index.spec.js +++ b/docs/src/demos/Nodes/Paragraph/index.spec.js @@ -1,6 +1,6 @@ -context('/api/extensions/paragraph', () => { +context('/api/nodes/paragraph', () => { before(() => { - cy.visit('/api/extensions/paragraph') + cy.visit('/api/nodes/paragraph') }) beforeEach(() => { diff --git a/docs/src/demos/Extensions/Paragraph/index.vue b/docs/src/demos/Nodes/Paragraph/index.vue similarity index 100% rename from docs/src/demos/Extensions/Paragraph/index.vue rename to docs/src/demos/Nodes/Paragraph/index.vue diff --git a/docs/src/demos/Nodes/TaskList/index.spec.js b/docs/src/demos/Nodes/TaskList/index.spec.js new file mode 100644 index 00000000..6696b566 --- /dev/null +++ b/docs/src/demos/Nodes/TaskList/index.spec.js @@ -0,0 +1,119 @@ +context('/api/nodes/task-list', () => { + before(() => { + cy.visit('/api/nodes/task-list') + }) + + beforeEach(() => { + cy.get('.ProseMirror').then(([{ editor }]) => { + editor.setContent('Example Text') + editor.selectAll() + }) + }) + + it('should parse unordered lists correctly', () => { + cy.get('.ProseMirror').then(([{ editor }]) => { + editor.setContent('Example Text') + expect(editor.getHTML()).to.eq('Example Text') + }) + }) + + it('should parse unordered lists without paragraphs correctly', () => { + cy.get('.ProseMirror').then(([{ editor }]) => { + editor.setContent('Example Text') + expect(editor.getHTML()).to.eq('Example Text') + }) + }) + + it('the button should make the selected line a task list item', () => { + cy.get('.ProseMirror ul') + .should('not.exist') + + cy.get('.ProseMirror ul li') + .should('not.exist') + + cy.get('.demo__preview button:nth-child(1)') + .click() + + cy.get('.ProseMirror') + .find('ul[data-type="task_list"]') + .should('contain', 'Example Text') + + cy.get('.ProseMirror') + .find('ul[data-type="task_list"] li') + .should('contain', 'Example Text') + }) + + it('the button should toggle the task list', () => { + cy.get('.ProseMirror ul') + .should('not.exist') + + cy.get('.demo__preview button:nth-child(1)') + .click() + + cy.get('.ProseMirror') + .find('ul[data-type="task_list"]') + .should('contain', 'Example Text') + + cy.get('.demo__preview button:nth-child(1)') + .click() + + cy.get('.ProseMirror ul') + .should('not.exist') + }) + + it('should leave the list with double enter', () => { + cy.get('.ProseMirror').then(([{ editor }]) => { + editor.clearContent() + }) + + cy.get('.ProseMirror') + .type('[ ] List Item 1{enter}{enter}Paragraph') + + cy.get('.ProseMirror') + .find('li') + .its('length') + .should('eq', 1) + + cy.get('.ProseMirror') + .find('p') + .should('contain', 'Paragraph') + }) + + it('should make a task list from square brackets', () => { + cy.get('.ProseMirror').then(([{ editor }]) => { + editor.clearContent() + }) + + cy.get('.ProseMirror') + .type('[ ] List Item 1{enter}List Item 2') + + cy.get('.ProseMirror') + .find('li:nth-child(1)') + .should('contain', 'List Item 1') + .should('have.attr', 'data-checked', 'false') + + cy.get('.ProseMirror') + .find('li:nth-child(2)') + .should('contain', 'List Item 2') + .should('have.attr', 'data-checked', 'false') + }) + + it.only('should make a task list from checked square brackets', () => { + cy.get('.ProseMirror').then(([{ editor }]) => { + editor.clearContent() + }) + + cy.get('.ProseMirror') + .type('[x] List Item 1{enter}List Item 2') + + cy.get('.ProseMirror') + .find('li:nth-child(1)') + .should('contain', 'List Item 1') + .should('have.attr', 'data-checked', 'true') + + cy.get('.ProseMirror') + .find('li:nth-child(2)') + .should('contain', 'List Item 2') + .should('have.attr', 'data-checked', 'true') + }) +}) diff --git a/docs/src/demos/Nodes/TaskList/index.vue b/docs/src/demos/Nodes/TaskList/index.vue new file mode 100644 index 00000000..6baf52e5 --- /dev/null +++ b/docs/src/demos/Nodes/TaskList/index.vue @@ -0,0 +1,70 @@ + + + + task list + + + + + + + + + diff --git a/docs/src/demos/Extensions/Text/index.spec.js b/docs/src/demos/Nodes/Text/index.spec.js similarity index 80% rename from docs/src/demos/Extensions/Text/index.spec.js rename to docs/src/demos/Nodes/Text/index.spec.js index a9d851de..125c4571 100644 --- a/docs/src/demos/Extensions/Text/index.spec.js +++ b/docs/src/demos/Nodes/Text/index.spec.js @@ -1,6 +1,6 @@ -context('/api/extensions/text', () => { +context('/api/nodes/text', () => { before(() => { - cy.visit('/api/extensions/text') + cy.visit('/api/nodes/text') }) beforeEach(() => { diff --git a/docs/src/demos/Extensions/Text/index.vue b/docs/src/demos/Nodes/Text/index.vue similarity index 100% rename from docs/src/demos/Extensions/Text/index.vue rename to docs/src/demos/Nodes/Text/index.vue diff --git a/docs/src/demos/Overview/Installation/index.vue b/docs/src/demos/Overview/Installation/index.vue index 06e4677f..9e344727 100644 --- a/docs/src/demos/Overview/Installation/index.vue +++ b/docs/src/demos/Overview/Installation/index.vue @@ -18,7 +18,7 @@ export default { mounted() { this.editor = new Editor({ - content: 'Hello, Iโm tiptap running in Vue.js! ๐', + content: 'Hello, here is tiptap! ๐', extensions: defaultExtensions(), }) }, diff --git a/docs/src/docPages/api/commands.md b/docs/src/docPages/api/commands.md index 3192ed56..83d495ad 100644 --- a/docs/src/docPages/api/commands.md +++ b/docs/src/docPages/api/commands.md @@ -1,6 +1,6 @@ # Commands -## Table of Contents +## toc ## Introduction The editor provides a ton of commands to programmtically add or change content or alter the selection. If you want to build your own editor you definitely want to learn more about them. @@ -14,7 +14,7 @@ editor.bold() While thatโs perfectly fine and does make the selected bold, youโd likely want to change multiple commands in one run. Letโs have a look at how that works. -## Chain commands +### Chain commands Most commands can be executed combined to one call. First of all, thatโs shorter than separate function call in most cases. Here is an example to make the selected text bold: ```js @@ -27,35 +27,84 @@ When a user clicks on a button outside of the content, the editor isnโt in foc All chained commands are kind of queued up. They are combined to one single transaction. That means, the content is only updated once, also the `update` event is only triggered once. +### Dry run for commands +Sometimes, you donโt want to actually run the commands, but only know if it would be possible to run commands, for example to show or hide buttons in a menu. Thatโs what we added `.can()` for. Everything coming after this method will be executed, without applying the changes to the document: + +```js +editor.can().bold() +``` + +And you can use it together with `.chain()`, too. Here is an example which checks if itโs possible to apply all the commands: + +```js +editor.can().chain().bold().italic().run() +``` + +Both calls would return `true` if itโs possible to apply the commands, and `false` in case itโs not. + +### Try commands +If you want to run a list of commands, but want only the first successful command to be applied, you can do this with the `.try()` method. This method runs one command after the other and stops at the first which returns `true`. + +For example, the backspace key tries to undo an input rule first. If that was successful, it stops there. If no input rule has been applied and thus canโt be reverted, it runs the next command and deletes the selection, if there is one. Here is the simplified example: + +```js +editor.try(({ commands }) => [ + () => commands.undoInputRule(), + () => commands.deleteSelection(), + // โฆ +]) +``` + +Inside of commands you can do the same thing like that: + +```js +commands.try([ + () => commands.undoInputRule(), + () => commands.deleteSelection(), + // โฆ +]) +``` + ## List of commands Have a look at all of the core commands listed below. They should give you a good first impression of whatโs possible. ### Content -| Command | Description | -| --------------- | ----------------------------------------------------------- | -| .clearContent() | Clear the whole document. | -| .insertgetHTML() | Insert a string of HTML at the currently selected position. | -| .insertText() | Insert a string of text at the currently selected position. | -| .setContent() | Replace the whole document with new content. | +| Command | Description | +| ---------------- | ----------------------------------------------------------- | +| .clearContent() | Clear the whole document. | +| .insertgetHTML() | Insert a string of HTML at the currently selected position. | +| .insertText() | Insert a string of text at the currently selected position. | +| .insertHTML() | | +| .setContent() | Replace the whole document with new content. | ### Nodes & Marks -| Command | Description | -| ------------------- | ------------------------------------------------------ | -| .removeMark() | Remove a mark in the current selection. | -| .removeMarks() | Remove all marks in the current selection. | -| .selectParentNode() | Select the parent node. | -| .toggleMark() | Toggle a mark on and off. | -| .toggleBlockType() | Toggle a node with another node. | -| .setBlockType() | Replace a given range with a node. | -| .updateMark() | Update a mark with new attributes. | +| Command | Description | +| ---------------------- | ------------------------------------------ | +| .clearNodes() | | +| .removeMark() | | +| .removeMark() | Remove a mark in the current selection. | +| .removeMarks() | | +| .removeMarks() | Remove all marks in the current selection. | +| .resetNodeAttributes() | | +| .selectParentNode() | Select the parent node. | +| .setBlockType() | Replace a given range with a node. | +| .setNodeAttributes() | | +| .splitBlock() | Forks a new node from an existing node. | +| .toggleBlockType() | Toggle a node with another node. | +| .toggleMark() | | +| .toggleMark() | Toggle a mark on and off. | +| .toggleWrap() | | +| .updateMark() | | +| .updateMark() | Update a mark with new attributes. | ### Lists -| Command | Description | -| ------------------- | ------------------------------------------------------ | -| .liftListItem() | Lift the list item into a wrapping list. | -| .sinkListItem() | Sink the list item down into an inner list. | -| .splitListItem() | Splits a textblock of a list item into two list items. | -| .toggleList() | Toggle between different list styles. | +| Command | Description | +| ---------------- | ------------------------------------------------------ | +| .liftListItem() | Lift the list item into a wrapping list. | +| .sinkListItem() | Sink the list item down into an inner list. | +| .splitListItem() | Splits a textblock of a list item into two list items. | +| .toggleList() | Toggle between different list styles. | +| .wrapInList() | | ### Selection | Command | Description | @@ -66,5 +115,7 @@ Have a look at all of the core commands listed below. They should give you a goo | .scrollIntoView() | Scroll the selection into view. | | .selectAll() | Select the whole document. | -### Extensions -All extension can add additional commands (and most do), check out the specific [documentation for the provided extensions](/api/extensions) to learn more about that. Of course, you can [add your custom extensions](/guide/custom-extensions) with custom commands aswell. +## Add your own commands +All extensions can add additional commands (and most do), check out the specific [documentation for the provided nodes](/api/nodes), [marks](/api/marks), and [extensions](/api/extensions) to learn more about those. + +Of course, you can [add your custom extensions](/guide/build-custom-extensions) with custom commands aswell. diff --git a/docs/src/docPages/api/editor.md b/docs/src/docPages/api/editor.md index 1e0f0c73..721b9b03 100644 --- a/docs/src/docPages/api/editor.md +++ b/docs/src/docPages/api/editor.md @@ -1,6 +1,6 @@ # Editor -## Table of Contents +## toc ## Introduction This class is a central building block of tiptap. It does most of the heavy lifting of creating a working [ProseMirror](https://ProseMirror.net/) editor such as creating the [`EditorView`](https://ProseMirror.net/docs/ref/#view.EditorView), setting the initial [`EditorState`](https://ProseMirror.net/docs/ref/#state.Editor_State) and so on. @@ -10,25 +10,23 @@ This class is a central building block of tiptap. It does most of the heavy lift | ------------------ | --------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `autoFocus` | `Boolean` | `false` | Focus the editor on init. | | `content` | `Object|String` | `null` | The editor state object used by Prosemirror. You can also pass HTML to the `content` slot. When used both, the `content` slot will be ignored. | -| `dropCursor` | `Object` | `{}` | Config for `prosemirror-dropcursor`. | | `editable` | `Boolean` | `true` | When set to `false` the editor is read-only. | | `editorProps` | `Object` | `{}` | A list of [Prosemirror editorProps](https://prosemirror.net/docs/ref/#view.EditorProps). | -| `enableDropCursor` | `Boolean` | `true` | Enable/disable showing a cursor at the drop position when something is dragged over the editor. | -| `enableGapCursor` | `Boolean` | `true` | Enable/disable a cursor at places that donโt allow regular selection (such as positions that have a leaf block node, table, or the end of the document both before and after them). | | `extensions` | `Array` | `[]` | A list of extensions used, by the editor. This can be `Nodes`, `Marks` or `Plugins`. | | `parseOptions` | `Object` | `{}` | A list of [Prosemirror parseOptions](https://prosemirror.net/docs/ref/#model.ParseOptions). | | `onBlur` | `Function` | `undefined` | Returns an object with the `event` and current `state` and `view` of Prosemirror on blur. | | `onFocus` | `Function` | `undefined` | Returns an object with the `event` and current `state` and `view` of Prosemirror on focus. | | `onInit` | `Function` | `undefined` | Returns an object with the current `state` and `view` of Prosemirror on init. | -| `onUpdate` | `Function` | `undefined` | Returns an object with the current `state` of Prosemirror, a `getJSON()` and `getHTML()` function and the `transaction` on every change. | +| `onUpdate` | `Function` | `undefined` | Returns an object with the current `state` of Prosemirror, a `getJSON()` and `getHTML()` function and the `transaction` on every change. | ## Methods | Method | Parameters | Description | | -------------------- | ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | -| `getHTML()` | โ | Returns the current content as HTML. | -| `getJSON()` | โ | Returns the current content as JSON. | +| `getHTML()` | โ | Returns the current content as HTML. | +| `getJSON()` | โ | Returns the current content as JSON. | | `destroy()` | โ | Stops the editor instance and unbinds all events. | | `chain()` | - | Create a command chain to call multiple commands at once. | +| `can()` | - | Check if a command or a command chain can be executed. Without executing it. | | `setOptions()` | `options` A list of options | Update editor options. | | `isEditable()` | - | Returns whether the editor is editable. | | `state()` | - | Returns the editor state. | @@ -40,3 +38,4 @@ This class is a central building block of tiptap. It does most of the heavy lift | `getNodeAttrs()` | `name` Name of the node | Get attributes of the currently selected node. | | `getMarkAttrs()` | `name` Name of the mark | Get attributes of the currently selected mark. | | `isActive()` | `name` Name of the node or mark`attrs` Attributes of the node or mark | Returns if the currently selected node or mark is active. | +| `isEmpty()` | - | Check if there is no content. | diff --git a/docs/src/docPages/api/events.md b/docs/src/docPages/api/events.md index 45a6bb3c..3aee03a0 100644 --- a/docs/src/docPages/api/events.md +++ b/docs/src/docPages/api/events.md @@ -1,6 +1,6 @@ # Events -## Table of Contents +## toc ## Introduction The editor fires a few different events that you can hook into. There are two ways to register event listeners: @@ -31,6 +31,7 @@ const editor = new Editor({ ## Option 2: Later Or you can register your event listeners on a running editor instance: +### Bind event listeners ```js editor.on('init', () => { // The editor is ready. @@ -54,7 +55,6 @@ editor.on('transaction', ({ transaction }) => { ``` ### Unbind event listeners - If you need to unbind those event listeners at some point, you should register your event listeners with `.on()` and unbind them with `.off()` then. ```js diff --git a/docs/src/docPages/api/extensions.md b/docs/src/docPages/api/extensions.md index 82553d88..d46c4f44 100644 --- a/docs/src/docPages/api/extensions.md +++ b/docs/src/docPages/api/extensions.md @@ -1,54 +1,60 @@ # Extensions -## Table of Contents +## toc ## Introduction Extensions are the way to add functionality to tiptap. By default tiptap comes bare, without any of them, but we have a long list of extensions that are ready to be used with tiptap. -## A minimalist set of extensions -Youโll need at least three extensions: `Document`, `Paragraph` and `Text`. See [an example of a tiptap version for minimalists](/examples/minimalist). - -## Default extensions -You donโt have to use it, but we prepared a `@tiptap/vue-starter-kit` which includes the most common extensions. See [how you can use the `defaultExtensions()`](/examples/basic). - -## List of supported extensions +## List of provided extensions | Title | Default Extension | Source Code | | ----------------------------------------------------------- | ----------------- | ------------------------------------------------------------------------------------------------------ | -| [Blockquote](/api/extensions/blockquote) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-blockquote/) | -| [Bold](/api/extensions/bold) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-bold/) | -| [BulletList](/api/extensions/bullet-list) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-bullet-list/) | -| [Code](/api/extensions/code) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-code/) | -| [CodeBlock](/api/extensions/code-block) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-code-block/) | | [Collaboration](/api/extensions/collaboration) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-collaboration/) | | [CollaborationCursor](/api/extensions/collaboration-cursor) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-collaboration-cursor/) | -| [Document](/api/extensions/document) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-document/) | -| [HardBreak](/api/extensions/hard-break) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-hard-break/) | -| [Heading](/api/extensions/heading) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-heading/) | -| [Highlight](/api/extensions/highlight) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-highlight/) | -| [History](/api/extensions/history) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-history/) | -| [HorizontalRule](/api/extensions/horizontal-rule) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-horizontal-rule/) | -| [Italic](/api/extensions/italic) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-italic/) | -| [Link](/api/extensions/link) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-link/) | -| [ListItem](/api/extensions/list-item) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-list-item/) | -| [OrderedList](/api/extensions/ordered-list) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-ordered-list/) | -| [Paragraph](/api/extensions/paragraph) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-paragraph/) | -| [Strike](/api/extensions/strike) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-strike/) | -| [Text](/api/extensions/text) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-text/) | -| [Underline](/api/extensions/underline) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-underline/) | +| [Dropcursor](/api/extensions/dropcursor) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-dropcursor/) | +| [Focus](/api/extensions/focus) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-focus/) | +| [Gapcursor](/api/extensions/gapcursor) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-gapcursor/) | +| [History](/api/extensions/history) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-history/) | +| [TextAlign](/api/extensions/text-align) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-text-align/) | +| [Typography](/api/extensions/typography) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-typography/) | - - - - - - - - +You donโt have to use it, but we prepared a `@tiptap/vue-starter-kit` which includes the most common extensions. Learn [how you can use the `defaultExtensions()`](/examples/basic). -## Community extensions -:::warning Work in Progress -This section is not ready yet. Meanwhile, [search through GitHub issues](https://github.com/ueberdosis/tiptap/issues) to find code snippets. -::: +## Create a new extension +Youโre free to create your own extensions for tiptap. Here is the boilerplate code thatโs need to create and register your own extension: -## Your custom extensions -Didnโt find what youโre looking for? No worries, [you can build your own extensions](/guide/custom-extensions). +```js +import { createExtension } from '@tiptap/core' + +const CustomExtension = createExtension({ + // Your code here +}) + +const editor = new Editor({ + extensions: [ + // Register your custom extension with the editor. + CustomExtension(), + // โฆ and donโt forget all other extensions. + Document(), + Paragraph(), + Text(), + // โฆ + ], +``` + +Learn [more about custom extensions in our guide](/guide/build-custom-extensions). + +### ProseMirror plugins +ProseMirror has a fantastic eco system with many amazing plugins. If you want to use one of them, you can register them with tiptap like that: + +```js +import { history } from 'prosemirror-history' + +const History = createExtension({ + addProseMirrorPlugins() { + return [ + history(), + // โฆ + ] + }, +}) +``` diff --git a/docs/src/docPages/api/extensions/code-block-highlight.md b/docs/src/docPages/api/extensions/code-block-highlight.md deleted file mode 100644 index f5eb1540..00000000 --- a/docs/src/docPages/api/extensions/code-block-highlight.md +++ /dev/null @@ -1,11 +0,0 @@ -# CodeBlockHighlight -Enables you to use the `` HTML tag with auto-detected syntax highlighting in the editor. - -## Settings -*None* - -## Commands -*None* - -## Keyboard shortcuts -*None* \ No newline at end of file diff --git a/docs/src/docPages/api/extensions/collaboration-cursor.md b/docs/src/docPages/api/extensions/collaboration-cursor.md index 7f003c1a..8987916d 100644 --- a/docs/src/docPages/api/extensions/collaboration-cursor.md +++ b/docs/src/docPages/api/extensions/collaboration-cursor.md @@ -1,2 +1,34 @@ # Collaboration Cursor +:::premium Premium Extension +Using this in production requires a **tiptap pro** license. [Read more](/sponsor) +::: + +## Installation +```bash +# with npm +npm install @tiptap/extension-collaboration-cursor + +# with Yarn +yarn add @tiptap/extension-collaboration-cursor +``` + +## Settings +| Option | Type | Default | Description | +| -------- | ---- | ------- | ----------- | +| provider | | | | +| type | | | | + +## Commands +| Command | Parameters | Description | +| ------- | ------------- | ------------------------------------------------------------------------ | +| user | namecolor | The name of the current user.The color of the current userโs cursor. | + +## Source code +[packages/extension-collaboration-cursor/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-collaboration-cursor/) + +## Usage +:::warning Public +The content of this editor is shared with other users. +::: + diff --git a/docs/src/docPages/api/extensions/collaboration.md b/docs/src/docPages/api/extensions/collaboration.md index fa5bbab9..1815948b 100644 --- a/docs/src/docPages/api/extensions/collaboration.md +++ b/docs/src/docPages/api/extensions/collaboration.md @@ -1,12 +1,16 @@ # Collaboration -Enables you to collaborate with others on one document. +The Collaboration extension enables you to collaborate with others on one document. The implementation is based on [Y.js by Kevin Jahns](https://github.com/yjs/yjs), which is the coolest thing to [integrate collaborative editing](/guide/collaborative-editing) in your project. + +:::premium Premium Extension +Using this in production requires a **tiptap pro** license. [Read more](/sponsor) +::: ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-collaboration yjs y-webrtc -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-collaboration yjs y-webrtc ``` diff --git a/docs/src/docPages/api/extensions/dropcursor.md b/docs/src/docPages/api/extensions/dropcursor.md new file mode 100644 index 00000000..8759a51c --- /dev/null +++ b/docs/src/docPages/api/extensions/dropcursor.md @@ -0,0 +1,25 @@ +# Dropcursor + +## Installation +```bash +# with npm +npm install @tiptap/extension-dropcursor + +# with Yarn +yarn add @tiptap/extension-dropcursor +``` + +## Settings +*None* + +## Commands +*None* + +## Keyboard shortcuts +*None* + +## Source code +[packages/extension-dropcursor/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-dropcursor/) + +## Usage + diff --git a/docs/src/docPages/api/extensions/focus.md b/docs/src/docPages/api/extensions/focus.md new file mode 100644 index 00000000..2d011777 --- /dev/null +++ b/docs/src/docPages/api/extensions/focus.md @@ -0,0 +1,22 @@ +# Focus + +## Installation +```bash +# with npm +npm install @tiptap/extension-focus + +# with Yarn +yarn add @tiptap/extension-focus +``` + +## Settings +| Option | Type | Default | Description | +| --------- | ------- | --------- | ------------------------------------------------------ | +| className | string | has-focus | The class that is applied to the focused element. | +| nested | boolean | true | When enabled nested elements get the focus class, too. | + +## Source code +[packages/extension-focus/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-focus/) + +## Usage + diff --git a/docs/src/docPages/api/extensions/gapcursor.md b/docs/src/docPages/api/extensions/gapcursor.md new file mode 100644 index 00000000..a42b7ef0 --- /dev/null +++ b/docs/src/docPages/api/extensions/gapcursor.md @@ -0,0 +1,19 @@ +# Gapcursor +This extension loads the [ProseMirror Gapcursor plugin](https://github.com/ProseMirror/prosemirror-gapcursor) by Marijn Haverbeke, which adds a gap for the cursor in places that donโt allow regular selection. For example, after a table at the end of a document. + +Note that tiptap is renderless, but the dropcursor needs CSS for its appearance. The default CSS is added to the usage example below. + +## Installation +```bash +# with npm +npm install @tiptap/extension-gapcursor + +# with Yarn +yarn add @tiptap/extension-gapcursor +``` + +## Source code +[packages/extension-gapcursor/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-gapcursor/) + +## Usage + diff --git a/docs/src/docPages/api/extensions/history.md b/docs/src/docPages/api/extensions/history.md index 6d41c532..b4fa23a6 100644 --- a/docs/src/docPages/api/extensions/history.md +++ b/docs/src/docPages/api/extensions/history.md @@ -3,10 +3,10 @@ This extension provides history support. All changes to the document will be tra ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-history -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-history ``` @@ -17,7 +17,7 @@ yarn add @tiptap/extension-history | newGroupDelay | number | 500 | The delay between changes after which a new group should be started (in milliseconds). When changes arenโt adjacent, a new group is always started. | ## Commands -| Command | Options | Description | +| Command | Parameters | Description | | ------- | ------- | --------------------- | | undo | โ | Undo the last change. | | redo | โ | Redo the last change. | diff --git a/docs/src/docPages/api/extensions/image.md b/docs/src/docPages/api/extensions/image.md deleted file mode 100644 index e811d826..00000000 --- a/docs/src/docPages/api/extensions/image.md +++ /dev/null @@ -1,16 +0,0 @@ -# Image - -## Installation -```bash -# With npm -npm install @tiptap/extension-image - -# Or: With Yarn -yarn add @tiptap/extension-image -``` - -## Source code -[packages/extension-image/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-image/) - -## Usage - diff --git a/docs/src/docPages/api/extensions/mention.md b/docs/src/docPages/api/extensions/mention.md deleted file mode 100644 index 3c2c0838..00000000 --- a/docs/src/docPages/api/extensions/mention.md +++ /dev/null @@ -1,2 +0,0 @@ -# Mention -Enables you to use mentions in the editor. diff --git a/docs/src/docPages/api/extensions/placeholder.md b/docs/src/docPages/api/extensions/placeholder.md deleted file mode 100644 index cc9da006..00000000 --- a/docs/src/docPages/api/extensions/placeholder.md +++ /dev/null @@ -1,2 +0,0 @@ -# Placeholder -Enables you to show placeholders on empty paragraphs. diff --git a/docs/src/docPages/api/extensions/table-cell.md b/docs/src/docPages/api/extensions/table-cell.md deleted file mode 100644 index 09a28533..00000000 --- a/docs/src/docPages/api/extensions/table-cell.md +++ /dev/null @@ -1,6 +0,0 @@ -# TableCell -Enables you to use the `` HTML tag in the editor. - -::: warning Restrictions -This extensions is intended to be used with the `Table` extension. -::: diff --git a/docs/src/docPages/api/extensions/table-header.md b/docs/src/docPages/api/extensions/table-header.md deleted file mode 100644 index 25731c27..00000000 --- a/docs/src/docPages/api/extensions/table-header.md +++ /dev/null @@ -1,6 +0,0 @@ -# TableHeader -Enables you to use the `` HTML tag in the editor. - -::: warning Restrictions -This extensions is intended to be used with the `Table` extension. -::: \ No newline at end of file diff --git a/docs/src/docPages/api/extensions/table-row.md b/docs/src/docPages/api/extensions/table-row.md deleted file mode 100644 index 748e0c8c..00000000 --- a/docs/src/docPages/api/extensions/table-row.md +++ /dev/null @@ -1,6 +0,0 @@ -# TableRow -Enables you to use the `` HTML tag in the editor. - -::: warning Restrictions -This extensions is intended to be used with the `Table` extension. -::: \ No newline at end of file diff --git a/docs/src/docPages/api/extensions/text-align.md b/docs/src/docPages/api/extensions/text-align.md index fdb3680a..3c6fcf8f 100644 --- a/docs/src/docPages/api/extensions/text-align.md +++ b/docs/src/docPages/api/extensions/text-align.md @@ -1,14 +1,23 @@ -# Text Align +# TextAlign ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-text-align -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-text-align ``` +## Settings +*None* + +## Commands +*None* + +## Keyboard shortcuts +*None* + ## Source code [packages/extension-text-align/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-text-align/) diff --git a/docs/src/docPages/api/extensions/todo-item.md b/docs/src/docPages/api/extensions/todo-item.md deleted file mode 100644 index cd7f171a..00000000 --- a/docs/src/docPages/api/extensions/todo-item.md +++ /dev/null @@ -1,17 +0,0 @@ -# TodoItem -It renders a single toggleable item of a list. - -::: warning Restrictions -This extensions is intended to be used with the `TodoList` extension. -::: - -## Settings -| Option | Type | Default | Description | -| ------ | ------- | ------- | ------------------------------------- | -| nested | Boolean | false | Specifies if you can nest todo lists. | - -## Commands -*None* - -## Keyboard shortcuts -*None* \ No newline at end of file diff --git a/docs/src/docPages/api/extensions/todo-list.md b/docs/src/docPages/api/extensions/todo-list.md deleted file mode 100644 index 0fe0b300..00000000 --- a/docs/src/docPages/api/extensions/todo-list.md +++ /dev/null @@ -1,69 +0,0 @@ -# TodoList -Renders a toggleable list of items. - -::: warning Restrictions -This extensions is intended to be used with the `TodoItem` extension. -::: - -## Settings -*None* - -## Commands -| Command | Options | Description | -| --------- | ------- | ----------------- | -| todo_list | โ | Toggle todo list. | - -## Keyboard shortcuts -*None* - -## Usage -```markup - - - - - Todo List - - - - - - - - -``` \ No newline at end of file diff --git a/docs/src/docPages/api/extensions/typography.md b/docs/src/docPages/api/extensions/typography.md new file mode 100644 index 00000000..2cd372ea --- /dev/null +++ b/docs/src/docPages/api/extensions/typography.md @@ -0,0 +1,17 @@ +# Typography + + +## Installation +```bash +# with npm +npm install @tiptap/typography + +# with Yarn +yarn add @tiptap/typography +``` + +## Source code +[packages/typography/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/typography/) + +## Usage + diff --git a/docs/src/docPages/api/keyboard-shortcuts.md b/docs/src/docPages/api/keyboard-shortcuts.md index 39ff0298..d4db84bf 100644 --- a/docs/src/docPages/api/keyboard-shortcuts.md +++ b/docs/src/docPages/api/keyboard-shortcuts.md @@ -1,8 +1,85 @@ # Keyboard Shortcuts -## Table of Contents +## toc ## Introduction +tiptap comes with sensible keyboard shortcut defaults. Depending on what you want to use it for, youโll probably want to change those keyboard shortcuts to your liking. Letโs have a look at what we defined for you, and show you how to change it then! + +Funfact: A while ago, we built a [keyboard shortcut learning app](https://mouseless.app), to which we manually added exercises for thousands of keyboard shortcuts for a bunch of tools. + +## Predefined keyboard shortcuts +Most of the core extensions register their own keyboard shortcuts. Depending on what set of extension you use, not all of the below listed keyboard shortcuts work for your editor. + +### Essentials +โ = untested + +| Action | Windows/Linux | macOS | +| ------------------------ | ------------------------------- | --------------------------- | +| Copy | `Control` `C` | `Cmd` `C` | +| Cut | `Control` `X` | `Cmd` `X` | +| Paste | `Control` `V` | `Cmd` `V` | +| Paste without formatting | `Control` `Shift` `V` | `Cmd` `Shift` `V` | +| Undo | `Control` `Z` | `Cmd` `Z` | +| Redo | `Control` `Shift` `Z` | `Cmd` `Shift` `Z` | +| โ Insert or edit link | `Control` `K` | `Cmd` `K` | +| โ Open link | `Alt` `Enter` | `Alt` `Enter` | +| โ Find | `Control` `F` | `Cmd` `F` | +| โ Find and replace | `Control` `H` | `Cmd` `Shift` `H` | +| โ Find again | `Control` `G` | `Cmd` `G` | +| โ Find previous | `Control` `Shift` `G` | `Cmd` `Shift` `G` | +| โ Repeat last action | `Control` `Y` | `Cmd` `Y` | +| Add a line break | `Shift` `Enter` | `Shift` `Enter` | + +### Text Formatting +| Action | Windows/Linux | macOS | +| ----------------------- | -------------------------------------------- | --------------------------- | +| Bold | `Control` `B` | `Cmd` `B` | +| Italicize | `Control` `I` | `Cmd` `I` | +| Underline | `Control` `U` | `Cmd` `U` | +| โ Strikethrough | `Alt` `Shift` `5` | `Cmd` `Shift` `X` | +| โ Superscript | `Control` `.` | `Cmd` `.` | +| โ Subscript | `Control` `,` | `Cmd` `,` | +| โ Copy text formatting | `Control` `Alt` `C` | `Cmd` `Alt` `C` | +| โ Paste text formatting | `Control` `Alt` `V` | `Cmd` `Alt` `V` | +| โ Clear text formatting | `Control` `\``Control` `Space` | `Cmd` `\` | +| โ Increase font size | `Control` `Shift` `>` | `Cmd` `Shift` `>` | +| โ Decrease font size | `Control` `Shift` `<` | `Cmd` `Shift` `<` | + +### Paragraph Formatting +| Action | Windows/Linux | macOS | +| -------------------------------- | ------------------------------- | ------------------------------- | +| โ Increase paragraph indentation | `Control` `]` | `Cmd` `]` | +| โ Decrease paragraph indentation | `Control` `[` | `Cmd` `[` | +| Apply normal text style | `Control` `Alt` `0` | `Cmd` `Alt` `0` | +| Apply heading style 1 | `Control` `Alt` `1` | `Cmd` `Alt` `1` | +| Apply heading style 2 | `Control` `Alt` `2` | `Cmd` `Alt` `2` | +| Apply heading style 3 | `Control` `Alt` `3` | `Cmd` `Alt` `3` | +| Apply heading style 4 | `Control` `Alt` `4` | `Cmd` `Alt` `4` | +| Apply heading style 5 | `Control` `Alt` `5` | `Cmd` `Alt` `5` | +| Apply heading style 6 | `Control` `Alt` `6` | `Cmd` `Alt` `6` | +| Left align | `Control` `Shift` `L` | `Cmd` `Shift` `L` | +| Center align | `Control` `Shift` `E` | `Cmd` `Shift` `E` | +| Right align | `Control` `Shift` `R` | `Cmd` `Shift` `R` | +| Justify | `Control` `Shift` `J` | `Cmd` `Shift` `J` | +| โ Numbered list | `Control` `Shift` `7` | `Cmd` `Shift` `7` | +| โ Bulleted list | `Control` `Shift` `8` | `Cmd` `Shift` `8` | +| โ Move paragraph up | `Control` `Shift` `โ` | `Control` `Shift` `โ` | +| โ Move paragraph down | `Control` `Shift` `โ` | `Control` `Shift` `โ` | + +### Text Selection +| Action | Windows/Linux | macOS | +| ------------------------------------------------- | ------------------------------- | --------------------------- | +| Select all | `Control` `A` | `Cmd` `A` | +| Extend selection one character to left | `Shift` `โ` | `Shift` `โ` | +| Extend selection one character to right | `Shift` `โ` | `Shift` `โ` | +| Extend selection one line up | `Shift` `โ` | `Shift` `โ` | +| Extend selection one line down | `Shift` `โ` | `Shift` `โ` | +| โ Extend selection one paragraph up | `Alt` `Shift` `โ` | `Alt` `Shift` `โ` | +| โ Extend selection one paragraph down | `Alt` `Shift` `โ` | `Alt` `Shift` `โ` | +| Extend selection to the beginning of the document | `Control` `Shift` `โ` | `Cmd` `Shift` `โ` | +| โ Extend selection to the end of the document | `Control` `Shift` `โ` | `Cmd` `Shift` `โ` | + +## Overwrite keyboard shortcuts Keyboard shortcuts may be strings like `'Shift-Control-Enter'`. Keys are based on the strings that can appear in `event.key`, concatenated with a `-`. There is a little tool called [keycode.info](https://keycode.info/), which shows the `event.key` interactively. Use lowercase letters to refer to letter keys (or uppercase letters if you want shift to be held). You may use `Space` as an alias for the . @@ -11,94 +88,27 @@ Modifiers can be given in any order. `Shift`, `Alt`, `Control` and `Cmd` are rec You can use `Mod` as a shorthand for `Cmd` on Mac and `Control` on other platforms. -## Overwrite keyboard shortcuts +Here is an example how you can overwrite the keyboard shortcuts for an existing extension: ```js // 1. Import the extension import BulletList from '@tiptap/extension-bullet-list' // 2. Overwrite the keyboard shortcuts -const CustomBulletList = BulletList() - .keys(({ editor }) => ({ - // โ your new keyboard shortcut - 'Mod-l': () => editor.bulletList(), - })) - .create() // Donโt forget that! +const CustomBulletList = BulletList.extend({ + addKeyboardShortcuts() { + return { + // โ your new keyboard shortcut + 'Mod-l': () => this.editor.bulletList(), + } + }, +}) // 3. Add the custom extension to your editor new Editor({ extensions: [ - CustomBulletList(), - // โฆ + CustomBulletList(), + // โฆ ] }) ``` - -## Predefined keyboard shortcuts - -### Essentials -| Action | Windows/Linux | macOS | -| ------------------------ | --------------------- | ----------------- | -| Copy | `Control` `C` | `Cmd` `C` | -| Cut | `Control` `X` | `Cmd` `X` | -| Paste | `Control` `V` | `Cmd` `V` | -| Paste without formatting | `Control` `Shift` `V` | `Cmd` `Shift` `V` | -| Undo | `Control` `Z` | `Cmd` `Z` | -| Redo | `Control` `Shift` `Z` | `Cmd` `Shift` `Z` | -| Insert or edit link | `Control` `K` | `Cmd` `K` | -| Open link | `Alt` `Enter` | `Alt` `Enter` | -| Find | `Control` `F` | `Cmd` `F` | -| Find and replace | `Control` `H` | `Cmd` `Shift` `H` | -| Find again | `Control` `G` | `Cmd` `G` | -| Find previous | `Control` `Shift` `G` | `Cmd` `Shift` `G` | -| Repeat last action | `Control` `Y` | `Cmd` `Y` | -| Add a line break | `Shift` `Enter` | `Shift` `Enter` | - -### Text Formatting -| Action | Windows/Linux | macOS | -| --------------------- | --------------------------------------------- | ----------------- | -| Bold | `Control` `B` | `Cmd` `B` | -| Italicize | `Control` `I` | `Cmd` `I` | -| Underline | `Control` `U` | `Cmd` `U` | -| Strikethrough | `Alt` `Shift` `5` | `Cmd` `Shift` `X` | -| Superscript | `Control` `.` | `Cmd` `.` | -| Subscript | `Control` `,` | `Cmd` `,` | -| Copy text formatting | `Control` `Alt` `C` | `Cmd` `Alt` `C` | -| Paste text formatting | `Control` `Alt` `V` | `Cmd` `Alt` `V` | -| Clear text formatting | `Control` \`Control` `Space` | `Cmd` `\` | -| Increase font size | `Control` `Shift` `>` | `Cmd` `Shift` `>` | -| Decrease font size | `Control` `Shift` `<` | `Cmd` `Shift` `<` | - -### Paragraph Formatting -| Action | Windows/Linux | macOS | -| ------------------------------ | --------------------- | --------------------- | -| Increase paragraph indentation | `Control` `]` | `Cmd` `]` | -| Decrease paragraph indentation | `Control` `[` | `Cmd` `[` | -| Apply normal text style | `Control` `Alt` `0` | `Cmd` `Alt` `0` | -| Apply heading style 1 | `Control` `Alt` `1` | `Cmd` `Alt` `1` | -| Apply heading style 2 | `Control` `Alt` `2` | `Cmd` `Alt` `2` | -| Apply heading style 3 | `Control` `Alt` `3` | `Cmd` `Alt` `3` | -| Apply heading style 4 | `Control` `Alt` `4` | `Cmd` `Alt` `4` | -| Apply heading style 5 | `Control` `Alt` `5` | `Cmd` `Alt` `5` | -| Apply heading style 6 | `Control` `Alt` `6` | `Cmd` `Alt` `6` | -| Left align | `Control` `Shift` `L` | `Cmd` `Shift` `L` | -| Center align | `Control` `Shift` `E` | `Cmd` `Shift` `E` | -| Right align | `Control` `Shift` `R` | `Cmd` `Shift` `R` | -| Justify | `Control` `Shift` `J` | `Cmd` `Shift` `J` | -| Numbered list | `Control` `Shift` `7` | `Cmd` `Shift` `7` | -| Bulleted list | `Control` `Shift` `8` | `Cmd` `Shift` `8` | -| Move paragraph up | `Control` `Shift` `โ` | `Control` `Shift` `โ` | -| Move paragraph down | `Control` `Shift` `โ` | `Control` `Shift` `โ` | - -### Text Selection -| Action | Windows/Linux | macOS | -| ------------------------------------------------- | --------------------- | ----------------- | -| Select all | `Control` `A` | `Cmd` `A` | -| Extend selection one character to left | `Shift` `โ` | `Shift` `โ` | -| Extend selection one character to right | `Shift` `โ` | `Shift` `โ` | -| Extend selection one line up | `Shift` `โ` | `Shift` `โ` | -| Extend selection one line down | `Shift` `โ` | `Shift` `โ` | -| Extend selection one paragraph up | `Alt` `Shift` `โ` | `Alt` `Shift` `โ` | -| Extend selection one paragraph down | `Alt` `Shift` `โ` | `Alt` `Shift` `โ` | -| Extend selection to the beginning of the document | `Control` `Shift` `โ` | `Cmd` `Shift` `โ` | -| Extend selection to the end of the document | `Control` `Shift` `โ` | `Cmd` `Shift` `โ` | diff --git a/docs/src/docPages/api/marks.md b/docs/src/docPages/api/marks.md new file mode 100644 index 00000000..31acae58 --- /dev/null +++ b/docs/src/docPages/api/marks.md @@ -0,0 +1,15 @@ +# Marks + +## toc + +## Introduction + +## List of supported marks +| Title | Default Extension | Source Code | +| --------------------------------- | ----------------- | ------------------------------------------------------------------------------------------- | +| [Bold](/api/marks/bold) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-bold/) | +| [Code](/api/marks/code) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-code/) | +| [Italic](/api/marks/italic) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-italic/) | +| [Link](/api/marks/link) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-link/) | +| [Strike](/api/marks/strike) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-strike/) | +| [Underline](/api/marks/underline) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-underline/) | diff --git a/docs/src/docPages/api/extensions/bold.md b/docs/src/docPages/api/marks/bold.md similarity index 91% rename from docs/src/docPages/api/extensions/bold.md rename to docs/src/docPages/api/marks/bold.md index 9cecd744..d991247c 100644 --- a/docs/src/docPages/api/extensions/bold.md +++ b/docs/src/docPages/api/marks/bold.md @@ -9,10 +9,10 @@ The extension will generate the corresponding `` HTML tags when reading ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-bold -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-bold ``` @@ -22,7 +22,7 @@ yarn add @tiptap/extension-bold | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | +| Command | Parameters | Description | | ------- | ------- | --------------- | | bold | โ | Mark text bold. | @@ -34,4 +34,4 @@ yarn add @tiptap/extension-bold [packages/extension-bold/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-bold/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/code.md b/docs/src/docPages/api/marks/code.md similarity index 87% rename from docs/src/docPages/api/extensions/code.md rename to docs/src/docPages/api/marks/code.md index 2c00086c..e6f34272 100644 --- a/docs/src/docPages/api/extensions/code.md +++ b/docs/src/docPages/api/marks/code.md @@ -5,10 +5,10 @@ Type something with \`back-ticks around\` and it will magically tra ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-code -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-code ``` @@ -18,7 +18,7 @@ yarn add @tiptap/extension-code | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | +| Command | Parameters | Description | | ------- | ------- | ------------------------- | | code | โ | Mark text as inline code. | @@ -29,4 +29,4 @@ yarn add @tiptap/extension-code [packages/extension-code/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-code/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/highlight.md b/docs/src/docPages/api/marks/highlight.md similarity index 100% rename from docs/src/docPages/api/extensions/highlight.md rename to docs/src/docPages/api/marks/highlight.md diff --git a/docs/src/docPages/api/extensions/italic.md b/docs/src/docPages/api/marks/italic.md similarity index 90% rename from docs/src/docPages/api/extensions/italic.md rename to docs/src/docPages/api/marks/italic.md index b917844d..40717304 100644 --- a/docs/src/docPages/api/extensions/italic.md +++ b/docs/src/docPages/api/marks/italic.md @@ -9,10 +9,10 @@ The extension will generate the corresponding `` HTML tags when reading cont ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-italic -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-italic ``` @@ -22,7 +22,7 @@ yarn add @tiptap/extension-italic | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | +| Command | Parameters | Description | | ------- | ------- | ----------------- | | italic | โ | Mark text italic. | @@ -34,4 +34,4 @@ yarn add @tiptap/extension-italic [packages/extension-italic/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-italic/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/link.md b/docs/src/docPages/api/marks/link.md similarity index 89% rename from docs/src/docPages/api/extensions/link.md rename to docs/src/docPages/api/marks/link.md index 0eb0c14f..30ce4b20 100644 --- a/docs/src/docPages/api/extensions/link.md +++ b/docs/src/docPages/api/marks/link.md @@ -7,10 +7,10 @@ Pasted URLs will be linked automatically. ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-link -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-link ``` @@ -23,17 +23,17 @@ yarn add @tiptap/extension-link | target | string | _blank | Set the default `target` of links. | ## Commands -| Command | Options | Description | +| Command | Parameters | Description | | ------- | -------------- | ----------------------------------------------------------- | | link | hreftarget | Link the selected text. Removes a link, if `href` is empty. | ## Keyboard shortcuts :::warning Doesnโt have a keyboard shortcut -This extension doesnโt bind a specific keyboard shortcut. You would probably open your UI on `Mod-k` though. +This extension doesnโt bind a specific keyboard shortcut. You would probably open your custom UI on `Mod-k` though. ::: ## Source code [packages/extension-link/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-link/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/strike.md b/docs/src/docPages/api/marks/strike.md similarity index 90% rename from docs/src/docPages/api/extensions/strike.md rename to docs/src/docPages/api/marks/strike.md index 4cff00dd..16a1b780 100644 --- a/docs/src/docPages/api/extensions/strike.md +++ b/docs/src/docPages/api/marks/strike.md @@ -9,10 +9,10 @@ The extension will generate the corresponding `` HTML tags when reading conte ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-strike -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-strike ``` @@ -22,7 +22,7 @@ yarn add @tiptap/extension-strike | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | +| Command | Parameters | Description | | ------- | ------- | --------------------------- | | strike | โ | Mark text as strikethrough. | @@ -34,4 +34,4 @@ yarn add @tiptap/extension-strike [packages/extension-strike/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-strike/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/underline.md b/docs/src/docPages/api/marks/underline.md similarity index 83% rename from docs/src/docPages/api/extensions/underline.md rename to docs/src/docPages/api/marks/underline.md index 08b4616c..2f5045a7 100644 --- a/docs/src/docPages/api/extensions/underline.md +++ b/docs/src/docPages/api/marks/underline.md @@ -9,10 +9,10 @@ The extension will generate the corresponding `` HTML tags when reading conte ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-underline -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-underline ``` @@ -22,9 +22,9 @@ yarn add @tiptap/extension-underline | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | -| --------- | ------- | ------------------------ | -| underline | โ | Mark text as underlined. | +| Command | Parameters | Description | +| --------- | ---------- | ------------------------ | +| underline | โ | Mark text as underlined. | ## Keyboard shortcuts * Windows/Linux: `Control` `U` @@ -34,4 +34,4 @@ yarn add @tiptap/extension-underline [packages/extension-underline/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-underline/) ## Usage - + diff --git a/docs/src/docPages/api/nodes.md b/docs/src/docPages/api/nodes.md new file mode 100644 index 00000000..f7c12b50 --- /dev/null +++ b/docs/src/docPages/api/nodes.md @@ -0,0 +1,23 @@ +# Nodes + +## toc + +## Introduction + +## List of supported nodes +| Title | Default Extension | Source Code | +| -------------------------------------------- | ----------------- | ------------------------------------------------------------------------------------------------- | +| [Blockquote](/api/nodes/blockquote) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-blockquote/) | +| [BulletList](/api/nodes/bullet-list) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-bullet-list/) | +| [CodeBlock](/api/nodes/code-block) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-code-block/) | +| [Document](/api/nodes/document) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-document/) | +| [HardBreak](/api/nodes/hard-break) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-hard-break/) | +| [Heading](/api/nodes/heading) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-heading/) | +| [HorizontalRule](/api/nodes/horizontal-rule) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-horizontal-rule/) | +| [Image](/api/nodes/image) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-image/) | +| [ListItem](/api/nodes/list-item) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-list-item/) | +| [OrderedList](/api/nodes/ordered-list) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-ordered-list/) | +| [Paragraph](/api/nodes/paragraph) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-paragraph/) | +| [TaskItem](/api/nodes/task-item) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-task-item/) | +| [TaskList](/api/nodes/task-list) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-task-list/) | +| [Text](/api/nodes/text) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-text/) | diff --git a/docs/src/docPages/api/extensions/blockquote.md b/docs/src/docPages/api/nodes/blockquote.md similarity index 77% rename from docs/src/docPages/api/extensions/blockquote.md rename to docs/src/docPages/api/nodes/blockquote.md index 533c1a0a..66de2089 100644 --- a/docs/src/docPages/api/extensions/blockquote.md +++ b/docs/src/docPages/api/nodes/blockquote.md @@ -6,10 +6,10 @@ Type > at the beginning of a new line and it will magically t ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-blockquote -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-blockquote ``` @@ -19,9 +19,9 @@ yarn add @tiptap/extension-blockquote | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | -| ---------- | ------- | ----------------------------- | -| blockquote | โ | Wrap content in a blockquote. | +| Command | Parameters | Description | +| ---------- | ---------- | ----------------------------- | +| blockquote | โ | Wrap content in a blockquote. | ## Keyboard shortcuts * Windows/Linux: `Control` `Shift` `9` @@ -31,4 +31,4 @@ yarn add @tiptap/extension-blockquote [packages/extension-blockquote/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-blockquote/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/bullet-list.md b/docs/src/docPages/api/nodes/bullet-list.md similarity index 65% rename from docs/src/docPages/api/extensions/bullet-list.md rename to docs/src/docPages/api/nodes/bullet-list.md index 91cbdb76..6f5fff6c 100644 --- a/docs/src/docPages/api/extensions/bullet-list.md +++ b/docs/src/docPages/api/nodes/bullet-list.md @@ -1,18 +1,18 @@ # BulletList -This extension enables you to use bullet lists in the editor. They are rendered as `` HTML tags, +This extension enables you to use bullet lists in the editor. They are rendered as `` HTML tags. Type * , - or + at the beginning of a new line and it will magically transform to a bullet list. ## Installation ::: warning Use with ListItem -The `BulletList` extension is intended to be used with the [`ListItem`](/api/extensions/list-item) extension. Make sure to import that one too, otherwise youโll get a SyntaxError. +This extension requires the [`ListItem`](/api/nodes/list-item) extension. ::: ```bash -# With npm +# with npm npm install @tiptap/extension-bullet-list @tiptap/extension-list-item -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-bullet-list @tiptap/extension-list-item ``` @@ -22,9 +22,9 @@ yarn add @tiptap/extension-bullet-list @tiptap/extension-list-item | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | -| ----------- | ------- | --------------------- | -| bullet_list | โ | Toggle a bullet list. | +| Command | Parameters | Description | +| ----------- | ---------- | --------------------- | +| bulletList | โ | Toggle a bullet list. | ## Keyboard shortcuts * `Control` `Shift` `8` @@ -33,4 +33,4 @@ yarn add @tiptap/extension-bullet-list @tiptap/extension-list-item [packages/extension-bullet-list/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-bullet-list/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/code-block.md b/docs/src/docPages/api/nodes/code-block.md similarity index 85% rename from docs/src/docPages/api/extensions/code-block.md rename to docs/src/docPages/api/nodes/code-block.md index e8a45b6d..1dce417e 100644 --- a/docs/src/docPages/api/extensions/code-block.md +++ b/docs/src/docPages/api/nodes/code-block.md @@ -9,10 +9,10 @@ The CodeBlock extension doesnโt come with styling and has no syntax highlighti ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-code-block -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-code-block ``` @@ -23,9 +23,9 @@ yarn add @tiptap/extension-code-block | languageClassPrefix | string | language- | Adds a prefix to language classes that are applied to code tags. | ## Commands -| Command | Options | Description | -| --------- | ------- | ----------------------------- | -| codeBlock | โ | Wrap content in a code block. | +| Command | Parameters | Description | +| --------- | ---------- | ----------------------------- | +| codeBlock | โ | Wrap content in a code block. | ## Keyboard shortcuts * Windows/Linux: `Control` `Shift` `C` @@ -35,4 +35,4 @@ yarn add @tiptap/extension-code-block [packages/extension-code-block/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-code-block/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/document.md b/docs/src/docPages/api/nodes/document.md similarity index 86% rename from docs/src/docPages/api/extensions/document.md rename to docs/src/docPages/api/nodes/document.md index 246932a8..e887bed8 100644 --- a/docs/src/docPages/api/extensions/document.md +++ b/docs/src/docPages/api/nodes/document.md @@ -4,15 +4,15 @@ The node is very tiny though. It defines a name of the node (`document`), is configured to be a top node (`topNode: true`) and that it can contain multiple other nodes (`block`). Thatโs all. But have a look yourself: :::warning Breaking Change from 1.x โ 2.x -Tiptap 1 tried to hide that node from you, but it has always been there. A tiny, but important change though: **We renamed the default type from `doc` to `document`.** To keep it like that, use your own implementation of the `Document` node or migrate the stored JSON to use the new name. +tiptap 1 tried to hide that node from you, but it has always been there. A tiny, but important change though: **We renamed the default type from `doc` to `document`.** To keep it like that, use your own implementation of the `Document` node or migrate the stored JSON to use the new name. ::: ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-document -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-document ``` @@ -20,4 +20,4 @@ yarn add @tiptap/extension-document [packages/extension-document/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-document/) ## Usage - \ No newline at end of file + diff --git a/docs/src/docPages/api/extensions/hard-break.md b/docs/src/docPages/api/nodes/hard-break.md similarity index 66% rename from docs/src/docPages/api/extensions/hard-break.md rename to docs/src/docPages/api/nodes/hard-break.md index ae6687f4..83fc2a99 100644 --- a/docs/src/docPages/api/extensions/hard-break.md +++ b/docs/src/docPages/api/nodes/hard-break.md @@ -3,20 +3,17 @@ The HardBreak extensions adds support for the `` HTML tag, which forces a li ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-hard-break -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-hard-break ``` -## Settings -*None* - ## Commands -| Command | Options | Description | -| --------- | ------- | ----------------- | -| hardBreak | โ | Add a line break. | +| Command | Parameters | Description | +| --------- | ---------- | ----------------- | +| hardBreak | โ | Add a line break. | ## Keyboard shortcuts * `Shift` `Enter` @@ -27,4 +24,4 @@ yarn add @tiptap/extension-hard-break [packages/extension-hard-break/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-hard-break/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/heading.md b/docs/src/docPages/api/nodes/heading.md similarity index 80% rename from docs/src/docPages/api/extensions/heading.md rename to docs/src/docPages/api/nodes/heading.md index fefd6835..652d0630 100644 --- a/docs/src/docPages/api/extensions/heading.md +++ b/docs/src/docPages/api/nodes/heading.md @@ -5,10 +5,10 @@ Type # at the beginning of a new line and it will magically t ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-heading -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-heading ``` @@ -19,9 +19,9 @@ yarn add @tiptap/extension-heading | levels | Array | [1, 2, 3, 4, 5, 6] | Specifies which heading levels are supported. | ## Commands -| Command | Options | Description | -| ------- | ------- | ----------------------- | -| heading | level | Creates a heading node. | +| Command | Parameters | Description | +| ------- | ---------- | ------------------------------------------------ | +| heading | level | Creates a heading node with the specified level. | ## Keyboard shortcuts * Windows/Linux: `Control` `Alt` `1-6` @@ -31,4 +31,4 @@ yarn add @tiptap/extension-heading [packages/extension-heading/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-heading/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/horizontal-rule.md b/docs/src/docPages/api/nodes/horizontal-rule.md similarity index 76% rename from docs/src/docPages/api/extensions/horizontal-rule.md rename to docs/src/docPages/api/nodes/horizontal-rule.md index 2363e8b5..81b6c0e7 100644 --- a/docs/src/docPages/api/extensions/horizontal-rule.md +++ b/docs/src/docPages/api/nodes/horizontal-rule.md @@ -5,10 +5,10 @@ Type three dashes (---) or three underscores and a space (___ ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-horizontal-rule -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-horizontal-rule ``` @@ -18,9 +18,9 @@ yarn add @tiptap/extension-horizontal-rule | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | -| --------------- | ------- | ------------------------- | -| horizontalRule | โ | Create a horizontal rule. | +| Command | Parameters | Description | +| -------------- | ---------- | ------------------------- | +| horizontalRule | โ | Create a horizontal rule. | ## Keyboard shortcuts *None* @@ -29,4 +29,4 @@ yarn add @tiptap/extension-horizontal-rule [packages/extension-horizontal-rule/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-horizontal-rule/) ## Usage - + diff --git a/docs/src/docPages/api/nodes/image.md b/docs/src/docPages/api/nodes/image.md new file mode 100644 index 00000000..a4e93205 --- /dev/null +++ b/docs/src/docPages/api/nodes/image.md @@ -0,0 +1,26 @@ +# Image +Use this extension to render `` HTML tags. By default, those images are blocks. If you want to render images in line with text set the `inline` option to `true`. + +:::warning Restrictions +This extension does only the rendering of images. It doesnโt upload images to your server, thatโs a whole different story. +::: + +## Installation +```bash +# with npm +npm install @tiptap/extension-image + +# with Yarn +yarn add @tiptap/extension-image +``` + +## Settings +| Option | Type | Default | Description | +| ------ | ------- | ------- | ------------------------------ | +| inline | boolean | false | Renders the image node inline. | + +## Source code +[packages/extension-image/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-image/) + +## Usage + diff --git a/docs/src/docPages/api/extensions/list-item.md b/docs/src/docPages/api/nodes/list-item.md similarity index 69% rename from docs/src/docPages/api/extensions/list-item.md rename to docs/src/docPages/api/nodes/list-item.md index 8a81fb38..3fbc1f42 100644 --- a/docs/src/docPages/api/extensions/list-item.md +++ b/docs/src/docPages/api/nodes/list-item.md @@ -2,15 +2,15 @@ The ListItem extension adds support for the `` HTML tag. Itโs used for bullet lists and ordered lists and canโt really be used without them. ## Installation -::: warning Restrictions -This extensions is intended to be used with the [`BulletList`](/api/extensions/bullet-list) or [`OrderedList`](/api/extensions/ordered-list) extension. It doesnโt work without at least using one of them. +::: warning Use with BulletList and/or OrderedList +This extension requires the [`BulletList`](/api/nodes/bullet-list) or [`OrderedList`](/api/nodes/ordered-list) extension. ::: ```bash -# With npm +# with npm npm install @tiptap/extension-list-item -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-list-item ``` @@ -19,9 +19,6 @@ yarn add @tiptap/extension-list-item | ------ | ------ | ------- | -------------------------------------------- | | class | string | โ | Add a custom class to the rendered HTML tag. | -## Commands -*None* - ## Keyboard shortcuts * New list item: `Enter` * Sink a list item: `Tab` @@ -31,4 +28,4 @@ yarn add @tiptap/extension-list-item [packages/extension-list-item/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-list-item/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/ordered-list.md b/docs/src/docPages/api/nodes/ordered-list.md similarity index 65% rename from docs/src/docPages/api/extensions/ordered-list.md rename to docs/src/docPages/api/nodes/ordered-list.md index 3e9c2fd8..38dc26e7 100644 --- a/docs/src/docPages/api/extensions/ordered-list.md +++ b/docs/src/docPages/api/nodes/ordered-list.md @@ -1,18 +1,18 @@ # OrderedList -This extension enables you to use ordered lists in the editor. They are rendered as `` HTML tags, +This extension enables you to use ordered lists in the editor. They are rendered as `` HTML tags. Type 1. (or any other number followed by a dot) at the beginning of a new line and it will magically transform to a ordered list. ## Installation ::: warning Use with ListItem -The `OrderedList` extension is intended to be used with the [`ListItem`](/api/extensions/list-item) extension. Make sure to import that one too, otherwise youโll get a SyntaxError. +This extension requires the [`ListItem`](/api/nodes/list-item) extension. ::: ```bash -# With npm +# with npm npm install @tiptap/extension-ordered-list @tiptap/extension-list-item -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-ordered-list @tiptap/extension-list-item ``` @@ -22,9 +22,9 @@ yarn add @tiptap/extension-ordered-list @tiptap/extension-list-item | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | -| ------------ | ------- | ---------------------- | -| ordered_list | โ | Toggle a ordered list. | +| Command | Parameters | Description | +| ----------- | ---------- | ----------------------- | +| orderedList | โ | Toggle an ordered list. | ## Keyboard shortcuts * `Control` `Shift` `9` @@ -33,4 +33,4 @@ yarn add @tiptap/extension-ordered-list @tiptap/extension-list-item [packages/extension-ordered-list/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-ordered-list/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/paragraph.md b/docs/src/docPages/api/nodes/paragraph.md similarity index 70% rename from docs/src/docPages/api/extensions/paragraph.md rename to docs/src/docPages/api/nodes/paragraph.md index feac7701..6a3013d7 100644 --- a/docs/src/docPages/api/extensions/paragraph.md +++ b/docs/src/docPages/api/nodes/paragraph.md @@ -2,15 +2,15 @@ Yes, the schema is very strict. Without this extension you wonโt even be able to use paragraphs in the editor. :::warning Breaking Change from 1.x โ 2.x -Tiptap 1 tried to hide that node from you, but it has always been there. You have to explicitly import it from now on (or use `defaultExtensions()`). +tiptap 1 tried to hide that node from you, but it has always been there. You have to explicitly import it from now on (or use `defaultExtensions()`). ::: ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-paragraph -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-paragraph ``` @@ -20,9 +20,9 @@ yarn add @tiptap/extension-paragraph | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | -| --------- | ------- | -------------------------------------------- | -| paragraph | โ | Transforms all selected nodes to paragraphs. | +| Command | Parameters | Description | +| --------- | ---------- | -------------------------------------------- | +| paragraph | โ | Transforms all selected nodes to paragraphs. | ## Keyboard shortcuts * Windows & Linux: `Control` `Alt` `0` @@ -32,4 +32,4 @@ yarn add @tiptap/extension-paragraph [packages/extension-paragraph/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-paragraph/) ## Usage - + diff --git a/docs/src/docPages/api/nodes/task-item.md b/docs/src/docPages/api/nodes/task-item.md new file mode 100644 index 00000000..be6e772c --- /dev/null +++ b/docs/src/docPages/api/nodes/task-item.md @@ -0,0 +1,28 @@ +# TaskItem + +## Installation +::: warning Use with TaskList +This extension requires the [`TaskList`](/api/nodes/task-list) extension. +::: + +```bash +# With npm +npm install @tiptap/extension-task-list @tiptap/extension-task-item + +# Or: With Yarn +yarn add @tiptap/extension-task-list @tiptap/extension-task-item +``` + +## Settings +| Option | Type | Default | Description | +| ------ | ------ | ------- | -------------------------------------------- | +| class | string | โ | Add a custom class to the rendered HTML tag. | + +## Commands +*None* + +## Source code +[packages/extension-task-item/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-task-item/) + +## Usage + diff --git a/docs/src/docPages/api/nodes/task-list.md b/docs/src/docPages/api/nodes/task-list.md new file mode 100644 index 00000000..82a74d4b --- /dev/null +++ b/docs/src/docPages/api/nodes/task-list.md @@ -0,0 +1,33 @@ +# TaskList +This extension enables you to use task lists in the editor. They are rendered as ``. This implementation doesnโt require any framework, itโs using plain JavaScript only. + +Type [ ] or [x] at the beginning of a new line and it will magically transform to a task list. + +## Installation +::: warning Use with TaskItem +This extension requires the [`TaskItem`](/api/nodes/task-item) extension. +::: + +```bash +# with npm +npm install @tiptap/extension-task-list @tiptap/extension-task-item + +# with Yarn +yarn add @tiptap/extension-task-list @tiptap/extension-task-item +``` + +## Settings +| Option | Type | Default | Description | +| ------ | ------ | ------- | -------------------------------------------- | +| class | string | โ | Add a custom class to the rendered HTML tag. | + +## Commands +| Command | Parameters | Description | +| -------- | ---------- | ------------------- | +| taskList | โ | Toggle a task list. | + +## Source code +[packages/extension-task-list/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-task-list/) + +## Usage + diff --git a/docs/src/docPages/api/extensions/text.md b/docs/src/docPages/api/nodes/text.md similarity index 80% rename from docs/src/docPages/api/extensions/text.md rename to docs/src/docPages/api/nodes/text.md index d6664a5f..c283cc72 100644 --- a/docs/src/docPages/api/extensions/text.md +++ b/docs/src/docPages/api/nodes/text.md @@ -2,15 +2,15 @@ **The `Text` extension is required**, at least if you want to work with text of any kind and thatโs very likely. This extension is a little bit different, it doesnโt even render HTML. Itโs plain text, thatโs all. :::warning Breaking Change from 1.x โ 2.x -Tiptap 1 tried to hide that node from you, but it has always been there. You have to explicitly import it from now on (or use `defaultExtensions()`). +tiptap 1 tried to hide that node from you, but it has always been there. You have to explicitly import it from now on (or use `defaultExtensions()`). ::: ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-text -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-text ``` @@ -18,4 +18,4 @@ yarn add @tiptap/extension-text [packages/extension-text/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-text/) ## Usage - \ No newline at end of file + diff --git a/docs/src/docPages/api/overview.md b/docs/src/docPages/api/overview.md index f7b813bb..46b551c6 100644 --- a/docs/src/docPages/api/overview.md +++ b/docs/src/docPages/api/overview.md @@ -1,10 +1,13 @@ # Overview - tiptap is a friendly wrapper around [ProseMirror](https://ProseMirror.net). +tiptap is a friendly wrapper around [ProseMirror](https://ProseMirror.net). - ProseMirror works with a strict [Schema](/api/schema), which defines the allowed structure of a document. A document is a tree of headings, paragraphs and others elements, so called nodes. Marks can be attached to a node, e. g. to emphasize part of it. [Commands](/api/commands) change that document programmatically. +### Structure +ProseMirror works with a strict [Schema](/api/schema), which defines the allowed structure of a document. A document is a tree of headings, paragraphs and others elements, so called nodes. Marks can be attached to a node, e. g. to emphasize part of it. [Commands](/api/commands) change that document programmatically. - The document is stored in a state. All changes are applied as transactions to the state. The state has details about the current content, cursor position and selection. You can hook into a few different [events](/api/events), for example to alter transactions before they get applied. +### Content +The document is stored in a state. All changes are applied as transactions to the state. The state has details about the current content, cursor position and selection. You can hook into a few different [events](/api/events), for example to alter transactions before they get applied. - [Extensions](/api/extensions) add functionality like nodes, marks and/or commands to the editor. A huge amount of commands are bound to common [keyboard shortcuts](/api/keyboard-shortcuts). +### Extensions +Extensions add [nodes](/api/nodes), [marks](/api/marks) and/or [functionalities](/api/extensions) to the editor. A lot of those extensions bound their commands to common [keyboard shortcuts](/api/keyboard-shortcuts). -All of those concepts are explained in detail on the following pages. +All those concepts are explained in detail on the following pages. diff --git a/docs/src/docPages/api/schema.md b/docs/src/docPages/api/schema.md index 37a4b3fc..3fe871d4 100644 --- a/docs/src/docPages/api/schema.md +++ b/docs/src/docPages/api/schema.md @@ -1,6 +1,6 @@ # Schema -## Table of Contents +## toc ## Introduction Unlike many other editors, tiptap is based on a [schema](https://prosemirror.net/docs/guide/#schema) that defines how your content is structured. That enables you to define the kind of nodes that may occur in the document, its attributes and the way they can be nested. @@ -10,10 +10,10 @@ This schema is *very* strict. You canโt use any HTML element or attribute that Let me give you one example: If you paste something like `This is important` into tiptap, donโt have any extension that handles `strong` tags registered, youโll only see `This is important` โ without the strong tags. ## How a schema looks like - -The most simple schema for a typical *ProseMirror* editor is looking something like that: +When youโll work with the provided extensions only, you donโt have to care that much about the schema. If youโre building your own extensions, itโs probably helpful to understand how the schema works. Letโs look at the most simple schema for a typical ProseMirror editor: ```js +// the underlying ProseMirror schema { nodes: { document: { @@ -32,58 +32,225 @@ The most simple schema for a typical *ProseMirror* editor is looking something l } ``` -:::warning Out of date -This content is written for tiptap 1 and needs an update. -::: - We register three nodes here. `document`, `paragraph` and `text`. `document` is the root node which allows one or more block nodes as children (`content: 'block+'`). Since `paragraph` is in the group of block nodes (`group: 'block'`) our document can only contain paragraphs. Our paragraphs allow zero or more inline nodes as children (`content: 'inline*'`) so there can only be `text` in it. `parseDOM` defines how a node can be parsed from pasted HTML. `toDOM` defines how it will be rendered in the DOM. -In tiptap we define every node in its own `Extension` class instead. This allows us to split logic per node. Under the hood the schema will be merged together. +In tiptap every node, mark and extension is living in its own file. This allows us to split the logic. Under the hood the whole schema will be merged together: ```js -class Document extends Node { - name = 'document' - topNode = true +// the tiptap schema API +import { createNode } from '@tiptap/core' - schema() { - return { - content: 'block+', - } - } -} +const Document = createNode({ + name: 'document', + topNode: true, + content: 'block+', +}) -class Paragraph extends Node { - name = 'paragraph' +const Paragraph = createNode({ + name: 'paragraph', + group: 'block', + content: 'inline*', + parseHTML() { + return [ + { tag: 'p' }, + ] + }, + renderHTML({ attributes }) { + return ['p', attributes, 0] + }, +}) - schema() { - return { - content: 'inline*', - group: 'block', - parseDOM: [{ tag: 'p' }], - toDOM: () => ['p', 0], - } - } -} - -class Text extends Node { - name = 'text' - - schema() { - return { - group: 'inline', - } - } -} +const Text = createNode({ + name: 'text', + group: 'inline', +}) ``` -## Difference between a Node and a Mark +### Parse HTML -*Nodes* are like blocks of content, for example paragraphs, headings, code blocks, blockquotes and many more. +### Render HTML -*Marks* can apply a different style to specific parts of text inside a *Node*. Thatโs the case for **bold**, *italic* or ~~striked~~ text. [Links](#) are *Marks*, too. +## Nodes and marks + +### Differences +Nodes are like blocks of content, for example paragraphs, headings, code blocks, blockquotes and many more. + +Marks can be applied to specific parts of a node. Thatโs the case for **bold**, *italic* or ~~striked~~ text. [Links](#) are marks, too. + +### The node schema + +#### Content +The content attribute defines exactly what kind of content the node can have. ProseMirror is really strict with that. That means, content which doesnโt fit the schema is thrown away. It expects a name or group as a string. Here are a few examples: + +```js +createNode({ + // must have one ore more blocks + content: 'block+', + + // allows all kinds of 'inline' content (text or hard breaks) + content: 'inline*', + + // must not have anything else than 'text' + content: 'text*', + + // can have one or more paragraphs, or lists (if lists are used) + content: '(paragraph|list?)+', +}) +``` + + +#### Marks +You can define which marks are allowed inside of a node with the `marks` setting of the schema. Add a one or more names or groups of marks, allow all or disallow all marks like this: + +```js +createNode({ + // allows only the 'bold' mark + marks: 'bold', + + // allows only the 'bold' and 'italic' marks + marks: 'bold italic', + + // allows all marks + marks: '_', + + // disallows all marks + marks: '', +}) +``` + +#### Group +Add this node to a group of extensions, which can be referred to in the [content](#content) attribute of the schema. + +```js +createNode({ + // add to 'block' group + group: 'block', + + // add to 'inline' group + group: 'inline', + + // add to 'block' and 'list' group + group: 'block list', +}) +``` + +#### Inline +Nodes can be rendered inline, too. When setting `inline: true` nodes are rendered in line with the text. Thatโs the case for mentions. The result is more like a mark, but with the functionality of a node. One difference is the resulting JSON document. Multiple marks are applied at once, inline nodes would result in a nested structure. + +```js +createNode({ + // renders nodes in line with the text, for example + inline: true, +}) +``` + +#### Atom +Nodes with `atom: true` arenโt directly editable and should be treated as a single unit. Itโs not so likely to use that in a editor context, but this is how it would look like: + +```js +createNode({ + atom: true, +}) +``` + +#### Selectable +> Controls whether nodes of this type can be selected as a node selection. Defaults to true for non-text nodes. + +```js +createNode({ + selectable: true, +}) +``` + +#### Draggable +All nodes can be configured to be draggable (by default they arenโt) with this setting: + +```js +createNode({ + draggable: true, +}) +``` + +#### Code +Users expect code to behave very differently. For all kind of nodes containing code, you can set `code: true` to take this into account. + +```js +createNode({ + code: true, +}) +``` + +#### Defining +> Determines whether this node is considered an important parent node during replace operations (such as paste). Non-defining (the default) nodes get dropped when their entire content is replaced, whereas defining nodes persist and wrap the inserted content. Likewise, in inserted content the defining parents of the content are preserved when possible. Typically, non-default-paragraph textblock types, and possibly list items, are marked as defining. + +```js +createNode({ + defining: true, +}) +``` + +#### Isolating +For nodes that should fence the cursor for regular editing operations like backspacing, for example a TableCell, set `isolating: true`. + +```js +createNode({ + isolating: true, +}) +``` + +### The mark schema +#### Inclusive +If you donโt want the mark to be active when the cursor is at its end, set inclusive to `false`. For example, thatโs how itโs configured for [`Link`](/api/marks/link) marks: + +```js +createMark({ + inclusive: false, +}) +``` + +#### Excludes +By default all nodes can be applied at the same time. With the excludes attribute you can define which marks must not coexist with the mark. For example, the inline code mark excludes any other mark (bold, italic, and all others). + +```js +createMark({ + // must not coexist with the bold mark + excludes: 'bold' + // exclude any other mark + excludes: '_', +}) +``` + +#### Group +Add this mark to a group of extensions, which can be referred to in the content attribute of the schema. + +```js +createMark({ + // add this mark to the 'basic' group + group: 'basic', + // add this mark to the 'basic' and the 'foobar' group + group: 'foobar', +}) +``` + +#### Code +Users expect code to behave very differently. For all kind of marks containing code, you can set `code: true` to take this into account. + +```js +createMark({ + code: true, +}) +``` + +#### Spanning +By default marks can span multiple nodes when rendered as HTML. Set `spanning: false` to indicate that a mark must not span multiple nodes. + +```js +createMark({ + spanning: false, +}) +``` ## Get the underlying ProseMirror schema - There are a few use cases where you need to work with the underlying schema. Youโll need that if youโre using the tiptap collaborative text editing features or if you want to manually render your content as HTML. ### Option 1: With an Editor @@ -123,23 +290,3 @@ const schema = getSchema([ // add more extensions here ]) ``` - -## Generate HTML from ProseMirror JSON - -If you need to render the content on the server side, e. g. for a blog post that was written with tiptap, youโll probably need a way to do just that without an actual editor instance. - -Thatโs what `generategetHTML()` is for. Itโs a utility function that renders HTML without an actual editor instance. - -:::warning Work in progress -Currently, that works only in the browser (client side), but we plan to bring this to Node.js (to use it on the server side). -::: - - - -### Converting JSON<>HTML with PHP - -We needed to do the same thing in PHP at some point, so we published libraries to convert ProseMirror JSON to HTML and vice-versa: - -* [ueberdosis/prosemirror-php](https://github.com/ueberdosis/prosemirror-php) (PHP) -* [ueberdosis/prosemirror-to-html](https://github.com/ueberdosis/prosemirror-to-html) (PHP) -* [ueberdosis/html-to-prosemirror](https://github.com/ueberdosis/html-to-prosemirror) (PHP) diff --git a/docs/src/docPages/examples.md b/docs/src/docPages/examples.md index 555e143e..4b61ec78 100644 --- a/docs/src/docPages/examples.md +++ b/docs/src/docPages/examples.md @@ -1,9 +1,3 @@ # Examples -We put together a few examples to show the capabilities of tiptap, but keep in mind: tiptap is renderless and highly customizable. Everything you see can be changed, modified, combined or remixed. Feel free to copy the code to your project and change it to your liking. - -A few examples show what youโd probably expect from a text editor anyway: [Basic](/examples/basic), [Links](/examples/links), [History](/examples/history), [Read-only](/examples/read-only), [Export HTML or JSON](/examples/export-html-or-json). - -Some examples show how you can improve the user experience: [Markdown shortcuts](/examples/markdown-shortcuts). - -Or they show advanced use cases, like the [Collaborative editing](/examples/collaborative-editing) example, which is basically tiptap in multiplayer mode. +TODO: This page should redirect to [/examples/basic](/examples/basic). diff --git a/docs/src/docPages/examples/basic.md b/docs/src/docPages/examples/basic.md index 91004db3..c33b8158 100644 --- a/docs/src/docPages/examples/basic.md +++ b/docs/src/docPages/examples/basic.md @@ -1,4 +1,3 @@ # Basic -BUG: Headings canโt be transformed to a bullet or ordered list. diff --git a/docs/src/docPages/examples/collaborative-editing.md b/docs/src/docPages/examples/collaborative-editing.md index c085612e..7c0f4566 100644 --- a/docs/src/docPages/examples/collaborative-editing.md +++ b/docs/src/docPages/examples/collaborative-editing.md @@ -1,4 +1,9 @@ # Collaborative editing + +:::premium Requires Premium Extensions +Using this example in production requires a **tiptap pro** license. [Read more](/sponsor) +::: + This example shows how you can use tiptap to let different users collaboratively work on the same text in real-time. It connects client with WebRTC and merges changes to the document (no matter where they come from) with the awesome library [Y.js](https://github.com/yjs/yjs) by Kevin Jahns. Be aware that in a real-world scenario you would probably add a server, which is also able to merge changes with Y.js. diff --git a/docs/src/docPages/examples/formatting.md b/docs/src/docPages/examples/formatting.md new file mode 100644 index 00000000..e6e0f8ce --- /dev/null +++ b/docs/src/docPages/examples/formatting.md @@ -0,0 +1,3 @@ +# Formatting + + diff --git a/docs/src/docPages/examples/read-only.md b/docs/src/docPages/examples/read-only.md index fea24ee5..048465a7 100644 --- a/docs/src/docPages/examples/read-only.md +++ b/docs/src/docPages/examples/read-only.md @@ -1,3 +1,3 @@ # Read-only - + diff --git a/docs/src/docPages/guide/build-custom-extensions.md b/docs/src/docPages/guide/build-custom-extensions.md new file mode 100644 index 00000000..195d4b8d --- /dev/null +++ b/docs/src/docPages/guide/build-custom-extensions.md @@ -0,0 +1,305 @@ +# Build custom extensions + +## toc + +## Introduction +One of the strength of tiptap is itโs extendability. You donโt depend on the provided extensions, itโs intended to extend the editor to your liking. With custom extensions you can add new content types and new functionalities, on top of what already exists or starting from scratch. + +## Option 1: Extend existing extensions +Letโs say you want to change the keyboard shortcuts for the bullet list. You should start by looking at [the source code of the `BulletList` extension](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-bullet-list/index.ts) and find the part you would like to change. In that case, the keyboard shortcut, and just that. + +Every extension has an `extend()` method, which takes an object with everything you want to change or add to it. For the bespoken example, your code could like that: + +```js +// 1. Import the extension +import BulletList from '@tiptap/extension-bullet-list' + +// 2. Overwrite the keyboard shortcuts +const CustomBulletList = BulletList.extend({ + addKeyboardShortcuts() { + return { + 'Mod-l': () => this.editor.bulletList(), + } + }, +}) + +// 3. Add the custom extension to your editor +new Editor({ + extensions: [ + CustomBulletList(), + // โฆ + ] +}) +``` + +The same applies to every aspect of an existing extension, except to the name. Letโs look at all the things that you can change through the extend method. We focus on one aspect in every example, but you can combine all those examples and change multiple aspects in one `extend()` call too. + +### Name +The extension name is used in a whole lot of places and changing it isnโt too easy. If you want to change the name of an existing extension, we would recommended to copy the whole extension and change the name in all occurrences. + +The extension name is also part of the JSON. If you [store your content as JSON](/guide/store-content#option-1-json), you need to change the name there too. + +### Settings +All settings can be configured through the extension anyway, but if you want to change the default settings, for example to provide a library on top of tiptap for other developers, you can do it like that: + +```js +import Heading from '@tiptap/extension-heading' + +const CustomHeading = Heading.extend({ + defaultOptions: { + levels: [1, 2, 3], + }, +}) +``` + +### Schema +tiptap works with a strict schema, which configures how the content can be structured, nested, how it behaves and many more things. You [can change all aspects of the schema](/api/schema) for existing extensions. Letโs walk through a few common use cases. + +The default `Blockquote` extension can wrap other nodes, like headings. If you want to allow nothing but paragraphs in your blockquotes, this is how you could achieve it: + +```js +// Blockquotes must only include paragraphs +import Blockquote from '@tiptap/extension-blockquote' + +const CustomBlockquote = Blockquote.extend({ + content: 'paragraph*', +}) +``` + +The schema even allows to make your nodes draggable, thatโs what the `draggable` option is for, which defaults to `false`. + +```js +// Draggable paragraphs +import Paragraph from '@tiptap/extension-paragraph' + +const CustomParagraph = Paragraph.extend({ + draggable: true, +}) +``` + +Thatโs just two tiny examples, but [the underlying ProseMirror schema](https://prosemirror.net/docs/ref/#model.SchemaSpec) is really powerful. You should definitely read the documentation to understand all the nifty details. + +### Attributes +You can use attributes to store additional information in the content. Letโs say you want to extend the default paragraph extension to enable paragraphs to have different colors: + +```js +const CustomParagraph = Paragraph.extend({ + addAttributes() { + // Return an object with attribute configuration + return { + color: { + default: 'pink', + }, + }, + }, +}) + +// Result: +// Example Text +``` + +Thatโs already enough to tell tiptap about the new attribute, and set `'pink'` as the default value. All attributes will be rendered as a data-attributes by default, and parsed as data-attributes from the content. + +Letโs stick with the color example and assume youโll want to add an inline style to actually color the text. With the `renderHTML` function you can return HTML attributes which will be rendered in the output. + +This examples adds a style HTML attribute based on the value of color: + +```js +const CustomParagraph = Paragraph.extend({ + addAttributes() { + return { + color: { + default: null, + // Take the attribute values + renderHTML: attributes => { + // โฆ and return an object with HTML attributes. + return { + style: `color: ${attributes.color}`, + } + }, + }, + } + }, +}) + +// Result: +// Example Text +``` + +You can also control how the attribute is parsed from the HTML. Letโs say you want to store the color in an attribute called `data-my-fancy-color-attribute`. Legit, right? Anyway, hereโs how you would do that: + +```js +const CustomParagraph = Paragraph.extend({ + addAttributes() { + return { + color: { + default: null, + // Customize the HTML parsing (for example, to load the initial content) + parseHTML: element => { + return { + color: element.getAttribute('data-my-fancy-color-attribute'), + } + }, + // โฆ and customize the HTML rendering. + renderHTML: attributes => { + return { + 'data-my-fancy-color-attribute': atttributes.color, + style: `color: ${attributes.color}`, + } + }, + }, + } + }, +}) + +// Result: +// Example Text +``` + +### Global Attributes +Attributes can be applied to multiple extensions at once. Thatโs useful for text alignment, line height, color, font family, and other styling related attributes. + +Take a closer look at [the full source code](https://github.com/ueberdosis/tiptap-next/tree/main/packages/extension-text-align) of the [`TextAlign`](/api/extensions/text-align) extension to see a more complex example. But here is how it works in a nutshell: + +```js +import { createExtension } from '@tiptap/core' + +const TextAlign = createExtension({ + addGlobalAttributes() { + return [ + { + // Extend the following extensions + types: [ + 'heading', + 'paragraph', + ], + // โฆ with those attributes + attributes: { + textAlign: { + default: 'left', + renderHTML: attributes => ({ + style: `text-align: ${attributes.textAlign}`, + }), + parseHTML: element => ({ + textAlign: element.style.textAlign || 'left', + }), + }, + }, + }, + ] + }, +}) +``` + +### Render HTML +With the `renderHTML` function you can control how an extension is rendered to HTML. We pass an attributes object to it, with all local attributes, global attributes, and configured CSS classes. Here is an example from the `Bold` extension: + +```js +renderHTML({ attributes }) { + return ['strong', attributes, 0] +}, +``` + +The first value in the array should be the name of HTML tag. If the second element is an object, itโs interpreted as a set of attributes. Any elements after that are rendered as children. + +The number zero (representing a hole) is used to indicate where the content should be inserted. Letโs look at the rendering of the `CodeBlock` extension with two nested tags: + +```js +renderHTML({ attributes }) { + return ['pre', ['code', attributes, 0]] +}, +``` + +If you want to add some specific attributes there, import the `mergeAttributes` helper from `@tiptap/core`: + +```js +renderHTML({ attributes }) { + return ['a', mergeAttributes(attributes, { rel: this.options.rel }), 0] +}, +``` + +### Parse HTML +> Associates DOM parser information with this mark (see the corresponding node spec field). The mark field in the rules is implied. + +### Commands + +```js +import Paragraph from '@tiptap/extension-paragraph' + +const CustomParagraph = Paragraph.extend({ + addCommands() { + return { + paragraph: () => ({ commands }) => { + return commands.toggleBlockType('paragraph', 'paragraph') + }, + } + }, +}) +``` + +### Keyboard shortcuts +Most core extensions come with sensible keyboard shortcut defaults. Depending on what you want to build, youโll likely want to change them though. With the `addKeyboardShortcuts()` method you can overwrite the predefined shortcut map: + +```js +// Change the bullet list keyboard shortcut +import BulletList from '@tiptap/extension-bullet-list' + +const CustomBulletList = BulletList.extend({ + addKeyboardShortcuts() { + return { + 'Mod-l': () => this.editor.bulletList(), + } + }, +}) +``` + +### Input rules + +```js +// Use the ~single tilde~ markdown shortcut +import Strike from '@tiptap/extension-strike' +import { markInputRule } from '@tiptap/core' + +const inputRegex = /(?:^|\s)((?:~)((?:[^~]+))(?:~))$/gm + +const CustomStrike = Strike.extend({ + addInputRules() { + return [ + markInputRule(inputRegex, this.type), + ] + }, +}) +``` + +### Paste rules + +```js +// Overwrite the underline regex for pasted text +import Underline from '@tiptap/extension-underline' +import { markPasteRule } from '@tiptap/core' + +const pasteRegex = /(?:^|\s)((?:~)((?:[^~]+))(?:~))$/gm + +const CustomUnderline = Underline.extend({ + addPasteRules() { + return [ + markPasteRule(inputRegex, this.type), + ] + }, +}) +``` + +### Node views + +## Option 2: Start from scratch + +### Read the documentation +Although tiptap tries to hide most of the complexity of ProseMirror, itโs built on top of its APIs and we recommend you to read through the [ProseMirror Guide](https://ProseMirror.net/docs/guide/) for advanced usage. Youโll have a better understanding of how everything works under the hood and get more familiar with many terms and jargon used by tiptap. + +### Have a look at existing extensions + +### Get started + +### Ask questions + +### Share your extension diff --git a/docs/src/docPages/guide/collaborative-editing.md b/docs/src/docPages/guide/collaborative-editing.md index 9bbe3895..98b73209 100644 --- a/docs/src/docPages/guide/collaborative-editing.md +++ b/docs/src/docPages/guide/collaborative-editing.md @@ -1,9 +1,12 @@ # Collaborative editing -## Table of Contents +:::premium Requires Premium Extensions +Using the collaborative editing in production requires a **tiptap pro** license. [Read more](/sponsor) +::: + +## toc ## Introduction - Collaborative editing allows multiple users to work on the same text document in real-time. Itโs a complex topic that you should be aware before adding it blindly to you app. No worries though, here is everything you need to know. ## Configure collaboration diff --git a/docs/src/docPages/guide/configuration.md b/docs/src/docPages/guide/configuration.md index 0b9539e7..ee58cfc9 100644 --- a/docs/src/docPages/guide/configuration.md +++ b/docs/src/docPages/guide/configuration.md @@ -1,6 +1,6 @@ # Configuration -## Table of Contents +## toc ## Introduction tiptap is all about customization. There are a ton of options to configure the behavior and functionality of the editor. Most of those settings can be set before creating the Editor. Give tiptap a JSON with all the settings you would like to overwrite. diff --git a/docs/src/docPages/guide/build-your-editor.md b/docs/src/docPages/guide/create-your-editor.md similarity index 95% rename from docs/src/docPages/guide/build-your-editor.md rename to docs/src/docPages/guide/create-your-editor.md index 0d047478..1977a0ee 100644 --- a/docs/src/docPages/guide/build-your-editor.md +++ b/docs/src/docPages/guide/create-your-editor.md @@ -1,6 +1,6 @@ # Build your editor -## Table of Contents +## toc ## Introduction In its simplest version tiptap comes very raw. There is no menu, no buttons, no styling. Thatโs intended. See tiptap as your building blocks to build exactly the editor you would like to have. @@ -18,7 +18,7 @@ You might wonder what features tiptap supports out of the box. In the above exam * [List of available commands](/api/commands) ## Configure extensions -You are free to choose which parts of tiptap you want to use. Tiptap has support for different nodes (paragraphs, blockquotes, tables and many more) and different marks (bold, italic, links). If you want to explicitly configure what kind of nodes and marks are allowed and which are not allowed, you can configure those. +You are free to choose which parts of tiptap you want to use. tiptap has support for different nodes (paragraphs, blockquotes, tables and many more) and different marks (bold, italic, links). If you want to explicitly configure what kind of nodes and marks are allowed and which are not allowed, you can configure those. Note that `Document`, `Paragraph` and `Text` are required. Otherwise you wonโt be able to add any plain text. diff --git a/docs/src/docPages/guide/custom-extensions.md b/docs/src/docPages/guide/custom-extensions.md deleted file mode 100644 index 0e6d430a..00000000 --- a/docs/src/docPages/guide/custom-extensions.md +++ /dev/null @@ -1,142 +0,0 @@ -# Custom Extensions - -## Table of Contents - -## Introduction -One of the strength of tiptap is itโs extendability. You donโt depend on the provided extensions, itโs intended to extend the editor to your liking. With custom extensions you can add new content types and new functionalities, on top of what already exists or on top of that. - -## Option 1: Change defaults - -Letโs say you want to change the keyboard shortcuts for the bullet list. You should start by looking at [the source code of the `BulletList` extension](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-bullet-list/index.ts) and find the default youโd like to change. In that case, the keyboard shortcut, and just that. - -```js -// 1. Import the extension -import BulletList from '@tiptap/extension-bullet-list' - -// 2. Overwrite the keyboard shortcuts -const CustomBulletList = BulletList() - .keys(({ editor }) => ({ - 'Mod-l': () => editor.bulletList(), - })) - .create() // Donโt forget that! - -// 3. Add the custom extension to your editor -new Editor({ - extensions: [ - CustomBulletList(), - // โฆ - ] -}) -``` - -You can overwrite every aspect of an existing extension: - -### Name - -```js -import Document from '@tiptap/extension-document' - -const CustomDocument = Document() - .name('doc') - .create() -``` - -### Settings - -```js -import Heading from '@tiptap/extension-heading' - -const CustomHeading = Heading() - .defaults({ - levels: [1, 2, 3], - class: 'my-custom-heading', - }) - .create() -``` - -### Schema - -```js -import Code from '@tiptap/extension-code' - -const CustomCode = Code() - .schema(() => ({ - excludes: '_', - parseDOM: [ - { tag: 'code' }, - ], - toDOM: () => ['code', { 'data-attribute': 'foobar' }, 0], - })) - .create() -``` - -### Commands - -```js -import Paragraph from '@tiptap/extension-paragraph' - -const CustomParagraph = Paragraph() - .commands(() => ({ - paragraph: () => ({ commands }) => { - return commands.toggleBlockType(name, 'paragraph') - }, - })) - .create() -``` - -### Keyboard shortcuts - -```js -import BulletList from '@tiptap/extension-bullet-list' - -const CustomBulletList = BulletList() - .keys(({ editor }) => ({ - 'Mod-l': () => editor.bulletList(), - })) - .create() -``` - -### Input rules - -```js -import Strike from '@tiptap/extension-strike' -import { markInputRule } from '@tiptap/core' - -const inputRegex = /(?:^|\s)((?:~)((?:[^~]+))(?:~))$/gm - -const CustomStrike = Strike() - .inputRules(({ type }) => [ - markInputRule(inputRegex, type), - ]) - .create() -``` - -### Paste rules - -```js -import Underline from '@tiptap/extension-underline' -import { markPasteRule } from '@tiptap/core' - -const pasteRegex = /(?:^|\s)((?:~)((?:[^~]+))(?:~))$/gm - -const CustomUnderline = Underline() - .pasteRules(({ type }) => [ - markPasteRule(pasteRegex, type), - ]) - .create() -``` - -## Option 2: Extend existing extensions - -## Option 3: Start from scratch - -### 1. Read the documentation -Although tiptap tries to hide most of the complexity of ProseMirror, itโs built on top of its APIs and we recommend you to read through the [ProseMirror Guide](https://ProseMirror.net/docs/guide/) for advanced usage. Youโll have a better understanding of how everything works under the hood and get more familiar with many terms and jargon used by tiptap. - -### 2. Have a look at existing extensions - -### 3. Get started - -### 4. Ask questions - -### 5. Publish a community extension diff --git a/docs/src/docPages/guide/custom-styling.md b/docs/src/docPages/guide/custom-styling.md index b3c53c02..5fdf2c94 100644 --- a/docs/src/docPages/guide/custom-styling.md +++ b/docs/src/docPages/guide/custom-styling.md @@ -1,9 +1,9 @@ # Custom styling -## Table of Contents +## toc ## Introduction -Tiptap is renderless, that doesnโt mean there is no styling provided. You can decided how your editor should look like. +tiptap is renderless, that doesnโt mean there is no styling provided. You can decided how your editor should look like. ## Option 1: Style the plain HTML The whole editor is rendered inside of a container with the class `.ProseMirror`. You can use that to scope your styling to the editor content: @@ -28,15 +28,21 @@ p { ## Option 2: Add custom classes Most extensions have a `class` option, which you can use to add a custom CSS class to the HTML tag. +Most extensions allow you to add attributes to the rendered HTML through the `attributes` configuration. You can use that to add a custom class (or any other attribute): + ```js new Editor({ extensions: [ Document(), Paragraph({ - class: 'my-custom-paragraph', + attributes: { + class: 'my-custom-paragraph', + }, }), Heading({ - class: 'my-custom-heading', + attributes: { + class: 'my-custom-heading', + }, }), Text(), ] @@ -50,17 +56,21 @@ The rendered HTML will look like that: Wow, thatโs really custom. ``` +If there are already classes defined by the extensions, your classes will be added. + ## Option 3: Customize the HTML You can even customize the markup for every extension. This will make a custom bold extension that doesnโt render a `` tag, but a `` tag: ```js import Bold from '@tiptap/extension-bold' -const CustomBold = Bold - .schema(() => ({ - toDOM: () => ['b', 0], - })) - .create() +const CustomBold = Bold.extend({ + renderHTML({ attributes }) { + // Original: + // return ['strong', attributes, 0] + return ['b', attributes, 0] + }, +}) new Editor({ extensions: [ @@ -70,4 +80,4 @@ new Editor({ }) ``` -You should put your custom extensions in separate files though, but I think youโve got the idea. +You should put your custom extensions in separate files though, but I think you got the idea. diff --git a/docs/src/docPages/guide/getting-started.md b/docs/src/docPages/guide/getting-started.md index fbfac4ad..2ebbd29f 100644 --- a/docs/src/docPages/guide/getting-started.md +++ b/docs/src/docPages/guide/getting-started.md @@ -1,6 +1,6 @@ # Getting started -## Table of Contents +## toc ## Introduction tiptap is framework-agnostic and works with Vue.js and React. It even works with plain JavaScript, if thatโs your thing. To keep everything as small as possible, we put the code to use tiptap with those frameworks in different packages. @@ -19,7 +19,7 @@ yarn add @tiptap/vue @tiptap/vue-starter-kit The `@tiptap/vue-starter-kit` includes a few basics you would probably need anyway. Cool, you have got everything in place to set up tiptap! ๐ ## 2. Create a new component -Create a new Vue component (you can call it ``) and add the following content. This is the fastest way to get tiptap up and running with Vue.js. It will give you a very basic version of tiptap, without any buttons. No worries, you will be able to add more functionality soon. +Create a new Vue component (you can call it ``) and add the following content. This is the fastest way to get tiptap up and running with Vue.js. It will give you a very basic version of tiptap, without any buttons. No worries, you will be able to add more functionality soon. diff --git a/docs/src/docPages/guide/store-content.md b/docs/src/docPages/guide/store-content.md index d69d267f..4380a40a 100644 --- a/docs/src/docPages/guide/store-content.md +++ b/docs/src/docPages/guide/store-content.md @@ -1,6 +1,6 @@ # Store content -## Table of Contents +## toc ## Introduction You can store your content as a JSON object or as a good old HTML string. Both work fine. And of course, you can pass both formats to the editor to restore your content. @@ -85,6 +85,17 @@ Unfortunately, **tiptap doesnโt support Markdown as an input or output format* You should really consider to work with HTML or JSON to store your content, they are perfectly fine for most use cases. -If you still think you need Markdown, [Nextcloud Text](https://github.com/nextcloud/text) uses tiptap to work with Markdown. Their code is open source, so maybe you can learn from them. +If you still think you need Markdown, [Nextcloud Text](https://github.com/nextcloud/text) uses tiptap 1 to work with Markdown. Their code is open source, so maybe you can learn from them. That said, tiptap **does** support Markdown shortcuts to format your content. Try typing `**two asterisks**` to make your text bold for example. + +## Generate HTML from ProseMirror JSON +If you need to render the content on the server side, for example to render a blog post which was written with tiptap, youโll probably need a way to do just that without an actual editor instance. + +Thatโs what `generateHTML()` is for. Itโs a utility function that renders HTML without an actual editor instance. + +:::info Browser-only rendering +Import a lightweight implementation from `@tiptap/core` if youโre using the function in a browser context only. +::: + + diff --git a/docs/src/docPages/introduction.md b/docs/src/docPages/introduction.md index 5c6afa8b..b8a3280b 100644 --- a/docs/src/docPages/introduction.md +++ b/docs/src/docPages/introduction.md @@ -1,15 +1,17 @@ -:::warning Donโt try this at home -This version of tiptap is not production-ready, donโt use it anywhere. +:::error Donโt try this at home +Nothing here is production-ready, donโt use it anywhere. ::: # Introduction -[](https://www.npmjs.com/package/@tiptap/core) -[](https://npmcharts.com/compare/@tiptap/core?minimal=true) -[](https://www.npmjs.com/package/@tiptap/core) + + + + + [](https://github.com/sponsors/ueberdosis) -tiptap is a renderless wrapper around [ProseMirror](https://ProseMirror.net) โ a toolkit for building rich-text editors that is already in use at many well-known companies such as *New York Times*, *The Guardian* or *Atlassian*. +tiptap is a renderless wrapper around [ProseMirror](https://ProseMirror.net) โ a toolkit for building rich-text WYSIWYG editors, which is already in use at many well-known companies such as *New York Times*, *The Guardian* or *Atlassian*. Although tiptap tries to hide most of the complexity of ProseMirror, itโs built on top of its APIs and we recommend you to read through the [ProseMirror Guide](https://ProseMirror.net/docs/guide/) for advanced usage. Youโll have a better understanding of how everything works under the hood and get more familiar with many terms and jargon used by tiptap. @@ -17,9 +19,9 @@ Although tiptap tries to hide most of the complexity of ProseMirror, itโs buil **Renderless.** We donโt tell you what a menu should look like or where it should be rendered in the DOM. Thatโs why tiptap is renderless and comes without any CSS. You are in full control over markup and styling. -**Framework-agnostic.** We donโt care what framework you use. Tiptap is ready to be used with plain JavaScript or Vue.js. That makes it even possible to write a renderer for React, Svelte and others. +**Framework-agnostic.** We donโt care what framework you use. tiptap is ready to be used with plain JavaScript or Vue.js. That makes it even possible to write a renderer for React, Svelte and others. -**TypeScript.** Tiptap 2 is written in TypeScript. That gives you a nice autocomplete for the API (if your IDE supports that), helps to find bugs early and makes it possible to generate [a complete API documentation](#) on top of the extensive human written documentation. +**TypeScript.** tiptap 2 is written in TypeScript. That gives you a nice autocomplete for the API (if your IDE supports that), helps to find bugs early and makes it possible to generate [a complete API documentation](#) on top of the extensive human written documentation. ## Who uses tiptap? - [GitLab](https://gitlab.com) @@ -29,3 +31,6 @@ Although tiptap tries to hide most of the complexity of ProseMirror, itโs buil - [Directus CMS](https://directus.io) - [Nextcloud](https://apps.nextcloud.com/apps/text) - [and many more โ](https://github.com/ueberdosis/tiptap/network/dependents?package_id=UGFja2FnZS0xMzE5OTg0ODc%3D) + +## License +tiptap is licensed under MIT, so youโre free to whatever you want. Anyway, we kindly ask you to [become a sponsor](https://github.com/sponsors/ueberdosis) on GitHub to fund the development, maintenance and support of tiptap. diff --git a/docs/src/docPages/open.md b/docs/src/docPages/open.md new file mode 100644 index 00000000..b5d7cae3 --- /dev/null +++ b/docs/src/docPages/open.md @@ -0,0 +1,26 @@ +# Monthly reports + +## October 2020 +* Writing extensions for tiptap 2 +* 25 sponsors, $423/month +* 102 hours, $7,140 development costs (at $70/hour) +* Sponsored @calebporzio with $99 +* **Total -$6,816** + +## September 2020 +* Developing the API of tiptap 2, writing the documentation +* 125 hours, $8,750 development costs (at $70/hour) +* Sponsored @calebporzio with $99 +* **Total -$8,849** + +## August 2020 +* Setting up tiptap 2 +* 56 hours, $3,920 development costs (at $70/hour) +* Sponsored @calebporzio with $99 +* **Total -$4,019** + +## All time + +* **Total -$19.684** + + diff --git a/docs/src/docPages/overview/contributing.md b/docs/src/docPages/overview/contributing.md index 1f024d29..f28771ea 100644 --- a/docs/src/docPages/overview/contributing.md +++ b/docs/src/docPages/overview/contributing.md @@ -1,13 +1,14 @@ # Contributing -## Table of Contents +## toc ## Introduction -Tiptap would be nothing without its lively community. Contributions have always been and will always be welcome. Here is a little bit you should know, before you send your contribution: +tiptap would be nothing without its lively community. Contributions have always been and will always be welcome. Here is a little bit you should know, before you send your contribution: ## Welcome examples -* Improve the documentation, e. g. fix a typo, add a section -* New features for existing extensions, e. g. a new option +* Failing regression tests as bug reports +* Documentation improvements, e. g. fix a typo, add a section +* New features for existing extensions, e. g. a new configureable option * New extensions, which donโt require changes to the core or other core extensions * Well explained, non-breaking changes to the core diff --git a/docs/src/docPages/overview/installation.md b/docs/src/docPages/overview/installation.md index 57fc588c..2324a3f8 100644 --- a/docs/src/docPages/overview/installation.md +++ b/docs/src/docPages/overview/installation.md @@ -1,6 +1,6 @@ # Installation -## Table of Contents +## toc ## Introduction Youโre free to use tiptap with the framework of your choice. Depending on what you want to do, there are a few different ways to install tiptap in your project. Choose the way that fits your workflow. @@ -9,10 +9,10 @@ Youโre free to use tiptap with the framework of your choice. Depending on what Use tiptap with vanilla JavaScript for a very lightweight and raw experience. If you feel like it, you can even use it to connect tiptap with other frameworks not mentioned here. ```bash -# With npm +# with npm npm install @tiptap/core @tiptap/starter-kit -# Or: With Yarn +# with Yarn yarn add @tiptap/core @tiptap/starter-kit ``` @@ -33,10 +33,10 @@ new Editor({ To use tiptap with Vue.js (and tools that are based on Vue.js) install tiptap together with the Vue.js adapter in your project. We even prepared a Vue.js starter kit, which gives you a good headstart. ```bash -# With npm +# with npm npm install @tiptap/core @tiptap/vue @tiptap/vue-starter-kit -# Or: With Yarn +# with Yarn yarn add @tiptap/core @tiptap/vue @tiptap/vue-starter-kit ``` @@ -44,9 +44,10 @@ Create a new component and add the following content to get a basic version of t -::: warning Nuxt.js -If you use Nuxt.js, note that tiptap needs to run in the client, not on the server. Itโs required to wrap the editor in a `` tag. -::: +### Nuxt.js +Note that tiptap needs to run in the client, not on the server. Itโs required to wrap the editor in a `` tag. + +[Read more](https://nuxtjs.org/api/components-client-only)
{{ html }}
Example Text
This is basic example of implementing images. Try to drop new images here. Reordering also works.
This is a basic example of implementing images. Drag to re-order.
Hello, Iโm tiptap running in Vue.js! ๐
Hello, here is tiptap! ๐
` HTML tag with auto-detected syntax highlighting in the editor. - -## Settings -*None* - -## Commands -*None* - -## Keyboard shortcuts -*None* \ No newline at end of file diff --git a/docs/src/docPages/api/extensions/collaboration-cursor.md b/docs/src/docPages/api/extensions/collaboration-cursor.md index 7f003c1a..8987916d 100644 --- a/docs/src/docPages/api/extensions/collaboration-cursor.md +++ b/docs/src/docPages/api/extensions/collaboration-cursor.md @@ -1,2 +1,34 @@ # Collaboration Cursor +:::premium Premium Extension +Using this in production requires a **tiptap pro** license. [Read more](/sponsor) +::: + +## Installation +```bash +# with npm +npm install @tiptap/extension-collaboration-cursor + +# with Yarn +yarn add @tiptap/extension-collaboration-cursor +``` + +## Settings +| Option | Type | Default | Description | +| -------- | ---- | ------- | ----------- | +| provider | | | | +| type | | | | + +## Commands +| Command | Parameters | Description | +| ------- | ------------- | ------------------------------------------------------------------------ | +| user | namecolor | The name of the current user.The color of the current userโs cursor. | + +## Source code +[packages/extension-collaboration-cursor/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-collaboration-cursor/) + +## Usage +:::warning Public +The content of this editor is shared with other users. +::: + diff --git a/docs/src/docPages/api/extensions/collaboration.md b/docs/src/docPages/api/extensions/collaboration.md index fa5bbab9..1815948b 100644 --- a/docs/src/docPages/api/extensions/collaboration.md +++ b/docs/src/docPages/api/extensions/collaboration.md @@ -1,12 +1,16 @@ # Collaboration -Enables you to collaborate with others on one document. +The Collaboration extension enables you to collaborate with others on one document. The implementation is based on [Y.js by Kevin Jahns](https://github.com/yjs/yjs), which is the coolest thing to [integrate collaborative editing](/guide/collaborative-editing) in your project. + +:::premium Premium Extension +Using this in production requires a **tiptap pro** license. [Read more](/sponsor) +::: ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-collaboration yjs y-webrtc -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-collaboration yjs y-webrtc ``` diff --git a/docs/src/docPages/api/extensions/dropcursor.md b/docs/src/docPages/api/extensions/dropcursor.md new file mode 100644 index 00000000..8759a51c --- /dev/null +++ b/docs/src/docPages/api/extensions/dropcursor.md @@ -0,0 +1,25 @@ +# Dropcursor + +## Installation +```bash +# with npm +npm install @tiptap/extension-dropcursor + +# with Yarn +yarn add @tiptap/extension-dropcursor +``` + +## Settings +*None* + +## Commands +*None* + +## Keyboard shortcuts +*None* + +## Source code +[packages/extension-dropcursor/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-dropcursor/) + +## Usage + diff --git a/docs/src/docPages/api/extensions/focus.md b/docs/src/docPages/api/extensions/focus.md new file mode 100644 index 00000000..2d011777 --- /dev/null +++ b/docs/src/docPages/api/extensions/focus.md @@ -0,0 +1,22 @@ +# Focus + +## Installation +```bash +# with npm +npm install @tiptap/extension-focus + +# with Yarn +yarn add @tiptap/extension-focus +``` + +## Settings +| Option | Type | Default | Description | +| --------- | ------- | --------- | ------------------------------------------------------ | +| className | string | has-focus | The class that is applied to the focused element. | +| nested | boolean | true | When enabled nested elements get the focus class, too. | + +## Source code +[packages/extension-focus/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-focus/) + +## Usage + diff --git a/docs/src/docPages/api/extensions/gapcursor.md b/docs/src/docPages/api/extensions/gapcursor.md new file mode 100644 index 00000000..a42b7ef0 --- /dev/null +++ b/docs/src/docPages/api/extensions/gapcursor.md @@ -0,0 +1,19 @@ +# Gapcursor +This extension loads the [ProseMirror Gapcursor plugin](https://github.com/ProseMirror/prosemirror-gapcursor) by Marijn Haverbeke, which adds a gap for the cursor in places that donโt allow regular selection. For example, after a table at the end of a document. + +Note that tiptap is renderless, but the dropcursor needs CSS for its appearance. The default CSS is added to the usage example below. + +## Installation +```bash +# with npm +npm install @tiptap/extension-gapcursor + +# with Yarn +yarn add @tiptap/extension-gapcursor +``` + +## Source code +[packages/extension-gapcursor/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-gapcursor/) + +## Usage + diff --git a/docs/src/docPages/api/extensions/history.md b/docs/src/docPages/api/extensions/history.md index 6d41c532..b4fa23a6 100644 --- a/docs/src/docPages/api/extensions/history.md +++ b/docs/src/docPages/api/extensions/history.md @@ -3,10 +3,10 @@ This extension provides history support. All changes to the document will be tra ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-history -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-history ``` @@ -17,7 +17,7 @@ yarn add @tiptap/extension-history | newGroupDelay | number | 500 | The delay between changes after which a new group should be started (in milliseconds). When changes arenโt adjacent, a new group is always started. | ## Commands -| Command | Options | Description | +| Command | Parameters | Description | | ------- | ------- | --------------------- | | undo | โ | Undo the last change. | | redo | โ | Redo the last change. | diff --git a/docs/src/docPages/api/extensions/image.md b/docs/src/docPages/api/extensions/image.md deleted file mode 100644 index e811d826..00000000 --- a/docs/src/docPages/api/extensions/image.md +++ /dev/null @@ -1,16 +0,0 @@ -# Image - -## Installation -```bash -# With npm -npm install @tiptap/extension-image - -# Or: With Yarn -yarn add @tiptap/extension-image -``` - -## Source code -[packages/extension-image/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-image/) - -## Usage - diff --git a/docs/src/docPages/api/extensions/mention.md b/docs/src/docPages/api/extensions/mention.md deleted file mode 100644 index 3c2c0838..00000000 --- a/docs/src/docPages/api/extensions/mention.md +++ /dev/null @@ -1,2 +0,0 @@ -# Mention -Enables you to use mentions in the editor. diff --git a/docs/src/docPages/api/extensions/placeholder.md b/docs/src/docPages/api/extensions/placeholder.md deleted file mode 100644 index cc9da006..00000000 --- a/docs/src/docPages/api/extensions/placeholder.md +++ /dev/null @@ -1,2 +0,0 @@ -# Placeholder -Enables you to show placeholders on empty paragraphs. diff --git a/docs/src/docPages/api/extensions/table-cell.md b/docs/src/docPages/api/extensions/table-cell.md deleted file mode 100644 index 09a28533..00000000 --- a/docs/src/docPages/api/extensions/table-cell.md +++ /dev/null @@ -1,6 +0,0 @@ -# TableCell -Enables you to use the `` HTML tag in the editor. - -::: warning Restrictions -This extensions is intended to be used with the `Table` extension. -::: diff --git a/docs/src/docPages/api/extensions/table-header.md b/docs/src/docPages/api/extensions/table-header.md deleted file mode 100644 index 25731c27..00000000 --- a/docs/src/docPages/api/extensions/table-header.md +++ /dev/null @@ -1,6 +0,0 @@ -# TableHeader -Enables you to use the `` HTML tag in the editor. - -::: warning Restrictions -This extensions is intended to be used with the `Table` extension. -::: \ No newline at end of file diff --git a/docs/src/docPages/api/extensions/table-row.md b/docs/src/docPages/api/extensions/table-row.md deleted file mode 100644 index 748e0c8c..00000000 --- a/docs/src/docPages/api/extensions/table-row.md +++ /dev/null @@ -1,6 +0,0 @@ -# TableRow -Enables you to use the `` HTML tag in the editor. - -::: warning Restrictions -This extensions is intended to be used with the `Table` extension. -::: \ No newline at end of file diff --git a/docs/src/docPages/api/extensions/text-align.md b/docs/src/docPages/api/extensions/text-align.md index fdb3680a..3c6fcf8f 100644 --- a/docs/src/docPages/api/extensions/text-align.md +++ b/docs/src/docPages/api/extensions/text-align.md @@ -1,14 +1,23 @@ -# Text Align +# TextAlign ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-text-align -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-text-align ``` +## Settings +*None* + +## Commands +*None* + +## Keyboard shortcuts +*None* + ## Source code [packages/extension-text-align/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-text-align/) diff --git a/docs/src/docPages/api/extensions/todo-item.md b/docs/src/docPages/api/extensions/todo-item.md deleted file mode 100644 index cd7f171a..00000000 --- a/docs/src/docPages/api/extensions/todo-item.md +++ /dev/null @@ -1,17 +0,0 @@ -# TodoItem -It renders a single toggleable item of a list. - -::: warning Restrictions -This extensions is intended to be used with the `TodoList` extension. -::: - -## Settings -| Option | Type | Default | Description | -| ------ | ------- | ------- | ------------------------------------- | -| nested | Boolean | false | Specifies if you can nest todo lists. | - -## Commands -*None* - -## Keyboard shortcuts -*None* \ No newline at end of file diff --git a/docs/src/docPages/api/extensions/todo-list.md b/docs/src/docPages/api/extensions/todo-list.md deleted file mode 100644 index 0fe0b300..00000000 --- a/docs/src/docPages/api/extensions/todo-list.md +++ /dev/null @@ -1,69 +0,0 @@ -# TodoList -Renders a toggleable list of items. - -::: warning Restrictions -This extensions is intended to be used with the `TodoItem` extension. -::: - -## Settings -*None* - -## Commands -| Command | Options | Description | -| --------- | ------- | ----------------- | -| todo_list | โ | Toggle todo list. | - -## Keyboard shortcuts -*None* - -## Usage -```markup - - - - - Todo List - - - - - - - - -``` \ No newline at end of file diff --git a/docs/src/docPages/api/extensions/typography.md b/docs/src/docPages/api/extensions/typography.md new file mode 100644 index 00000000..2cd372ea --- /dev/null +++ b/docs/src/docPages/api/extensions/typography.md @@ -0,0 +1,17 @@ +# Typography + + +## Installation +```bash +# with npm +npm install @tiptap/typography + +# with Yarn +yarn add @tiptap/typography +``` + +## Source code +[packages/typography/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/typography/) + +## Usage + diff --git a/docs/src/docPages/api/keyboard-shortcuts.md b/docs/src/docPages/api/keyboard-shortcuts.md index 39ff0298..d4db84bf 100644 --- a/docs/src/docPages/api/keyboard-shortcuts.md +++ b/docs/src/docPages/api/keyboard-shortcuts.md @@ -1,8 +1,85 @@ # Keyboard Shortcuts -## Table of Contents +## toc ## Introduction +tiptap comes with sensible keyboard shortcut defaults. Depending on what you want to use it for, youโll probably want to change those keyboard shortcuts to your liking. Letโs have a look at what we defined for you, and show you how to change it then! + +Funfact: A while ago, we built a [keyboard shortcut learning app](https://mouseless.app), to which we manually added exercises for thousands of keyboard shortcuts for a bunch of tools. + +## Predefined keyboard shortcuts +Most of the core extensions register their own keyboard shortcuts. Depending on what set of extension you use, not all of the below listed keyboard shortcuts work for your editor. + +### Essentials +โ = untested + +| Action | Windows/Linux | macOS | +| ------------------------ | ------------------------------- | --------------------------- | +| Copy | `Control` `C` | `Cmd` `C` | +| Cut | `Control` `X` | `Cmd` `X` | +| Paste | `Control` `V` | `Cmd` `V` | +| Paste without formatting | `Control` `Shift` `V` | `Cmd` `Shift` `V` | +| Undo | `Control` `Z` | `Cmd` `Z` | +| Redo | `Control` `Shift` `Z` | `Cmd` `Shift` `Z` | +| โ Insert or edit link | `Control` `K` | `Cmd` `K` | +| โ Open link | `Alt` `Enter` | `Alt` `Enter` | +| โ Find | `Control` `F` | `Cmd` `F` | +| โ Find and replace | `Control` `H` | `Cmd` `Shift` `H` | +| โ Find again | `Control` `G` | `Cmd` `G` | +| โ Find previous | `Control` `Shift` `G` | `Cmd` `Shift` `G` | +| โ Repeat last action | `Control` `Y` | `Cmd` `Y` | +| Add a line break | `Shift` `Enter` | `Shift` `Enter` | + +### Text Formatting +| Action | Windows/Linux | macOS | +| ----------------------- | -------------------------------------------- | --------------------------- | +| Bold | `Control` `B` | `Cmd` `B` | +| Italicize | `Control` `I` | `Cmd` `I` | +| Underline | `Control` `U` | `Cmd` `U` | +| โ Strikethrough | `Alt` `Shift` `5` | `Cmd` `Shift` `X` | +| โ Superscript | `Control` `.` | `Cmd` `.` | +| โ Subscript | `Control` `,` | `Cmd` `,` | +| โ Copy text formatting | `Control` `Alt` `C` | `Cmd` `Alt` `C` | +| โ Paste text formatting | `Control` `Alt` `V` | `Cmd` `Alt` `V` | +| โ Clear text formatting | `Control` `\``Control` `Space` | `Cmd` `\` | +| โ Increase font size | `Control` `Shift` `>` | `Cmd` `Shift` `>` | +| โ Decrease font size | `Control` `Shift` `<` | `Cmd` `Shift` `<` | + +### Paragraph Formatting +| Action | Windows/Linux | macOS | +| -------------------------------- | ------------------------------- | ------------------------------- | +| โ Increase paragraph indentation | `Control` `]` | `Cmd` `]` | +| โ Decrease paragraph indentation | `Control` `[` | `Cmd` `[` | +| Apply normal text style | `Control` `Alt` `0` | `Cmd` `Alt` `0` | +| Apply heading style 1 | `Control` `Alt` `1` | `Cmd` `Alt` `1` | +| Apply heading style 2 | `Control` `Alt` `2` | `Cmd` `Alt` `2` | +| Apply heading style 3 | `Control` `Alt` `3` | `Cmd` `Alt` `3` | +| Apply heading style 4 | `Control` `Alt` `4` | `Cmd` `Alt` `4` | +| Apply heading style 5 | `Control` `Alt` `5` | `Cmd` `Alt` `5` | +| Apply heading style 6 | `Control` `Alt` `6` | `Cmd` `Alt` `6` | +| Left align | `Control` `Shift` `L` | `Cmd` `Shift` `L` | +| Center align | `Control` `Shift` `E` | `Cmd` `Shift` `E` | +| Right align | `Control` `Shift` `R` | `Cmd` `Shift` `R` | +| Justify | `Control` `Shift` `J` | `Cmd` `Shift` `J` | +| โ Numbered list | `Control` `Shift` `7` | `Cmd` `Shift` `7` | +| โ Bulleted list | `Control` `Shift` `8` | `Cmd` `Shift` `8` | +| โ Move paragraph up | `Control` `Shift` `โ` | `Control` `Shift` `โ` | +| โ Move paragraph down | `Control` `Shift` `โ` | `Control` `Shift` `โ` | + +### Text Selection +| Action | Windows/Linux | macOS | +| ------------------------------------------------- | ------------------------------- | --------------------------- | +| Select all | `Control` `A` | `Cmd` `A` | +| Extend selection one character to left | `Shift` `โ` | `Shift` `โ` | +| Extend selection one character to right | `Shift` `โ` | `Shift` `โ` | +| Extend selection one line up | `Shift` `โ` | `Shift` `โ` | +| Extend selection one line down | `Shift` `โ` | `Shift` `โ` | +| โ Extend selection one paragraph up | `Alt` `Shift` `โ` | `Alt` `Shift` `โ` | +| โ Extend selection one paragraph down | `Alt` `Shift` `โ` | `Alt` `Shift` `โ` | +| Extend selection to the beginning of the document | `Control` `Shift` `โ` | `Cmd` `Shift` `โ` | +| โ Extend selection to the end of the document | `Control` `Shift` `โ` | `Cmd` `Shift` `โ` | + +## Overwrite keyboard shortcuts Keyboard shortcuts may be strings like `'Shift-Control-Enter'`. Keys are based on the strings that can appear in `event.key`, concatenated with a `-`. There is a little tool called [keycode.info](https://keycode.info/), which shows the `event.key` interactively. Use lowercase letters to refer to letter keys (or uppercase letters if you want shift to be held). You may use `Space` as an alias for the . @@ -11,94 +88,27 @@ Modifiers can be given in any order. `Shift`, `Alt`, `Control` and `Cmd` are rec You can use `Mod` as a shorthand for `Cmd` on Mac and `Control` on other platforms. -## Overwrite keyboard shortcuts +Here is an example how you can overwrite the keyboard shortcuts for an existing extension: ```js // 1. Import the extension import BulletList from '@tiptap/extension-bullet-list' // 2. Overwrite the keyboard shortcuts -const CustomBulletList = BulletList() - .keys(({ editor }) => ({ - // โ your new keyboard shortcut - 'Mod-l': () => editor.bulletList(), - })) - .create() // Donโt forget that! +const CustomBulletList = BulletList.extend({ + addKeyboardShortcuts() { + return { + // โ your new keyboard shortcut + 'Mod-l': () => this.editor.bulletList(), + } + }, +}) // 3. Add the custom extension to your editor new Editor({ extensions: [ - CustomBulletList(), - // โฆ + CustomBulletList(), + // โฆ ] }) ``` - -## Predefined keyboard shortcuts - -### Essentials -| Action | Windows/Linux | macOS | -| ------------------------ | --------------------- | ----------------- | -| Copy | `Control` `C` | `Cmd` `C` | -| Cut | `Control` `X` | `Cmd` `X` | -| Paste | `Control` `V` | `Cmd` `V` | -| Paste without formatting | `Control` `Shift` `V` | `Cmd` `Shift` `V` | -| Undo | `Control` `Z` | `Cmd` `Z` | -| Redo | `Control` `Shift` `Z` | `Cmd` `Shift` `Z` | -| Insert or edit link | `Control` `K` | `Cmd` `K` | -| Open link | `Alt` `Enter` | `Alt` `Enter` | -| Find | `Control` `F` | `Cmd` `F` | -| Find and replace | `Control` `H` | `Cmd` `Shift` `H` | -| Find again | `Control` `G` | `Cmd` `G` | -| Find previous | `Control` `Shift` `G` | `Cmd` `Shift` `G` | -| Repeat last action | `Control` `Y` | `Cmd` `Y` | -| Add a line break | `Shift` `Enter` | `Shift` `Enter` | - -### Text Formatting -| Action | Windows/Linux | macOS | -| --------------------- | --------------------------------------------- | ----------------- | -| Bold | `Control` `B` | `Cmd` `B` | -| Italicize | `Control` `I` | `Cmd` `I` | -| Underline | `Control` `U` | `Cmd` `U` | -| Strikethrough | `Alt` `Shift` `5` | `Cmd` `Shift` `X` | -| Superscript | `Control` `.` | `Cmd` `.` | -| Subscript | `Control` `,` | `Cmd` `,` | -| Copy text formatting | `Control` `Alt` `C` | `Cmd` `Alt` `C` | -| Paste text formatting | `Control` `Alt` `V` | `Cmd` `Alt` `V` | -| Clear text formatting | `Control` \`Control` `Space` | `Cmd` `\` | -| Increase font size | `Control` `Shift` `>` | `Cmd` `Shift` `>` | -| Decrease font size | `Control` `Shift` `<` | `Cmd` `Shift` `<` | - -### Paragraph Formatting -| Action | Windows/Linux | macOS | -| ------------------------------ | --------------------- | --------------------- | -| Increase paragraph indentation | `Control` `]` | `Cmd` `]` | -| Decrease paragraph indentation | `Control` `[` | `Cmd` `[` | -| Apply normal text style | `Control` `Alt` `0` | `Cmd` `Alt` `0` | -| Apply heading style 1 | `Control` `Alt` `1` | `Cmd` `Alt` `1` | -| Apply heading style 2 | `Control` `Alt` `2` | `Cmd` `Alt` `2` | -| Apply heading style 3 | `Control` `Alt` `3` | `Cmd` `Alt` `3` | -| Apply heading style 4 | `Control` `Alt` `4` | `Cmd` `Alt` `4` | -| Apply heading style 5 | `Control` `Alt` `5` | `Cmd` `Alt` `5` | -| Apply heading style 6 | `Control` `Alt` `6` | `Cmd` `Alt` `6` | -| Left align | `Control` `Shift` `L` | `Cmd` `Shift` `L` | -| Center align | `Control` `Shift` `E` | `Cmd` `Shift` `E` | -| Right align | `Control` `Shift` `R` | `Cmd` `Shift` `R` | -| Justify | `Control` `Shift` `J` | `Cmd` `Shift` `J` | -| Numbered list | `Control` `Shift` `7` | `Cmd` `Shift` `7` | -| Bulleted list | `Control` `Shift` `8` | `Cmd` `Shift` `8` | -| Move paragraph up | `Control` `Shift` `โ` | `Control` `Shift` `โ` | -| Move paragraph down | `Control` `Shift` `โ` | `Control` `Shift` `โ` | - -### Text Selection -| Action | Windows/Linux | macOS | -| ------------------------------------------------- | --------------------- | ----------------- | -| Select all | `Control` `A` | `Cmd` `A` | -| Extend selection one character to left | `Shift` `โ` | `Shift` `โ` | -| Extend selection one character to right | `Shift` `โ` | `Shift` `โ` | -| Extend selection one line up | `Shift` `โ` | `Shift` `โ` | -| Extend selection one line down | `Shift` `โ` | `Shift` `โ` | -| Extend selection one paragraph up | `Alt` `Shift` `โ` | `Alt` `Shift` `โ` | -| Extend selection one paragraph down | `Alt` `Shift` `โ` | `Alt` `Shift` `โ` | -| Extend selection to the beginning of the document | `Control` `Shift` `โ` | `Cmd` `Shift` `โ` | -| Extend selection to the end of the document | `Control` `Shift` `โ` | `Cmd` `Shift` `โ` | diff --git a/docs/src/docPages/api/marks.md b/docs/src/docPages/api/marks.md new file mode 100644 index 00000000..31acae58 --- /dev/null +++ b/docs/src/docPages/api/marks.md @@ -0,0 +1,15 @@ +# Marks + +## toc + +## Introduction + +## List of supported marks +| Title | Default Extension | Source Code | +| --------------------------------- | ----------------- | ------------------------------------------------------------------------------------------- | +| [Bold](/api/marks/bold) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-bold/) | +| [Code](/api/marks/code) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-code/) | +| [Italic](/api/marks/italic) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-italic/) | +| [Link](/api/marks/link) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-link/) | +| [Strike](/api/marks/strike) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-strike/) | +| [Underline](/api/marks/underline) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-underline/) | diff --git a/docs/src/docPages/api/extensions/bold.md b/docs/src/docPages/api/marks/bold.md similarity index 91% rename from docs/src/docPages/api/extensions/bold.md rename to docs/src/docPages/api/marks/bold.md index 9cecd744..d991247c 100644 --- a/docs/src/docPages/api/extensions/bold.md +++ b/docs/src/docPages/api/marks/bold.md @@ -9,10 +9,10 @@ The extension will generate the corresponding `` HTML tags when reading ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-bold -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-bold ``` @@ -22,7 +22,7 @@ yarn add @tiptap/extension-bold | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | +| Command | Parameters | Description | | ------- | ------- | --------------- | | bold | โ | Mark text bold. | @@ -34,4 +34,4 @@ yarn add @tiptap/extension-bold [packages/extension-bold/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-bold/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/code.md b/docs/src/docPages/api/marks/code.md similarity index 87% rename from docs/src/docPages/api/extensions/code.md rename to docs/src/docPages/api/marks/code.md index 2c00086c..e6f34272 100644 --- a/docs/src/docPages/api/extensions/code.md +++ b/docs/src/docPages/api/marks/code.md @@ -5,10 +5,10 @@ Type something with \`back-ticks around\` and it will magically tra ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-code -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-code ``` @@ -18,7 +18,7 @@ yarn add @tiptap/extension-code | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | +| Command | Parameters | Description | | ------- | ------- | ------------------------- | | code | โ | Mark text as inline code. | @@ -29,4 +29,4 @@ yarn add @tiptap/extension-code [packages/extension-code/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-code/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/highlight.md b/docs/src/docPages/api/marks/highlight.md similarity index 100% rename from docs/src/docPages/api/extensions/highlight.md rename to docs/src/docPages/api/marks/highlight.md diff --git a/docs/src/docPages/api/extensions/italic.md b/docs/src/docPages/api/marks/italic.md similarity index 90% rename from docs/src/docPages/api/extensions/italic.md rename to docs/src/docPages/api/marks/italic.md index b917844d..40717304 100644 --- a/docs/src/docPages/api/extensions/italic.md +++ b/docs/src/docPages/api/marks/italic.md @@ -9,10 +9,10 @@ The extension will generate the corresponding `` HTML tags when reading cont ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-italic -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-italic ``` @@ -22,7 +22,7 @@ yarn add @tiptap/extension-italic | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | +| Command | Parameters | Description | | ------- | ------- | ----------------- | | italic | โ | Mark text italic. | @@ -34,4 +34,4 @@ yarn add @tiptap/extension-italic [packages/extension-italic/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-italic/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/link.md b/docs/src/docPages/api/marks/link.md similarity index 89% rename from docs/src/docPages/api/extensions/link.md rename to docs/src/docPages/api/marks/link.md index 0eb0c14f..30ce4b20 100644 --- a/docs/src/docPages/api/extensions/link.md +++ b/docs/src/docPages/api/marks/link.md @@ -7,10 +7,10 @@ Pasted URLs will be linked automatically. ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-link -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-link ``` @@ -23,17 +23,17 @@ yarn add @tiptap/extension-link | target | string | _blank | Set the default `target` of links. | ## Commands -| Command | Options | Description | +| Command | Parameters | Description | | ------- | -------------- | ----------------------------------------------------------- | | link | hreftarget | Link the selected text. Removes a link, if `href` is empty. | ## Keyboard shortcuts :::warning Doesnโt have a keyboard shortcut -This extension doesnโt bind a specific keyboard shortcut. You would probably open your UI on `Mod-k` though. +This extension doesnโt bind a specific keyboard shortcut. You would probably open your custom UI on `Mod-k` though. ::: ## Source code [packages/extension-link/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-link/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/strike.md b/docs/src/docPages/api/marks/strike.md similarity index 90% rename from docs/src/docPages/api/extensions/strike.md rename to docs/src/docPages/api/marks/strike.md index 4cff00dd..16a1b780 100644 --- a/docs/src/docPages/api/extensions/strike.md +++ b/docs/src/docPages/api/marks/strike.md @@ -9,10 +9,10 @@ The extension will generate the corresponding `` HTML tags when reading conte ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-strike -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-strike ``` @@ -22,7 +22,7 @@ yarn add @tiptap/extension-strike | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | +| Command | Parameters | Description | | ------- | ------- | --------------------------- | | strike | โ | Mark text as strikethrough. | @@ -34,4 +34,4 @@ yarn add @tiptap/extension-strike [packages/extension-strike/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-strike/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/underline.md b/docs/src/docPages/api/marks/underline.md similarity index 83% rename from docs/src/docPages/api/extensions/underline.md rename to docs/src/docPages/api/marks/underline.md index 08b4616c..2f5045a7 100644 --- a/docs/src/docPages/api/extensions/underline.md +++ b/docs/src/docPages/api/marks/underline.md @@ -9,10 +9,10 @@ The extension will generate the corresponding `` HTML tags when reading conte ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-underline -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-underline ``` @@ -22,9 +22,9 @@ yarn add @tiptap/extension-underline | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | -| --------- | ------- | ------------------------ | -| underline | โ | Mark text as underlined. | +| Command | Parameters | Description | +| --------- | ---------- | ------------------------ | +| underline | โ | Mark text as underlined. | ## Keyboard shortcuts * Windows/Linux: `Control` `U` @@ -34,4 +34,4 @@ yarn add @tiptap/extension-underline [packages/extension-underline/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-underline/) ## Usage - + diff --git a/docs/src/docPages/api/nodes.md b/docs/src/docPages/api/nodes.md new file mode 100644 index 00000000..f7c12b50 --- /dev/null +++ b/docs/src/docPages/api/nodes.md @@ -0,0 +1,23 @@ +# Nodes + +## toc + +## Introduction + +## List of supported nodes +| Title | Default Extension | Source Code | +| -------------------------------------------- | ----------------- | ------------------------------------------------------------------------------------------------- | +| [Blockquote](/api/nodes/blockquote) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-blockquote/) | +| [BulletList](/api/nodes/bullet-list) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-bullet-list/) | +| [CodeBlock](/api/nodes/code-block) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-code-block/) | +| [Document](/api/nodes/document) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-document/) | +| [HardBreak](/api/nodes/hard-break) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-hard-break/) | +| [Heading](/api/nodes/heading) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-heading/) | +| [HorizontalRule](/api/nodes/horizontal-rule) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-horizontal-rule/) | +| [Image](/api/nodes/image) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-image/) | +| [ListItem](/api/nodes/list-item) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-list-item/) | +| [OrderedList](/api/nodes/ordered-list) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-ordered-list/) | +| [Paragraph](/api/nodes/paragraph) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-paragraph/) | +| [TaskItem](/api/nodes/task-item) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-task-item/) | +| [TaskList](/api/nodes/task-list) | โ | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-task-list/) | +| [Text](/api/nodes/text) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-text/) | diff --git a/docs/src/docPages/api/extensions/blockquote.md b/docs/src/docPages/api/nodes/blockquote.md similarity index 77% rename from docs/src/docPages/api/extensions/blockquote.md rename to docs/src/docPages/api/nodes/blockquote.md index 533c1a0a..66de2089 100644 --- a/docs/src/docPages/api/extensions/blockquote.md +++ b/docs/src/docPages/api/nodes/blockquote.md @@ -6,10 +6,10 @@ Type > at the beginning of a new line and it will magically t ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-blockquote -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-blockquote ``` @@ -19,9 +19,9 @@ yarn add @tiptap/extension-blockquote | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | -| ---------- | ------- | ----------------------------- | -| blockquote | โ | Wrap content in a blockquote. | +| Command | Parameters | Description | +| ---------- | ---------- | ----------------------------- | +| blockquote | โ | Wrap content in a blockquote. | ## Keyboard shortcuts * Windows/Linux: `Control` `Shift` `9` @@ -31,4 +31,4 @@ yarn add @tiptap/extension-blockquote [packages/extension-blockquote/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-blockquote/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/bullet-list.md b/docs/src/docPages/api/nodes/bullet-list.md similarity index 65% rename from docs/src/docPages/api/extensions/bullet-list.md rename to docs/src/docPages/api/nodes/bullet-list.md index 91cbdb76..6f5fff6c 100644 --- a/docs/src/docPages/api/extensions/bullet-list.md +++ b/docs/src/docPages/api/nodes/bullet-list.md @@ -1,18 +1,18 @@ # BulletList -This extension enables you to use bullet lists in the editor. They are rendered as `` HTML tags, +This extension enables you to use bullet lists in the editor. They are rendered as `` HTML tags. Type * , - or + at the beginning of a new line and it will magically transform to a bullet list. ## Installation ::: warning Use with ListItem -The `BulletList` extension is intended to be used with the [`ListItem`](/api/extensions/list-item) extension. Make sure to import that one too, otherwise youโll get a SyntaxError. +This extension requires the [`ListItem`](/api/nodes/list-item) extension. ::: ```bash -# With npm +# with npm npm install @tiptap/extension-bullet-list @tiptap/extension-list-item -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-bullet-list @tiptap/extension-list-item ``` @@ -22,9 +22,9 @@ yarn add @tiptap/extension-bullet-list @tiptap/extension-list-item | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | -| ----------- | ------- | --------------------- | -| bullet_list | โ | Toggle a bullet list. | +| Command | Parameters | Description | +| ----------- | ---------- | --------------------- | +| bulletList | โ | Toggle a bullet list. | ## Keyboard shortcuts * `Control` `Shift` `8` @@ -33,4 +33,4 @@ yarn add @tiptap/extension-bullet-list @tiptap/extension-list-item [packages/extension-bullet-list/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-bullet-list/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/code-block.md b/docs/src/docPages/api/nodes/code-block.md similarity index 85% rename from docs/src/docPages/api/extensions/code-block.md rename to docs/src/docPages/api/nodes/code-block.md index e8a45b6d..1dce417e 100644 --- a/docs/src/docPages/api/extensions/code-block.md +++ b/docs/src/docPages/api/nodes/code-block.md @@ -9,10 +9,10 @@ The CodeBlock extension doesnโt come with styling and has no syntax highlighti ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-code-block -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-code-block ``` @@ -23,9 +23,9 @@ yarn add @tiptap/extension-code-block | languageClassPrefix | string | language- | Adds a prefix to language classes that are applied to code tags. | ## Commands -| Command | Options | Description | -| --------- | ------- | ----------------------------- | -| codeBlock | โ | Wrap content in a code block. | +| Command | Parameters | Description | +| --------- | ---------- | ----------------------------- | +| codeBlock | โ | Wrap content in a code block. | ## Keyboard shortcuts * Windows/Linux: `Control` `Shift` `C` @@ -35,4 +35,4 @@ yarn add @tiptap/extension-code-block [packages/extension-code-block/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-code-block/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/document.md b/docs/src/docPages/api/nodes/document.md similarity index 86% rename from docs/src/docPages/api/extensions/document.md rename to docs/src/docPages/api/nodes/document.md index 246932a8..e887bed8 100644 --- a/docs/src/docPages/api/extensions/document.md +++ b/docs/src/docPages/api/nodes/document.md @@ -4,15 +4,15 @@ The node is very tiny though. It defines a name of the node (`document`), is configured to be a top node (`topNode: true`) and that it can contain multiple other nodes (`block`). Thatโs all. But have a look yourself: :::warning Breaking Change from 1.x โ 2.x -Tiptap 1 tried to hide that node from you, but it has always been there. A tiny, but important change though: **We renamed the default type from `doc` to `document`.** To keep it like that, use your own implementation of the `Document` node or migrate the stored JSON to use the new name. +tiptap 1 tried to hide that node from you, but it has always been there. A tiny, but important change though: **We renamed the default type from `doc` to `document`.** To keep it like that, use your own implementation of the `Document` node or migrate the stored JSON to use the new name. ::: ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-document -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-document ``` @@ -20,4 +20,4 @@ yarn add @tiptap/extension-document [packages/extension-document/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-document/) ## Usage - \ No newline at end of file + diff --git a/docs/src/docPages/api/extensions/hard-break.md b/docs/src/docPages/api/nodes/hard-break.md similarity index 66% rename from docs/src/docPages/api/extensions/hard-break.md rename to docs/src/docPages/api/nodes/hard-break.md index ae6687f4..83fc2a99 100644 --- a/docs/src/docPages/api/extensions/hard-break.md +++ b/docs/src/docPages/api/nodes/hard-break.md @@ -3,20 +3,17 @@ The HardBreak extensions adds support for the `` HTML tag, which forces a li ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-hard-break -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-hard-break ``` -## Settings -*None* - ## Commands -| Command | Options | Description | -| --------- | ------- | ----------------- | -| hardBreak | โ | Add a line break. | +| Command | Parameters | Description | +| --------- | ---------- | ----------------- | +| hardBreak | โ | Add a line break. | ## Keyboard shortcuts * `Shift` `Enter` @@ -27,4 +24,4 @@ yarn add @tiptap/extension-hard-break [packages/extension-hard-break/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-hard-break/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/heading.md b/docs/src/docPages/api/nodes/heading.md similarity index 80% rename from docs/src/docPages/api/extensions/heading.md rename to docs/src/docPages/api/nodes/heading.md index fefd6835..652d0630 100644 --- a/docs/src/docPages/api/extensions/heading.md +++ b/docs/src/docPages/api/nodes/heading.md @@ -5,10 +5,10 @@ Type # at the beginning of a new line and it will magically t ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-heading -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-heading ``` @@ -19,9 +19,9 @@ yarn add @tiptap/extension-heading | levels | Array | [1, 2, 3, 4, 5, 6] | Specifies which heading levels are supported. | ## Commands -| Command | Options | Description | -| ------- | ------- | ----------------------- | -| heading | level | Creates a heading node. | +| Command | Parameters | Description | +| ------- | ---------- | ------------------------------------------------ | +| heading | level | Creates a heading node with the specified level. | ## Keyboard shortcuts * Windows/Linux: `Control` `Alt` `1-6` @@ -31,4 +31,4 @@ yarn add @tiptap/extension-heading [packages/extension-heading/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-heading/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/horizontal-rule.md b/docs/src/docPages/api/nodes/horizontal-rule.md similarity index 76% rename from docs/src/docPages/api/extensions/horizontal-rule.md rename to docs/src/docPages/api/nodes/horizontal-rule.md index 2363e8b5..81b6c0e7 100644 --- a/docs/src/docPages/api/extensions/horizontal-rule.md +++ b/docs/src/docPages/api/nodes/horizontal-rule.md @@ -5,10 +5,10 @@ Type three dashes (---) or three underscores and a space (___ ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-horizontal-rule -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-horizontal-rule ``` @@ -18,9 +18,9 @@ yarn add @tiptap/extension-horizontal-rule | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | -| --------------- | ------- | ------------------------- | -| horizontalRule | โ | Create a horizontal rule. | +| Command | Parameters | Description | +| -------------- | ---------- | ------------------------- | +| horizontalRule | โ | Create a horizontal rule. | ## Keyboard shortcuts *None* @@ -29,4 +29,4 @@ yarn add @tiptap/extension-horizontal-rule [packages/extension-horizontal-rule/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-horizontal-rule/) ## Usage - + diff --git a/docs/src/docPages/api/nodes/image.md b/docs/src/docPages/api/nodes/image.md new file mode 100644 index 00000000..a4e93205 --- /dev/null +++ b/docs/src/docPages/api/nodes/image.md @@ -0,0 +1,26 @@ +# Image +Use this extension to render `` HTML tags. By default, those images are blocks. If you want to render images in line with text set the `inline` option to `true`. + +:::warning Restrictions +This extension does only the rendering of images. It doesnโt upload images to your server, thatโs a whole different story. +::: + +## Installation +```bash +# with npm +npm install @tiptap/extension-image + +# with Yarn +yarn add @tiptap/extension-image +``` + +## Settings +| Option | Type | Default | Description | +| ------ | ------- | ------- | ------------------------------ | +| inline | boolean | false | Renders the image node inline. | + +## Source code +[packages/extension-image/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-image/) + +## Usage + diff --git a/docs/src/docPages/api/extensions/list-item.md b/docs/src/docPages/api/nodes/list-item.md similarity index 69% rename from docs/src/docPages/api/extensions/list-item.md rename to docs/src/docPages/api/nodes/list-item.md index 8a81fb38..3fbc1f42 100644 --- a/docs/src/docPages/api/extensions/list-item.md +++ b/docs/src/docPages/api/nodes/list-item.md @@ -2,15 +2,15 @@ The ListItem extension adds support for the `` HTML tag. Itโs used for bullet lists and ordered lists and canโt really be used without them. ## Installation -::: warning Restrictions -This extensions is intended to be used with the [`BulletList`](/api/extensions/bullet-list) or [`OrderedList`](/api/extensions/ordered-list) extension. It doesnโt work without at least using one of them. +::: warning Use with BulletList and/or OrderedList +This extension requires the [`BulletList`](/api/nodes/bullet-list) or [`OrderedList`](/api/nodes/ordered-list) extension. ::: ```bash -# With npm +# with npm npm install @tiptap/extension-list-item -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-list-item ``` @@ -19,9 +19,6 @@ yarn add @tiptap/extension-list-item | ------ | ------ | ------- | -------------------------------------------- | | class | string | โ | Add a custom class to the rendered HTML tag. | -## Commands -*None* - ## Keyboard shortcuts * New list item: `Enter` * Sink a list item: `Tab` @@ -31,4 +28,4 @@ yarn add @tiptap/extension-list-item [packages/extension-list-item/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-list-item/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/ordered-list.md b/docs/src/docPages/api/nodes/ordered-list.md similarity index 65% rename from docs/src/docPages/api/extensions/ordered-list.md rename to docs/src/docPages/api/nodes/ordered-list.md index 3e9c2fd8..38dc26e7 100644 --- a/docs/src/docPages/api/extensions/ordered-list.md +++ b/docs/src/docPages/api/nodes/ordered-list.md @@ -1,18 +1,18 @@ # OrderedList -This extension enables you to use ordered lists in the editor. They are rendered as `` HTML tags, +This extension enables you to use ordered lists in the editor. They are rendered as `` HTML tags. Type 1. (or any other number followed by a dot) at the beginning of a new line and it will magically transform to a ordered list. ## Installation ::: warning Use with ListItem -The `OrderedList` extension is intended to be used with the [`ListItem`](/api/extensions/list-item) extension. Make sure to import that one too, otherwise youโll get a SyntaxError. +This extension requires the [`ListItem`](/api/nodes/list-item) extension. ::: ```bash -# With npm +# with npm npm install @tiptap/extension-ordered-list @tiptap/extension-list-item -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-ordered-list @tiptap/extension-list-item ``` @@ -22,9 +22,9 @@ yarn add @tiptap/extension-ordered-list @tiptap/extension-list-item | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | -| ------------ | ------- | ---------------------- | -| ordered_list | โ | Toggle a ordered list. | +| Command | Parameters | Description | +| ----------- | ---------- | ----------------------- | +| orderedList | โ | Toggle an ordered list. | ## Keyboard shortcuts * `Control` `Shift` `9` @@ -33,4 +33,4 @@ yarn add @tiptap/extension-ordered-list @tiptap/extension-list-item [packages/extension-ordered-list/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-ordered-list/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/paragraph.md b/docs/src/docPages/api/nodes/paragraph.md similarity index 70% rename from docs/src/docPages/api/extensions/paragraph.md rename to docs/src/docPages/api/nodes/paragraph.md index feac7701..6a3013d7 100644 --- a/docs/src/docPages/api/extensions/paragraph.md +++ b/docs/src/docPages/api/nodes/paragraph.md @@ -2,15 +2,15 @@ Yes, the schema is very strict. Without this extension you wonโt even be able to use paragraphs in the editor. :::warning Breaking Change from 1.x โ 2.x -Tiptap 1 tried to hide that node from you, but it has always been there. You have to explicitly import it from now on (or use `defaultExtensions()`). +tiptap 1 tried to hide that node from you, but it has always been there. You have to explicitly import it from now on (or use `defaultExtensions()`). ::: ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-paragraph -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-paragraph ``` @@ -20,9 +20,9 @@ yarn add @tiptap/extension-paragraph | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | -| --------- | ------- | -------------------------------------------- | -| paragraph | โ | Transforms all selected nodes to paragraphs. | +| Command | Parameters | Description | +| --------- | ---------- | -------------------------------------------- | +| paragraph | โ | Transforms all selected nodes to paragraphs. | ## Keyboard shortcuts * Windows & Linux: `Control` `Alt` `0` @@ -32,4 +32,4 @@ yarn add @tiptap/extension-paragraph [packages/extension-paragraph/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-paragraph/) ## Usage - + diff --git a/docs/src/docPages/api/nodes/task-item.md b/docs/src/docPages/api/nodes/task-item.md new file mode 100644 index 00000000..be6e772c --- /dev/null +++ b/docs/src/docPages/api/nodes/task-item.md @@ -0,0 +1,28 @@ +# TaskItem + +## Installation +::: warning Use with TaskList +This extension requires the [`TaskList`](/api/nodes/task-list) extension. +::: + +```bash +# With npm +npm install @tiptap/extension-task-list @tiptap/extension-task-item + +# Or: With Yarn +yarn add @tiptap/extension-task-list @tiptap/extension-task-item +``` + +## Settings +| Option | Type | Default | Description | +| ------ | ------ | ------- | -------------------------------------------- | +| class | string | โ | Add a custom class to the rendered HTML tag. | + +## Commands +*None* + +## Source code +[packages/extension-task-item/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-task-item/) + +## Usage + diff --git a/docs/src/docPages/api/nodes/task-list.md b/docs/src/docPages/api/nodes/task-list.md new file mode 100644 index 00000000..82a74d4b --- /dev/null +++ b/docs/src/docPages/api/nodes/task-list.md @@ -0,0 +1,33 @@ +# TaskList +This extension enables you to use task lists in the editor. They are rendered as ``. This implementation doesnโt require any framework, itโs using plain JavaScript only. + +Type [ ] or [x] at the beginning of a new line and it will magically transform to a task list. + +## Installation +::: warning Use with TaskItem +This extension requires the [`TaskItem`](/api/nodes/task-item) extension. +::: + +```bash +# with npm +npm install @tiptap/extension-task-list @tiptap/extension-task-item + +# with Yarn +yarn add @tiptap/extension-task-list @tiptap/extension-task-item +``` + +## Settings +| Option | Type | Default | Description | +| ------ | ------ | ------- | -------------------------------------------- | +| class | string | โ | Add a custom class to the rendered HTML tag. | + +## Commands +| Command | Parameters | Description | +| -------- | ---------- | ------------------- | +| taskList | โ | Toggle a task list. | + +## Source code +[packages/extension-task-list/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-task-list/) + +## Usage + diff --git a/docs/src/docPages/api/extensions/text.md b/docs/src/docPages/api/nodes/text.md similarity index 80% rename from docs/src/docPages/api/extensions/text.md rename to docs/src/docPages/api/nodes/text.md index d6664a5f..c283cc72 100644 --- a/docs/src/docPages/api/extensions/text.md +++ b/docs/src/docPages/api/nodes/text.md @@ -2,15 +2,15 @@ **The `Text` extension is required**, at least if you want to work with text of any kind and thatโs very likely. This extension is a little bit different, it doesnโt even render HTML. Itโs plain text, thatโs all. :::warning Breaking Change from 1.x โ 2.x -Tiptap 1 tried to hide that node from you, but it has always been there. You have to explicitly import it from now on (or use `defaultExtensions()`). +tiptap 1 tried to hide that node from you, but it has always been there. You have to explicitly import it from now on (or use `defaultExtensions()`). ::: ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-text -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-text ``` @@ -18,4 +18,4 @@ yarn add @tiptap/extension-text [packages/extension-text/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-text/) ## Usage - \ No newline at end of file + diff --git a/docs/src/docPages/api/overview.md b/docs/src/docPages/api/overview.md index f7b813bb..46b551c6 100644 --- a/docs/src/docPages/api/overview.md +++ b/docs/src/docPages/api/overview.md @@ -1,10 +1,13 @@ # Overview - tiptap is a friendly wrapper around [ProseMirror](https://ProseMirror.net). +tiptap is a friendly wrapper around [ProseMirror](https://ProseMirror.net). - ProseMirror works with a strict [Schema](/api/schema), which defines the allowed structure of a document. A document is a tree of headings, paragraphs and others elements, so called nodes. Marks can be attached to a node, e. g. to emphasize part of it. [Commands](/api/commands) change that document programmatically. +### Structure +ProseMirror works with a strict [Schema](/api/schema), which defines the allowed structure of a document. A document is a tree of headings, paragraphs and others elements, so called nodes. Marks can be attached to a node, e. g. to emphasize part of it. [Commands](/api/commands) change that document programmatically. - The document is stored in a state. All changes are applied as transactions to the state. The state has details about the current content, cursor position and selection. You can hook into a few different [events](/api/events), for example to alter transactions before they get applied. +### Content +The document is stored in a state. All changes are applied as transactions to the state. The state has details about the current content, cursor position and selection. You can hook into a few different [events](/api/events), for example to alter transactions before they get applied. - [Extensions](/api/extensions) add functionality like nodes, marks and/or commands to the editor. A huge amount of commands are bound to common [keyboard shortcuts](/api/keyboard-shortcuts). +### Extensions +Extensions add [nodes](/api/nodes), [marks](/api/marks) and/or [functionalities](/api/extensions) to the editor. A lot of those extensions bound their commands to common [keyboard shortcuts](/api/keyboard-shortcuts). -All of those concepts are explained in detail on the following pages. +All those concepts are explained in detail on the following pages. diff --git a/docs/src/docPages/api/schema.md b/docs/src/docPages/api/schema.md index 37a4b3fc..3fe871d4 100644 --- a/docs/src/docPages/api/schema.md +++ b/docs/src/docPages/api/schema.md @@ -1,6 +1,6 @@ # Schema -## Table of Contents +## toc ## Introduction Unlike many other editors, tiptap is based on a [schema](https://prosemirror.net/docs/guide/#schema) that defines how your content is structured. That enables you to define the kind of nodes that may occur in the document, its attributes and the way they can be nested. @@ -10,10 +10,10 @@ This schema is *very* strict. You canโt use any HTML element or attribute that Let me give you one example: If you paste something like `This is important` into tiptap, donโt have any extension that handles `strong` tags registered, youโll only see `This is important` โ without the strong tags. ## How a schema looks like - -The most simple schema for a typical *ProseMirror* editor is looking something like that: +When youโll work with the provided extensions only, you donโt have to care that much about the schema. If youโre building your own extensions, itโs probably helpful to understand how the schema works. Letโs look at the most simple schema for a typical ProseMirror editor: ```js +// the underlying ProseMirror schema { nodes: { document: { @@ -32,58 +32,225 @@ The most simple schema for a typical *ProseMirror* editor is looking something l } ``` -:::warning Out of date -This content is written for tiptap 1 and needs an update. -::: - We register three nodes here. `document`, `paragraph` and `text`. `document` is the root node which allows one or more block nodes as children (`content: 'block+'`). Since `paragraph` is in the group of block nodes (`group: 'block'`) our document can only contain paragraphs. Our paragraphs allow zero or more inline nodes as children (`content: 'inline*'`) so there can only be `text` in it. `parseDOM` defines how a node can be parsed from pasted HTML. `toDOM` defines how it will be rendered in the DOM. -In tiptap we define every node in its own `Extension` class instead. This allows us to split logic per node. Under the hood the schema will be merged together. +In tiptap every node, mark and extension is living in its own file. This allows us to split the logic. Under the hood the whole schema will be merged together: ```js -class Document extends Node { - name = 'document' - topNode = true +// the tiptap schema API +import { createNode } from '@tiptap/core' - schema() { - return { - content: 'block+', - } - } -} +const Document = createNode({ + name: 'document', + topNode: true, + content: 'block+', +}) -class Paragraph extends Node { - name = 'paragraph' +const Paragraph = createNode({ + name: 'paragraph', + group: 'block', + content: 'inline*', + parseHTML() { + return [ + { tag: 'p' }, + ] + }, + renderHTML({ attributes }) { + return ['p', attributes, 0] + }, +}) - schema() { - return { - content: 'inline*', - group: 'block', - parseDOM: [{ tag: 'p' }], - toDOM: () => ['p', 0], - } - } -} - -class Text extends Node { - name = 'text' - - schema() { - return { - group: 'inline', - } - } -} +const Text = createNode({ + name: 'text', + group: 'inline', +}) ``` -## Difference between a Node and a Mark +### Parse HTML -*Nodes* are like blocks of content, for example paragraphs, headings, code blocks, blockquotes and many more. +### Render HTML -*Marks* can apply a different style to specific parts of text inside a *Node*. Thatโs the case for **bold**, *italic* or ~~striked~~ text. [Links](#) are *Marks*, too. +## Nodes and marks + +### Differences +Nodes are like blocks of content, for example paragraphs, headings, code blocks, blockquotes and many more. + +Marks can be applied to specific parts of a node. Thatโs the case for **bold**, *italic* or ~~striked~~ text. [Links](#) are marks, too. + +### The node schema + +#### Content +The content attribute defines exactly what kind of content the node can have. ProseMirror is really strict with that. That means, content which doesnโt fit the schema is thrown away. It expects a name or group as a string. Here are a few examples: + +```js +createNode({ + // must have one ore more blocks + content: 'block+', + + // allows all kinds of 'inline' content (text or hard breaks) + content: 'inline*', + + // must not have anything else than 'text' + content: 'text*', + + // can have one or more paragraphs, or lists (if lists are used) + content: '(paragraph|list?)+', +}) +``` + + +#### Marks +You can define which marks are allowed inside of a node with the `marks` setting of the schema. Add a one or more names or groups of marks, allow all or disallow all marks like this: + +```js +createNode({ + // allows only the 'bold' mark + marks: 'bold', + + // allows only the 'bold' and 'italic' marks + marks: 'bold italic', + + // allows all marks + marks: '_', + + // disallows all marks + marks: '', +}) +``` + +#### Group +Add this node to a group of extensions, which can be referred to in the [content](#content) attribute of the schema. + +```js +createNode({ + // add to 'block' group + group: 'block', + + // add to 'inline' group + group: 'inline', + + // add to 'block' and 'list' group + group: 'block list', +}) +``` + +#### Inline +Nodes can be rendered inline, too. When setting `inline: true` nodes are rendered in line with the text. Thatโs the case for mentions. The result is more like a mark, but with the functionality of a node. One difference is the resulting JSON document. Multiple marks are applied at once, inline nodes would result in a nested structure. + +```js +createNode({ + // renders nodes in line with the text, for example + inline: true, +}) +``` + +#### Atom +Nodes with `atom: true` arenโt directly editable and should be treated as a single unit. Itโs not so likely to use that in a editor context, but this is how it would look like: + +```js +createNode({ + atom: true, +}) +``` + +#### Selectable +> Controls whether nodes of this type can be selected as a node selection. Defaults to true for non-text nodes. + +```js +createNode({ + selectable: true, +}) +``` + +#### Draggable +All nodes can be configured to be draggable (by default they arenโt) with this setting: + +```js +createNode({ + draggable: true, +}) +``` + +#### Code +Users expect code to behave very differently. For all kind of nodes containing code, you can set `code: true` to take this into account. + +```js +createNode({ + code: true, +}) +``` + +#### Defining +> Determines whether this node is considered an important parent node during replace operations (such as paste). Non-defining (the default) nodes get dropped when their entire content is replaced, whereas defining nodes persist and wrap the inserted content. Likewise, in inserted content the defining parents of the content are preserved when possible. Typically, non-default-paragraph textblock types, and possibly list items, are marked as defining. + +```js +createNode({ + defining: true, +}) +``` + +#### Isolating +For nodes that should fence the cursor for regular editing operations like backspacing, for example a TableCell, set `isolating: true`. + +```js +createNode({ + isolating: true, +}) +``` + +### The mark schema +#### Inclusive +If you donโt want the mark to be active when the cursor is at its end, set inclusive to `false`. For example, thatโs how itโs configured for [`Link`](/api/marks/link) marks: + +```js +createMark({ + inclusive: false, +}) +``` + +#### Excludes +By default all nodes can be applied at the same time. With the excludes attribute you can define which marks must not coexist with the mark. For example, the inline code mark excludes any other mark (bold, italic, and all others). + +```js +createMark({ + // must not coexist with the bold mark + excludes: 'bold' + // exclude any other mark + excludes: '_', +}) +``` + +#### Group +Add this mark to a group of extensions, which can be referred to in the content attribute of the schema. + +```js +createMark({ + // add this mark to the 'basic' group + group: 'basic', + // add this mark to the 'basic' and the 'foobar' group + group: 'foobar', +}) +``` + +#### Code +Users expect code to behave very differently. For all kind of marks containing code, you can set `code: true` to take this into account. + +```js +createMark({ + code: true, +}) +``` + +#### Spanning +By default marks can span multiple nodes when rendered as HTML. Set `spanning: false` to indicate that a mark must not span multiple nodes. + +```js +createMark({ + spanning: false, +}) +``` ## Get the underlying ProseMirror schema - There are a few use cases where you need to work with the underlying schema. Youโll need that if youโre using the tiptap collaborative text editing features or if you want to manually render your content as HTML. ### Option 1: With an Editor @@ -123,23 +290,3 @@ const schema = getSchema([ // add more extensions here ]) ``` - -## Generate HTML from ProseMirror JSON - -If you need to render the content on the server side, e. g. for a blog post that was written with tiptap, youโll probably need a way to do just that without an actual editor instance. - -Thatโs what `generategetHTML()` is for. Itโs a utility function that renders HTML without an actual editor instance. - -:::warning Work in progress -Currently, that works only in the browser (client side), but we plan to bring this to Node.js (to use it on the server side). -::: - - - -### Converting JSON<>HTML with PHP - -We needed to do the same thing in PHP at some point, so we published libraries to convert ProseMirror JSON to HTML and vice-versa: - -* [ueberdosis/prosemirror-php](https://github.com/ueberdosis/prosemirror-php) (PHP) -* [ueberdosis/prosemirror-to-html](https://github.com/ueberdosis/prosemirror-to-html) (PHP) -* [ueberdosis/html-to-prosemirror](https://github.com/ueberdosis/html-to-prosemirror) (PHP) diff --git a/docs/src/docPages/examples.md b/docs/src/docPages/examples.md index 555e143e..4b61ec78 100644 --- a/docs/src/docPages/examples.md +++ b/docs/src/docPages/examples.md @@ -1,9 +1,3 @@ # Examples -We put together a few examples to show the capabilities of tiptap, but keep in mind: tiptap is renderless and highly customizable. Everything you see can be changed, modified, combined or remixed. Feel free to copy the code to your project and change it to your liking. - -A few examples show what youโd probably expect from a text editor anyway: [Basic](/examples/basic), [Links](/examples/links), [History](/examples/history), [Read-only](/examples/read-only), [Export HTML or JSON](/examples/export-html-or-json). - -Some examples show how you can improve the user experience: [Markdown shortcuts](/examples/markdown-shortcuts). - -Or they show advanced use cases, like the [Collaborative editing](/examples/collaborative-editing) example, which is basically tiptap in multiplayer mode. +TODO: This page should redirect to [/examples/basic](/examples/basic). diff --git a/docs/src/docPages/examples/basic.md b/docs/src/docPages/examples/basic.md index 91004db3..c33b8158 100644 --- a/docs/src/docPages/examples/basic.md +++ b/docs/src/docPages/examples/basic.md @@ -1,4 +1,3 @@ # Basic -BUG: Headings canโt be transformed to a bullet or ordered list. diff --git a/docs/src/docPages/examples/collaborative-editing.md b/docs/src/docPages/examples/collaborative-editing.md index c085612e..7c0f4566 100644 --- a/docs/src/docPages/examples/collaborative-editing.md +++ b/docs/src/docPages/examples/collaborative-editing.md @@ -1,4 +1,9 @@ # Collaborative editing + +:::premium Requires Premium Extensions +Using this example in production requires a **tiptap pro** license. [Read more](/sponsor) +::: + This example shows how you can use tiptap to let different users collaboratively work on the same text in real-time. It connects client with WebRTC and merges changes to the document (no matter where they come from) with the awesome library [Y.js](https://github.com/yjs/yjs) by Kevin Jahns. Be aware that in a real-world scenario you would probably add a server, which is also able to merge changes with Y.js. diff --git a/docs/src/docPages/examples/formatting.md b/docs/src/docPages/examples/formatting.md new file mode 100644 index 00000000..e6e0f8ce --- /dev/null +++ b/docs/src/docPages/examples/formatting.md @@ -0,0 +1,3 @@ +# Formatting + + diff --git a/docs/src/docPages/examples/read-only.md b/docs/src/docPages/examples/read-only.md index fea24ee5..048465a7 100644 --- a/docs/src/docPages/examples/read-only.md +++ b/docs/src/docPages/examples/read-only.md @@ -1,3 +1,3 @@ # Read-only - + diff --git a/docs/src/docPages/guide/build-custom-extensions.md b/docs/src/docPages/guide/build-custom-extensions.md new file mode 100644 index 00000000..195d4b8d --- /dev/null +++ b/docs/src/docPages/guide/build-custom-extensions.md @@ -0,0 +1,305 @@ +# Build custom extensions + +## toc + +## Introduction +One of the strength of tiptap is itโs extendability. You donโt depend on the provided extensions, itโs intended to extend the editor to your liking. With custom extensions you can add new content types and new functionalities, on top of what already exists or starting from scratch. + +## Option 1: Extend existing extensions +Letโs say you want to change the keyboard shortcuts for the bullet list. You should start by looking at [the source code of the `BulletList` extension](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-bullet-list/index.ts) and find the part you would like to change. In that case, the keyboard shortcut, and just that. + +Every extension has an `extend()` method, which takes an object with everything you want to change or add to it. For the bespoken example, your code could like that: + +```js +// 1. Import the extension +import BulletList from '@tiptap/extension-bullet-list' + +// 2. Overwrite the keyboard shortcuts +const CustomBulletList = BulletList.extend({ + addKeyboardShortcuts() { + return { + 'Mod-l': () => this.editor.bulletList(), + } + }, +}) + +// 3. Add the custom extension to your editor +new Editor({ + extensions: [ + CustomBulletList(), + // โฆ + ] +}) +``` + +The same applies to every aspect of an existing extension, except to the name. Letโs look at all the things that you can change through the extend method. We focus on one aspect in every example, but you can combine all those examples and change multiple aspects in one `extend()` call too. + +### Name +The extension name is used in a whole lot of places and changing it isnโt too easy. If you want to change the name of an existing extension, we would recommended to copy the whole extension and change the name in all occurrences. + +The extension name is also part of the JSON. If you [store your content as JSON](/guide/store-content#option-1-json), you need to change the name there too. + +### Settings +All settings can be configured through the extension anyway, but if you want to change the default settings, for example to provide a library on top of tiptap for other developers, you can do it like that: + +```js +import Heading from '@tiptap/extension-heading' + +const CustomHeading = Heading.extend({ + defaultOptions: { + levels: [1, 2, 3], + }, +}) +``` + +### Schema +tiptap works with a strict schema, which configures how the content can be structured, nested, how it behaves and many more things. You [can change all aspects of the schema](/api/schema) for existing extensions. Letโs walk through a few common use cases. + +The default `Blockquote` extension can wrap other nodes, like headings. If you want to allow nothing but paragraphs in your blockquotes, this is how you could achieve it: + +```js +// Blockquotes must only include paragraphs +import Blockquote from '@tiptap/extension-blockquote' + +const CustomBlockquote = Blockquote.extend({ + content: 'paragraph*', +}) +``` + +The schema even allows to make your nodes draggable, thatโs what the `draggable` option is for, which defaults to `false`. + +```js +// Draggable paragraphs +import Paragraph from '@tiptap/extension-paragraph' + +const CustomParagraph = Paragraph.extend({ + draggable: true, +}) +``` + +Thatโs just two tiny examples, but [the underlying ProseMirror schema](https://prosemirror.net/docs/ref/#model.SchemaSpec) is really powerful. You should definitely read the documentation to understand all the nifty details. + +### Attributes +You can use attributes to store additional information in the content. Letโs say you want to extend the default paragraph extension to enable paragraphs to have different colors: + +```js +const CustomParagraph = Paragraph.extend({ + addAttributes() { + // Return an object with attribute configuration + return { + color: { + default: 'pink', + }, + }, + }, +}) + +// Result: +// Example Text +``` + +Thatโs already enough to tell tiptap about the new attribute, and set `'pink'` as the default value. All attributes will be rendered as a data-attributes by default, and parsed as data-attributes from the content. + +Letโs stick with the color example and assume youโll want to add an inline style to actually color the text. With the `renderHTML` function you can return HTML attributes which will be rendered in the output. + +This examples adds a style HTML attribute based on the value of color: + +```js +const CustomParagraph = Paragraph.extend({ + addAttributes() { + return { + color: { + default: null, + // Take the attribute values + renderHTML: attributes => { + // โฆ and return an object with HTML attributes. + return { + style: `color: ${attributes.color}`, + } + }, + }, + } + }, +}) + +// Result: +// Example Text +``` + +You can also control how the attribute is parsed from the HTML. Letโs say you want to store the color in an attribute called `data-my-fancy-color-attribute`. Legit, right? Anyway, hereโs how you would do that: + +```js +const CustomParagraph = Paragraph.extend({ + addAttributes() { + return { + color: { + default: null, + // Customize the HTML parsing (for example, to load the initial content) + parseHTML: element => { + return { + color: element.getAttribute('data-my-fancy-color-attribute'), + } + }, + // โฆ and customize the HTML rendering. + renderHTML: attributes => { + return { + 'data-my-fancy-color-attribute': atttributes.color, + style: `color: ${attributes.color}`, + } + }, + }, + } + }, +}) + +// Result: +// Example Text +``` + +### Global Attributes +Attributes can be applied to multiple extensions at once. Thatโs useful for text alignment, line height, color, font family, and other styling related attributes. + +Take a closer look at [the full source code](https://github.com/ueberdosis/tiptap-next/tree/main/packages/extension-text-align) of the [`TextAlign`](/api/extensions/text-align) extension to see a more complex example. But here is how it works in a nutshell: + +```js +import { createExtension } from '@tiptap/core' + +const TextAlign = createExtension({ + addGlobalAttributes() { + return [ + { + // Extend the following extensions + types: [ + 'heading', + 'paragraph', + ], + // โฆ with those attributes + attributes: { + textAlign: { + default: 'left', + renderHTML: attributes => ({ + style: `text-align: ${attributes.textAlign}`, + }), + parseHTML: element => ({ + textAlign: element.style.textAlign || 'left', + }), + }, + }, + }, + ] + }, +}) +``` + +### Render HTML +With the `renderHTML` function you can control how an extension is rendered to HTML. We pass an attributes object to it, with all local attributes, global attributes, and configured CSS classes. Here is an example from the `Bold` extension: + +```js +renderHTML({ attributes }) { + return ['strong', attributes, 0] +}, +``` + +The first value in the array should be the name of HTML tag. If the second element is an object, itโs interpreted as a set of attributes. Any elements after that are rendered as children. + +The number zero (representing a hole) is used to indicate where the content should be inserted. Letโs look at the rendering of the `CodeBlock` extension with two nested tags: + +```js +renderHTML({ attributes }) { + return ['pre', ['code', attributes, 0]] +}, +``` + +If you want to add some specific attributes there, import the `mergeAttributes` helper from `@tiptap/core`: + +```js +renderHTML({ attributes }) { + return ['a', mergeAttributes(attributes, { rel: this.options.rel }), 0] +}, +``` + +### Parse HTML +> Associates DOM parser information with this mark (see the corresponding node spec field). The mark field in the rules is implied. + +### Commands + +```js +import Paragraph from '@tiptap/extension-paragraph' + +const CustomParagraph = Paragraph.extend({ + addCommands() { + return { + paragraph: () => ({ commands }) => { + return commands.toggleBlockType('paragraph', 'paragraph') + }, + } + }, +}) +``` + +### Keyboard shortcuts +Most core extensions come with sensible keyboard shortcut defaults. Depending on what you want to build, youโll likely want to change them though. With the `addKeyboardShortcuts()` method you can overwrite the predefined shortcut map: + +```js +// Change the bullet list keyboard shortcut +import BulletList from '@tiptap/extension-bullet-list' + +const CustomBulletList = BulletList.extend({ + addKeyboardShortcuts() { + return { + 'Mod-l': () => this.editor.bulletList(), + } + }, +}) +``` + +### Input rules + +```js +// Use the ~single tilde~ markdown shortcut +import Strike from '@tiptap/extension-strike' +import { markInputRule } from '@tiptap/core' + +const inputRegex = /(?:^|\s)((?:~)((?:[^~]+))(?:~))$/gm + +const CustomStrike = Strike.extend({ + addInputRules() { + return [ + markInputRule(inputRegex, this.type), + ] + }, +}) +``` + +### Paste rules + +```js +// Overwrite the underline regex for pasted text +import Underline from '@tiptap/extension-underline' +import { markPasteRule } from '@tiptap/core' + +const pasteRegex = /(?:^|\s)((?:~)((?:[^~]+))(?:~))$/gm + +const CustomUnderline = Underline.extend({ + addPasteRules() { + return [ + markPasteRule(inputRegex, this.type), + ] + }, +}) +``` + +### Node views + +## Option 2: Start from scratch + +### Read the documentation +Although tiptap tries to hide most of the complexity of ProseMirror, itโs built on top of its APIs and we recommend you to read through the [ProseMirror Guide](https://ProseMirror.net/docs/guide/) for advanced usage. Youโll have a better understanding of how everything works under the hood and get more familiar with many terms and jargon used by tiptap. + +### Have a look at existing extensions + +### Get started + +### Ask questions + +### Share your extension diff --git a/docs/src/docPages/guide/collaborative-editing.md b/docs/src/docPages/guide/collaborative-editing.md index 9bbe3895..98b73209 100644 --- a/docs/src/docPages/guide/collaborative-editing.md +++ b/docs/src/docPages/guide/collaborative-editing.md @@ -1,9 +1,12 @@ # Collaborative editing -## Table of Contents +:::premium Requires Premium Extensions +Using the collaborative editing in production requires a **tiptap pro** license. [Read more](/sponsor) +::: + +## toc ## Introduction - Collaborative editing allows multiple users to work on the same text document in real-time. Itโs a complex topic that you should be aware before adding it blindly to you app. No worries though, here is everything you need to know. ## Configure collaboration diff --git a/docs/src/docPages/guide/configuration.md b/docs/src/docPages/guide/configuration.md index 0b9539e7..ee58cfc9 100644 --- a/docs/src/docPages/guide/configuration.md +++ b/docs/src/docPages/guide/configuration.md @@ -1,6 +1,6 @@ # Configuration -## Table of Contents +## toc ## Introduction tiptap is all about customization. There are a ton of options to configure the behavior and functionality of the editor. Most of those settings can be set before creating the Editor. Give tiptap a JSON with all the settings you would like to overwrite. diff --git a/docs/src/docPages/guide/build-your-editor.md b/docs/src/docPages/guide/create-your-editor.md similarity index 95% rename from docs/src/docPages/guide/build-your-editor.md rename to docs/src/docPages/guide/create-your-editor.md index 0d047478..1977a0ee 100644 --- a/docs/src/docPages/guide/build-your-editor.md +++ b/docs/src/docPages/guide/create-your-editor.md @@ -1,6 +1,6 @@ # Build your editor -## Table of Contents +## toc ## Introduction In its simplest version tiptap comes very raw. There is no menu, no buttons, no styling. Thatโs intended. See tiptap as your building blocks to build exactly the editor you would like to have. @@ -18,7 +18,7 @@ You might wonder what features tiptap supports out of the box. In the above exam * [List of available commands](/api/commands) ## Configure extensions -You are free to choose which parts of tiptap you want to use. Tiptap has support for different nodes (paragraphs, blockquotes, tables and many more) and different marks (bold, italic, links). If you want to explicitly configure what kind of nodes and marks are allowed and which are not allowed, you can configure those. +You are free to choose which parts of tiptap you want to use. tiptap has support for different nodes (paragraphs, blockquotes, tables and many more) and different marks (bold, italic, links). If you want to explicitly configure what kind of nodes and marks are allowed and which are not allowed, you can configure those. Note that `Document`, `Paragraph` and `Text` are required. Otherwise you wonโt be able to add any plain text. diff --git a/docs/src/docPages/guide/custom-extensions.md b/docs/src/docPages/guide/custom-extensions.md deleted file mode 100644 index 0e6d430a..00000000 --- a/docs/src/docPages/guide/custom-extensions.md +++ /dev/null @@ -1,142 +0,0 @@ -# Custom Extensions - -## Table of Contents - -## Introduction -One of the strength of tiptap is itโs extendability. You donโt depend on the provided extensions, itโs intended to extend the editor to your liking. With custom extensions you can add new content types and new functionalities, on top of what already exists or on top of that. - -## Option 1: Change defaults - -Letโs say you want to change the keyboard shortcuts for the bullet list. You should start by looking at [the source code of the `BulletList` extension](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-bullet-list/index.ts) and find the default youโd like to change. In that case, the keyboard shortcut, and just that. - -```js -// 1. Import the extension -import BulletList from '@tiptap/extension-bullet-list' - -// 2. Overwrite the keyboard shortcuts -const CustomBulletList = BulletList() - .keys(({ editor }) => ({ - 'Mod-l': () => editor.bulletList(), - })) - .create() // Donโt forget that! - -// 3. Add the custom extension to your editor -new Editor({ - extensions: [ - CustomBulletList(), - // โฆ - ] -}) -``` - -You can overwrite every aspect of an existing extension: - -### Name - -```js -import Document from '@tiptap/extension-document' - -const CustomDocument = Document() - .name('doc') - .create() -``` - -### Settings - -```js -import Heading from '@tiptap/extension-heading' - -const CustomHeading = Heading() - .defaults({ - levels: [1, 2, 3], - class: 'my-custom-heading', - }) - .create() -``` - -### Schema - -```js -import Code from '@tiptap/extension-code' - -const CustomCode = Code() - .schema(() => ({ - excludes: '_', - parseDOM: [ - { tag: 'code' }, - ], - toDOM: () => ['code', { 'data-attribute': 'foobar' }, 0], - })) - .create() -``` - -### Commands - -```js -import Paragraph from '@tiptap/extension-paragraph' - -const CustomParagraph = Paragraph() - .commands(() => ({ - paragraph: () => ({ commands }) => { - return commands.toggleBlockType(name, 'paragraph') - }, - })) - .create() -``` - -### Keyboard shortcuts - -```js -import BulletList from '@tiptap/extension-bullet-list' - -const CustomBulletList = BulletList() - .keys(({ editor }) => ({ - 'Mod-l': () => editor.bulletList(), - })) - .create() -``` - -### Input rules - -```js -import Strike from '@tiptap/extension-strike' -import { markInputRule } from '@tiptap/core' - -const inputRegex = /(?:^|\s)((?:~)((?:[^~]+))(?:~))$/gm - -const CustomStrike = Strike() - .inputRules(({ type }) => [ - markInputRule(inputRegex, type), - ]) - .create() -``` - -### Paste rules - -```js -import Underline from '@tiptap/extension-underline' -import { markPasteRule } from '@tiptap/core' - -const pasteRegex = /(?:^|\s)((?:~)((?:[^~]+))(?:~))$/gm - -const CustomUnderline = Underline() - .pasteRules(({ type }) => [ - markPasteRule(pasteRegex, type), - ]) - .create() -``` - -## Option 2: Extend existing extensions - -## Option 3: Start from scratch - -### 1. Read the documentation -Although tiptap tries to hide most of the complexity of ProseMirror, itโs built on top of its APIs and we recommend you to read through the [ProseMirror Guide](https://ProseMirror.net/docs/guide/) for advanced usage. Youโll have a better understanding of how everything works under the hood and get more familiar with many terms and jargon used by tiptap. - -### 2. Have a look at existing extensions - -### 3. Get started - -### 4. Ask questions - -### 5. Publish a community extension diff --git a/docs/src/docPages/guide/custom-styling.md b/docs/src/docPages/guide/custom-styling.md index b3c53c02..5fdf2c94 100644 --- a/docs/src/docPages/guide/custom-styling.md +++ b/docs/src/docPages/guide/custom-styling.md @@ -1,9 +1,9 @@ # Custom styling -## Table of Contents +## toc ## Introduction -Tiptap is renderless, that doesnโt mean there is no styling provided. You can decided how your editor should look like. +tiptap is renderless, that doesnโt mean there is no styling provided. You can decided how your editor should look like. ## Option 1: Style the plain HTML The whole editor is rendered inside of a container with the class `.ProseMirror`. You can use that to scope your styling to the editor content: @@ -28,15 +28,21 @@ p { ## Option 2: Add custom classes Most extensions have a `class` option, which you can use to add a custom CSS class to the HTML tag. +Most extensions allow you to add attributes to the rendered HTML through the `attributes` configuration. You can use that to add a custom class (or any other attribute): + ```js new Editor({ extensions: [ Document(), Paragraph({ - class: 'my-custom-paragraph', + attributes: { + class: 'my-custom-paragraph', + }, }), Heading({ - class: 'my-custom-heading', + attributes: { + class: 'my-custom-heading', + }, }), Text(), ] @@ -50,17 +56,21 @@ The rendered HTML will look like that: Wow, thatโs really custom. ``` +If there are already classes defined by the extensions, your classes will be added. + ## Option 3: Customize the HTML You can even customize the markup for every extension. This will make a custom bold extension that doesnโt render a `` tag, but a `` tag: ```js import Bold from '@tiptap/extension-bold' -const CustomBold = Bold - .schema(() => ({ - toDOM: () => ['b', 0], - })) - .create() +const CustomBold = Bold.extend({ + renderHTML({ attributes }) { + // Original: + // return ['strong', attributes, 0] + return ['b', attributes, 0] + }, +}) new Editor({ extensions: [ @@ -70,4 +80,4 @@ new Editor({ }) ``` -You should put your custom extensions in separate files though, but I think youโve got the idea. +You should put your custom extensions in separate files though, but I think you got the idea. diff --git a/docs/src/docPages/guide/getting-started.md b/docs/src/docPages/guide/getting-started.md index fbfac4ad..2ebbd29f 100644 --- a/docs/src/docPages/guide/getting-started.md +++ b/docs/src/docPages/guide/getting-started.md @@ -1,6 +1,6 @@ # Getting started -## Table of Contents +## toc ## Introduction tiptap is framework-agnostic and works with Vue.js and React. It even works with plain JavaScript, if thatโs your thing. To keep everything as small as possible, we put the code to use tiptap with those frameworks in different packages. @@ -19,7 +19,7 @@ yarn add @tiptap/vue @tiptap/vue-starter-kit The `@tiptap/vue-starter-kit` includes a few basics you would probably need anyway. Cool, you have got everything in place to set up tiptap! ๐ ## 2. Create a new component -Create a new Vue component (you can call it ``) and add the following content. This is the fastest way to get tiptap up and running with Vue.js. It will give you a very basic version of tiptap, without any buttons. No worries, you will be able to add more functionality soon. +Create a new Vue component (you can call it ``) and add the following content. This is the fastest way to get tiptap up and running with Vue.js. It will give you a very basic version of tiptap, without any buttons. No worries, you will be able to add more functionality soon. diff --git a/docs/src/docPages/guide/store-content.md b/docs/src/docPages/guide/store-content.md index d69d267f..4380a40a 100644 --- a/docs/src/docPages/guide/store-content.md +++ b/docs/src/docPages/guide/store-content.md @@ -1,6 +1,6 @@ # Store content -## Table of Contents +## toc ## Introduction You can store your content as a JSON object or as a good old HTML string. Both work fine. And of course, you can pass both formats to the editor to restore your content. @@ -85,6 +85,17 @@ Unfortunately, **tiptap doesnโt support Markdown as an input or output format* You should really consider to work with HTML or JSON to store your content, they are perfectly fine for most use cases. -If you still think you need Markdown, [Nextcloud Text](https://github.com/nextcloud/text) uses tiptap to work with Markdown. Their code is open source, so maybe you can learn from them. +If you still think you need Markdown, [Nextcloud Text](https://github.com/nextcloud/text) uses tiptap 1 to work with Markdown. Their code is open source, so maybe you can learn from them. That said, tiptap **does** support Markdown shortcuts to format your content. Try typing `**two asterisks**` to make your text bold for example. + +## Generate HTML from ProseMirror JSON +If you need to render the content on the server side, for example to render a blog post which was written with tiptap, youโll probably need a way to do just that without an actual editor instance. + +Thatโs what `generateHTML()` is for. Itโs a utility function that renders HTML without an actual editor instance. + +:::info Browser-only rendering +Import a lightweight implementation from `@tiptap/core` if youโre using the function in a browser context only. +::: + + diff --git a/docs/src/docPages/introduction.md b/docs/src/docPages/introduction.md index 5c6afa8b..b8a3280b 100644 --- a/docs/src/docPages/introduction.md +++ b/docs/src/docPages/introduction.md @@ -1,15 +1,17 @@ -:::warning Donโt try this at home -This version of tiptap is not production-ready, donโt use it anywhere. +:::error Donโt try this at home +Nothing here is production-ready, donโt use it anywhere. ::: # Introduction -[](https://www.npmjs.com/package/@tiptap/core) -[](https://npmcharts.com/compare/@tiptap/core?minimal=true) -[](https://www.npmjs.com/package/@tiptap/core) + + + + + [](https://github.com/sponsors/ueberdosis) -tiptap is a renderless wrapper around [ProseMirror](https://ProseMirror.net) โ a toolkit for building rich-text editors that is already in use at many well-known companies such as *New York Times*, *The Guardian* or *Atlassian*. +tiptap is a renderless wrapper around [ProseMirror](https://ProseMirror.net) โ a toolkit for building rich-text WYSIWYG editors, which is already in use at many well-known companies such as *New York Times*, *The Guardian* or *Atlassian*. Although tiptap tries to hide most of the complexity of ProseMirror, itโs built on top of its APIs and we recommend you to read through the [ProseMirror Guide](https://ProseMirror.net/docs/guide/) for advanced usage. Youโll have a better understanding of how everything works under the hood and get more familiar with many terms and jargon used by tiptap. @@ -17,9 +19,9 @@ Although tiptap tries to hide most of the complexity of ProseMirror, itโs buil **Renderless.** We donโt tell you what a menu should look like or where it should be rendered in the DOM. Thatโs why tiptap is renderless and comes without any CSS. You are in full control over markup and styling. -**Framework-agnostic.** We donโt care what framework you use. Tiptap is ready to be used with plain JavaScript or Vue.js. That makes it even possible to write a renderer for React, Svelte and others. +**Framework-agnostic.** We donโt care what framework you use. tiptap is ready to be used with plain JavaScript or Vue.js. That makes it even possible to write a renderer for React, Svelte and others. -**TypeScript.** Tiptap 2 is written in TypeScript. That gives you a nice autocomplete for the API (if your IDE supports that), helps to find bugs early and makes it possible to generate [a complete API documentation](#) on top of the extensive human written documentation. +**TypeScript.** tiptap 2 is written in TypeScript. That gives you a nice autocomplete for the API (if your IDE supports that), helps to find bugs early and makes it possible to generate [a complete API documentation](#) on top of the extensive human written documentation. ## Who uses tiptap? - [GitLab](https://gitlab.com) @@ -29,3 +31,6 @@ Although tiptap tries to hide most of the complexity of ProseMirror, itโs buil - [Directus CMS](https://directus.io) - [Nextcloud](https://apps.nextcloud.com/apps/text) - [and many more โ](https://github.com/ueberdosis/tiptap/network/dependents?package_id=UGFja2FnZS0xMzE5OTg0ODc%3D) + +## License +tiptap is licensed under MIT, so youโre free to whatever you want. Anyway, we kindly ask you to [become a sponsor](https://github.com/sponsors/ueberdosis) on GitHub to fund the development, maintenance and support of tiptap. diff --git a/docs/src/docPages/open.md b/docs/src/docPages/open.md new file mode 100644 index 00000000..b5d7cae3 --- /dev/null +++ b/docs/src/docPages/open.md @@ -0,0 +1,26 @@ +# Monthly reports + +## October 2020 +* Writing extensions for tiptap 2 +* 25 sponsors, $423/month +* 102 hours, $7,140 development costs (at $70/hour) +* Sponsored @calebporzio with $99 +* **Total -$6,816** + +## September 2020 +* Developing the API of tiptap 2, writing the documentation +* 125 hours, $8,750 development costs (at $70/hour) +* Sponsored @calebporzio with $99 +* **Total -$8,849** + +## August 2020 +* Setting up tiptap 2 +* 56 hours, $3,920 development costs (at $70/hour) +* Sponsored @calebporzio with $99 +* **Total -$4,019** + +## All time + +* **Total -$19.684** + + diff --git a/docs/src/docPages/overview/contributing.md b/docs/src/docPages/overview/contributing.md index 1f024d29..f28771ea 100644 --- a/docs/src/docPages/overview/contributing.md +++ b/docs/src/docPages/overview/contributing.md @@ -1,13 +1,14 @@ # Contributing -## Table of Contents +## toc ## Introduction -Tiptap would be nothing without its lively community. Contributions have always been and will always be welcome. Here is a little bit you should know, before you send your contribution: +tiptap would be nothing without its lively community. Contributions have always been and will always be welcome. Here is a little bit you should know, before you send your contribution: ## Welcome examples -* Improve the documentation, e. g. fix a typo, add a section -* New features for existing extensions, e. g. a new option +* Failing regression tests as bug reports +* Documentation improvements, e. g. fix a typo, add a section +* New features for existing extensions, e. g. a new configureable option * New extensions, which donโt require changes to the core or other core extensions * Well explained, non-breaking changes to the core diff --git a/docs/src/docPages/overview/installation.md b/docs/src/docPages/overview/installation.md index 57fc588c..2324a3f8 100644 --- a/docs/src/docPages/overview/installation.md +++ b/docs/src/docPages/overview/installation.md @@ -1,6 +1,6 @@ # Installation -## Table of Contents +## toc ## Introduction Youโre free to use tiptap with the framework of your choice. Depending on what you want to do, there are a few different ways to install tiptap in your project. Choose the way that fits your workflow. @@ -9,10 +9,10 @@ Youโre free to use tiptap with the framework of your choice. Depending on what Use tiptap with vanilla JavaScript for a very lightweight and raw experience. If you feel like it, you can even use it to connect tiptap with other frameworks not mentioned here. ```bash -# With npm +# with npm npm install @tiptap/core @tiptap/starter-kit -# Or: With Yarn +# with Yarn yarn add @tiptap/core @tiptap/starter-kit ``` @@ -33,10 +33,10 @@ new Editor({ To use tiptap with Vue.js (and tools that are based on Vue.js) install tiptap together with the Vue.js adapter in your project. We even prepared a Vue.js starter kit, which gives you a good headstart. ```bash -# With npm +# with npm npm install @tiptap/core @tiptap/vue @tiptap/vue-starter-kit -# Or: With Yarn +# with Yarn yarn add @tiptap/core @tiptap/vue @tiptap/vue-starter-kit ``` @@ -44,9 +44,10 @@ Create a new component and add the following content to get a basic version of t -::: warning Nuxt.js -If you use Nuxt.js, note that tiptap needs to run in the client, not on the server. Itโs required to wrap the editor in a `` tag. -::: +### Nuxt.js +Note that tiptap needs to run in the client, not on the server. Itโs required to wrap the editor in a `` tag. + +[Read more](https://nuxtjs.org/api/components-client-only)
\
\`back-ticks around\`
>
*
-
+
#
---
___ ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-horizontal-rule -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-horizontal-rule ``` @@ -18,9 +18,9 @@ yarn add @tiptap/extension-horizontal-rule | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | -| --------------- | ------- | ------------------------- | -| horizontalRule | โ | Create a horizontal rule. | +| Command | Parameters | Description | +| -------------- | ---------- | ------------------------- | +| horizontalRule | โ | Create a horizontal rule. | ## Keyboard shortcuts *None* @@ -29,4 +29,4 @@ yarn add @tiptap/extension-horizontal-rule [packages/extension-horizontal-rule/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-horizontal-rule/) ## Usage - + diff --git a/docs/src/docPages/api/nodes/image.md b/docs/src/docPages/api/nodes/image.md new file mode 100644 index 00000000..a4e93205 --- /dev/null +++ b/docs/src/docPages/api/nodes/image.md @@ -0,0 +1,26 @@ +# Image +Use this extension to render `` HTML tags. By default, those images are blocks. If you want to render images in line with text set the `inline` option to `true`. + +:::warning Restrictions +This extension does only the rendering of images. It doesnโt upload images to your server, thatโs a whole different story. +::: + +## Installation +```bash +# with npm +npm install @tiptap/extension-image + +# with Yarn +yarn add @tiptap/extension-image +``` + +## Settings +| Option | Type | Default | Description | +| ------ | ------- | ------- | ------------------------------ | +| inline | boolean | false | Renders the image node inline. | + +## Source code +[packages/extension-image/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-image/) + +## Usage + diff --git a/docs/src/docPages/api/extensions/list-item.md b/docs/src/docPages/api/nodes/list-item.md similarity index 69% rename from docs/src/docPages/api/extensions/list-item.md rename to docs/src/docPages/api/nodes/list-item.md index 8a81fb38..3fbc1f42 100644 --- a/docs/src/docPages/api/extensions/list-item.md +++ b/docs/src/docPages/api/nodes/list-item.md @@ -2,15 +2,15 @@ The ListItem extension adds support for the `` HTML tag. Itโs used for bullet lists and ordered lists and canโt really be used without them. ## Installation -::: warning Restrictions -This extensions is intended to be used with the [`BulletList`](/api/extensions/bullet-list) or [`OrderedList`](/api/extensions/ordered-list) extension. It doesnโt work without at least using one of them. +::: warning Use with BulletList and/or OrderedList +This extension requires the [`BulletList`](/api/nodes/bullet-list) or [`OrderedList`](/api/nodes/ordered-list) extension. ::: ```bash -# With npm +# with npm npm install @tiptap/extension-list-item -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-list-item ``` @@ -19,9 +19,6 @@ yarn add @tiptap/extension-list-item | ------ | ------ | ------- | -------------------------------------------- | | class | string | โ | Add a custom class to the rendered HTML tag. | -## Commands -*None* - ## Keyboard shortcuts * New list item: `Enter` * Sink a list item: `Tab` @@ -31,4 +28,4 @@ yarn add @tiptap/extension-list-item [packages/extension-list-item/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-list-item/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/ordered-list.md b/docs/src/docPages/api/nodes/ordered-list.md similarity index 65% rename from docs/src/docPages/api/extensions/ordered-list.md rename to docs/src/docPages/api/nodes/ordered-list.md index 3e9c2fd8..38dc26e7 100644 --- a/docs/src/docPages/api/extensions/ordered-list.md +++ b/docs/src/docPages/api/nodes/ordered-list.md @@ -1,18 +1,18 @@ # OrderedList -This extension enables you to use ordered lists in the editor. They are rendered as `` HTML tags, +This extension enables you to use ordered lists in the editor. They are rendered as `` HTML tags. Type 1. (or any other number followed by a dot) at the beginning of a new line and it will magically transform to a ordered list. ## Installation ::: warning Use with ListItem -The `OrderedList` extension is intended to be used with the [`ListItem`](/api/extensions/list-item) extension. Make sure to import that one too, otherwise youโll get a SyntaxError. +This extension requires the [`ListItem`](/api/nodes/list-item) extension. ::: ```bash -# With npm +# with npm npm install @tiptap/extension-ordered-list @tiptap/extension-list-item -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-ordered-list @tiptap/extension-list-item ``` @@ -22,9 +22,9 @@ yarn add @tiptap/extension-ordered-list @tiptap/extension-list-item | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | -| ------------ | ------- | ---------------------- | -| ordered_list | โ | Toggle a ordered list. | +| Command | Parameters | Description | +| ----------- | ---------- | ----------------------- | +| orderedList | โ | Toggle an ordered list. | ## Keyboard shortcuts * `Control` `Shift` `9` @@ -33,4 +33,4 @@ yarn add @tiptap/extension-ordered-list @tiptap/extension-list-item [packages/extension-ordered-list/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-ordered-list/) ## Usage - + diff --git a/docs/src/docPages/api/extensions/paragraph.md b/docs/src/docPages/api/nodes/paragraph.md similarity index 70% rename from docs/src/docPages/api/extensions/paragraph.md rename to docs/src/docPages/api/nodes/paragraph.md index feac7701..6a3013d7 100644 --- a/docs/src/docPages/api/extensions/paragraph.md +++ b/docs/src/docPages/api/nodes/paragraph.md @@ -2,15 +2,15 @@ Yes, the schema is very strict. Without this extension you wonโt even be able to use paragraphs in the editor. :::warning Breaking Change from 1.x โ 2.x -Tiptap 1 tried to hide that node from you, but it has always been there. You have to explicitly import it from now on (or use `defaultExtensions()`). +tiptap 1 tried to hide that node from you, but it has always been there. You have to explicitly import it from now on (or use `defaultExtensions()`). ::: ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-paragraph -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-paragraph ``` @@ -20,9 +20,9 @@ yarn add @tiptap/extension-paragraph | class | string | โ | Add a custom class to the rendered HTML tag. | ## Commands -| Command | Options | Description | -| --------- | ------- | -------------------------------------------- | -| paragraph | โ | Transforms all selected nodes to paragraphs. | +| Command | Parameters | Description | +| --------- | ---------- | -------------------------------------------- | +| paragraph | โ | Transforms all selected nodes to paragraphs. | ## Keyboard shortcuts * Windows & Linux: `Control` `Alt` `0` @@ -32,4 +32,4 @@ yarn add @tiptap/extension-paragraph [packages/extension-paragraph/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-paragraph/) ## Usage - + diff --git a/docs/src/docPages/api/nodes/task-item.md b/docs/src/docPages/api/nodes/task-item.md new file mode 100644 index 00000000..be6e772c --- /dev/null +++ b/docs/src/docPages/api/nodes/task-item.md @@ -0,0 +1,28 @@ +# TaskItem + +## Installation +::: warning Use with TaskList +This extension requires the [`TaskList`](/api/nodes/task-list) extension. +::: + +```bash +# With npm +npm install @tiptap/extension-task-list @tiptap/extension-task-item + +# Or: With Yarn +yarn add @tiptap/extension-task-list @tiptap/extension-task-item +``` + +## Settings +| Option | Type | Default | Description | +| ------ | ------ | ------- | -------------------------------------------- | +| class | string | โ | Add a custom class to the rendered HTML tag. | + +## Commands +*None* + +## Source code +[packages/extension-task-item/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-task-item/) + +## Usage + diff --git a/docs/src/docPages/api/nodes/task-list.md b/docs/src/docPages/api/nodes/task-list.md new file mode 100644 index 00000000..82a74d4b --- /dev/null +++ b/docs/src/docPages/api/nodes/task-list.md @@ -0,0 +1,33 @@ +# TaskList +This extension enables you to use task lists in the editor. They are rendered as ``. This implementation doesnโt require any framework, itโs using plain JavaScript only. + +Type [ ] or [x] at the beginning of a new line and it will magically transform to a task list. + +## Installation +::: warning Use with TaskItem +This extension requires the [`TaskItem`](/api/nodes/task-item) extension. +::: + +```bash +# with npm +npm install @tiptap/extension-task-list @tiptap/extension-task-item + +# with Yarn +yarn add @tiptap/extension-task-list @tiptap/extension-task-item +``` + +## Settings +| Option | Type | Default | Description | +| ------ | ------ | ------- | -------------------------------------------- | +| class | string | โ | Add a custom class to the rendered HTML tag. | + +## Commands +| Command | Parameters | Description | +| -------- | ---------- | ------------------- | +| taskList | โ | Toggle a task list. | + +## Source code +[packages/extension-task-list/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-task-list/) + +## Usage + diff --git a/docs/src/docPages/api/extensions/text.md b/docs/src/docPages/api/nodes/text.md similarity index 80% rename from docs/src/docPages/api/extensions/text.md rename to docs/src/docPages/api/nodes/text.md index d6664a5f..c283cc72 100644 --- a/docs/src/docPages/api/extensions/text.md +++ b/docs/src/docPages/api/nodes/text.md @@ -2,15 +2,15 @@ **The `Text` extension is required**, at least if you want to work with text of any kind and thatโs very likely. This extension is a little bit different, it doesnโt even render HTML. Itโs plain text, thatโs all. :::warning Breaking Change from 1.x โ 2.x -Tiptap 1 tried to hide that node from you, but it has always been there. You have to explicitly import it from now on (or use `defaultExtensions()`). +tiptap 1 tried to hide that node from you, but it has always been there. You have to explicitly import it from now on (or use `defaultExtensions()`). ::: ## Installation ```bash -# With npm +# with npm npm install @tiptap/extension-text -# Or: With Yarn +# with Yarn yarn add @tiptap/extension-text ``` @@ -18,4 +18,4 @@ yarn add @tiptap/extension-text [packages/extension-text/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-text/) ## Usage - \ No newline at end of file + diff --git a/docs/src/docPages/api/overview.md b/docs/src/docPages/api/overview.md index f7b813bb..46b551c6 100644 --- a/docs/src/docPages/api/overview.md +++ b/docs/src/docPages/api/overview.md @@ -1,10 +1,13 @@ # Overview - tiptap is a friendly wrapper around [ProseMirror](https://ProseMirror.net). +tiptap is a friendly wrapper around [ProseMirror](https://ProseMirror.net). - ProseMirror works with a strict [Schema](/api/schema), which defines the allowed structure of a document. A document is a tree of headings, paragraphs and others elements, so called nodes. Marks can be attached to a node, e. g. to emphasize part of it. [Commands](/api/commands) change that document programmatically. +### Structure +ProseMirror works with a strict [Schema](/api/schema), which defines the allowed structure of a document. A document is a tree of headings, paragraphs and others elements, so called nodes. Marks can be attached to a node, e. g. to emphasize part of it. [Commands](/api/commands) change that document programmatically. - The document is stored in a state. All changes are applied as transactions to the state. The state has details about the current content, cursor position and selection. You can hook into a few different [events](/api/events), for example to alter transactions before they get applied. +### Content +The document is stored in a state. All changes are applied as transactions to the state. The state has details about the current content, cursor position and selection. You can hook into a few different [events](/api/events), for example to alter transactions before they get applied. - [Extensions](/api/extensions) add functionality like nodes, marks and/or commands to the editor. A huge amount of commands are bound to common [keyboard shortcuts](/api/keyboard-shortcuts). +### Extensions +Extensions add [nodes](/api/nodes), [marks](/api/marks) and/or [functionalities](/api/extensions) to the editor. A lot of those extensions bound their commands to common [keyboard shortcuts](/api/keyboard-shortcuts). -All of those concepts are explained in detail on the following pages. +All those concepts are explained in detail on the following pages. diff --git a/docs/src/docPages/api/schema.md b/docs/src/docPages/api/schema.md index 37a4b3fc..3fe871d4 100644 --- a/docs/src/docPages/api/schema.md +++ b/docs/src/docPages/api/schema.md @@ -1,6 +1,6 @@ # Schema -## Table of Contents +## toc ## Introduction Unlike many other editors, tiptap is based on a [schema](https://prosemirror.net/docs/guide/#schema) that defines how your content is structured. That enables you to define the kind of nodes that may occur in the document, its attributes and the way they can be nested. @@ -10,10 +10,10 @@ This schema is *very* strict. You canโt use any HTML element or attribute that Let me give you one example: If you paste something like `This is important` into tiptap, donโt have any extension that handles `strong` tags registered, youโll only see `This is important` โ without the strong tags. ## How a schema looks like - -The most simple schema for a typical *ProseMirror* editor is looking something like that: +When youโll work with the provided extensions only, you donโt have to care that much about the schema. If youโre building your own extensions, itโs probably helpful to understand how the schema works. Letโs look at the most simple schema for a typical ProseMirror editor: ```js +// the underlying ProseMirror schema { nodes: { document: { @@ -32,58 +32,225 @@ The most simple schema for a typical *ProseMirror* editor is looking something l } ``` -:::warning Out of date -This content is written for tiptap 1 and needs an update. -::: - We register three nodes here. `document`, `paragraph` and `text`. `document` is the root node which allows one or more block nodes as children (`content: 'block+'`). Since `paragraph` is in the group of block nodes (`group: 'block'`) our document can only contain paragraphs. Our paragraphs allow zero or more inline nodes as children (`content: 'inline*'`) so there can only be `text` in it. `parseDOM` defines how a node can be parsed from pasted HTML. `toDOM` defines how it will be rendered in the DOM. -In tiptap we define every node in its own `Extension` class instead. This allows us to split logic per node. Under the hood the schema will be merged together. +In tiptap every node, mark and extension is living in its own file. This allows us to split the logic. Under the hood the whole schema will be merged together: ```js -class Document extends Node { - name = 'document' - topNode = true +// the tiptap schema API +import { createNode } from '@tiptap/core' - schema() { - return { - content: 'block+', - } - } -} +const Document = createNode({ + name: 'document', + topNode: true, + content: 'block+', +}) -class Paragraph extends Node { - name = 'paragraph' +const Paragraph = createNode({ + name: 'paragraph', + group: 'block', + content: 'inline*', + parseHTML() { + return [ + { tag: 'p' }, + ] + }, + renderHTML({ attributes }) { + return ['p', attributes, 0] + }, +}) - schema() { - return { - content: 'inline*', - group: 'block', - parseDOM: [{ tag: 'p' }], - toDOM: () => ['p', 0], - } - } -} - -class Text extends Node { - name = 'text' - - schema() { - return { - group: 'inline', - } - } -} +const Text = createNode({ + name: 'text', + group: 'inline', +}) ``` -## Difference between a Node and a Mark +### Parse HTML -*Nodes* are like blocks of content, for example paragraphs, headings, code blocks, blockquotes and many more. +### Render HTML -*Marks* can apply a different style to specific parts of text inside a *Node*. Thatโs the case for **bold**, *italic* or ~~striked~~ text. [Links](#) are *Marks*, too. +## Nodes and marks + +### Differences +Nodes are like blocks of content, for example paragraphs, headings, code blocks, blockquotes and many more. + +Marks can be applied to specific parts of a node. Thatโs the case for **bold**, *italic* or ~~striked~~ text. [Links](#) are marks, too. + +### The node schema + +#### Content +The content attribute defines exactly what kind of content the node can have. ProseMirror is really strict with that. That means, content which doesnโt fit the schema is thrown away. It expects a name or group as a string. Here are a few examples: + +```js +createNode({ + // must have one ore more blocks + content: 'block+', + + // allows all kinds of 'inline' content (text or hard breaks) + content: 'inline*', + + // must not have anything else than 'text' + content: 'text*', + + // can have one or more paragraphs, or lists (if lists are used) + content: '(paragraph|list?)+', +}) +``` + + +#### Marks +You can define which marks are allowed inside of a node with the `marks` setting of the schema. Add a one or more names or groups of marks, allow all or disallow all marks like this: + +```js +createNode({ + // allows only the 'bold' mark + marks: 'bold', + + // allows only the 'bold' and 'italic' marks + marks: 'bold italic', + + // allows all marks + marks: '_', + + // disallows all marks + marks: '', +}) +``` + +#### Group +Add this node to a group of extensions, which can be referred to in the [content](#content) attribute of the schema. + +```js +createNode({ + // add to 'block' group + group: 'block', + + // add to 'inline' group + group: 'inline', + + // add to 'block' and 'list' group + group: 'block list', +}) +``` + +#### Inline +Nodes can be rendered inline, too. When setting `inline: true` nodes are rendered in line with the text. Thatโs the case for mentions. The result is more like a mark, but with the functionality of a node. One difference is the resulting JSON document. Multiple marks are applied at once, inline nodes would result in a nested structure. + +```js +createNode({ + // renders nodes in line with the text, for example + inline: true, +}) +``` + +#### Atom +Nodes with `atom: true` arenโt directly editable and should be treated as a single unit. Itโs not so likely to use that in a editor context, but this is how it would look like: + +```js +createNode({ + atom: true, +}) +``` + +#### Selectable +> Controls whether nodes of this type can be selected as a node selection. Defaults to true for non-text nodes. + +```js +createNode({ + selectable: true, +}) +``` + +#### Draggable +All nodes can be configured to be draggable (by default they arenโt) with this setting: + +```js +createNode({ + draggable: true, +}) +``` + +#### Code +Users expect code to behave very differently. For all kind of nodes containing code, you can set `code: true` to take this into account. + +```js +createNode({ + code: true, +}) +``` + +#### Defining +> Determines whether this node is considered an important parent node during replace operations (such as paste). Non-defining (the default) nodes get dropped when their entire content is replaced, whereas defining nodes persist and wrap the inserted content. Likewise, in inserted content the defining parents of the content are preserved when possible. Typically, non-default-paragraph textblock types, and possibly list items, are marked as defining. + +```js +createNode({ + defining: true, +}) +``` + +#### Isolating +For nodes that should fence the cursor for regular editing operations like backspacing, for example a TableCell, set `isolating: true`. + +```js +createNode({ + isolating: true, +}) +``` + +### The mark schema +#### Inclusive +If you donโt want the mark to be active when the cursor is at its end, set inclusive to `false`. For example, thatโs how itโs configured for [`Link`](/api/marks/link) marks: + +```js +createMark({ + inclusive: false, +}) +``` + +#### Excludes +By default all nodes can be applied at the same time. With the excludes attribute you can define which marks must not coexist with the mark. For example, the inline code mark excludes any other mark (bold, italic, and all others). + +```js +createMark({ + // must not coexist with the bold mark + excludes: 'bold' + // exclude any other mark + excludes: '_', +}) +``` + +#### Group +Add this mark to a group of extensions, which can be referred to in the content attribute of the schema. + +```js +createMark({ + // add this mark to the 'basic' group + group: 'basic', + // add this mark to the 'basic' and the 'foobar' group + group: 'foobar', +}) +``` + +#### Code +Users expect code to behave very differently. For all kind of marks containing code, you can set `code: true` to take this into account. + +```js +createMark({ + code: true, +}) +``` + +#### Spanning +By default marks can span multiple nodes when rendered as HTML. Set `spanning: false` to indicate that a mark must not span multiple nodes. + +```js +createMark({ + spanning: false, +}) +``` ## Get the underlying ProseMirror schema - There are a few use cases where you need to work with the underlying schema. Youโll need that if youโre using the tiptap collaborative text editing features or if you want to manually render your content as HTML. ### Option 1: With an Editor @@ -123,23 +290,3 @@ const schema = getSchema([ // add more extensions here ]) ``` - -## Generate HTML from ProseMirror JSON - -If you need to render the content on the server side, e. g. for a blog post that was written with tiptap, youโll probably need a way to do just that without an actual editor instance. - -Thatโs what `generategetHTML()` is for. Itโs a utility function that renders HTML without an actual editor instance. - -:::warning Work in progress -Currently, that works only in the browser (client side), but we plan to bring this to Node.js (to use it on the server side). -::: - - - -### Converting JSON<>HTML with PHP - -We needed to do the same thing in PHP at some point, so we published libraries to convert ProseMirror JSON to HTML and vice-versa: - -* [ueberdosis/prosemirror-php](https://github.com/ueberdosis/prosemirror-php) (PHP) -* [ueberdosis/prosemirror-to-html](https://github.com/ueberdosis/prosemirror-to-html) (PHP) -* [ueberdosis/html-to-prosemirror](https://github.com/ueberdosis/html-to-prosemirror) (PHP) diff --git a/docs/src/docPages/examples.md b/docs/src/docPages/examples.md index 555e143e..4b61ec78 100644 --- a/docs/src/docPages/examples.md +++ b/docs/src/docPages/examples.md @@ -1,9 +1,3 @@ # Examples -We put together a few examples to show the capabilities of tiptap, but keep in mind: tiptap is renderless and highly customizable. Everything you see can be changed, modified, combined or remixed. Feel free to copy the code to your project and change it to your liking. - -A few examples show what youโd probably expect from a text editor anyway: [Basic](/examples/basic), [Links](/examples/links), [History](/examples/history), [Read-only](/examples/read-only), [Export HTML or JSON](/examples/export-html-or-json). - -Some examples show how you can improve the user experience: [Markdown shortcuts](/examples/markdown-shortcuts). - -Or they show advanced use cases, like the [Collaborative editing](/examples/collaborative-editing) example, which is basically tiptap in multiplayer mode. +TODO: This page should redirect to [/examples/basic](/examples/basic). diff --git a/docs/src/docPages/examples/basic.md b/docs/src/docPages/examples/basic.md index 91004db3..c33b8158 100644 --- a/docs/src/docPages/examples/basic.md +++ b/docs/src/docPages/examples/basic.md @@ -1,4 +1,3 @@ # Basic -BUG: Headings canโt be transformed to a bullet or ordered list. diff --git a/docs/src/docPages/examples/collaborative-editing.md b/docs/src/docPages/examples/collaborative-editing.md index c085612e..7c0f4566 100644 --- a/docs/src/docPages/examples/collaborative-editing.md +++ b/docs/src/docPages/examples/collaborative-editing.md @@ -1,4 +1,9 @@ # Collaborative editing + +:::premium Requires Premium Extensions +Using this example in production requires a **tiptap pro** license. [Read more](/sponsor) +::: + This example shows how you can use tiptap to let different users collaboratively work on the same text in real-time. It connects client with WebRTC and merges changes to the document (no matter where they come from) with the awesome library [Y.js](https://github.com/yjs/yjs) by Kevin Jahns. Be aware that in a real-world scenario you would probably add a server, which is also able to merge changes with Y.js. diff --git a/docs/src/docPages/examples/formatting.md b/docs/src/docPages/examples/formatting.md new file mode 100644 index 00000000..e6e0f8ce --- /dev/null +++ b/docs/src/docPages/examples/formatting.md @@ -0,0 +1,3 @@ +# Formatting + + diff --git a/docs/src/docPages/examples/read-only.md b/docs/src/docPages/examples/read-only.md index fea24ee5..048465a7 100644 --- a/docs/src/docPages/examples/read-only.md +++ b/docs/src/docPages/examples/read-only.md @@ -1,3 +1,3 @@ # Read-only - + diff --git a/docs/src/docPages/guide/build-custom-extensions.md b/docs/src/docPages/guide/build-custom-extensions.md new file mode 100644 index 00000000..195d4b8d --- /dev/null +++ b/docs/src/docPages/guide/build-custom-extensions.md @@ -0,0 +1,305 @@ +# Build custom extensions + +## toc + +## Introduction +One of the strength of tiptap is itโs extendability. You donโt depend on the provided extensions, itโs intended to extend the editor to your liking. With custom extensions you can add new content types and new functionalities, on top of what already exists or starting from scratch. + +## Option 1: Extend existing extensions +Letโs say you want to change the keyboard shortcuts for the bullet list. You should start by looking at [the source code of the `BulletList` extension](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-bullet-list/index.ts) and find the part you would like to change. In that case, the keyboard shortcut, and just that. + +Every extension has an `extend()` method, which takes an object with everything you want to change or add to it. For the bespoken example, your code could like that: + +```js +// 1. Import the extension +import BulletList from '@tiptap/extension-bullet-list' + +// 2. Overwrite the keyboard shortcuts +const CustomBulletList = BulletList.extend({ + addKeyboardShortcuts() { + return { + 'Mod-l': () => this.editor.bulletList(), + } + }, +}) + +// 3. Add the custom extension to your editor +new Editor({ + extensions: [ + CustomBulletList(), + // โฆ + ] +}) +``` + +The same applies to every aspect of an existing extension, except to the name. Letโs look at all the things that you can change through the extend method. We focus on one aspect in every example, but you can combine all those examples and change multiple aspects in one `extend()` call too. + +### Name +The extension name is used in a whole lot of places and changing it isnโt too easy. If you want to change the name of an existing extension, we would recommended to copy the whole extension and change the name in all occurrences. + +The extension name is also part of the JSON. If you [store your content as JSON](/guide/store-content#option-1-json), you need to change the name there too. + +### Settings +All settings can be configured through the extension anyway, but if you want to change the default settings, for example to provide a library on top of tiptap for other developers, you can do it like that: + +```js +import Heading from '@tiptap/extension-heading' + +const CustomHeading = Heading.extend({ + defaultOptions: { + levels: [1, 2, 3], + }, +}) +``` + +### Schema +tiptap works with a strict schema, which configures how the content can be structured, nested, how it behaves and many more things. You [can change all aspects of the schema](/api/schema) for existing extensions. Letโs walk through a few common use cases. + +The default `Blockquote` extension can wrap other nodes, like headings. If you want to allow nothing but paragraphs in your blockquotes, this is how you could achieve it: + +```js +// Blockquotes must only include paragraphs +import Blockquote from '@tiptap/extension-blockquote' + +const CustomBlockquote = Blockquote.extend({ + content: 'paragraph*', +}) +``` + +The schema even allows to make your nodes draggable, thatโs what the `draggable` option is for, which defaults to `false`. + +```js +// Draggable paragraphs +import Paragraph from '@tiptap/extension-paragraph' + +const CustomParagraph = Paragraph.extend({ + draggable: true, +}) +``` + +Thatโs just two tiny examples, but [the underlying ProseMirror schema](https://prosemirror.net/docs/ref/#model.SchemaSpec) is really powerful. You should definitely read the documentation to understand all the nifty details. + +### Attributes +You can use attributes to store additional information in the content. Letโs say you want to extend the default paragraph extension to enable paragraphs to have different colors: + +```js +const CustomParagraph = Paragraph.extend({ + addAttributes() { + // Return an object with attribute configuration + return { + color: { + default: 'pink', + }, + }, + }, +}) + +// Result: +// Example Text +``` + +Thatโs already enough to tell tiptap about the new attribute, and set `'pink'` as the default value. All attributes will be rendered as a data-attributes by default, and parsed as data-attributes from the content. + +Letโs stick with the color example and assume youโll want to add an inline style to actually color the text. With the `renderHTML` function you can return HTML attributes which will be rendered in the output. + +This examples adds a style HTML attribute based on the value of color: + +```js +const CustomParagraph = Paragraph.extend({ + addAttributes() { + return { + color: { + default: null, + // Take the attribute values + renderHTML: attributes => { + // โฆ and return an object with HTML attributes. + return { + style: `color: ${attributes.color}`, + } + }, + }, + } + }, +}) + +// Result: +// Example Text +``` + +You can also control how the attribute is parsed from the HTML. Letโs say you want to store the color in an attribute called `data-my-fancy-color-attribute`. Legit, right? Anyway, hereโs how you would do that: + +```js +const CustomParagraph = Paragraph.extend({ + addAttributes() { + return { + color: { + default: null, + // Customize the HTML parsing (for example, to load the initial content) + parseHTML: element => { + return { + color: element.getAttribute('data-my-fancy-color-attribute'), + } + }, + // โฆ and customize the HTML rendering. + renderHTML: attributes => { + return { + 'data-my-fancy-color-attribute': atttributes.color, + style: `color: ${attributes.color}`, + } + }, + }, + } + }, +}) + +// Result: +// Example Text +``` + +### Global Attributes +Attributes can be applied to multiple extensions at once. Thatโs useful for text alignment, line height, color, font family, and other styling related attributes. + +Take a closer look at [the full source code](https://github.com/ueberdosis/tiptap-next/tree/main/packages/extension-text-align) of the [`TextAlign`](/api/extensions/text-align) extension to see a more complex example. But here is how it works in a nutshell: + +```js +import { createExtension } from '@tiptap/core' + +const TextAlign = createExtension({ + addGlobalAttributes() { + return [ + { + // Extend the following extensions + types: [ + 'heading', + 'paragraph', + ], + // โฆ with those attributes + attributes: { + textAlign: { + default: 'left', + renderHTML: attributes => ({ + style: `text-align: ${attributes.textAlign}`, + }), + parseHTML: element => ({ + textAlign: element.style.textAlign || 'left', + }), + }, + }, + }, + ] + }, +}) +``` + +### Render HTML +With the `renderHTML` function you can control how an extension is rendered to HTML. We pass an attributes object to it, with all local attributes, global attributes, and configured CSS classes. Here is an example from the `Bold` extension: + +```js +renderHTML({ attributes }) { + return ['strong', attributes, 0] +}, +``` + +The first value in the array should be the name of HTML tag. If the second element is an object, itโs interpreted as a set of attributes. Any elements after that are rendered as children. + +The number zero (representing a hole) is used to indicate where the content should be inserted. Letโs look at the rendering of the `CodeBlock` extension with two nested tags: + +```js +renderHTML({ attributes }) { + return ['pre', ['code', attributes, 0]] +}, +``` + +If you want to add some specific attributes there, import the `mergeAttributes` helper from `@tiptap/core`: + +```js +renderHTML({ attributes }) { + return ['a', mergeAttributes(attributes, { rel: this.options.rel }), 0] +}, +``` + +### Parse HTML +> Associates DOM parser information with this mark (see the corresponding node spec field). The mark field in the rules is implied. + +### Commands + +```js +import Paragraph from '@tiptap/extension-paragraph' + +const CustomParagraph = Paragraph.extend({ + addCommands() { + return { + paragraph: () => ({ commands }) => { + return commands.toggleBlockType('paragraph', 'paragraph') + }, + } + }, +}) +``` + +### Keyboard shortcuts +Most core extensions come with sensible keyboard shortcut defaults. Depending on what you want to build, youโll likely want to change them though. With the `addKeyboardShortcuts()` method you can overwrite the predefined shortcut map: + +```js +// Change the bullet list keyboard shortcut +import BulletList from '@tiptap/extension-bullet-list' + +const CustomBulletList = BulletList.extend({ + addKeyboardShortcuts() { + return { + 'Mod-l': () => this.editor.bulletList(), + } + }, +}) +``` + +### Input rules + +```js +// Use the ~single tilde~ markdown shortcut +import Strike from '@tiptap/extension-strike' +import { markInputRule } from '@tiptap/core' + +const inputRegex = /(?:^|\s)((?:~)((?:[^~]+))(?:~))$/gm + +const CustomStrike = Strike.extend({ + addInputRules() { + return [ + markInputRule(inputRegex, this.type), + ] + }, +}) +``` + +### Paste rules + +```js +// Overwrite the underline regex for pasted text +import Underline from '@tiptap/extension-underline' +import { markPasteRule } from '@tiptap/core' + +const pasteRegex = /(?:^|\s)((?:~)((?:[^~]+))(?:~))$/gm + +const CustomUnderline = Underline.extend({ + addPasteRules() { + return [ + markPasteRule(inputRegex, this.type), + ] + }, +}) +``` + +### Node views + +## Option 2: Start from scratch + +### Read the documentation +Although tiptap tries to hide most of the complexity of ProseMirror, itโs built on top of its APIs and we recommend you to read through the [ProseMirror Guide](https://ProseMirror.net/docs/guide/) for advanced usage. Youโll have a better understanding of how everything works under the hood and get more familiar with many terms and jargon used by tiptap. + +### Have a look at existing extensions + +### Get started + +### Ask questions + +### Share your extension diff --git a/docs/src/docPages/guide/collaborative-editing.md b/docs/src/docPages/guide/collaborative-editing.md index 9bbe3895..98b73209 100644 --- a/docs/src/docPages/guide/collaborative-editing.md +++ b/docs/src/docPages/guide/collaborative-editing.md @@ -1,9 +1,12 @@ # Collaborative editing -## Table of Contents +:::premium Requires Premium Extensions +Using the collaborative editing in production requires a **tiptap pro** license. [Read more](/sponsor) +::: + +## toc ## Introduction - Collaborative editing allows multiple users to work on the same text document in real-time. Itโs a complex topic that you should be aware before adding it blindly to you app. No worries though, here is everything you need to know. ## Configure collaboration diff --git a/docs/src/docPages/guide/configuration.md b/docs/src/docPages/guide/configuration.md index 0b9539e7..ee58cfc9 100644 --- a/docs/src/docPages/guide/configuration.md +++ b/docs/src/docPages/guide/configuration.md @@ -1,6 +1,6 @@ # Configuration -## Table of Contents +## toc ## Introduction tiptap is all about customization. There are a ton of options to configure the behavior and functionality of the editor. Most of those settings can be set before creating the Editor. Give tiptap a JSON with all the settings you would like to overwrite. diff --git a/docs/src/docPages/guide/build-your-editor.md b/docs/src/docPages/guide/create-your-editor.md similarity index 95% rename from docs/src/docPages/guide/build-your-editor.md rename to docs/src/docPages/guide/create-your-editor.md index 0d047478..1977a0ee 100644 --- a/docs/src/docPages/guide/build-your-editor.md +++ b/docs/src/docPages/guide/create-your-editor.md @@ -1,6 +1,6 @@ # Build your editor -## Table of Contents +## toc ## Introduction In its simplest version tiptap comes very raw. There is no menu, no buttons, no styling. Thatโs intended. See tiptap as your building blocks to build exactly the editor you would like to have. @@ -18,7 +18,7 @@ You might wonder what features tiptap supports out of the box. In the above exam * [List of available commands](/api/commands) ## Configure extensions -You are free to choose which parts of tiptap you want to use. Tiptap has support for different nodes (paragraphs, blockquotes, tables and many more) and different marks (bold, italic, links). If you want to explicitly configure what kind of nodes and marks are allowed and which are not allowed, you can configure those. +You are free to choose which parts of tiptap you want to use. tiptap has support for different nodes (paragraphs, blockquotes, tables and many more) and different marks (bold, italic, links). If you want to explicitly configure what kind of nodes and marks are allowed and which are not allowed, you can configure those. Note that `Document`, `Paragraph` and `Text` are required. Otherwise you wonโt be able to add any plain text. diff --git a/docs/src/docPages/guide/custom-extensions.md b/docs/src/docPages/guide/custom-extensions.md deleted file mode 100644 index 0e6d430a..00000000 --- a/docs/src/docPages/guide/custom-extensions.md +++ /dev/null @@ -1,142 +0,0 @@ -# Custom Extensions - -## Table of Contents - -## Introduction -One of the strength of tiptap is itโs extendability. You donโt depend on the provided extensions, itโs intended to extend the editor to your liking. With custom extensions you can add new content types and new functionalities, on top of what already exists or on top of that. - -## Option 1: Change defaults - -Letโs say you want to change the keyboard shortcuts for the bullet list. You should start by looking at [the source code of the `BulletList` extension](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-bullet-list/index.ts) and find the default youโd like to change. In that case, the keyboard shortcut, and just that. - -```js -// 1. Import the extension -import BulletList from '@tiptap/extension-bullet-list' - -// 2. Overwrite the keyboard shortcuts -const CustomBulletList = BulletList() - .keys(({ editor }) => ({ - 'Mod-l': () => editor.bulletList(), - })) - .create() // Donโt forget that! - -// 3. Add the custom extension to your editor -new Editor({ - extensions: [ - CustomBulletList(), - // โฆ - ] -}) -``` - -You can overwrite every aspect of an existing extension: - -### Name - -```js -import Document from '@tiptap/extension-document' - -const CustomDocument = Document() - .name('doc') - .create() -``` - -### Settings - -```js -import Heading from '@tiptap/extension-heading' - -const CustomHeading = Heading() - .defaults({ - levels: [1, 2, 3], - class: 'my-custom-heading', - }) - .create() -``` - -### Schema - -```js -import Code from '@tiptap/extension-code' - -const CustomCode = Code() - .schema(() => ({ - excludes: '_', - parseDOM: [ - { tag: 'code' }, - ], - toDOM: () => ['code', { 'data-attribute': 'foobar' }, 0], - })) - .create() -``` - -### Commands - -```js -import Paragraph from '@tiptap/extension-paragraph' - -const CustomParagraph = Paragraph() - .commands(() => ({ - paragraph: () => ({ commands }) => { - return commands.toggleBlockType(name, 'paragraph') - }, - })) - .create() -``` - -### Keyboard shortcuts - -```js -import BulletList from '@tiptap/extension-bullet-list' - -const CustomBulletList = BulletList() - .keys(({ editor }) => ({ - 'Mod-l': () => editor.bulletList(), - })) - .create() -``` - -### Input rules - -```js -import Strike from '@tiptap/extension-strike' -import { markInputRule } from '@tiptap/core' - -const inputRegex = /(?:^|\s)((?:~)((?:[^~]+))(?:~))$/gm - -const CustomStrike = Strike() - .inputRules(({ type }) => [ - markInputRule(inputRegex, type), - ]) - .create() -``` - -### Paste rules - -```js -import Underline from '@tiptap/extension-underline' -import { markPasteRule } from '@tiptap/core' - -const pasteRegex = /(?:^|\s)((?:~)((?:[^~]+))(?:~))$/gm - -const CustomUnderline = Underline() - .pasteRules(({ type }) => [ - markPasteRule(pasteRegex, type), - ]) - .create() -``` - -## Option 2: Extend existing extensions - -## Option 3: Start from scratch - -### 1. Read the documentation -Although tiptap tries to hide most of the complexity of ProseMirror, itโs built on top of its APIs and we recommend you to read through the [ProseMirror Guide](https://ProseMirror.net/docs/guide/) for advanced usage. Youโll have a better understanding of how everything works under the hood and get more familiar with many terms and jargon used by tiptap. - -### 2. Have a look at existing extensions - -### 3. Get started - -### 4. Ask questions - -### 5. Publish a community extension diff --git a/docs/src/docPages/guide/custom-styling.md b/docs/src/docPages/guide/custom-styling.md index b3c53c02..5fdf2c94 100644 --- a/docs/src/docPages/guide/custom-styling.md +++ b/docs/src/docPages/guide/custom-styling.md @@ -1,9 +1,9 @@ # Custom styling -## Table of Contents +## toc ## Introduction -Tiptap is renderless, that doesnโt mean there is no styling provided. You can decided how your editor should look like. +tiptap is renderless, that doesnโt mean there is no styling provided. You can decided how your editor should look like. ## Option 1: Style the plain HTML The whole editor is rendered inside of a container with the class `.ProseMirror`. You can use that to scope your styling to the editor content: @@ -28,15 +28,21 @@ p { ## Option 2: Add custom classes Most extensions have a `class` option, which you can use to add a custom CSS class to the HTML tag. +Most extensions allow you to add attributes to the rendered HTML through the `attributes` configuration. You can use that to add a custom class (or any other attribute): + ```js new Editor({ extensions: [ Document(), Paragraph({ - class: 'my-custom-paragraph', + attributes: { + class: 'my-custom-paragraph', + }, }), Heading({ - class: 'my-custom-heading', + attributes: { + class: 'my-custom-heading', + }, }), Text(), ] @@ -50,17 +56,21 @@ The rendered HTML will look like that: Wow, thatโs really custom. ``` +If there are already classes defined by the extensions, your classes will be added. + ## Option 3: Customize the HTML You can even customize the markup for every extension. This will make a custom bold extension that doesnโt render a `` tag, but a `` tag: ```js import Bold from '@tiptap/extension-bold' -const CustomBold = Bold - .schema(() => ({ - toDOM: () => ['b', 0], - })) - .create() +const CustomBold = Bold.extend({ + renderHTML({ attributes }) { + // Original: + // return ['strong', attributes, 0] + return ['b', attributes, 0] + }, +}) new Editor({ extensions: [ @@ -70,4 +80,4 @@ new Editor({ }) ``` -You should put your custom extensions in separate files though, but I think youโve got the idea. +You should put your custom extensions in separate files though, but I think you got the idea. diff --git a/docs/src/docPages/guide/getting-started.md b/docs/src/docPages/guide/getting-started.md index fbfac4ad..2ebbd29f 100644 --- a/docs/src/docPages/guide/getting-started.md +++ b/docs/src/docPages/guide/getting-started.md @@ -1,6 +1,6 @@ # Getting started -## Table of Contents +## toc ## Introduction tiptap is framework-agnostic and works with Vue.js and React. It even works with plain JavaScript, if thatโs your thing. To keep everything as small as possible, we put the code to use tiptap with those frameworks in different packages. @@ -19,7 +19,7 @@ yarn add @tiptap/vue @tiptap/vue-starter-kit The `@tiptap/vue-starter-kit` includes a few basics you would probably need anyway. Cool, you have got everything in place to set up tiptap! ๐ ## 2. Create a new component -Create a new Vue component (you can call it ``) and add the following content. This is the fastest way to get tiptap up and running with Vue.js. It will give you a very basic version of tiptap, without any buttons. No worries, you will be able to add more functionality soon. +Create a new Vue component (you can call it ``) and add the following content. This is the fastest way to get tiptap up and running with Vue.js. It will give you a very basic version of tiptap, without any buttons. No worries, you will be able to add more functionality soon. diff --git a/docs/src/docPages/guide/store-content.md b/docs/src/docPages/guide/store-content.md index d69d267f..4380a40a 100644 --- a/docs/src/docPages/guide/store-content.md +++ b/docs/src/docPages/guide/store-content.md @@ -1,6 +1,6 @@ # Store content -## Table of Contents +## toc ## Introduction You can store your content as a JSON object or as a good old HTML string. Both work fine. And of course, you can pass both formats to the editor to restore your content. @@ -85,6 +85,17 @@ Unfortunately, **tiptap doesnโt support Markdown as an input or output format* You should really consider to work with HTML or JSON to store your content, they are perfectly fine for most use cases. -If you still think you need Markdown, [Nextcloud Text](https://github.com/nextcloud/text) uses tiptap to work with Markdown. Their code is open source, so maybe you can learn from them. +If you still think you need Markdown, [Nextcloud Text](https://github.com/nextcloud/text) uses tiptap 1 to work with Markdown. Their code is open source, so maybe you can learn from them. That said, tiptap **does** support Markdown shortcuts to format your content. Try typing `**two asterisks**` to make your text bold for example. + +## Generate HTML from ProseMirror JSON +If you need to render the content on the server side, for example to render a blog post which was written with tiptap, youโll probably need a way to do just that without an actual editor instance. + +Thatโs what `generateHTML()` is for. Itโs a utility function that renders HTML without an actual editor instance. + +:::info Browser-only rendering +Import a lightweight implementation from `@tiptap/core` if youโre using the function in a browser context only. +::: + + diff --git a/docs/src/docPages/introduction.md b/docs/src/docPages/introduction.md index 5c6afa8b..b8a3280b 100644 --- a/docs/src/docPages/introduction.md +++ b/docs/src/docPages/introduction.md @@ -1,15 +1,17 @@ -:::warning Donโt try this at home -This version of tiptap is not production-ready, donโt use it anywhere. +:::error Donโt try this at home +Nothing here is production-ready, donโt use it anywhere. ::: # Introduction -[](https://www.npmjs.com/package/@tiptap/core) -[](https://npmcharts.com/compare/@tiptap/core?minimal=true) -[](https://www.npmjs.com/package/@tiptap/core) + + + + + [](https://github.com/sponsors/ueberdosis) -tiptap is a renderless wrapper around [ProseMirror](https://ProseMirror.net) โ a toolkit for building rich-text editors that is already in use at many well-known companies such as *New York Times*, *The Guardian* or *Atlassian*. +tiptap is a renderless wrapper around [ProseMirror](https://ProseMirror.net) โ a toolkit for building rich-text WYSIWYG editors, which is already in use at many well-known companies such as *New York Times*, *The Guardian* or *Atlassian*. Although tiptap tries to hide most of the complexity of ProseMirror, itโs built on top of its APIs and we recommend you to read through the [ProseMirror Guide](https://ProseMirror.net/docs/guide/) for advanced usage. Youโll have a better understanding of how everything works under the hood and get more familiar with many terms and jargon used by tiptap. @@ -17,9 +19,9 @@ Although tiptap tries to hide most of the complexity of ProseMirror, itโs buil **Renderless.** We donโt tell you what a menu should look like or where it should be rendered in the DOM. Thatโs why tiptap is renderless and comes without any CSS. You are in full control over markup and styling. -**Framework-agnostic.** We donโt care what framework you use. Tiptap is ready to be used with plain JavaScript or Vue.js. That makes it even possible to write a renderer for React, Svelte and others. +**Framework-agnostic.** We donโt care what framework you use. tiptap is ready to be used with plain JavaScript or Vue.js. That makes it even possible to write a renderer for React, Svelte and others. -**TypeScript.** Tiptap 2 is written in TypeScript. That gives you a nice autocomplete for the API (if your IDE supports that), helps to find bugs early and makes it possible to generate [a complete API documentation](#) on top of the extensive human written documentation. +**TypeScript.** tiptap 2 is written in TypeScript. That gives you a nice autocomplete for the API (if your IDE supports that), helps to find bugs early and makes it possible to generate [a complete API documentation](#) on top of the extensive human written documentation. ## Who uses tiptap? - [GitLab](https://gitlab.com) @@ -29,3 +31,6 @@ Although tiptap tries to hide most of the complexity of ProseMirror, itโs buil - [Directus CMS](https://directus.io) - [Nextcloud](https://apps.nextcloud.com/apps/text) - [and many more โ](https://github.com/ueberdosis/tiptap/network/dependents?package_id=UGFja2FnZS0xMzE5OTg0ODc%3D) + +## License +tiptap is licensed under MIT, so youโre free to whatever you want. Anyway, we kindly ask you to [become a sponsor](https://github.com/sponsors/ueberdosis) on GitHub to fund the development, maintenance and support of tiptap. diff --git a/docs/src/docPages/open.md b/docs/src/docPages/open.md new file mode 100644 index 00000000..b5d7cae3 --- /dev/null +++ b/docs/src/docPages/open.md @@ -0,0 +1,26 @@ +# Monthly reports + +## October 2020 +* Writing extensions for tiptap 2 +* 25 sponsors, $423/month +* 102 hours, $7,140 development costs (at $70/hour) +* Sponsored @calebporzio with $99 +* **Total -$6,816** + +## September 2020 +* Developing the API of tiptap 2, writing the documentation +* 125 hours, $8,750 development costs (at $70/hour) +* Sponsored @calebporzio with $99 +* **Total -$8,849** + +## August 2020 +* Setting up tiptap 2 +* 56 hours, $3,920 development costs (at $70/hour) +* Sponsored @calebporzio with $99 +* **Total -$4,019** + +## All time + +* **Total -$19.684** + + diff --git a/docs/src/docPages/overview/contributing.md b/docs/src/docPages/overview/contributing.md index 1f024d29..f28771ea 100644 --- a/docs/src/docPages/overview/contributing.md +++ b/docs/src/docPages/overview/contributing.md @@ -1,13 +1,14 @@ # Contributing -## Table of Contents +## toc ## Introduction -Tiptap would be nothing without its lively community. Contributions have always been and will always be welcome. Here is a little bit you should know, before you send your contribution: +tiptap would be nothing without its lively community. Contributions have always been and will always be welcome. Here is a little bit you should know, before you send your contribution: ## Welcome examples -* Improve the documentation, e. g. fix a typo, add a section -* New features for existing extensions, e. g. a new option +* Failing regression tests as bug reports +* Documentation improvements, e. g. fix a typo, add a section +* New features for existing extensions, e. g. a new configureable option * New extensions, which donโt require changes to the core or other core extensions * Well explained, non-breaking changes to the core diff --git a/docs/src/docPages/overview/installation.md b/docs/src/docPages/overview/installation.md index 57fc588c..2324a3f8 100644 --- a/docs/src/docPages/overview/installation.md +++ b/docs/src/docPages/overview/installation.md @@ -1,6 +1,6 @@ # Installation -## Table of Contents +## toc ## Introduction Youโre free to use tiptap with the framework of your choice. Depending on what you want to do, there are a few different ways to install tiptap in your project. Choose the way that fits your workflow. @@ -9,10 +9,10 @@ Youโre free to use tiptap with the framework of your choice. Depending on what Use tiptap with vanilla JavaScript for a very lightweight and raw experience. If you feel like it, you can even use it to connect tiptap with other frameworks not mentioned here. ```bash -# With npm +# with npm npm install @tiptap/core @tiptap/starter-kit -# Or: With Yarn +# with Yarn yarn add @tiptap/core @tiptap/starter-kit ``` @@ -33,10 +33,10 @@ new Editor({ To use tiptap with Vue.js (and tools that are based on Vue.js) install tiptap together with the Vue.js adapter in your project. We even prepared a Vue.js starter kit, which gives you a good headstart. ```bash -# With npm +# with npm npm install @tiptap/core @tiptap/vue @tiptap/vue-starter-kit -# Or: With Yarn +# with Yarn yarn add @tiptap/core @tiptap/vue @tiptap/vue-starter-kit ``` @@ -44,9 +44,10 @@ Create a new component and add the following content to get a basic version of t -::: warning Nuxt.js -If you use Nuxt.js, note that tiptap needs to run in the client, not on the server. Itโs required to wrap the editor in a `` tag. -::: +### Nuxt.js +Note that tiptap needs to run in the client, not on the server. Itโs required to wrap the editor in a `` tag. + +[Read more](https://nuxtjs.org/api/components-client-only)
1.
[ ]
[x]
Wow, thatโs really custom.