mirror of
https://github.com/ueberdosis/tiptap.git
synced 2025-01-18 06:03:22 +08:00
Merge branch 'main' of https://github.com/ueberdosis/tiptap-next into main
This commit is contained in:
commit
8c3f69e2fd
@ -19,9 +19,17 @@ export class AnnotationState {
|
||||
|
||||
constructor(options: AnnotationStateOptions) {
|
||||
this.options = options
|
||||
|
||||
// TODO: Observe Y.js changes and re-render decorations
|
||||
// this.options.map.observe(e => {
|
||||
// console.log('e', e)
|
||||
// })
|
||||
}
|
||||
|
||||
findAnnotation(id: number) {
|
||||
// TODO: Get from Y.js?
|
||||
// this.decorations.get(id)
|
||||
|
||||
const current = this.decorations.find()
|
||||
|
||||
for (let i = 0; i < current.length; i += 1) {
|
||||
|
@ -1,68 +0,0 @@
|
||||
// @ts-nocheck
|
||||
import { Extension } from '@tiptap/core'
|
||||
import { Decoration, DecorationSet } from 'prosemirror-view'
|
||||
import { Plugin } from 'prosemirror-state'
|
||||
|
||||
function detectColors(doc) {
|
||||
const hexColor = /(#[0-9a-f]{3,6})\b/ig
|
||||
const results = []
|
||||
const decorations: [any?] = []
|
||||
|
||||
doc.descendants((node: any, position: any) => {
|
||||
if (!node.isText) {
|
||||
return
|
||||
}
|
||||
|
||||
let matches
|
||||
|
||||
// eslint-disable-next-line
|
||||
while (matches = hexColor.exec(node.text)) {
|
||||
results.push({
|
||||
color: matches[0],
|
||||
from: position + matches.index,
|
||||
to: position + matches.index + matches[0].length,
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
results.forEach(issue => {
|
||||
decorations.push(Decoration.inline(issue.from, issue.to, {
|
||||
class: 'color',
|
||||
style: `--color: ${issue.color}`,
|
||||
}))
|
||||
})
|
||||
|
||||
return DecorationSet.create(doc, decorations)
|
||||
}
|
||||
|
||||
export const Color = Extension.create({
|
||||
name: 'color',
|
||||
|
||||
addProseMirrorPlugins() {
|
||||
return [
|
||||
new Plugin({
|
||||
state: {
|
||||
init(_, { doc }) {
|
||||
return detectColors(doc)
|
||||
},
|
||||
apply(transaction, oldState) {
|
||||
return transaction.docChanged
|
||||
? detectColors(transaction.doc)
|
||||
: oldState
|
||||
},
|
||||
},
|
||||
props: {
|
||||
decorations(state) {
|
||||
return this.getState(state)
|
||||
},
|
||||
},
|
||||
}),
|
||||
]
|
||||
},
|
||||
})
|
||||
|
||||
declare module '@tiptap/core' {
|
||||
interface AllExtensions {
|
||||
Color: typeof Color,
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
import { Color } from './Color'
|
||||
|
||||
export * from './Color'
|
||||
export default Color
|
@ -1,76 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<editor-content :editor="editor" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Editor, EditorContent } from '@tiptap/vue-starter-kit'
|
||||
import Document from '@tiptap/extension-document'
|
||||
import Text from '@tiptap/extension-text'
|
||||
import Paragraph from '@tiptap/extension-paragraph'
|
||||
import Heading from '@tiptap/extension-heading'
|
||||
import Color from './extension'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EditorContent,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
editor: null,
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.editor = new Editor({
|
||||
extensions: [
|
||||
Document,
|
||||
Paragraph,
|
||||
Heading,
|
||||
Text,
|
||||
Color,
|
||||
],
|
||||
content: `
|
||||
<p>
|
||||
For triplets with repeated values, you can eliminate the repetition by writing in shorthand, for instance, #00FFFF becomes #0FF. This system is easy for computers to understand, and it pretty short to write, which makes it useful for quick copy paste and designation in programming. If you’re going to work with colors in a more involved way, though, HSL is a little bit more human-readable.
|
||||
</p>
|
||||
<p>
|
||||
A few more examples: #FFF, #0D0D0D, #616161, #A975FF, #FB5151, #FD9170, #FFCB6B, #68CEF8, #80cbc4, #9DEF8F
|
||||
</p>
|
||||
`,
|
||||
})
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
this.editor.destroy()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
/* Basic editor styles */
|
||||
.ProseMirror {
|
||||
> * + * {
|
||||
margin-top: 0.75em;
|
||||
}
|
||||
}
|
||||
|
||||
.color {
|
||||
white-space: nowrap;
|
||||
|
||||
&::before {
|
||||
content: ' ';
|
||||
display: inline-block;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
border: 1px solid rgba(128, 128, 128, 0.3);
|
||||
vertical-align: middle;
|
||||
margin-right: 0.1em;
|
||||
margin-bottom: 0.15em;
|
||||
border-radius: 2px;
|
||||
background-color: var(--color);
|
||||
}
|
||||
}
|
||||
</style>
|
@ -3,12 +3,11 @@ Congratulations! You’ve found our playground with a list of experiments. Be aw
|
||||
|
||||
## New
|
||||
* [Linter](/experiments/linter)
|
||||
* [Comments](/experiments/comments)
|
||||
* [Color](/experiments/color)
|
||||
* [Commands](/experiments/commands)
|
||||
* [Embeds](/experiments/embeds)
|
||||
* [Multiple editors](/experiments/multiple-editors)
|
||||
* [Details](/experiments/details)
|
||||
* [@tiptap/extension-slash-command?](/experiments/commands)
|
||||
* [@tiptap/extension-iframe?](/experiments/embeds)
|
||||
* [@tiptap/extension-toggle-list?](/experiments/details)
|
||||
* [@tiptap/extension-collaboration-annotation?](/experiments/comments)
|
||||
|
||||
## Waiting for approval
|
||||
* [@tiptap/extension-placeholder](/experiments/placeholder)
|
||||
|
@ -1,5 +0,0 @@
|
||||
# Color
|
||||
|
||||
⚠️ Experiment
|
||||
|
||||
<demo name="Experiments/Color" />
|
@ -37,8 +37,27 @@ This will do the following:
|
||||
5. make the text editable (but that’s the default anyway), and
|
||||
6. disable the loading of [the default CSS](https://github.com/ueberdosis/tiptap-next/tree/main/packages/core/src/style.ts) (which is not much anyway).
|
||||
|
||||
## Configure extensions
|
||||
A lot of the extension can be configured, too. Add an `.configure()` to the extension and pass an object to it. The following example will disable the default heading levels 4, 5 and 6:
|
||||
## Nodes, marks and extensions
|
||||
Most features are packed into [nodes](/api/nodes), [marks](/api/marks) and [extensions](/api/extensions). Import what you need and pass them as an Array to the editor and you are good to go. Here is the minimal setup with only three extensions:
|
||||
|
||||
```js
|
||||
import { Editor } from '@tiptap/core'
|
||||
import Document from '@tiptap/extension-document'
|
||||
import Paragraph from '@tiptap/extension-paragraph'
|
||||
import Text from '@tiptap/extension-text'
|
||||
|
||||
new Editor({
|
||||
element: document.querySelector('.element'),
|
||||
extensions: [
|
||||
Document,
|
||||
Paragraph,
|
||||
Text,
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
### Configure an extensions
|
||||
Most extensions can be configured. Add a `.configure()` to pass an object to it. The following example will disable the default heading levels 4, 5 and 6:
|
||||
|
||||
```js
|
||||
import { Editor } from '@tiptap/core'
|
||||
@ -60,4 +79,57 @@ new Editor({
|
||||
})
|
||||
```
|
||||
|
||||
Have a look at the documentation of the extension you’re using to learn more about their settings.
|
||||
Have a look at the documentation of the extension you use to learn more about their settings.
|
||||
|
||||
### Default extensions
|
||||
We have put together a few of the most common extensions and provide a `defaultExtensions()` helper to load them. Here is how you to use that:
|
||||
|
||||
```js
|
||||
import { Editor, defaultExtensions } from '@tiptap/starter-kit'
|
||||
|
||||
new Editor({
|
||||
extensions: defaultExtensions(),
|
||||
})
|
||||
```
|
||||
|
||||
And you can even pass configuration for all default extensions as an object. Just prefix the configuration with the extension name:
|
||||
|
||||
```js
|
||||
import { Editor, defaultExtensions } from '@tiptap/starter-kit'
|
||||
|
||||
new Editor({
|
||||
extensions: defaultExtensions({
|
||||
heading: {
|
||||
levels: [1, 2, 3]
|
||||
},
|
||||
}),
|
||||
})
|
||||
```
|
||||
|
||||
The `defaultExtensions()` function returns an array, so if you want to load them and add some custom extensions you could write it like that:
|
||||
|
||||
```js
|
||||
import { Editor, defaultExtensions } from '@tiptap/starter-kit'
|
||||
import Strike from '@tiptap/extension-strike'
|
||||
|
||||
new Editor({
|
||||
extensions: [
|
||||
...defaultExtensions(),
|
||||
Strike,
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
Don’t want to load a specific extension? Just filter it out:
|
||||
|
||||
```js
|
||||
import { Editor, defaultExtensions } from '@tiptap/starter-kit'
|
||||
|
||||
new Editor({
|
||||
extensions: [
|
||||
...defaultExtensions().filter(extension => extension.config.name !== 'history'),
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
You’ll probably see something like that in collaborative editing examples. The [`Collaboration`](/api/extensions/collaboration) comes with its own history extension, you need to remove the default [`History`](/api/extensions/history) extension to avoid conflicts.
|
||||
|
Loading…
Reference in New Issue
Block a user