feat(email): text colour menu in WYSIWYG (LinumIQ blue + presets)
This commit is contained in:
@@ -2,8 +2,19 @@ import { useEditor, EditorContent } from "@tiptap/react";
|
||||
import StarterKit from "@tiptap/starter-kit";
|
||||
import Link from "@tiptap/extension-link";
|
||||
import Image from "@tiptap/extension-image";
|
||||
import { TextStyle } from "@tiptap/extension-text-style";
|
||||
import { Color } from "@tiptap/extension-color";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
const PRESET_COLORS = [
|
||||
{ name: "Default", value: null as string | null },
|
||||
{ name: "LinumIQ blue", value: "#0883DA" },
|
||||
{ name: "Black", value: "#000000" },
|
||||
{ name: "Grey", value: "#6d7175" },
|
||||
{ name: "Red", value: "#d72c0d" },
|
||||
{ name: "Green", value: "#1a7e3a" },
|
||||
];
|
||||
|
||||
interface RichTextEditorProps {
|
||||
/** Hidden form field name; the rendered HTML is mirrored into it. */
|
||||
name: string;
|
||||
@@ -70,6 +81,8 @@ export function RichTextEditor({
|
||||
};
|
||||
},
|
||||
}).configure({ inline: false, allowBase64: true }),
|
||||
TextStyle,
|
||||
Color,
|
||||
],
|
||||
content: swapCidToLogo(defaultValue || "<p></p>", logoDataUrl),
|
||||
editorProps: {
|
||||
@@ -190,6 +203,8 @@ export function RichTextEditor({
|
||||
title="Insert/remove link"
|
||||
/>
|
||||
<Sep />
|
||||
<ColorMenu editor={editor} />
|
||||
<Sep />
|
||||
<ToolbarButton
|
||||
onClick={() => editor?.chain().focus().undo().run()}
|
||||
active={false}
|
||||
@@ -276,6 +291,51 @@ function Sep() {
|
||||
return <span aria-hidden style={{ width: 1, background: "#c9cccf", margin: "2px 4px" }} />;
|
||||
}
|
||||
|
||||
function ColorMenu({ editor }: { editor: ReturnType<typeof useEditor> | null }) {
|
||||
if (!editor) return null;
|
||||
return (
|
||||
<span style={{ display: "inline-flex", gap: 2, alignItems: "center" }} title="Text colour">
|
||||
{PRESET_COLORS.map((c) => (
|
||||
<button
|
||||
key={c.name}
|
||||
type="button"
|
||||
onClick={() =>
|
||||
c.value
|
||||
? editor.chain().focus().setColor(c.value).run()
|
||||
: editor.chain().focus().unsetColor().run()
|
||||
}
|
||||
title={c.name}
|
||||
style={{
|
||||
width: 20,
|
||||
height: 20,
|
||||
border: "1px solid #c9cccf",
|
||||
borderRadius: 4,
|
||||
background: c.value ?? "#fff",
|
||||
cursor: "pointer",
|
||||
position: "relative",
|
||||
}}
|
||||
>
|
||||
{c.value === null ? (
|
||||
<span
|
||||
aria-hidden
|
||||
style={{
|
||||
position: "absolute",
|
||||
inset: 0,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
fontSize: 11,
|
||||
}}
|
||||
>
|
||||
×
|
||||
</span>
|
||||
) : null}
|
||||
</button>
|
||||
))}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces `src="cid:invoice-logo"` with the supplied URL so the editor
|
||||
* can display the actual logo. Done as a string replace because TipTap
|
||||
|
||||
Reference in New Issue
Block a user