diff --git a/.env.example b/.env.example
index a2ab1826..ae4a3763 100644
--- a/.env.example
+++ b/.env.example
@@ -22,4 +22,4 @@ FROM_EMAIL="hello@usesend.com"
API_RATE_LIMIT=2
AUTH_EMAIL_RATE_LIMIT=5
-NEXT_PUBLIC_IS_CLOUD=true
+NEXT_PUBLIC_IS_CLOUD=true
\ No newline at end of file
diff --git a/packages/email-editor/src/menus/TextMenu.tsx b/packages/email-editor/src/menus/TextMenu.tsx
index f7df6871..5d439794 100644
--- a/packages/email-editor/src/menus/TextMenu.tsx
+++ b/packages/email-editor/src/menus/TextMenu.tsx
@@ -1,4 +1,9 @@
-import { BubbleMenu, BubbleMenuProps, isTextSelection } from "@tiptap/react";
+import {
+ BubbleMenu,
+ BubbleMenuProps,
+ Editor,
+ isTextSelection,
+} from "@tiptap/react";
import {
AlignCenterIcon,
AlignLeftIcon,
@@ -20,16 +25,13 @@ import {
TextQuoteIcon,
UnderlineIcon,
} from "lucide-react";
-import { TextMenuButton } from "./TextMenuButton";
-import { Button } from "@usesend/ui/src/button";
-import {
- Popover,
- PopoverContent,
- PopoverTrigger,
-} from "@usesend/ui/src/popover";
-import { Separator } from "@usesend/ui/src/separator";
-import { useMemo, useState } from "react";
-import { LinkEditorPanel } from "../components/panels/LinkEditorPanel";
+import {TextMenuButton} from "./TextMenuButton";
+import {Button} from "@usesend/ui/src/button";
+import {Popover, PopoverContent, PopoverTrigger} from "@usesend/ui/src/popover";
+import {Separator} from "@usesend/ui/src/separator";
+import {useMemo, useState} from "react";
+import {LinkEditorPanel} from "../components/panels/LinkEditorPanel";
+import {EditorState} from "@tiptap/pm/state";
// import { allowedLogoAlignment } from "../nodes/logo";
export interface TextMenuItem {
@@ -92,15 +94,15 @@ const textColors = [
];
export function TextMenu(props: TextMenuProps) {
- const { editor } = props;
+ const {editor} = props;
const icons = [AlignLeftIcon, AlignCenterIcon, AlignRightIcon];
const alignmentItems: TextMenuItem[] = ["left", "center", "right"].map(
(alignment, index) => ({
name: alignment,
- isActive: () => editor?.isActive({ textAlign: alignment })!,
+ isActive: () => editor?.isActive({textAlign: alignment})!,
command: () => {
- if (props?.editor?.isActive({ textAlign: alignment })) {
+ if (props?.editor?.isActive({textAlign: alignment})) {
props?.editor?.chain()?.focus().unsetTextAlign().run();
} else {
props?.editor?.chain().focus().setTextAlign(alignment).run()!;
@@ -185,11 +187,11 @@ export function TextMenu(props: TextMenuProps) {
.focus()
.lift("taskItem")
.liftListItem("listItem")
- .setHeading({ level: 1 })
+ .setHeading({level: 1})
.run(),
id: "heading1",
- disabled: () => !editor?.can().setHeading({ level: 1 }),
- isActive: () => editor?.isActive("heading", { level: 1 }),
+ disabled: () => !editor?.can().setHeading({level: 1}),
+ isActive: () => editor?.isActive("heading", {level: 1}),
label: "Heading 1",
type: "option",
},
@@ -201,11 +203,11 @@ export function TextMenu(props: TextMenuProps) {
?.focus()
?.lift("taskItem")
.liftListItem("listItem")
- .setHeading({ level: 2 })
+ .setHeading({level: 2})
.run(),
id: "heading2",
- disabled: () => !editor?.can().setHeading({ level: 2 }),
- isActive: () => editor?.isActive("heading", { level: 2 }),
+ disabled: () => !editor?.can().setHeading({level: 2}),
+ isActive: () => editor?.isActive("heading", {level: 2}),
label: "Heading 2",
type: "option",
},
@@ -217,11 +219,11 @@ export function TextMenu(props: TextMenuProps) {
?.focus()
?.lift("taskItem")
.liftListItem("listItem")
- .setHeading({ level: 3 })
+ .setHeading({level: 3})
.run(),
id: "heading3",
- disabled: () => !editor?.can().setHeading({ level: 3 }),
- isActive: () => editor?.isActive("heading", { level: 3 }),
+ disabled: () => !editor?.can().setHeading({level: 3}),
+ isActive: () => editor?.isActive("heading", {level: 3}),
label: "Heading 3",
type: "option",
},
@@ -249,9 +251,9 @@ export function TextMenu(props: TextMenuProps) {
const bubbleMenuProps: TextMenuProps = {
...props,
- shouldShow: ({ editor, state, from, to }) => {
- const { doc, selection } = state;
- const { empty } = selection;
+ shouldShow: ({editor, state, from, to}) => {
+ const {doc, selection} = state;
+ const {empty} = selection;
// Sometime check for `empty` is not enough.
// Doubleclick an empty paragraph returns a node size of 2.
@@ -300,11 +302,7 @@ export function TextMenu(props: TextMenuProps) {
{
- editor
- ?.chain()
- .focus()
- .setLink({ href: url, target: "_blank" })
- .run();
+ editor?.chain().focus().setLink({href: url, target: "_blank"}).run();
// editor?.commands.blur();
}}
@@ -320,7 +318,7 @@ export function TextMenu(props: TextMenuProps) {
variant="ghost"
className="hover:bg-slate-100 hover:text-slate-900"
>
- A
+ A
@@ -341,7 +339,7 @@ export function TextMenu(props: TextMenuProps) {
: ""
}`}
>
- A
+ A
{color.name}
))}
@@ -355,7 +353,7 @@ type ContentTypePickerProps = {
options: ContentTypePickerOption[];
};
-function ContentTypePicker({ options }: ContentTypePickerProps) {
+function ContentTypePicker({options}: ContentTypePickerProps) {
const activeOption = useMemo(
() => options.find((option) => option.isActive()),
[options]
@@ -401,7 +399,7 @@ type EditLinkPopoverType = {
onSetLink: (url: string) => void;
};
-function EditLinkPopover({ onSetLink }: EditLinkPopoverType) {
+function EditLinkPopover({onSetLink}: EditLinkPopoverType) {
return (
diff --git a/packages/email-editor/src/nodes/variable.tsx b/packages/email-editor/src/nodes/variable.tsx
index 0788da5b..84f3ed7b 100644
--- a/packages/email-editor/src/nodes/variable.tsx
+++ b/packages/email-editor/src/nodes/variable.tsx
@@ -1,16 +1,12 @@
-import { NodeViewProps, NodeViewWrapper, ReactRenderer } from "@tiptap/react";
-import {
- Popover,
- PopoverContent,
- PopoverTrigger,
-} from "@usesend/ui/src/popover";
-import { cn } from "@usesend/ui/lib/utils";
-import { Input } from "@usesend/ui/src/input";
-import { Button } from "@usesend/ui/src/button";
-import { forwardRef, useEffect, useImperativeHandle, useState } from "react";
-import { SuggestionOptions } from "@tiptap/suggestion";
-import tippy, { GetReferenceClientRect } from "tippy.js";
-import { CheckIcon, TriangleAlert } from "lucide-react";
+import {NodeViewProps, NodeViewWrapper, ReactRenderer} from "@tiptap/react";
+import {Popover, PopoverContent, PopoverTrigger} from "@usesend/ui/src/popover";
+import {cn} from "@usesend/ui/lib/utils";
+import {Input} from "@usesend/ui/src/input";
+import {Button} from "@usesend/ui/src/button";
+import {forwardRef, useEffect, useImperativeHandle, useState} from "react";
+import {SuggestionOptions} from "@tiptap/suggestion";
+import tippy, {GetReferenceClientRect} from "tippy.js";
+import {CheckIcon, TriangleAlert} from "lucide-react";
export interface VariableOptions {
name: string;
@@ -26,14 +22,14 @@ export const VariableList = forwardRef((props: any, ref) => {
console.log("item: ", item);
if (item) {
- props.command({ id: item, name: item, fallback: "" });
+ props.command({id: item, name: item, fallback: ""});
}
};
useEffect(() => setSelectedIndex(0), [props.items]);
useImperativeHandle(ref, () => ({
- onKeyDown: ({ event }: { event: KeyboardEvent }) => {
+ onKeyDown: ({event}: {event: KeyboardEvent}) => {
if (event.key === "ArrowUp") {
setSelectedIndex(
(selectedIndex + props.items.length - 1) % props.items.length
@@ -85,7 +81,7 @@ export function getVariableSuggestions(
variables: Array = []
): Omit {
return {
- items: ({ query }) => {
+ items: ({query}) => {
return variables
.concat(query.length > 0 ? [query] : [])
.filter((item) => item.toLowerCase().startsWith(query.toLowerCase()))
@@ -154,9 +150,10 @@ export function getVariableSuggestions(
}
export function VariableComponent(props: NodeViewProps) {
- const { name, fallback } = props.node.attrs as VariableOptions;
+ const [isEditing, setIsEditing] = useState(false);
+ const {name, fallback} = props.node.attrs as VariableOptions;
const [fallbackValue, setFallbackValue] = useState(fallback);
- const { getPos, editor } = props;
+ const {getPos, editor} = props;
console.log(props.selected);
@@ -165,6 +162,8 @@ export function VariableComponent(props: NodeViewProps) {
props.updateAttributes({
fallback: fallbackValue,
});
+
+ setIsEditing(false);
};
return (
@@ -175,17 +174,26 @@ export function VariableComponent(props: NodeViewProps) {
draggable="false"
data-drag-handle=""
>
-
+ !open && setIsEditing(false)}
+ >