Skip to content
This repository has been archived by the owner on Nov 29, 2023. It is now read-only.

Commit

Permalink
feat: add image resize support
Browse files Browse the repository at this point in the history
  • Loading branch information
ruibaby committed Nov 25, 2022
1 parent 40dc46b commit 9418829
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 10 deletions.
1 change: 1 addition & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ module.exports = {
rules: {
"vue/multi-word-component-names": 0,
"@typescript-eslint/ban-ts-comment": 0,
"@typescript-eslint/no-explicit-any": "off",
},
};
1 change: 1 addition & 0 deletions packages/editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"@tiptap/extension-underline": "2.0.0-beta.202",
"@tiptap/suggestion": "2.0.0-beta.202",
"@tiptap/vue-3": "2.0.0-beta.202",
"@vueuse/core": "^9.6.0",
"floating-vue": "2.0.0-beta.20",
"katex": "^0.16.3",
"lowlight": "^2.7.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/editor/src/components/Editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ defineProps({
<div class="h-full flex flex-row w-full">
<editor-content
:editor="editor"
class="editor-content prose prose-base !max-w-none prose-pre:p-0 bg-white prose-p:mt-3 prose-p:mb-3"
class="editor-content prose prose-base !max-w-none prose-pre:p-0 bg-white prose-p:mt-3 prose-p:mb-3 prose-img:mt-0 prose-img:mb-0"
/>
<div class="h-full">
<slot name="extra"></slot>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
<script lang="ts" setup>
import { NodeViewContent, nodeViewProps, NodeViewWrapper } from "@tiptap/vue-3";
import type { Node as ProseMirrorNode } from "prosemirror-model";
import type { Decoration } from "prosemirror-view";
import { NodeViewContent, NodeViewWrapper, Editor, Node } from "@tiptap/vue-3";
import lowlight from "./lowlight";
import { computed } from "vue";
const props = defineProps(nodeViewProps);
const props = defineProps<{
editor: Editor;
node: ProseMirrorNode;
decorations: Decoration[];
selected: boolean;
extension: Node<any, any>;
getPos: () => number;
updateAttributes: (attributes: Record<string, any>) => void;
deleteNode: () => void;
}>();
const languages = computed(() => {
return lowlight.listLanguages();
Expand Down
62 changes: 62 additions & 0 deletions packages/editor/src/extensions/image/ImageView.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<script lang="ts" setup>
import type { Node as ProseMirrorNode } from "prosemirror-model";
import type { Decoration } from "prosemirror-view";
import { Editor, NodeViewWrapper, Node } from "@tiptap/vue-3";
import { computed, ref } from "vue";
import { useResizeObserver } from "@vueuse/core";
const props = defineProps<{
editor: Editor;
node: ProseMirrorNode;
decorations: Decoration[];
selected: boolean;
extension: Node<any, any>;
getPos: () => number;
updateAttributes: (attributes: Record<string, any>) => void;
deleteNode: () => void;
}>();
const src = computed(() => {
return props.node.attrs.src;
});
const alt = computed({
get: () => {
return props.node?.attrs.alt;
},
set: (alt: string) => {
props.updateAttributes({ alt: alt });
},
});
const resizeRef = ref<HTMLElement>();
useResizeObserver(resizeRef, (entries) => {
const entry = entries[0];
const { width, height } = entry.contentRect;
props.updateAttributes({ width: width, height: height });
});
</script>

<template>
<node-view-wrapper as="div">
<div
ref="resizeRef"
class="resize mt-4 mb-4 inline-block overflow-hidden transition-all text-center relative"
:class="{
'ring-2 rounded': selected,
}"
:style="{
width: `${props.node.attrs.width}px`,
height: `${props.node.attrs.height}px`,
}"
>
<img
:src="src"
:title="node.attrs.title"
:alt="alt"
class="w-full h-full"
/>
</div>
</node-view-wrapper>
</template>
59 changes: 59 additions & 0 deletions packages/editor/src/extensions/image/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import TiptapImage from "@tiptap/extension-image";
import { VueNodeViewRenderer } from "@tiptap/vue-3";
import ImageView from "./ImageView.vue";

const Image = TiptapImage.extend({
inline() {
return true;
},

group() {
return "inline";
},

addAttributes() {
return {
...this.parent?.(),
width: {
default: null,
parseHTML: (element) => {
const width =
element.style.width || element.getAttribute("width") || null;
return width == null ? null : parseInt(width, 10);
},
renderHTML: (attributes) => {
return {
width: attributes.width,
};
},
},
height: {
default: null,
parseHTML: (element) => {
const height =
element.style.height || element.getAttribute("height") || null;
return height == null ? null : parseInt(height, 10);
},
renderHTML: (attributes) => {
return {
height: attributes.height,
};
},
},
};
},

addNodeView() {
return VueNodeViewRenderer(ImageView);
},

parseHTML() {
return [
{
tag: "img[src]",
},
];
},
});

export default Image;
9 changes: 2 additions & 7 deletions packages/editor/src/extensions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import ExtensionOrderedList from "@tiptap/extension-ordered-list";
import ExtensionParagraph from "@tiptap/extension-paragraph";
import ExtensionStrike from "@tiptap/extension-strike";
import ExtensionText from "@tiptap/extension-text";
import ExtensionImage from "@tiptap/extension-image";
import ExtensionImage from "./image";
import ExtensionTaskList from "@tiptap/extension-task-list";
import ExtensionTaskItem from "@tiptap/extension-task-item";
import ExtensionLink from "@tiptap/extension-link";
Expand Down Expand Up @@ -55,12 +55,7 @@ const allExtensions = [
ExtensionParagraph,
ExtensionStrike,
ExtensionText,
ExtensionImage.configure({
inline: true,
HTMLAttributes: {
loading: "lazy",
},
}),
ExtensionImage,
ExtensionTaskList,
ExtensionTaskItem,
ExtensionLink.configure({
Expand Down
44 changes: 44 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 9418829

Please sign in to comment.