forked from github/plane
link form removed
This commit is contained in:
parent
2ac72651d1
commit
d500dbc2e1
@ -2,7 +2,7 @@ import { Editor } from "@tiptap/core";
|
|||||||
import { Check, Trash } from "lucide-react";
|
import { Check, Trash } from "lucide-react";
|
||||||
import { Dispatch, FC, SetStateAction, useEffect, useRef } from "react";
|
import { Dispatch, FC, SetStateAction, useEffect, useRef } from "react";
|
||||||
import { cn } from "../utils";
|
import { cn } from "../utils";
|
||||||
|
import isValidHttpUrl from "./utils/link-validator";
|
||||||
interface LinkSelectorProps {
|
interface LinkSelectorProps {
|
||||||
editor: Editor;
|
editor: Editor;
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
@ -38,14 +38,7 @@ export const LinkSelector: FC<LinkSelectorProps> = ({ editor, isOpen, setIsOpen
|
|||||||
</p>
|
</p>
|
||||||
</button>
|
</button>
|
||||||
{isOpen && (
|
{isOpen && (
|
||||||
<form
|
<div
|
||||||
onSubmit={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
const form = e.target as HTMLFormElement;
|
|
||||||
const input = form.elements[0] as HTMLInputElement;
|
|
||||||
editor.chain().focus().setLink({ href: input.value }).run();
|
|
||||||
setIsOpen(false);
|
|
||||||
}}
|
|
||||||
className="fixed top-full z-[99999] mt-1 flex w-60 overflow-hidden rounded border border-custom-border-300 bg-custom-background-100 dow-xl animate-in fade-in slide-in-from-top-1"
|
className="fixed top-full z-[99999] mt-1 flex w-60 overflow-hidden rounded border border-custom-border-300 bg-custom-background-100 dow-xl animate-in fade-in slide-in-from-top-1"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
@ -57,6 +50,7 @@ export const LinkSelector: FC<LinkSelectorProps> = ({ editor, isOpen, setIsOpen
|
|||||||
/>
|
/>
|
||||||
{editor.getAttributes("link").href ? (
|
{editor.getAttributes("link").href ? (
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
className="flex items-center rounded-sm p-1 text-red-600 transition-all hover:bg-red-100 dark:hover:bg-red-800"
|
className="flex items-center rounded-sm p-1 text-red-600 transition-all hover:bg-red-100 dark:hover:bg-red-800"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
editor.chain().focus().unsetLink().run();
|
editor.chain().focus().unsetLink().run();
|
||||||
@ -66,11 +60,20 @@ export const LinkSelector: FC<LinkSelectorProps> = ({ editor, isOpen, setIsOpen
|
|||||||
<Trash className="h-4 w-4" />
|
<Trash className="h-4 w-4" />
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<button className="flex items-center rounded-sm p-1 text-custom-text-300 transition-all hover:bg-custom-background-90">
|
<button className="flex items-center rounded-sm p-1 text-custom-text-300 transition-all hover:bg-custom-background-90" type="button"
|
||||||
|
onClick={() => {
|
||||||
|
const input = inputRef.current;
|
||||||
|
const url = input?.value;
|
||||||
|
if (url && isValidHttpUrl(url)) {
|
||||||
|
editor.chain().focus().setLink({ href: url }).run();
|
||||||
|
setIsOpen(false);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Check className="h-4 w-4" />
|
<Check className="h-4 w-4" />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</form>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
export default function isValidHttpUrl(string: string): boolean {
|
||||||
|
let url;
|
||||||
|
|
||||||
|
try {
|
||||||
|
url = new URL(string);
|
||||||
|
} catch (_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return url.protocol === "http:" || url.protocol === "https:";
|
||||||
|
}
|
||||||
|
|
@ -21,6 +21,7 @@ import "highlight.js/styles/github-dark.css";
|
|||||||
import UploadImagesPlugin from "../plugins/upload-image";
|
import UploadImagesPlugin from "../plugins/upload-image";
|
||||||
import UniqueID from "@tiptap-pro/extension-unique-id";
|
import UniqueID from "@tiptap-pro/extension-unique-id";
|
||||||
import UpdatedImage from "./updated-image";
|
import UpdatedImage from "./updated-image";
|
||||||
|
import isValidHttpUrl from "../bubble-menu/utils/link-validator";
|
||||||
|
|
||||||
lowlight.registerLanguage("ts", ts);
|
lowlight.registerLanguage("ts", ts);
|
||||||
|
|
||||||
@ -94,6 +95,8 @@ export const TiptapExtensions = [
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
TiptapLink.configure({
|
TiptapLink.configure({
|
||||||
|
protocols: ["http", "https"],
|
||||||
|
validate: (url) => isValidHttpUrl(url),
|
||||||
HTMLAttributes: {
|
HTMLAttributes: {
|
||||||
class:
|
class:
|
||||||
"text-custom-primary-300 underline underline-offset-[3px] hover:text-custom-primary-500 transition-colors cursor-pointer",
|
"text-custom-primary-300 underline underline-offset-[3px] hover:text-custom-primary-500 transition-colors cursor-pointer",
|
||||||
|
Loading…
Reference in New Issue
Block a user