your personal website on atproto - mirror blento.app
at small-event-card-fixes 182 lines 6.3 kB view raw
1<script lang="ts"> 2 import { cn, Toggle, toggleVariants, Tooltip } from '@foxui/core'; 3 import type { Editor } from '@tiptap/core'; 4 import Select from './Select.svelte'; 5 import type { RichTextTypes } from '.'; 6 7 let { 8 editor, 9 isBold, 10 isImage, 11 isItalic, 12 isUnderline, 13 isStrikethrough, 14 isLink, 15 clickedLink, 16 selectedType = $bindable('paragraph'), 17 ref = $bindable(null), 18 processImageFile, 19 switchTo 20 }: { 21 editor: Editor | null; 22 isBold: boolean; 23 isImage: boolean; 24 isItalic: boolean; 25 isUnderline: boolean; 26 isStrikethrough: boolean; 27 isLink: boolean; 28 clickedLink: () => void; 29 selectedType: RichTextTypes; 30 ref: HTMLElement | null; 31 processImageFile: (file: File, input: HTMLInputElement) => void; 32 switchTo: (value: RichTextTypes) => void; 33 } = $props(); 34 35 function handleFileProcess(event: Event) { 36 const input = event.target as HTMLInputElement; 37 if (!input.files?.length) return; 38 const file = input.files[0]; 39 if (!file || !file.type.startsWith('image/')) return; 40 processImageFile(file, input); 41 } 42 43 let fileInput = $state<HTMLInputElement | null>(null); 44</script> 45 46<div 47 bind:this={ref} 48 style="visibility: hidden; opacity: 0;" 49 class="bg-base-50 dark:bg-base-900 border-base-500/20 dark:border-base-700/20 relative w-fit rounded-2xl border px-1 py-1 shadow-lg backdrop-blur-sm" 50> 51 <Select 52 onValueChange={(value) => { 53 switchTo(value as RichTextTypes); 54 }} 55 type="single" 56 items={[ 57 { value: 'paragraph', label: 'Text' }, 58 { value: 'heading-1', label: 'Heading 1' }, 59 { value: 'heading-2', label: 'Heading 2' }, 60 { value: 'heading-3', label: 'Heading 3' }, 61 { value: 'blockquote', label: 'Blockquote' }, 62 { value: 'code', label: 'Code Block' }, 63 { value: 'bullet-list', label: 'Bullet List' }, 64 { value: 'ordered-list', label: 'Ordered List' } 65 ]} 66 bind:value={selectedType} 67 /> 68 <!-- <Tooltip withContext text="Bold" delayDuration={0}> 69 {#snippet child({ props })} --> 70 <Toggle 71 size="sm" 72 onclick={() => editor?.chain().focus().toggleBold().run()} 73 bind:pressed={() => isBold, (bold) => {}} 74 > 75 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-6"> 76 <path 77 fill-rule="evenodd" 78 d="M5.246 3.744a.75.75 0 0 1 .75-.75h7.125a4.875 4.875 0 0 1 3.346 8.422 5.25 5.25 0 0 1-2.97 9.58h-7.5a.75.75 0 0 1-.75-.75V3.744Zm7.125 6.75a2.625 2.625 0 0 0 0-5.25H8.246v5.25h4.125Zm-4.125 2.251v6h4.5a3 3 0 0 0 0-6h-4.5Z" 79 clip-rule="evenodd" 80 /> 81 </svg> 82 83 <span class="sr-only">Bold</span> 84 </Toggle> 85 <!-- {/snippet} 86 </Tooltip> --> 87 <Toggle 88 size="sm" 89 onclick={() => editor?.chain().focus().toggleItalic().run()} 90 bind:pressed={() => isItalic, (italic) => {}} 91 > 92 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-6"> 93 <path 94 fill-rule="evenodd" 95 d="M10.497 3.744a.75.75 0 0 1 .75-.75h7.5a.75.75 0 0 1 0 1.5h-3.275l-5.357 15.002h2.632a.75.75 0 1 1 0 1.5h-7.5a.75.75 0 1 1 0-1.5h3.275l5.357-15.002h-2.632a.75.75 0 0 1-.75-.75Z" 96 clip-rule="evenodd" 97 /> 98 </svg> 99 100 <span class="sr-only">Italic</span> 101 </Toggle> 102 103 <Toggle 104 size="sm" 105 onclick={() => editor?.chain().focus().toggleUnderline().run()} 106 bind:pressed={() => isUnderline, (underline) => {}} 107 > 108 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-6"> 109 <path 110 fill-rule="evenodd" 111 d="M5.995 2.994a.75.75 0 0 1 .75.75v7.5a5.25 5.25 0 1 0 10.5 0v-7.5a.75.75 0 0 1 1.5 0v7.5a6.75 6.75 0 1 1-13.5 0v-7.5a.75.75 0 0 1 .75-.75Zm-3 17.252a.75.75 0 0 1 .75-.75h16.5a.75.75 0 0 1 0 1.5h-16.5a.75.75 0 0 1-.75-.75Z" 112 clip-rule="evenodd" 113 /> 114 </svg> 115 116 <span class="sr-only">Underline</span> 117 </Toggle> 118 119 <Toggle 120 size="sm" 121 onclick={() => editor?.chain().focus().toggleStrike().run()} 122 bind:pressed={() => isStrikethrough, (strikethrough) => {}} 123 > 124 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-6"> 125 <path 126 fill-rule="evenodd" 127 d="M9.657 4.728c-1.086.385-1.766 1.057-1.979 1.85-.214.8.046 1.733.81 2.616.746.862 1.93 1.612 3.388 2.003.07.019.14.037.21.053h8.163a.75.75 0 0 1 0 1.5h-8.24a.66.66 0 0 1-.02 0H3.75a.75.75 0 0 1 0-1.5h4.78a7.108 7.108 0 0 1-1.175-1.074C6.372 9.042 5.849 7.61 6.229 6.19c.377-1.408 1.528-2.38 2.927-2.876 1.402-.497 3.127-.55 4.855-.086A8.937 8.937 0 0 1 16.94 4.6a.75.75 0 0 1-.881 1.215 7.437 7.437 0 0 0-2.436-1.14c-1.473-.394-2.885-.331-3.966.052Zm6.533 9.632a.75.75 0 0 1 1.03.25c.592.974.846 2.094.55 3.2-.378 1.408-1.529 2.38-2.927 2.876-1.402.497-3.127.55-4.855.087-1.712-.46-3.168-1.354-4.134-2.47a.75.75 0 0 1 1.134-.982c.746.862 1.93 1.612 3.388 2.003 1.473.394 2.884.331 3.966-.052 1.085-.384 1.766-1.056 1.978-1.85.169-.628.046-1.33-.381-2.032a.75.75 0 0 1 .25-1.03Z" 128 clip-rule="evenodd" 129 /> 130 </svg> 131 132 <span class="sr-only">Strikethrough</span> 133 </Toggle> 134 135 <Toggle 136 size="sm" 137 onclick={() => { 138 clickedLink(); 139 }} 140 bind:pressed={() => isLink, (link) => {}} 141 > 142 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-6"> 143 <path 144 fill-rule="evenodd" 145 d="M19.902 4.098a3.75 3.75 0 0 0-5.304 0l-4.5 4.5a3.75 3.75 0 0 0 1.035 6.037.75.75 0 0 1-.646 1.353 5.25 5.25 0 0 1-1.449-8.45l4.5-4.5a5.25 5.25 0 1 1 7.424 7.424l-1.757 1.757a.75.75 0 1 1-1.06-1.06l1.757-1.757a3.75 3.75 0 0 0 0-5.304Zm-7.389 4.267a.75.75 0 0 1 1-.353 5.25 5.25 0 0 1 1.449 8.45l-4.5 4.5a5.25 5.25 0 1 1-7.424-7.424l1.757-1.757a.75.75 0 1 1 1.06 1.06l-1.757 1.757a3.75 3.75 0 1 0 5.304 5.304l4.5-4.5a3.75 3.75 0 0 0-1.035-6.037.75.75 0 0 1-.354-1Z" 146 clip-rule="evenodd" 147 /> 148 </svg> 149 150 <span class="sr-only">Link</span> 151 </Toggle> 152 153 <!-- <Toggle 154 size="sm" 155 onclick={() => { 156 fileInput?.click(); 157 }} 158 bind:pressed={() => isImage, (image) => {}} 159 > 160 <svg 161 xmlns="http://www.w3.org/2000/svg" 162 viewBox="0 0 24 24" 163 fill="none" 164 stroke="currentColor" 165 stroke-width="2" 166 stroke-linecap="round" 167 stroke-linejoin="round" 168 ><rect width="18" height="18" x="3" y="3" rx="2" ry="2" /><circle cx="9" cy="9" r="2" /><path 169 d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" 170 /></svg 171 > 172 </Toggle> --> 173 174 <input 175 type="file" 176 accept="image/*" 177 class="hidden" 178 onchange={handleFileProcess} 179 tabindex="-1" 180 bind:this={fileInput} 181 /> 182</div>