Add image component for editor (#57)
* Add image component * More image editor * add more image changes
This commit is contained in:
51
packages/email-editor/src/extensions/ImageExtension.tsx
Normal file
51
packages/email-editor/src/extensions/ImageExtension.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
import { ReactNodeViewRenderer } from "@tiptap/react";
|
||||
import TipTapImage from "@tiptap/extension-image";
|
||||
import { ResizableImageTemplate } from "../nodes/image-resize";
|
||||
|
||||
const BORDER_COLOR = "#0096fd";
|
||||
|
||||
export const ResizableImageExtension = TipTapImage.extend({
|
||||
addAttributes() {
|
||||
return {
|
||||
...this.parent?.(),
|
||||
width: { renderHTML: ({ width }) => ({ width }), default: "600" },
|
||||
height: { renderHTML: ({ height }) => ({ height }) },
|
||||
borderRadius: {
|
||||
default: "0",
|
||||
},
|
||||
borderWidth: {
|
||||
default: "0",
|
||||
},
|
||||
borderColor: {
|
||||
default: "rgb(0, 0, 0)",
|
||||
},
|
||||
alignment: {
|
||||
default: "center",
|
||||
renderHTML: ({ alignment }) => ({ "data-alignment": alignment }),
|
||||
parseHTML: (element) =>
|
||||
element.getAttribute("data-alignment") || "center",
|
||||
},
|
||||
externalLink: {
|
||||
default: null,
|
||||
renderHTML: ({ externalLink }) => {
|
||||
if (!externalLink) {
|
||||
return {};
|
||||
}
|
||||
return {
|
||||
"data-external-link": externalLink,
|
||||
};
|
||||
},
|
||||
parseHTML: (element) => {
|
||||
const externalLink = element.getAttribute("data-external-link");
|
||||
return externalLink ? { externalLink } : null;
|
||||
},
|
||||
},
|
||||
alt: {
|
||||
default: "image",
|
||||
},
|
||||
};
|
||||
},
|
||||
addNodeView() {
|
||||
return ReactNodeViewRenderer(ResizableImageTemplate);
|
||||
},
|
||||
});
|
@@ -8,6 +8,7 @@ import {
|
||||
Heading1Icon,
|
||||
Heading2Icon,
|
||||
Heading3Icon,
|
||||
ImageIcon,
|
||||
ListIcon,
|
||||
ListOrderedIcon,
|
||||
RectangleEllipsisIcon,
|
||||
@@ -151,70 +152,22 @@ const DEFAULT_SLASH_COMMANDS: SlashCommandItem[] = [
|
||||
editor.chain().focus().deleteRange(range).toggleOrderedList().run();
|
||||
},
|
||||
},
|
||||
// {
|
||||
// title: "Image",
|
||||
// description: "Full width image",
|
||||
// searchTerms: ["image"],
|
||||
// icon: <ImageIcon className="h-4 w-4" />,
|
||||
// command: ({ editor, range }: CommandProps) => {
|
||||
// const imageUrl = prompt("Image URL: ") || "";
|
||||
{
|
||||
title: "Image",
|
||||
description: "Full width image",
|
||||
searchTerms: ["image"],
|
||||
icon: <ImageIcon className="h-4 w-4" />,
|
||||
command: ({ editor, range }: CommandProps) => {
|
||||
const imageUrl = prompt("Image URL: ") || "";
|
||||
|
||||
// if (!imageUrl) {
|
||||
// return;
|
||||
// }
|
||||
if (!imageUrl) {
|
||||
return;
|
||||
}
|
||||
|
||||
// editor.chain().focus().deleteRange(range).run();
|
||||
// editor.chain().focus().setImage({ src: imageUrl }).run();
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// title: "Logo",
|
||||
// description: "Add your brand logo",
|
||||
// searchTerms: ["image", "logo"],
|
||||
// icon: <ImageIcon className="h-4 w-4" />,
|
||||
// command: ({ editor, range }: CommandProps) => {
|
||||
// const logoUrl = prompt("Logo URL: ") || "";
|
||||
|
||||
// if (!logoUrl) {
|
||||
// return;
|
||||
// }
|
||||
// editor.chain().focus().deleteRange(range).run();
|
||||
// editor.chain().focus().setLogoImage({ src: logoUrl }).run();
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// title: "Spacer",
|
||||
// description:
|
||||
// "Add a spacer to email. Useful for adding space between sections.",
|
||||
// searchTerms: ["space", "gap", "divider"],
|
||||
// icon: <MoveVertical className="h-4 w-4" />,
|
||||
// command: ({ editor, range }: CommandProps) => {
|
||||
// editor
|
||||
// .chain()
|
||||
// .focus()
|
||||
// .deleteRange(range)
|
||||
// .setSpacer({ height: "sm" })
|
||||
// .run();
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// title: "Button",
|
||||
// description: "Add a call to action button to email.",
|
||||
// searchTerms: ["link", "button", "cta"],
|
||||
// icon: <MousePointer className="h-4 w-4" />,
|
||||
// command: ({ editor, range }: CommandProps) => {
|
||||
// editor.chain().focus().deleteRange(range).setButton().run();
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// title: "Link Card",
|
||||
// description: "Add a link card to email.",
|
||||
// searchTerms: ["link", "button", "image"],
|
||||
// icon: <ArrowUpRightSquare className="h-4 w-4" />,
|
||||
// command: ({ editor, range }: CommandProps) => {
|
||||
// editor.chain().focus().deleteRange(range).setLinkCard().run();
|
||||
// },
|
||||
// },
|
||||
editor.chain().focus().deleteRange(range).run();
|
||||
editor.chain().focus().setImage({ src: imageUrl }).run();
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Hard Break",
|
||||
description: "Add a break between lines.",
|
||||
|
@@ -16,6 +16,7 @@ import { SlashCommand, getSlashCommandSuggestions } from "./SlashCommand";
|
||||
import { VariableExtension } from "./VariableExtension";
|
||||
import { getVariableSuggestions } from "../nodes/variable";
|
||||
import { UnsubscribeFooterExtension } from "./UnsubsubscribeExtension";
|
||||
import { ResizableImageExtension } from "./ImageExtension";
|
||||
|
||||
export function extensions({ variables }: { variables?: Array<string> }) {
|
||||
const extensions = [
|
||||
@@ -74,6 +75,7 @@ export function extensions({ variables }: { variables?: Array<string> }) {
|
||||
suggestion: getVariableSuggestions(variables),
|
||||
}),
|
||||
UnsubscribeFooterExtension,
|
||||
ResizableImageExtension,
|
||||
];
|
||||
|
||||
return extensions;
|
||||
|
Reference in New Issue
Block a user