Merge branch 'main' of github.com:ueberdosis/tiptap
This commit is contained in:
7
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
7
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -11,6 +11,13 @@ body:
|
||||
placeholder: "I’m always frustrated when …"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: Which browser was this experienced in? Are any special extensions installed?
|
||||
description: Please give us more information about your browser environment so we can reproduce the bug faster.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
|
||||
20
.github/workflows/build.yml
vendored
20
.github/workflows/build.yml
vendored
@@ -24,15 +24,15 @@ jobs:
|
||||
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: actions/checkout@v3.0.0
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2.5.1
|
||||
uses: actions/setup-node@v3.1.1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Load cached dependencies
|
||||
uses: actions/cache@v2.1.7
|
||||
uses: actions/cache@v3.0.2
|
||||
id: cache
|
||||
with:
|
||||
path: |
|
||||
@@ -80,10 +80,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: actions/checkout@v3.0.0
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2.5.1
|
||||
uses: actions/setup-node@v3.1.1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
@@ -99,7 +99,7 @@ jobs:
|
||||
quiet: true
|
||||
|
||||
- name: Export screenshots (on failure only)
|
||||
uses: actions/upload-artifact@v2.3.1
|
||||
uses: actions/upload-artifact@v3.0.0
|
||||
if: failure()
|
||||
with:
|
||||
name: cypress-screenshots
|
||||
@@ -107,7 +107,7 @@ jobs:
|
||||
retention-days: 7
|
||||
|
||||
- name: Export screen recordings (on failure only)
|
||||
uses: actions/upload-artifact@v2.3.1
|
||||
uses: actions/upload-artifact@v3.0.0
|
||||
if: failure()
|
||||
with:
|
||||
name: cypress-videos
|
||||
@@ -136,15 +136,15 @@ jobs:
|
||||
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: actions/checkout@v3.0.0
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2.5.1
|
||||
uses: actions/setup-node@v3.1.1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Load cached dependencies
|
||||
uses: actions/cache@v2.1.7
|
||||
uses: actions/cache@v3.0.2
|
||||
id: cache
|
||||
with:
|
||||
path: |
|
||||
|
||||
11
.vscode/launch.json
vendored
Normal file
11
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Launch Tiptap demos in Google Chrome",
|
||||
"request": "launch",
|
||||
"type": "chrome",
|
||||
"url": "http://localhost:3000",
|
||||
"webRoot": "${workspaceFolder}"
|
||||
}
|
||||
]
|
||||
}
|
||||
87
demos/package-lock.json
generated
87
demos/package-lock.json
generated
@@ -24,8 +24,8 @@
|
||||
"autoprefixer": "^10.4.2",
|
||||
"iframe-resizer": "^4.3.2",
|
||||
"postcss": "^8.4.6",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
"sass": "^1.49.7",
|
||||
"tailwindcss": "^2.2.19",
|
||||
"typescript": "^4.5.5",
|
||||
@@ -2345,9 +2345,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/minimist": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/modern-normalize": {
|
||||
@@ -2424,15 +2424,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/object-hash": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz",
|
||||
@@ -2703,30 +2694,28 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react": {
|
||||
"version": "17.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz",
|
||||
"integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==",
|
||||
"version": "18.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-18.0.0.tgz",
|
||||
"integrity": "sha512-x+VL6wbT4JRVPm7EGxXhZ8w8LTROaxPXOqhlGyVSrv0sB1jkyFGgXxJ8LVoPRLvPR6/CIZGFmfzqUa2NYeMr2A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"object-assign": "^4.1.1"
|
||||
"loose-envify": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom": {
|
||||
"version": "17.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz",
|
||||
"integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==",
|
||||
"version": "18.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.0.0.tgz",
|
||||
"integrity": "sha512-XqX7uzmFo0pUceWFCt7Gff6IyIMzFUn7QMZrbrQfGxtaxXZIcGQzoNpRLE3fQLnS4XzLLPMZX2T9TRcSrasicw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"scheduler": "^0.20.2"
|
||||
"scheduler": "^0.21.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "17.0.2"
|
||||
"react": "^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-refresh": {
|
||||
@@ -2917,13 +2906,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/scheduler": {
|
||||
"version": "0.20.2",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz",
|
||||
"integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==",
|
||||
"version": "0.21.0",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz",
|
||||
"integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"object-assign": "^4.1.1"
|
||||
"loose-envify": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
@@ -5338,9 +5326,9 @@
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
|
||||
"dev": true
|
||||
},
|
||||
"modern-normalize": {
|
||||
@@ -5396,12 +5384,6 @@
|
||||
"path-key": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||
"dev": true
|
||||
},
|
||||
"object-hash": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz",
|
||||
@@ -5576,24 +5558,22 @@
|
||||
}
|
||||
},
|
||||
"react": {
|
||||
"version": "17.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz",
|
||||
"integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==",
|
||||
"version": "18.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-18.0.0.tgz",
|
||||
"integrity": "sha512-x+VL6wbT4JRVPm7EGxXhZ8w8LTROaxPXOqhlGyVSrv0sB1jkyFGgXxJ8LVoPRLvPR6/CIZGFmfzqUa2NYeMr2A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"object-assign": "^4.1.1"
|
||||
"loose-envify": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"react-dom": {
|
||||
"version": "17.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz",
|
||||
"integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==",
|
||||
"version": "18.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.0.0.tgz",
|
||||
"integrity": "sha512-XqX7uzmFo0pUceWFCt7Gff6IyIMzFUn7QMZrbrQfGxtaxXZIcGQzoNpRLE3fQLnS4XzLLPMZX2T9TRcSrasicw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"scheduler": "^0.20.2"
|
||||
"scheduler": "^0.21.0"
|
||||
}
|
||||
},
|
||||
"react-refresh": {
|
||||
@@ -5735,13 +5715,12 @@
|
||||
}
|
||||
},
|
||||
"scheduler": {
|
||||
"version": "0.20.2",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz",
|
||||
"integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==",
|
||||
"version": "0.21.0",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz",
|
||||
"integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"object-assign": "^4.1.1"
|
||||
"loose-envify": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
"autoprefixer": "^10.4.2",
|
||||
"iframe-resizer": "^4.3.2",
|
||||
"postcss": "^8.4.6",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
"sass": "^1.49.7",
|
||||
"tailwindcss": "^2.2.19",
|
||||
"typescript": "^4.5.5",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import 'iframe-resizer/js/iframeResizer.contentWindow'
|
||||
import { debug, splitName } from './helper'
|
||||
import './style.scss'
|
||||
@@ -13,7 +13,11 @@ export default function init(name: string, source: any) {
|
||||
|
||||
import(`../src/${demoCategory}/${demoName}/React/index.jsx`)
|
||||
.then(module => {
|
||||
ReactDOM.render(React.createElement(module.default), document.getElementById('app'))
|
||||
const root = document.getElementById('app')
|
||||
|
||||
if (root) {
|
||||
createRoot(root).render(React.createElement(module.default))
|
||||
}
|
||||
debug()
|
||||
})
|
||||
}
|
||||
|
||||
3
demos/src/Examples/CSSModules/Vue/index.css
Normal file
3
demos/src/Examples/CSSModules/Vue/index.css
Normal file
@@ -0,0 +1,3 @@
|
||||
h1 {
|
||||
color: red;
|
||||
}
|
||||
0
demos/src/Examples/CSSModules/Vue/index.html
Normal file
0
demos/src/Examples/CSSModules/Vue/index.html
Normal file
17
demos/src/Examples/CSSModules/Vue/index.spec.js
Normal file
17
demos/src/Examples/CSSModules/Vue/index.spec.js
Normal file
@@ -0,0 +1,17 @@
|
||||
context('/src/Examples/CSSModules/Vue/', () => {
|
||||
before(() => {
|
||||
cy.visit('/src/Examples/CSSModules/Vue/')
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||
editor.commands.setContent('<h1>Example Text</h1>')
|
||||
cy.get('.ProseMirror').type('{selectall}')
|
||||
})
|
||||
})
|
||||
|
||||
it('should apply a red headline style to h1', () => {
|
||||
cy.get('.ProseMirror h1').should('exist')
|
||||
cy.get('.ProseMirror h1').should('have.css', 'color', '#f00');
|
||||
})
|
||||
})
|
||||
187
demos/src/Examples/CSSModules/Vue/index.vue
Normal file
187
demos/src/Examples/CSSModules/Vue/index.vue
Normal file
@@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<div v-if="editor">
|
||||
<button @click="editor.chain().focus().toggleBold().run()" :class="{ 'is-active': editor.isActive('bold') }">
|
||||
bold
|
||||
</button>
|
||||
<button @click="editor.chain().focus().toggleItalic().run()" :class="{ 'is-active': editor.isActive('italic') }">
|
||||
italic
|
||||
</button>
|
||||
<button @click="editor.chain().focus().toggleStrike().run()" :class="{ 'is-active': editor.isActive('strike') }">
|
||||
strike
|
||||
</button>
|
||||
<button @click="editor.chain().focus().toggleCode().run()" :class="{ 'is-active': editor.isActive('code') }">
|
||||
code
|
||||
</button>
|
||||
<button @click="editor.chain().focus().unsetAllMarks().run()">
|
||||
clear marks
|
||||
</button>
|
||||
<button @click="editor.chain().focus().clearNodes().run()">
|
||||
clear nodes
|
||||
</button>
|
||||
<button @click="editor.chain().focus().setParagraph().run()" :class="{ 'is-active': editor.isActive('paragraph') }">
|
||||
paragraph
|
||||
</button>
|
||||
<button @click="editor.chain().focus().toggleHeading({ level: 1 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 1 }) }">
|
||||
h1
|
||||
</button>
|
||||
<button @click="editor.chain().focus().toggleHeading({ level: 2 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 2 }) }">
|
||||
h2
|
||||
</button>
|
||||
<button @click="editor.chain().focus().toggleHeading({ level: 3 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 3 }) }">
|
||||
h3
|
||||
</button>
|
||||
<button @click="editor.chain().focus().toggleHeading({ level: 4 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 4 }) }">
|
||||
h4
|
||||
</button>
|
||||
<button @click="editor.chain().focus().toggleHeading({ level: 5 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 5 }) }">
|
||||
h5
|
||||
</button>
|
||||
<button @click="editor.chain().focus().toggleHeading({ level: 6 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 6 }) }">
|
||||
h6
|
||||
</button>
|
||||
<button @click="editor.chain().focus().toggleBulletList().run()" :class="{ 'is-active': editor.isActive('bulletList') }">
|
||||
bullet list
|
||||
</button>
|
||||
<button @click="editor.chain().focus().toggleOrderedList().run()" :class="{ 'is-active': editor.isActive('orderedList') }">
|
||||
ordered list
|
||||
</button>
|
||||
<button @click="editor.chain().focus().toggleCodeBlock().run()" :class="{ 'is-active': editor.isActive('codeBlock') }">
|
||||
code block
|
||||
</button>
|
||||
<button @click="editor.chain().focus().toggleBlockquote().run()" :class="{ 'is-active': editor.isActive('blockquote') }">
|
||||
blockquote
|
||||
</button>
|
||||
<button @click="editor.chain().focus().setHorizontalRule().run()">
|
||||
horizontal rule
|
||||
</button>
|
||||
<button @click="editor.chain().focus().setHardBreak().run()">
|
||||
hard break
|
||||
</button>
|
||||
<button @click="editor.chain().focus().undo().run()">
|
||||
undo
|
||||
</button>
|
||||
<button @click="editor.chain().focus().redo().run()">
|
||||
redo
|
||||
</button>
|
||||
</div>
|
||||
<editor-content :editor="editor" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Editor, EditorContent } from '@tiptap/vue-3'
|
||||
import StarterKit from '@tiptap/starter-kit'
|
||||
import './index.css';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EditorContent,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
editor: null,
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.editor = new Editor({
|
||||
extensions: [
|
||||
StarterKit,
|
||||
],
|
||||
content: `
|
||||
<h1>
|
||||
This is a red headline
|
||||
</h1>
|
||||
<p>
|
||||
this is a <em>basic</em> example of <strong>tiptap</strong>. Sure, there are all kind of basic text styles you’d probably expect from a text editor. But wait until you see the lists:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
That’s a bullet list with one …
|
||||
</li>
|
||||
<li>
|
||||
… or two list items.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
Isn’t that great? And all of that is editable. But wait, there’s more. Let’s try a code block:
|
||||
</p>
|
||||
<pre><code class="language-css">body {
|
||||
display: none;
|
||||
}</code></pre>
|
||||
<p>
|
||||
I know, I know, this is impressive. It’s only the tip of the iceberg though. Give it a try and click a little bit around. Don’t forget to check the other examples too.
|
||||
</p>
|
||||
<blockquote>
|
||||
Wow, that’s amazing. Good work, boy! 👏
|
||||
<br />
|
||||
— Mom
|
||||
</blockquote>
|
||||
`,
|
||||
})
|
||||
},
|
||||
|
||||
beforeUnmount() {
|
||||
this.editor.destroy()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
/* Basic editor styles */
|
||||
.ProseMirror {
|
||||
> * + * {
|
||||
margin-top: 0.75em;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: rgba(#616161, 0.1);
|
||||
color: #616161;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #0D0D0D;
|
||||
color: #FFF;
|
||||
font-family: 'JetBrainsMono', monospace;
|
||||
padding: 0.75rem 1rem;
|
||||
border-radius: 0.5rem;
|
||||
|
||||
code {
|
||||
color: inherit;
|
||||
padding: 0;
|
||||
background: none;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
padding-left: 1rem;
|
||||
border-left: 2px solid rgba(#0D0D0D, 0.1);
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 2px solid rgba(#0D0D0D, 0.1);
|
||||
margin: 2rem 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -16,7 +16,7 @@ export default () => {
|
||||
|
||||
useEffect(() => {
|
||||
if (!editor) {
|
||||
return null
|
||||
return undefined
|
||||
}
|
||||
|
||||
// Get the initial content …
|
||||
|
||||
@@ -16,7 +16,7 @@ export default () => {
|
||||
|
||||
useEffect(() => {
|
||||
if (!editor) {
|
||||
return null
|
||||
return undefined
|
||||
}
|
||||
|
||||
// Get the initial content …
|
||||
|
||||
@@ -20,7 +20,7 @@ export default () => {
|
||||
|
||||
useEffect(() => {
|
||||
if (!editor) {
|
||||
return null
|
||||
return undefined
|
||||
}
|
||||
|
||||
editor.setEditable(editable)
|
||||
|
||||
@@ -12,7 +12,7 @@ We provide [an official PHP package to work with Tiptap content](/api/utilities/
|
||||
|
||||
## Laravel Livewire
|
||||
|
||||
### editor.blade.php
|
||||
### my-livewire-component.blade.php
|
||||
```html
|
||||
<!--
|
||||
In your livewire component you could add an
|
||||
@@ -25,7 +25,7 @@ We provide [an official PHP package to work with Tiptap content](/api/utilities/
|
||||
></x-editor>
|
||||
```
|
||||
|
||||
### my-livewire-component.blade.php
|
||||
### editor.blade.php
|
||||
```html
|
||||
<div
|
||||
x-data="setupEditor(
|
||||
|
||||
28461
package-lock.json
generated
Normal file
28461
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -60,8 +60,6 @@ export const Keymap = Extension.create({
|
||||
|
||||
const pcKeymap = {
|
||||
...baseKeymap,
|
||||
Home: () => this.editor.commands.selectTextblockStart(),
|
||||
End: () => this.editor.commands.selectTextblockEnd(),
|
||||
}
|
||||
|
||||
const macKeymap = {
|
||||
|
||||
@@ -32,5 +32,6 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/ueberdosis/tiptap",
|
||||
"directory": "packages/extension-bubble-menu"
|
||||
}
|
||||
},
|
||||
"sideEffects": false
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ export class BubbleMenuView {
|
||||
}
|
||||
|
||||
this.tippy?.setProps({
|
||||
getReferenceClientRect: () => {
|
||||
getReferenceClientRect: this.tippyOptions?.getReferenceClientRect || (() => {
|
||||
if (isNodeSelection(state.selection)) {
|
||||
const node = view.nodeDOM(from) as HTMLElement
|
||||
|
||||
@@ -190,7 +190,7 @@ export class BubbleMenuView {
|
||||
}
|
||||
|
||||
return posToDOMRect(view, from, to)
|
||||
},
|
||||
}),
|
||||
})
|
||||
|
||||
this.show()
|
||||
|
||||
@@ -21,8 +21,7 @@
|
||||
"dist"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.0.0-beta.1",
|
||||
"@tiptap/extension-text-style": "^2.0.0-beta.1"
|
||||
"@tiptap/core": "^2.0.0-beta.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.16.1",
|
||||
|
||||
@@ -32,5 +32,6 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/ueberdosis/tiptap",
|
||||
"directory": "packages/extension-floating-menu"
|
||||
}
|
||||
},
|
||||
"sideEffects": false
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ export class FloatingMenuView {
|
||||
}
|
||||
|
||||
this.tippy?.setProps({
|
||||
getReferenceClientRect: () => posToDOMRect(view, from, to),
|
||||
getReferenceClientRect: this.tippyOptions?.getReferenceClientRect || (() => posToDOMRect(view, from, to)),
|
||||
})
|
||||
|
||||
this.show()
|
||||
|
||||
@@ -78,7 +78,7 @@ export const Link = Mark.create<LinkOptions>({
|
||||
|
||||
parseHTML() {
|
||||
return [
|
||||
{ tag: 'a[href]' },
|
||||
{ tag: 'a[href]:not([href *= "javascript:" i])' },
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ export interface TaskItemOptions {
|
||||
HTMLAttributes: Record<string, any>,
|
||||
}
|
||||
|
||||
export const inputRegex = /^\s*(\[([ |x])\])\s$/
|
||||
export const inputRegex = /^\s*(\[([( |x])?\])\s$/
|
||||
|
||||
export const TaskItem = Node.create<TaskItemOptions>({
|
||||
name: 'taskItem',
|
||||
|
||||
@@ -21,15 +21,15 @@
|
||||
"dist"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/react": "^17.0.39",
|
||||
"@types/react-dom": "^17.0.11",
|
||||
"react": "^17.0.0",
|
||||
"react-dom": "^17.0.0"
|
||||
"@types/react": "^18.0.1",
|
||||
"@types/react-dom": "^18.0.0",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.0.0-beta.1",
|
||||
"react": "^17.0.0",
|
||||
"react-dom": "^17.0.0"
|
||||
"react": "^17.0.0 || ^18.0.0",
|
||||
"react-dom": "^17.0.0 || ^18.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tiptap/extension-bubble-menu": "^2.0.0-beta.55",
|
||||
|
||||
@@ -7,9 +7,10 @@ type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>
|
||||
|
||||
export type BubbleMenuProps = Omit<Optional<BubbleMenuPluginProps, 'pluginKey'>, 'element'> & {
|
||||
className?: string,
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
export const BubbleMenu: React.FC<BubbleMenuProps> = props => {
|
||||
export const BubbleMenu = (props: BubbleMenuProps) => {
|
||||
const [element, setElement] = useState<HTMLDivElement | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -7,9 +7,10 @@ type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>
|
||||
|
||||
export type FloatingMenuProps = Omit<Optional<FloatingMenuPluginProps, 'pluginKey'>, 'element'> & {
|
||||
className?: string,
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
export const FloatingMenu: React.FC<FloatingMenuProps> = props => {
|
||||
export const FloatingMenu = (props: FloatingMenuProps) => {
|
||||
const [element, setElement] = useState<HTMLDivElement | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -169,6 +169,7 @@ export function Suggestion({
|
||||
|
||||
// Apply changes to the plugin state from a view transaction.
|
||||
apply(transaction, prev, oldState, state) {
|
||||
const { isEditable } = editor
|
||||
const { composing } = editor.view
|
||||
const { selection } = transaction
|
||||
const { empty, from } = selection
|
||||
@@ -176,9 +177,10 @@ export function Suggestion({
|
||||
|
||||
next.composing = composing
|
||||
|
||||
// We can only be suggesting if there is no selection
|
||||
// or a composition is active (see: https://github.com/ueberdosis/tiptap/issues/1449)
|
||||
if (empty || editor.view.composing) {
|
||||
// We can only be suggesting if the view is editable, and:
|
||||
// * there is no selection, or
|
||||
// * a composition is active (see: https://github.com/ueberdosis/tiptap/issues/1449)
|
||||
if (isEditable && (empty || editor.view.composing)) {
|
||||
// Reset active state if we just left the previous suggestion range
|
||||
if (
|
||||
(from < prev.range.from || from > prev.range.to)
|
||||
|
||||
@@ -15,35 +15,35 @@ import { VueRenderer } from './VueRenderer'
|
||||
export const nodeViewProps = {
|
||||
editor: {
|
||||
type: Object as PropType<NodeViewProps['editor']>,
|
||||
required: true,
|
||||
required: true as const,
|
||||
},
|
||||
node: {
|
||||
type: Object as PropType<NodeViewProps['node']>,
|
||||
required: true,
|
||||
required: true as const,
|
||||
},
|
||||
decorations: {
|
||||
type: Object as PropType<NodeViewProps['decorations']>,
|
||||
required: true,
|
||||
required: true as const,
|
||||
},
|
||||
selected: {
|
||||
type: Boolean as PropType<NodeViewProps['selected']>,
|
||||
required: true,
|
||||
required: true as const,
|
||||
},
|
||||
extension: {
|
||||
type: Object as PropType<NodeViewProps['extension']>,
|
||||
required: true,
|
||||
required: true as const,
|
||||
},
|
||||
getPos: {
|
||||
type: Function as PropType<NodeViewProps['getPos']>,
|
||||
required: true,
|
||||
required: true as const,
|
||||
},
|
||||
updateAttributes: {
|
||||
type: Function as PropType<NodeViewProps['updateAttributes']>,
|
||||
required: true,
|
||||
required: true as const,
|
||||
},
|
||||
deleteNode: {
|
||||
type: Function as PropType<NodeViewProps['deleteNode']>,
|
||||
required: true,
|
||||
required: true as const,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -21,35 +21,35 @@ import { VueRenderer } from './VueRenderer'
|
||||
export const nodeViewProps = {
|
||||
editor: {
|
||||
type: Object as PropType<NodeViewProps['editor']>,
|
||||
required: true,
|
||||
required: true as const,
|
||||
},
|
||||
node: {
|
||||
type: Object as PropType<NodeViewProps['node']>,
|
||||
required: true,
|
||||
required: true as const,
|
||||
},
|
||||
decorations: {
|
||||
type: Object as PropType<NodeViewProps['decorations']>,
|
||||
required: true,
|
||||
required: true as const,
|
||||
},
|
||||
selected: {
|
||||
type: Boolean as PropType<NodeViewProps['selected']>,
|
||||
required: true,
|
||||
required: true as const,
|
||||
},
|
||||
extension: {
|
||||
type: Object as PropType<NodeViewProps['extension']>,
|
||||
required: true,
|
||||
required: true as const,
|
||||
},
|
||||
getPos: {
|
||||
type: Function as PropType<NodeViewProps['getPos']>,
|
||||
required: true,
|
||||
required: true as const,
|
||||
},
|
||||
updateAttributes: {
|
||||
type: Function as PropType<NodeViewProps['updateAttributes']>,
|
||||
required: true,
|
||||
required: true as const,
|
||||
},
|
||||
deleteNode: {
|
||||
type: Function as PropType<NodeViewProps['deleteNode']>,
|
||||
required: true,
|
||||
required: true as const,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -101,6 +101,10 @@ class VueNodeView extends NodeView<Component, Editor, VueNodeViewRendererOptions
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line
|
||||
__scopeId: this.component.__scopeId,
|
||||
// add support for CSS Modules
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line
|
||||
__cssModules: this.component.__cssModules,
|
||||
})
|
||||
|
||||
this.renderer = new VueRenderer(extendedComponent, {
|
||||
|
||||
Reference in New Issue
Block a user