Merge branch 'main' of https://github.com/ueberdosis/tiptap-next into feature/replace-classes
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
<component :is="mainFile" v-if="mode === 'vue'" />
|
||||
<react-renderer :component="mainFile" v-if="mode === 'react'" />
|
||||
</div>
|
||||
<div class="demo__source">
|
||||
<div class="demo__source" v-if="!hideSourceCode">
|
||||
<div class="demo__tabs" v-if="showFileNames">
|
||||
<button
|
||||
class="demo__tab"
|
||||
@@ -62,6 +62,11 @@ export default {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
|
||||
hideSourceCode: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
&__preview {
|
||||
padding: 1.5rem;
|
||||
border: 1px solid rgba($colorBlack, 0.1);
|
||||
border-bottom-width: 0;
|
||||
border-top-left-radius: inherit;
|
||||
border-top-right-radius: inherit;
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
|
||||
&__source {
|
||||
@@ -53,11 +53,14 @@
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
padding: 1rem 1.5rem;
|
||||
padding: 0.5rem 1.5rem;
|
||||
border: 1px solid rgba($colorWhite, 0.1);
|
||||
border: 1px solid rgba($colorBlack, 0.1);
|
||||
border-top-width: 0;
|
||||
border-bottom-left-radius: inherit;
|
||||
border-bottom-right-radius: inherit;
|
||||
border-top-width: 0;
|
||||
background-color: rgba($colorBlack, 0.9);
|
||||
color: $colorWhite;
|
||||
}
|
||||
|
||||
&__link {
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
context('basic', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/examples/basic')
|
||||
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
const { editor } = window
|
||||
editor.setContent('<p>foo</p>')
|
||||
})
|
||||
})
|
||||
|
||||
describe('export', () => {
|
||||
@@ -41,7 +46,7 @@ context('basic', () => {
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
const { editor } = window
|
||||
|
||||
editor.insertText('bar')
|
||||
editor.focus(1).insertText('bar')
|
||||
cy.get('.ProseMirror p:first').should('contain', 'barfoo')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,5 +1,48 @@
|
||||
<template>
|
||||
<editor-content :editor="editor" />
|
||||
<div>
|
||||
<div v-if="editor">
|
||||
<button @click="editor.focus().removeMarks()">
|
||||
clear format
|
||||
</button>
|
||||
<button @click="editor.focus().bold()" :class="{ 'is-active': editor.isActive('bold') }">
|
||||
bold
|
||||
</button>
|
||||
<button @click="editor.focus().italic()" :class="{ 'is-active': editor.isActive('italic') }">
|
||||
italic
|
||||
</button>
|
||||
<button @click="editor.focus().code()" :class="{ 'is-active': editor.isActive('code') }">
|
||||
code
|
||||
</button>
|
||||
<button @click="editor.focus().codeBlock()" :class="{ 'is-active': editor.isActive('code_block') }">
|
||||
code_block
|
||||
</button>
|
||||
<button @click="editor.focus().heading({ level: 1 })" :class="{ 'is-active': editor.isActive('heading', { level: 1 }) }">
|
||||
h1
|
||||
</button>
|
||||
<button @click="editor.focus().heading({ level: 2 })" :class="{ 'is-active': editor.isActive('heading', { level: 2 }) }">
|
||||
h2
|
||||
</button>
|
||||
<button @click="editor.focus().heading({ level: 3 })" :class="{ 'is-active': editor.isActive('heading', { level: 3 }) }">
|
||||
h3
|
||||
</button>
|
||||
<button @click="editor.focus().heading({ level: 4 })" :class="{ 'is-active': editor.isActive('heading', { level: 4 }) }">
|
||||
h4
|
||||
</button>
|
||||
<button @click="editor.focus().heading({ level: 5 })" :class="{ 'is-active': editor.isActive('heading', { level: 5 }) }">
|
||||
h5
|
||||
</button>
|
||||
<button @click="editor.focus().heading({ level: 6 })" :class="{ 'is-active': editor.isActive('heading', { level: 6 }) }">
|
||||
h6
|
||||
</button>
|
||||
<button @click="editor.focus().undo()">
|
||||
undo
|
||||
</button>
|
||||
<button @click="editor.focus().redo()">
|
||||
redo
|
||||
</button>
|
||||
</div>
|
||||
<editor-content :editor="editor" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -18,7 +61,10 @@ export default {
|
||||
|
||||
mounted() {
|
||||
this.editor = new Editor({
|
||||
content: '<p>foo</p>',
|
||||
content: `
|
||||
<h2>Hey there!</h2>
|
||||
<p>This editor is based on Prosemirror, fully extendable and renderless. You can easily add custom nodes as Vue components.</p>
|
||||
`,
|
||||
extensions: defaultExtensions(),
|
||||
})
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
.this-is-a-test {
|
||||
color: black;
|
||||
}
|
||||
36
docs/src/demos/Examples/History/index.spec.js
Normal file
36
docs/src/demos/Examples/History/index.spec.js
Normal file
@@ -0,0 +1,36 @@
|
||||
context('history', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/examples/history')
|
||||
})
|
||||
|
||||
describe('undo', () => {
|
||||
it('should not have a mistake', () => {
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
const { editor } = window
|
||||
const html = editor.html()
|
||||
|
||||
cy.get('.ProseMirror h2:first').should('not.contain', 'Mistake')
|
||||
})
|
||||
})
|
||||
|
||||
it('should have a mistake', () => {
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
const { editor } = window
|
||||
const html = editor.html()
|
||||
|
||||
editor.insertText('Mistake')
|
||||
cy.get('.ProseMirror h2:first').should('contain', 'Mistake')
|
||||
})
|
||||
})
|
||||
|
||||
it('the mistake should be removed again', () => {
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
const { editor } = window
|
||||
const html = editor.html()
|
||||
|
||||
editor.undo()
|
||||
cy.get('.ProseMirror h2:first').should('not.contain', 'Mistake')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
49
docs/src/demos/Examples/History/index.vue
Normal file
49
docs/src/demos/Examples/History/index.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="editor">
|
||||
<button @click="editor.focus().undo()">
|
||||
undo
|
||||
</button>
|
||||
<button @click="editor.focus().redo()">
|
||||
redo
|
||||
</button>
|
||||
</div>
|
||||
<editor-content :editor="editor" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Editor, EditorContent, defaultExtensions } from '@tiptap/vue-starter-kit'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EditorContent,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
editor: null,
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.editor = new Editor({
|
||||
content: `
|
||||
<h2>
|
||||
History
|
||||
</h2>
|
||||
<p>
|
||||
Try to change some content here. With the <code>History</code> extension you are able to undo and redo your changes. You can also use keyboard shortcuts for this (<code>Control/Command + Z</code> and <code>Control/Command + Shift + Z</code>).
|
||||
</p>
|
||||
`,
|
||||
extensions: defaultExtensions(),
|
||||
})
|
||||
|
||||
window.editor = this.editor
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
this.editor.destroy()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
126
docs/src/demos/Examples/MarkdownShortcuts/index.spec.js
Normal file
126
docs/src/demos/Examples/MarkdownShortcuts/index.spec.js
Normal file
@@ -0,0 +1,126 @@
|
||||
context('markdown-shortcuts', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/examples/markdown-shortcuts')
|
||||
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
const { editor } = window
|
||||
editor.setContent('<p></p>')
|
||||
})
|
||||
})
|
||||
|
||||
describe('headlines', () => {
|
||||
it('should make a h1', () => {
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
cy.get('.ProseMirror')
|
||||
.type('# Headline', {force: true})
|
||||
.contains('h1', 'Headline')
|
||||
})
|
||||
})
|
||||
|
||||
it('should make a h2', () => {
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
cy.get('.ProseMirror')
|
||||
.type('## Headline', {force: true})
|
||||
.contains('h2', 'Headline')
|
||||
})
|
||||
})
|
||||
|
||||
it('should make a h3', () => {
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
cy.get('.ProseMirror')
|
||||
.type('### Headline', {force: true})
|
||||
.contains('h3', 'Headline')
|
||||
})
|
||||
})
|
||||
|
||||
it('should make a h4', () => {
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
cy.get('.ProseMirror')
|
||||
.type('#### Headline', {force: true})
|
||||
.contains('h4', 'Headline')
|
||||
})
|
||||
})
|
||||
|
||||
it('should make a h5', () => {
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
cy.get('.ProseMirror')
|
||||
.type('##### Headline', {force: true})
|
||||
.contains('h5', 'Headline')
|
||||
})
|
||||
})
|
||||
|
||||
it('should make a h6', () => {
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
cy.get('.ProseMirror')
|
||||
.type('###### Headline', {force: true})
|
||||
.contains('h6', 'Headline')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('code', () => {
|
||||
it('should create inline code', () => {
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
cy.get('.ProseMirror')
|
||||
.type('`$foobar`', {force: true})
|
||||
.contains('code', '$foobar')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('code block', () => {
|
||||
it('should create a code block without language', () => {
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
cy.get('.ProseMirror')
|
||||
.type('``` {enter}const foo = bar{enter}```', {force: true})
|
||||
.contains('pre', 'const foo = bar')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('bullet list', () => {
|
||||
it('should create a bullet list from asteriks', () => {
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
cy.get('.ProseMirror')
|
||||
.type('* foobar', {force: true})
|
||||
.contains('ul', 'foobar')
|
||||
})
|
||||
})
|
||||
|
||||
it('should create a bullet list from dashes', () => {
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
cy.get('.ProseMirror')
|
||||
.type('- foobar', {force: true})
|
||||
.contains('ul', 'foobar')
|
||||
})
|
||||
})
|
||||
|
||||
it('should create a bullet list from pluses', () => {
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
cy.get('.ProseMirror')
|
||||
.type('+ foobar', {force: true})
|
||||
.contains('ul', 'foobar')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('ordered list', () => {
|
||||
it('should create a ordered list', () => {
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
cy.get('.ProseMirror')
|
||||
.type('1. foobar', {force: true})
|
||||
.contains('ol', 'foobar')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('blockquote', () => {
|
||||
it('should create a blockquote', () => {
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
cy.get('.ProseMirror')
|
||||
.type('> foobar', {force: true})
|
||||
.contains('blockquote', 'foobar')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
44
docs/src/demos/Examples/MarkdownShortcuts/index.vue
Normal file
44
docs/src/demos/Examples/MarkdownShortcuts/index.vue
Normal file
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<div>
|
||||
<editor-content :editor="editor" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Editor, EditorContent, defaultExtensions } from '@tiptap/vue-starter-kit'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EditorContent,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
editor: null,
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.editor = new Editor({
|
||||
content: `
|
||||
<p>
|
||||
Start a new line and type <code>#</code> followed by a space to get a headline. Try <code>#</code>, <code>##</code>, <code>###</code>, <code>####</code>, <code>#####</code>, <code>######</code> for different levels.
|
||||
</p>
|
||||
<p>
|
||||
Those conventions are called <strong>input rules</strong> in tiptap. Some of those shortcuts are enabled by default. Try <code>></code> for blockquotes, <code>*</code>, <code>-</code> or <code>+</code> for bullet lists, <code>\`foobar\`</code> to highlight code.
|
||||
</p>
|
||||
<p>
|
||||
You can add your own input rules through adding the <code>inputRules()</code> method in your nodes and marks.
|
||||
</p>
|
||||
`,
|
||||
extensions: defaultExtensions(),
|
||||
})
|
||||
|
||||
window.editor = this.editor
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
this.editor.destroy()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
5
docs/src/demos/Examples/Simple/index.spec.js
Normal file
5
docs/src/demos/Examples/Simple/index.spec.js
Normal file
@@ -0,0 +1,5 @@
|
||||
context('simple', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/examples/simple')
|
||||
})
|
||||
})
|
||||
40
docs/src/demos/Examples/Simple/index.vue
Normal file
40
docs/src/demos/Examples/Simple/index.vue
Normal file
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<editor-content :editor="editor" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Editor, EditorContent } from '@tiptap/vue-starter-kit'
|
||||
import Document from '@tiptap/extension-document'
|
||||
import Paragraph from '@tiptap/extension-paragraph'
|
||||
import Text from '@tiptap/extension-text'
|
||||
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EditorContent,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
editor: null,
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.editor = new Editor({
|
||||
content: '<p>This is a radically reduced version of tiptap for minimalisits. It has only support for a document, paragraphs and text, that’s it.</p>',
|
||||
extensions: [
|
||||
new Document(),
|
||||
new Paragraph(),
|
||||
new Text(),
|
||||
],
|
||||
})
|
||||
|
||||
window.editor = this.editor
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
this.editor.destroy()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
37
docs/src/demos/Extensions/Bold/index.spec.js
Normal file
37
docs/src/demos/Extensions/Bold/index.spec.js
Normal file
@@ -0,0 +1,37 @@
|
||||
context('/api/extensions/bold', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/api/extensions/bold')
|
||||
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
const { editor } = window
|
||||
editor.setContent('<p>Example Text</p>')
|
||||
editor.focus().selectAll()
|
||||
})
|
||||
})
|
||||
|
||||
describe('bold', () => {
|
||||
it('the button should make the selected text bold', () => {
|
||||
cy.get('.demo__preview button:first').click({ force: true })
|
||||
cy.get('.ProseMirror').contains('strong', 'Example Text')
|
||||
})
|
||||
|
||||
it('the button should toggle the selected text bold', () => {
|
||||
cy.get('.demo__preview button:first').dblclick({ force: true })
|
||||
cy.get('.ProseMirror strong').should('not.exist')
|
||||
})
|
||||
|
||||
it('the keyboard shortcut should make the selected text bold', () => {
|
||||
const shortcut = Cypress.platform === 'darwin' ? '{meta}b' : '{ctrl}b'
|
||||
|
||||
cy.get('.ProseMirror').type(shortcut, {force: true})
|
||||
cy.get('.ProseMirror').contains('strong', 'Example Text')
|
||||
})
|
||||
|
||||
it('the keyboard shortcut should toggle the selected text bold', () => {
|
||||
const shortcut = Cypress.platform === 'darwin' ? '{meta}b' : '{ctrl}b'
|
||||
|
||||
cy.get('.ProseMirror').type(shortcut, {force: true}).type(shortcut, {force: true})
|
||||
cy.get('.ProseMirror strong').should('not.exist')
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -45,6 +45,8 @@ export default {
|
||||
<p style="font-weight: 999">Up to font weight 999!!!</p>
|
||||
`,
|
||||
})
|
||||
|
||||
window.editor = this.editor
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
|
||||
23
docs/src/demos/Extensions/Code/index.spec.js
Normal file
23
docs/src/demos/Extensions/Code/index.spec.js
Normal file
@@ -0,0 +1,23 @@
|
||||
context('/api/extensions/code', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/api/extensions/code')
|
||||
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
const { editor } = window
|
||||
editor.setContent('<p>Example Text</p>')
|
||||
editor.focus().selectAll()
|
||||
})
|
||||
})
|
||||
|
||||
describe('code', () => {
|
||||
it('should mark the selected text as inline code', () => {
|
||||
cy.get('.demo__preview button:first').click({ force: true })
|
||||
cy.get('.ProseMirror').contains('code', 'Example Text')
|
||||
})
|
||||
|
||||
it('should toggle the selected text as inline code', () => {
|
||||
cy.get('.demo__preview button:first').dblclick({ force: true })
|
||||
cy.get('.ProseMirror code').should('not.exist')
|
||||
})
|
||||
})
|
||||
})
|
||||
51
docs/src/demos/Extensions/Code/index.vue
Normal file
51
docs/src/demos/Extensions/Code/index.vue
Normal file
@@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<div v-if="editor">
|
||||
<button @click="editor.focus().code()" :class="{ 'is-active': editor.isActive('code') }">
|
||||
code
|
||||
</button>
|
||||
|
||||
<editor-content :editor="editor" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Editor } from '@tiptap/core'
|
||||
import { EditorContent } from '@tiptap/vue'
|
||||
import Document from '@tiptap/extension-document'
|
||||
import Paragraph from '@tiptap/extension-paragraph'
|
||||
import Text from '@tiptap/extension-text'
|
||||
import Code from '@tiptap/extension-code'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EditorContent,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
editor: null,
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.editor = new Editor({
|
||||
extensions: [
|
||||
new Document(),
|
||||
new Paragraph(),
|
||||
new Text(),
|
||||
new Code(),
|
||||
],
|
||||
content: `
|
||||
<p>This isn’t code.</p>
|
||||
<p><code>This is code.</code></p>
|
||||
`,
|
||||
})
|
||||
|
||||
window.editor = this.editor
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
this.editor.destroy()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
52
docs/src/demos/Extensions/History/index.spec.js
Normal file
52
docs/src/demos/Extensions/History/index.spec.js
Normal file
@@ -0,0 +1,52 @@
|
||||
context('/api/extensions/history', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/api/extensions/history')
|
||||
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
const { editor } = window
|
||||
editor.setContent('<p>Mistake</p>')
|
||||
})
|
||||
})
|
||||
|
||||
describe('undo', () => {
|
||||
it('should make the last change undone', () => {
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
cy.get('.ProseMirror').should('contain', 'Mistake')
|
||||
|
||||
cy.get('.demo__preview button:first').click({ force: true })
|
||||
cy.get('.ProseMirror').should('not.contain', 'Mistake')
|
||||
})
|
||||
})
|
||||
|
||||
it('the keyboard shortcut should make the last change undone', () => {
|
||||
const shortcut = Cypress.platform === 'darwin' ? '{meta}z' : '{ctrl}z'
|
||||
|
||||
cy.get('.ProseMirror').type(shortcut, {force: true})
|
||||
cy.get('.ProseMirror').should('not.contain', 'Mistake')
|
||||
})
|
||||
})
|
||||
|
||||
describe('redo', () => {
|
||||
it('should apply the last undone change again', () => {
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
cy.get('.ProseMirror').should('contain', 'Mistake')
|
||||
|
||||
cy.get('.demo__preview button:first').click({ force: true })
|
||||
cy.get('.ProseMirror').should('not.contain', 'Mistake')
|
||||
cy.get('.demo__preview button:nth-child(2)').click({ force: true })
|
||||
cy.get('.ProseMirror').should('contain', 'Mistake')
|
||||
})
|
||||
})
|
||||
|
||||
it('the keyboard shortcut should apply the last undone change again', () => {
|
||||
const undoShortcut = Cypress.platform === 'darwin' ? '{meta}z' : '{ctrl}z'
|
||||
const redoShortcut = Cypress.platform === 'darwin' ? '{meta}{shift}z' : '{ctrl}{shift}z'
|
||||
|
||||
cy.get('.ProseMirror').type(undoShortcut, {force: true})
|
||||
cy.get('.ProseMirror').should('not.contain', 'Mistake')
|
||||
|
||||
cy.get('.ProseMirror').type(redoShortcut, {force: true})
|
||||
cy.get('.ProseMirror').should('contain', 'Mistake')
|
||||
})
|
||||
})
|
||||
})
|
||||
53
docs/src/demos/Extensions/History/index.vue
Normal file
53
docs/src/demos/Extensions/History/index.vue
Normal file
@@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<div v-if="editor">
|
||||
<button @click="editor.focus().undo()">
|
||||
undo
|
||||
</button>
|
||||
<button @click="editor.focus().redo()">
|
||||
redo
|
||||
</button>
|
||||
|
||||
<editor-content :editor="editor" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Editor } from '@tiptap/core'
|
||||
import { EditorContent } from '@tiptap/vue'
|
||||
import Document from '@tiptap/extension-document'
|
||||
import Paragraph from '@tiptap/extension-paragraph'
|
||||
import Text from '@tiptap/extension-text'
|
||||
import History from '@tiptap/extension-history'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EditorContent,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
editor: null,
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.editor = new Editor({
|
||||
extensions: [
|
||||
new Document(),
|
||||
new Paragraph(),
|
||||
new Text(),
|
||||
new History(),
|
||||
],
|
||||
content: `
|
||||
<p>Edit this text and press undo to test this extension.</p>
|
||||
`,
|
||||
})
|
||||
|
||||
window.editor = this.editor
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
this.editor.destroy()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
37
docs/src/demos/Extensions/Italic/index.spec.js
Normal file
37
docs/src/demos/Extensions/Italic/index.spec.js
Normal file
@@ -0,0 +1,37 @@
|
||||
context('/api/extensions/italic', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/api/extensions/italic')
|
||||
|
||||
cy.get('.ProseMirror').window().then(window => {
|
||||
const { editor } = window
|
||||
editor.setContent('<p>Example Text</p>')
|
||||
editor.focus().selectAll()
|
||||
})
|
||||
})
|
||||
|
||||
describe('italic', () => {
|
||||
it('the button should make the selected text italic', () => {
|
||||
cy.get('.demo__preview button:first').click({ force: true })
|
||||
cy.get('.ProseMirror').contains('em', 'Example Text')
|
||||
})
|
||||
|
||||
it('the button should toggle the selected text italic', () => {
|
||||
cy.get('.demo__preview button:first').dblclick({ force: true })
|
||||
cy.get('.ProseMirror em').should('not.exist')
|
||||
})
|
||||
|
||||
it('the keyboard shortcut should make the selected text italic', () => {
|
||||
const shortcut = Cypress.platform === 'darwin' ? '{meta}i' : '{ctrl}i'
|
||||
|
||||
cy.get('.ProseMirror').type(shortcut, {force: true})
|
||||
cy.get('.ProseMirror').contains('em', 'Example Text')
|
||||
})
|
||||
|
||||
it('the keyboard shortcut should toggle the selected text italic', () => {
|
||||
const shortcut = Cypress.platform === 'darwin' ? '{meta}i' : '{ctrl}i'
|
||||
|
||||
cy.get('.ProseMirror').type(shortcut, {force: true}).type(shortcut, {force: true})
|
||||
cy.get('.ProseMirror em').should('not.exist')
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -42,6 +42,8 @@ export default {
|
||||
<p style="font-style: italic">This as well.</p>
|
||||
`,
|
||||
})
|
||||
|
||||
window.editor = this.editor
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
# Commands
|
||||
|
||||
:::warning Out of date
|
||||
This content is written for tiptap 1 and needs an update.
|
||||
:::
|
||||
|
||||
- menus
|
||||
- buttons
|
||||
- commands
|
||||
|
||||
|
||||
## .clearContent()
|
||||
|
||||
Clear the whole document.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
# Editor
|
||||
|
||||
:::warning Out of date
|
||||
This content is written for tiptap 1 and needs an update.
|
||||
:::
|
||||
|
||||
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.
|
||||
@@ -1,32 +1,55 @@
|
||||
# Extensions
|
||||
|
||||
> ⚠️ TODO: This is old content.
|
||||
|
||||
By default, the editor will only support paragraphs. Other nodes and marks are available as **extensions**. You must
|
||||
install `tiptap-extensions` package separately so that you can use basic Nodes, Marks, or Plugins. An extension is
|
||||
usually tied to a Command. The official set of commands are part of the
|
||||
[`tiptap-commands`][@npmjs-tiptap-commands] package.
|
||||
|
||||
## Default extensions
|
||||
|
||||
Starterkits have defaultExtensions, that include ...
|
||||
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
|
||||
|
||||
Document, Paragraph, Text
|
||||
You’ll need at least three extensions: Document, Paragraph and Text. See [an example of a tiptap version for minimalists](/examples/simple).
|
||||
|
||||
## List of extensions
|
||||
## Default extensions
|
||||
|
||||
* Bold
|
||||
* Italic
|
||||
...
|
||||
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
|
||||
|
||||
| Title | Default Extension | Source Code |
|
||||
| ----- | ------- | ----------- |
|
||||
| [Blockquote](/api/extensions/blockquote) | – | [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) | – | [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/)
|
||||
| [CodeBlockHighlight](/api/extensions/code-block-highlight) | – | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packagescode-block-highlight/extension-/)
|
||||
| [Collaboration](/api/extensions/collaboration) | – | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-collaboration/)
|
||||
| [Document](/api/extensions/document) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-document/)
|
||||
| [HardBreak](/api/extensions/hard-break) | – | [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/)
|
||||
| [History](/api/extensions/history) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-history/)
|
||||
| [HorizontalRule](/api/extensions/horizontal-rule) | – | [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) | – | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-list-item/)
|
||||
| [Mention](/api/extensions/mention) | – | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-mention/)
|
||||
| [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/)
|
||||
| [Placeholder](/api/extensions/placeholder) | – | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-placeholder/)
|
||||
| [Strike](/api/extensions/strike) | – | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-strike/)
|
||||
| [TableCell](/api/extensions/table-cell) | – | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-table-cell/)
|
||||
| [TableHeader](/api/extensions/table-header) | – | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-table-header/)
|
||||
| [TableTow](/api/extensions/table-row) | – | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-table-row/)
|
||||
| [Text](/api/extensions/text) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-text/)
|
||||
| [TodoItem](/api/extensions/todo-item) | – | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-todo-item/)
|
||||
| [TodoList](/api/extensions/todo-list) | – | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-todo-list/)
|
||||
| [Underline](/api/extensions/underline) | – | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-underline/)
|
||||
|
||||
## Community extensions
|
||||
|
||||
How does that work?
|
||||
:::warning Work in Progress
|
||||
This section is not ready yet. Meanwhile, [search through the GitHub issues](https://github.com/ueberdosis/tiptap/issues) to find code snippets.
|
||||
:::
|
||||
|
||||
## Your custom extensions
|
||||
|
||||
Link to the Guide
|
||||
Didn’t find what you’re looking for? No worries, [you can build your own extensions](/guide/custom-extensions).
|
||||
|
||||
[@npmjs-tiptap-commands]: https://npmjs.org/package/tiptap-commands
|
||||
|
||||
@@ -10,7 +10,7 @@ The extension will generate the corresponding `<strong>` HTML tags when reading
|
||||
|
||||
## Commands
|
||||
| Command | Options | Description |
|
||||
| ------ | ---- | ---------------- |
|
||||
| ------- | ------- | ----------- |
|
||||
| bold | — | Mark text bold. |
|
||||
|
||||
## Keybindings
|
||||
@@ -21,4 +21,4 @@ The extension will generate the corresponding `<strong>` HTML tags when reading
|
||||
[packages/extension-bold/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-bold/)
|
||||
|
||||
## Usage
|
||||
<Demo name="Extensions/Bold" highlight="3-5,17,36" />
|
||||
<demo name="Extensions/Bold" highlight="3-5,17,36" />
|
||||
@@ -1,55 +1,19 @@
|
||||
# Code
|
||||
The Code extensions enables you to use the `<code>` HTML tag in the editor.
|
||||
The Code extensions enables you to use the `<code>` HTML tag in the editor. If you paste in text with `<code>` tags it will rendered accordingly.
|
||||
|
||||
## Options
|
||||
*None*
|
||||
|
||||
## Commands
|
||||
| Command | Options | Description |
|
||||
| ------ | ---- | ---------------- |
|
||||
| code | — | Mark text as code. |
|
||||
| ------- | ------- | ----------- |
|
||||
| code | — | Mark text as inline code. |
|
||||
|
||||
## Keybindings
|
||||
* `Alt` + `
|
||||
|
||||
## Source Code
|
||||
[packages/extension-code/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-code/)
|
||||
|
||||
## Usage
|
||||
```markup
|
||||
<template>
|
||||
<div>
|
||||
<editor-menu-bar :editor="editor" v-slot="{ commands, isActive }">
|
||||
<button type="button" :class="{ 'is-active': isActive.code() }" @click="commands.code">
|
||||
Code
|
||||
</button>
|
||||
</editor-menu-bar>
|
||||
|
||||
<editor-content :editor="editor" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Editor, EditorContent, EditorMenuBar } from 'tiptap'
|
||||
import { Code } from 'tiptap-extensions'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EditorMenuBar,
|
||||
EditorContent,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
editor: new Editor({
|
||||
extensions: [
|
||||
new Code(),
|
||||
],
|
||||
content: `
|
||||
<p>This is some <code>inline code.</code></p>
|
||||
`,
|
||||
}),
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.editor.destroy()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
<demo name="Extensions/Code" highlight="3-5,17,36" />
|
||||
1
docs/src/docPages/api/extensions/document.md
Normal file
1
docs/src/docPages/api/extensions/document.md
Normal file
@@ -0,0 +1 @@
|
||||
# Document
|
||||
@@ -1,58 +1,25 @@
|
||||
# History
|
||||
Enables history support.
|
||||
This extension provides history support. All changes to the document will be tracked and can be removed with `undo`. Undone changes can be applied with `redo` again.
|
||||
|
||||
## Options
|
||||
*None*
|
||||
|
||||
## Commands
|
||||
| Command | Options | Description |
|
||||
| ------ | ---- | ---------------- |
|
||||
| undo | — | Undo the latest change. |
|
||||
| redo | — | Redo the latest change. |
|
||||
| ------- | ------- | ----------- |
|
||||
| undo | — | Undo the last change. |
|
||||
| redo | — | Redo the last change. |
|
||||
|
||||
## Keybindings
|
||||
* Windows & Linux: `Control` + `Z` → Undo
|
||||
* Windows & Linux: `Shift` + `Control` + `Z` → Redo
|
||||
* macOS: `Command` + `Z` → Undo
|
||||
* macOS: `Shift` + `Command` + `Z` → Redo
|
||||
* Windows & Linux: `Control` + `Z`
|
||||
* macOS: `Command` + `Z`
|
||||
|
||||
### Redo
|
||||
* Windows & Linux: `Shift` + `Control` + `Z`
|
||||
* macOS: `Shift` + `Command` + `Z`
|
||||
|
||||
## Source Code
|
||||
[packages/extension-history/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-history/)
|
||||
|
||||
## Usage
|
||||
```markup
|
||||
<template>
|
||||
<div>
|
||||
<editor-menu-bar :editor="editor" v-slot="{ commands, isActive }">
|
||||
<div>
|
||||
<button type="button" @click="commands.undo">
|
||||
Undo
|
||||
</button>
|
||||
<button type="button" @click="commands.redo">
|
||||
Redo
|
||||
</button>
|
||||
</div>
|
||||
</editor-menu-bar>
|
||||
|
||||
<editor-content :editor="editor" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Editor, EditorContent, EditorMenuBar } from 'tiptap'
|
||||
import { History } from 'tiptap-extensions'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EditorMenuBar,
|
||||
EditorContent,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
editor: new Editor({
|
||||
extensions: [
|
||||
new History(),
|
||||
],
|
||||
}),
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.editor.destroy()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
<demo name="Extensions/History" highlight="3-8,20,39" />
|
||||
@@ -10,7 +10,7 @@ The extension will generate the corresponding `<em>` HTML tags when reading cont
|
||||
|
||||
## Commands
|
||||
| Command | Options | Description |
|
||||
| ------ | ---- | ---------------- |
|
||||
| ------- | ------- | ----------- |
|
||||
| italic | — | Mark text italic. |
|
||||
|
||||
## Keybindings
|
||||
@@ -21,4 +21,4 @@ The extension will generate the corresponding `<em>` HTML tags when reading cont
|
||||
[packages/extension-italic/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-italic/)
|
||||
|
||||
## Usage
|
||||
<Demo name="Extensions/Italic" highlight="3-5,17,36" />
|
||||
<demo name="Extensions/Italic" highlight="3-5,17,36" />
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
## Mention
|
||||
# Mention
|
||||
Enables you to use mentions in the editor.
|
||||
2
docs/src/docPages/api/extensions/paragraph.md
Normal file
2
docs/src/docPages/api/extensions/paragraph.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# Paragraph
|
||||
Enables you to use paragraphs in the editor.
|
||||
2
docs/src/docPages/api/extensions/text.md
Normal file
2
docs/src/docPages/api/extensions/text.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# Text
|
||||
Enables you to use text in the editor.
|
||||
@@ -1,5 +1,9 @@
|
||||
# Schema
|
||||
|
||||
:::warning Out of date
|
||||
This content is written for tiptap 1 and needs an update.
|
||||
:::
|
||||
|
||||
Unlike many other editors, tiptap is based on a [schema](https://prosemirror.net/docs/guide/#schema) that defines how your content is structured. This enables you to define the kind of nodes that may occur in the document, its attributes and the way they can be nested.
|
||||
|
||||
This schema is *very* strict. You can’t use any HTML-element or attribute that is not defined in your schema.
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
# Use tiptap with Vue.js
|
||||
|
||||
tiptap is framework-agnostic and works with plain JavaScript, Vue.js and React. To use tiptap with Vue.js or one of the tools that are based on Vue.js like Nuxt.js or Gridsome, you’ll need the tiptap Vue.js adapter. Install it as an dependency in your project:
|
||||
|
||||
```bash
|
||||
# Install tiptap & Vue.js adapter with npm
|
||||
npm install @tiptap/core @tiptap/starter-kit @tiptap/vue
|
||||
|
||||
# Install tiptap & Vue.js adapter with Yarn
|
||||
yarn add @tiptap/core @tiptap/starter-kit @tiptap/vue
|
||||
```
|
||||
|
||||
Create a new Vue component (e. g. `<Tiptap />`) and add the following content. That’s the shortest way to get tiptap up and running with Vue.js. No worries, you’ll be able to add more functionality soon.
|
||||
|
||||
<demo name="VueSetup" />
|
||||
@@ -1,3 +1,5 @@
|
||||
# Basic
|
||||
|
||||
TODO: CodeBlock throws an exception.
|
||||
|
||||
<demo name="Examples/Basic" />
|
||||
@@ -1,3 +1,3 @@
|
||||
# History
|
||||
|
||||
<demo name="Examples/History" />
|
||||
<demo name="Examples/History" highlight="4-9" />
|
||||
3
docs/src/docPages/examples/simple.md
Normal file
3
docs/src/docPages/examples/simple.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Simple
|
||||
|
||||
<demo name="Examples/Simple" highlight="7-9,27-29" />
|
||||
@@ -41,7 +41,7 @@ yarn add @tiptap/vue @tiptap/vue-starter-kit
|
||||
|
||||
We even prepared a Vue.js starter kit for you. That should give you a good headstart. Create a new component and add the following content to get a basic version of tiptap:
|
||||
|
||||
<demo name="VueSetup" />
|
||||
<demo name="General/Installation" />
|
||||
|
||||
## CodeSandbox
|
||||
|
||||
73
docs/src/docPages/general/roadmap.md
Normal file
73
docs/src/docPages/general/roadmap.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# Roadmap
|
||||
|
||||
## New features
|
||||
|
||||
* generate schema without initializing tiptap, to make SSR easier (e. g. `getSchema([new Doc(), new Paragraph()])`)
|
||||
|
||||
## Requested features
|
||||
|
||||
* Basic Styling
|
||||
* https://github.com/ueberdosis/tiptap/issues/507
|
||||
* Support vor Vue.js 3
|
||||
* Easily add custom classes to everything
|
||||
* https://github.com/ueberdosis/tiptap/discussions/817
|
||||
* Text snippets
|
||||
* https://github.com/ueberdosis/tiptap/issues/737
|
||||
* Markdown Support
|
||||
|
||||
## Requested extensions
|
||||
|
||||
* Alignment
|
||||
* https://github.com/ueberdosis/tiptap/pull/544
|
||||
* Font color
|
||||
* Font family
|
||||
* Font size
|
||||
* Created embed from pasted YouTube URL
|
||||
* Superscript/Subscript
|
||||
* https://github.com/ueberdosis/tiptap/discussions/813
|
||||
* Math Support
|
||||
* https://github.com/ueberdosis/tiptap/issues/179
|
||||
* https://github.com/ueberdosis/tiptap/issues/698
|
||||
* Resizeable Images
|
||||
* https://gist.github.com/zachjharris/a5442efbdff11948d085b6b1406dfbe6
|
||||
|
||||
## Ideas
|
||||
|
||||
* A `@tiptap/extensions` package would be helpful to make imports easier.
|
||||
* Add more shorcuts:
|
||||
* Ctrl+I → Italic ✅
|
||||
* Ctrl+B → Bold ✅
|
||||
* Ctrl+K → Link (Medium, Tumblr, Slack, Google Docs, Word)
|
||||
* Ctrl+Shift+K → Code (Slack)
|
||||
* Shift+Enter → Line break
|
||||
* Ctrl+Shift+X → Strikethrough (Slack)
|
||||
* Alt+Shift+5 → Strikethrough (Google Docs)
|
||||
* Ctrl+Shift+6 → Strikethrough (Tumblr)
|
||||
* Ctrl+Alt+0 → Paragraph (Google Docs)
|
||||
* Ctrl+Alt+1 to 6 → Heading (Google Docs, Word, ~Medium, ~Slack)
|
||||
* Ctrl+Shift+2 → Heading (Tumblr)
|
||||
* Ctrl+Shift+7 → Ordered list (Google Docs, Slack, Tumblr)
|
||||
* Ctrl+Shift+8 → Unordered list (Google Docs, Slack, Tumblr)
|
||||
* Tab, Shift+Tab → Increase / decrease nesting in lists
|
||||
* Ctrl+], Ctrl+[ → Same as above (when Tab needs to be used)
|
||||
* Ctrl+Shift+9 → Blockquote (Tumblr)
|
||||
* Ctrl+Alt+K → Code block (Slack)
|
||||
* Ctrl+R → Horizontal ruler (Stack Overflow)
|
||||
* Markdown shortcuts
|
||||
* #+Space → Heading (the number of # determines the header level)
|
||||
* *+Space, -+Space → Unordered list
|
||||
* 1.+Space → Ordered list
|
||||
* >+Space → Blockquote
|
||||
* ```+Space → Code block
|
||||
* ---- → Horizontal ruler
|
||||
* ![] → Embedded resource (not part of Slack, but would it not be fancy?)
|
||||
* :emoji: → Emoji (based on the name). A nice-to-have, most certainly.
|
||||
* General shortcuts
|
||||
* Ctrl+C, Ctrl+X, Ctrl+V: copy, cut, paste
|
||||
* Ctrl+Z, Ctrl+Shift+Z, Ctrl+Y: undo, redo
|
||||
* Ctrl+Backspace: delete previous word
|
||||
* Ctrl+Delete: delete next word
|
||||
* Ctrl+Home, Ctrl+End: go to the start / end of the whole document
|
||||
* Ctrl+F, Ctrl+G: find, find next occurrence
|
||||
* Ctrl+S: if there is no auto-saving, this should save the document
|
||||
* Ctrl+/: show shortcuts (Medium, Slack)
|
||||
@@ -22,7 +22,7 @@ You are free to choose which parts of tiptap you want to use. Tiptap has support
|
||||
|
||||
Note that `Document`, `Paragraph` and `Text` are required. Otherwise you won’t be able to add any plain text.
|
||||
|
||||
<demo name="ExtensionConfiguration" highlight="10-13,30-33" />
|
||||
<demo name="Guide/BuildYourEditor" highlight="10-13,30-33" />
|
||||
|
||||
That’s also the place where you can register custom extensions, which you or someone else built for tiptap.
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ The `@tiptap/vue-starter-kit` includes a few basics you would probably need anyw
|
||||
|
||||
Create a new Vue component (you can call it `<Tiptap />`) 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.
|
||||
|
||||
<demo name="GettingStarted" />
|
||||
<demo name="Guide/GettingStarted" />
|
||||
|
||||
::: warning Using with Nuxt.js
|
||||
If you are using Nuxt.js, note that tiptap needs to run in the client, not on the server. It’s required to wrap the editor in a `<client-only>` tag.
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
# Introduction
|
||||
|
||||
tiptap is a <g-link to="/renderless">renderless</g-link> wrapper around [ProseMirror](https://ProseMirror.net) – a toolkit for building rich-text editors that are 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 is built on top of its APIs and we strongly recommend you to read through the [ProseMirror Guide](https://ProseMirror.net/docs/guide/). You’ll have a better understanding of how everything works under the hood and get familiar with many terms and jargon used by tiptap.
|
||||
|
||||
## Who is using tiptap?
|
||||
## Renderless
|
||||
The implementation of a text editor can be very specific for each use case. We don’t want to 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’ll have full control over markup and styling.
|
||||
|
||||
## TypeScript
|
||||
Tiptap 2 is written in TypeScript. That gives you a nice autocomplete for the API (if your IDE supports those), helps us to find bugs early and makes it possible to generate [a complete API documentation](#) on top of the extensive human written documentation.
|
||||
|
||||
## Framework-agnostic
|
||||
We don’t care what framework you use. Tiptap is ready to be used with plain JavaScript, Vue.js or React. That makes it even possible to write a renderer for Svelte and others.
|
||||
|
||||
## Who uses tiptap?
|
||||
- [GitLab](https://gitlab.com)
|
||||
- [Statamic CMS](https://statamic.com)
|
||||
- [Twill CMS](https://twill.io)
|
||||
@@ -1,3 +0,0 @@
|
||||
# Renderless
|
||||
|
||||
The implementation of a text editor can be very specific for each use case. We don’t want to 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’ll have full control over markup and styling.
|
||||
@@ -93,4 +93,10 @@ blockquote {
|
||||
.is-active {
|
||||
background: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.ProseMirror {
|
||||
p {
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
}
|
||||
@@ -45,13 +45,13 @@
|
||||
</div>
|
||||
<ul class="app__link-list">
|
||||
<li v-for="(item, j) in linkGroup.items" :key="j">
|
||||
<g-link class="app__link" :to="item.link">
|
||||
<g-link :class="{ 'app__link': true, 'app__link--draft': item.draft === true }" :to="item.link" :exact="item.link === '/'">
|
||||
{{ item.title }}
|
||||
</g-link>
|
||||
|
||||
<ul v-if="item.items" class="app__link-list">
|
||||
<li v-for="(item, k) in item.items" :key="k">
|
||||
<g-link class="app__link" :to="item.link">
|
||||
<g-link :class="{ 'app__link': true, 'app__link--draft': item.draft === true }" :to="item.link" exact>
|
||||
{{ item.title }}
|
||||
</g-link>
|
||||
</li>
|
||||
@@ -69,6 +69,9 @@
|
||||
<span>Edit this page on GitHub</span>
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
Made with 🖤 by <a href="https://twitter.com/_ueberdosis">überdosis</a>
|
||||
</p>
|
||||
<page-navigation />
|
||||
</main>
|
||||
</div>
|
||||
|
||||
@@ -25,12 +25,17 @@ $menuBreakPoint: 750px;
|
||||
}
|
||||
|
||||
&__link-list &__link-list {
|
||||
display: none;
|
||||
padding-left: 1rem;
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-left: 2px solid rgba($colorBlack, 0.1);
|
||||
}
|
||||
|
||||
.active + &__link-list {
|
||||
display: block;
|
||||
}
|
||||
|
||||
&__link {
|
||||
display: block;
|
||||
padding: 0.1rem 0.5rem;
|
||||
@@ -48,6 +53,10 @@ $menuBreakPoint: 750px;
|
||||
color: $colorBlack;
|
||||
background-color: rgba($colorBlack, 0.05);
|
||||
}
|
||||
|
||||
&--draft {
|
||||
color: rgba($colorBlack, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
&__header {
|
||||
@@ -156,4 +165,4 @@ $menuBreakPoint: 750px;
|
||||
min-width: 0;
|
||||
padding-top: $navHeight + 2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,73 +1,101 @@
|
||||
- title: Getting Started
|
||||
- title: General
|
||||
items:
|
||||
- title: Introduction
|
||||
link: /getting-started/introduction/
|
||||
link: /
|
||||
- title: Installation
|
||||
link: /getting-started/installation/
|
||||
link: /general/installation
|
||||
- title: Upgrade Guide
|
||||
link: /getting-started/upgrade-guide/
|
||||
link: /general/upgrade-guide
|
||||
draft: true
|
||||
- title: Roadmap
|
||||
link: /general/roadmap
|
||||
draft: true
|
||||
|
||||
- title: Guide
|
||||
items:
|
||||
- title: Getting started
|
||||
link: /guide/getting-started/
|
||||
link: /guide/getting-started
|
||||
- title: Configuration
|
||||
link: /guide/configuration/
|
||||
link: /guide/configuration
|
||||
draft: true
|
||||
- title: Build your editor
|
||||
link: /guide/build-your-editor/
|
||||
link: /guide/build-your-editor
|
||||
draft: true
|
||||
- title: Custom styling
|
||||
link: /guide/custom-styling/
|
||||
link: /guide/custom-styling
|
||||
draft: true
|
||||
- title: Get content
|
||||
link: /guide/get-content/
|
||||
link: /guide/get-content
|
||||
draft: true
|
||||
- title: Custom extensions
|
||||
link: /guide/custom-extensions/
|
||||
link: /guide/custom-extensions
|
||||
draft: true
|
||||
- title: Use Vue Components
|
||||
link: /guide/use-vue-components/
|
||||
link: /guide/use-vue-components
|
||||
draft: true
|
||||
|
||||
- title: Examples
|
||||
items:
|
||||
- title: Basic
|
||||
link: /examples/basic
|
||||
- title: Simple
|
||||
link: /examples/simple
|
||||
- title: Menu Bubble
|
||||
link: /examples/menu-bubble
|
||||
draft: true
|
||||
- title: Floating Menu
|
||||
link: /examples/floating-menu
|
||||
draft: true
|
||||
- title: Links
|
||||
link: /examples/links
|
||||
draft: true
|
||||
- title: Images
|
||||
link: /examples/images
|
||||
draft: true
|
||||
- title: Hiding Menu Bar
|
||||
link: /examples/hiding-menu-bar
|
||||
draft: true
|
||||
- title: Todo List
|
||||
link: /examples/todo-list
|
||||
draft: true
|
||||
- title: Tables
|
||||
link: /examples/tables
|
||||
draft: true
|
||||
- title: Search and Replace
|
||||
link: /examples/search-and-replace
|
||||
draft: true
|
||||
- title: Suggestions
|
||||
link: /examples/suggestions
|
||||
draft: true
|
||||
- title: Markdown Shortcuts
|
||||
link: /examples/markdown-shortcuts
|
||||
- title: Code Highlighting
|
||||
link: /examples/code-highlighting
|
||||
draft: true
|
||||
- title: History
|
||||
link: /examples/history
|
||||
- title: Read-Only
|
||||
link: /examples/read-only
|
||||
- title: Embeds
|
||||
link: /examples/embeds
|
||||
draft: true
|
||||
- title: Placeholder
|
||||
link: /examples/placeholder
|
||||
draft: true
|
||||
- title: Focus
|
||||
link: /examples/focus
|
||||
- title: Collaboration
|
||||
link: /examples/collaboration
|
||||
draft: true
|
||||
- title: Title
|
||||
link: /examples/title
|
||||
draft: true
|
||||
- title: Trailing Paragraph
|
||||
link: /examples/trailing-paragraph
|
||||
draft: true
|
||||
- title: Drag Handle
|
||||
link: /examples/drag-handle
|
||||
draft: true
|
||||
- title: Export HTML or JSON
|
||||
link: /examples/export-html-or-json
|
||||
|
||||
@@ -75,60 +103,93 @@
|
||||
items:
|
||||
- title: Editor
|
||||
link: /api/editor/
|
||||
draft: true
|
||||
- title: Extensions
|
||||
link: /api/extensions/
|
||||
items:
|
||||
- title: Blockquote
|
||||
link: /api/extensions/blockquote
|
||||
draft: true
|
||||
- title: Bold
|
||||
link: /api/extensions/bold
|
||||
- title: BulletList
|
||||
link: /api/extensions/bullet-list
|
||||
draft: true
|
||||
- title: Code
|
||||
link: /api/extensions/code
|
||||
- title: CodeBlock
|
||||
link: /api/extensions/code-block
|
||||
draft: true
|
||||
- title: CodeBlockHighlight
|
||||
link: /api/extensions/code-block-highlight
|
||||
draft: true
|
||||
- title: Collaboration
|
||||
link: /api/extensions/collaboration
|
||||
draft: true
|
||||
- title: Document
|
||||
link: /api/extensions/document
|
||||
draft: true
|
||||
- title: Hardbreak
|
||||
link: /api/extensions/hard-break
|
||||
draft: true
|
||||
- title: Heading
|
||||
link: /api/extensions/heading
|
||||
draft: true
|
||||
- title: History
|
||||
link: /api/extensions/history
|
||||
- title: HorizontalRule
|
||||
link: /api/extensions/horizontal-rule
|
||||
draft: true
|
||||
- title: Italic
|
||||
link: /api/extensions/italic
|
||||
- title: Link
|
||||
link: /api/extensions/link
|
||||
draft: true
|
||||
- title: ListItem
|
||||
link: /api/extensions/list-item
|
||||
draft: true
|
||||
- title: Mention
|
||||
link: /api/extensions/mention
|
||||
draft: true
|
||||
- title: OrderedList
|
||||
link: /api/extensions/ordered-list
|
||||
draft: true
|
||||
- title: Paragraph
|
||||
link: /api/extensions/paragraph
|
||||
draft: true
|
||||
- title: Placeholder
|
||||
link: /api/extensions/placeholder
|
||||
draft: true
|
||||
- title: Strike
|
||||
link: /api/extensions/strike
|
||||
draft: true
|
||||
- title: Text
|
||||
link: /api/extensions/text
|
||||
draft: true
|
||||
- title: TableCell
|
||||
link: /api/extensions/table-cell
|
||||
draft: true
|
||||
- title: TableHeader
|
||||
link: /api/extensions/table-header
|
||||
draft: true
|
||||
- title: TableRow
|
||||
link: /api/extensions/table-row
|
||||
draft: true
|
||||
- title: TodoItem
|
||||
link: /api/extensions/todo-item
|
||||
draft: true
|
||||
- title: TodoList
|
||||
link: /api/extensions/todo-list
|
||||
draft: true
|
||||
- title: Underline
|
||||
link: /api/extensions/underline
|
||||
draft: true
|
||||
- title: Commands
|
||||
link: /api/commands/
|
||||
link: /api/commands
|
||||
draft: true
|
||||
- title: Events
|
||||
link: /api/events/
|
||||
link: /api/events
|
||||
draft: true
|
||||
- title: Schema
|
||||
link: /api/schema/
|
||||
link: /api/schema
|
||||
draft: true
|
||||
@@ -1,5 +0,0 @@
|
||||
<template>
|
||||
<Layout>
|
||||
Hi there! 👋
|
||||
</Layout>
|
||||
</template>
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
> * + * {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
position: relative;
|
||||
@@ -80,7 +80,7 @@
|
||||
|
||||
> * + * {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
position: relative;
|
||||
@@ -146,7 +146,7 @@
|
||||
padding: 1rem;
|
||||
border: 2px solid rgba($colorBlack, 0.1);
|
||||
border-radius: 0.25rem;
|
||||
|
||||
|
||||
&.warning {
|
||||
border-color:#ffd8a8;
|
||||
background-color: #fff4e6;
|
||||
|
||||
Reference in New Issue
Block a user