experiments: add a figure + figcaption node
This commit is contained in:
104
docs/src/demos/Experiments/Figure/figure.ts
Normal file
104
docs/src/demos/Experiments/Figure/figure.ts
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
import {
|
||||||
|
Command,
|
||||||
|
Node,
|
||||||
|
nodeInputRule,
|
||||||
|
} from '@tiptap/core'
|
||||||
|
|
||||||
|
export interface FigureOptions {
|
||||||
|
HTMLAttributes: Record<string, any>,
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '@tiptap/core' {
|
||||||
|
interface Commands {
|
||||||
|
figure: {
|
||||||
|
/**
|
||||||
|
* Add a figure element
|
||||||
|
*/
|
||||||
|
setFigure: (options: { src: string, alt?: string, title?: string }) => Command,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const inputRegex = /!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\)/
|
||||||
|
|
||||||
|
export const Figure = Node.create<FigureOptions>({
|
||||||
|
name: 'figure',
|
||||||
|
|
||||||
|
defaultOptions: {
|
||||||
|
// inline: false,
|
||||||
|
HTMLAttributes: {},
|
||||||
|
},
|
||||||
|
|
||||||
|
group: 'block',
|
||||||
|
|
||||||
|
content: 'inline*',
|
||||||
|
|
||||||
|
draggable: true,
|
||||||
|
|
||||||
|
addAttributes() {
|
||||||
|
return {
|
||||||
|
src: {
|
||||||
|
default: null,
|
||||||
|
parseHTML: element => {
|
||||||
|
return {
|
||||||
|
src: element.querySelector('img')?.getAttribute('src'),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
alt: {
|
||||||
|
default: null,
|
||||||
|
parseHTML: element => {
|
||||||
|
return {
|
||||||
|
alt: element.querySelector('img')?.getAttribute('alt'),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
default: null,
|
||||||
|
parseHTML: element => {
|
||||||
|
return {
|
||||||
|
title: element.querySelector('img')?.getAttribute('title'),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
parseHTML() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
tag: 'figure',
|
||||||
|
contentELement: 'figcaption',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
renderHTML({ HTMLAttributes }) {
|
||||||
|
return [
|
||||||
|
'figure', this.options.HTMLAttributes,
|
||||||
|
['img', HTMLAttributes],
|
||||||
|
['figcaption', 0],
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
addCommands() {
|
||||||
|
return {
|
||||||
|
setFigure: options => ({ commands }) => {
|
||||||
|
return commands.insertContent({
|
||||||
|
type: this.name,
|
||||||
|
attrs: options,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
addInputRules() {
|
||||||
|
return [
|
||||||
|
nodeInputRule(inputRegex, this.type, match => {
|
||||||
|
const [, alt, src, title] = match
|
||||||
|
|
||||||
|
return { src, alt, title }
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
},
|
||||||
|
})
|
||||||
81
docs/src/demos/Experiments/Figure/index.vue
Normal file
81
docs/src/demos/Experiments/Figure/index.vue
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="editor">
|
||||||
|
<editor-content :editor="editor" />
|
||||||
|
|
||||||
|
<h2>HTML</h2>
|
||||||
|
{{ editor.getHTML() }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Editor, EditorContent } from '@tiptap/vue-2'
|
||||||
|
import StarterKit from '@tiptap/starter-kit'
|
||||||
|
import { Figure } from './figure'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
EditorContent,
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
editor: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.editor = new Editor({
|
||||||
|
extensions: [
|
||||||
|
StarterKit,
|
||||||
|
Figure,
|
||||||
|
],
|
||||||
|
content: `
|
||||||
|
<p>Figure + Figcaption</p>
|
||||||
|
<figure>
|
||||||
|
<img src="https://source.unsplash.com/8xznAGy4HcY/800x400" alt="Random photo of something" title="Who’s dat?">
|
||||||
|
<figcaption>
|
||||||
|
<p>Amazing caption</p>
|
||||||
|
</figcaption>
|
||||||
|
</figure>
|
||||||
|
<p>That’s it.</p>
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
this.editor.destroy()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
::v-deep {
|
||||||
|
.ProseMirror {
|
||||||
|
> * + * {
|
||||||
|
margin-top: 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
figure {
|
||||||
|
max-width: 25rem;
|
||||||
|
border: 3px solid #0D0D0D;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
margin: 1rem 0;
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
figcaption {
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
text-align: center;
|
||||||
|
padding: 0.5rem;
|
||||||
|
border: 2px dashed #0D0D0D20;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -11,3 +11,4 @@ Congratulations! You’ve found our playground with a list of experiments. Be aw
|
|||||||
* [@tiptap/extension-collaboration-annotation](/experiments/collaboration-annotation)
|
* [@tiptap/extension-collaboration-annotation](/experiments/collaboration-annotation)
|
||||||
* [@tiptap/extension-word-break](/experiments/word-break)
|
* [@tiptap/extension-word-break](/experiments/word-break)
|
||||||
* [@tiptap/extension-trailing-node](/experiments/trailing-node)
|
* [@tiptap/extension-trailing-node](/experiments/trailing-node)
|
||||||
|
* [@tiptap/extension-figure](/experiments/figure)
|
||||||
|
|||||||
17
docs/src/docPages/experiments/figure.md
Normal file
17
docs/src/docPages/experiments/figure.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Figure
|
||||||
|
|
||||||
|
⚠️ Experiment
|
||||||
|
|
||||||
|
## Known issues
|
||||||
|
* Dragging should move the image, but duplicates it
|
||||||
|
|
||||||
|
## Tasks
|
||||||
|
* Add the caption as an optional parameter to the command
|
||||||
|
* Build commands to wrap an image into a figure + figcaption?
|
||||||
|
* Build commands to unrwap figure + figcaption to an image?
|
||||||
|
|
||||||
|
## Related links
|
||||||
|
* https://github.com/ueberdosis/tiptap/issues/573#issuecomment-730122427
|
||||||
|
* https://discuss.prosemirror.net/t/figure-and-editable-caption/462/5
|
||||||
|
|
||||||
|
<demo name="Experiments/Figure" />
|
||||||
Reference in New Issue
Block a user