your personal website on atproto - mirror
blento.app
1<script lang="ts">
2 import { Button, Input } from '@foxui/core';
3 import type { Editor } from '@tiptap/core';
4
5 let {
6 editor,
7 link = $bindable(''),
8 ref = $bindable(null),
9 linkInput = $bindable(null)
10 }: {
11 editor: Editor | null;
12 link: string;
13 ref: HTMLElement | null;
14 linkInput: HTMLInputElement | null;
15 } = $props();
16
17 function processLink(link: string) {
18 return link.includes(':') ? link : `http://${link}`;
19 }
20</script>
21
22<div
23 bind:this={ref}
24 style="visibility: hidden; opacity: 0;"
25 class="menu bg-base-50 dark:bg-base-900 relative w-fit rounded-2xl px-1 py-1 shadow-lg backdrop-blur-sm"
26>
27 <div class="flex items-center gap-1">
28 <Input
29 bind:ref={linkInput}
30 sizeVariant="sm"
31 bind:value={link}
32 placeholder="Enter link"
33 onblur={() => {
34 if (link === '') {
35 editor?.chain().focus().extendMarkRange('link').unsetLink().run();
36 } else {
37 editor
38 ?.chain()
39 .focus()
40 .extendMarkRange('link')
41 .setLink({ href: processLink(link) })
42 .run();
43 }
44 }}
45 onkeydown={(e: KeyboardEvent) => {
46 if (e.key === 'Enter') {
47 if (link === '') {
48 editor?.chain().focus().extendMarkRange('link').unsetLink().run();
49 } else {
50 editor
51 ?.chain()
52 .focus()
53 .extendMarkRange('link')
54 .setLink({ href: processLink(link) })
55 .run();
56 }
57 }
58 }}
59 />
60 <Button
61 size="iconSm"
62 onclick={() => {
63 if (link === '') {
64 editor?.chain().focus().extendMarkRange('link').unsetLink().run();
65 } else {
66 editor
67 ?.chain()
68 .focus()
69 .extendMarkRange('link')
70 .setLink({ href: processLink(link) })
71 .run();
72 }
73 }}
74 >
75 <svg
76 xmlns="http://www.w3.org/2000/svg"
77 fill="none"
78 viewBox="0 0 24 24"
79 stroke-width="1.5"
80 stroke="currentColor"
81 class="size-6"
82 >
83 <path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5" />
84 </svg>
85
86 <span class="sr-only">save link</span>
87 </Button>
88 <Button
89 size="iconSm"
90 onclick={() => {
91 editor?.chain().focus().extendMarkRange('link').unsetLink().run();
92 }}
93 variant="ghost"
94 >
95 <svg
96 xmlns="http://www.w3.org/2000/svg"
97 fill="none"
98 viewBox="0 0 24 24"
99 stroke-width="1.5"
100 stroke="currentColor"
101 >
102 <path
103 stroke-linecap="round"
104 stroke-linejoin="round"
105 d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0"
106 />
107 </svg>
108 <span class="sr-only">remove link</span>
109 </Button>
110 </div>
111</div>