your personal website on atproto - mirror blento.app
at fix-formatting 91 lines 1.9 kB view raw
1<script lang="ts"> 2 import { onDestroy, onMount } from 'svelte'; 3 import { Editor, type Extensions } from '@tiptap/core'; 4 import Placeholder from '@tiptap/extension-placeholder'; 5 import Paragraph from '@tiptap/extension-paragraph'; 6 import Document from '@tiptap/extension-document'; 7 import Text from '@tiptap/extension-text'; 8 import type { Item } from '$lib/types'; 9 10 let element: HTMLElement | undefined = $state(); 11 let editor: Editor | null = $state(null); 12 13 let { 14 contentDict = $bindable(), 15 key, 16 class: className, 17 placeholder = '', 18 defaultContent = '' 19 }: { 20 contentDict: Record<string, any>; 21 key: string; 22 class?: string; 23 placeholder?: string; 24 defaultContent?: string; 25 } = $props(); 26 27 const update = async () => { 28 if (!editor) return; 29 30 contentDict[key] = editor.getText(); 31 }; 32 33 onMount(async () => { 34 if (!element || editor) return; 35 36 let extensions: Extensions = [Document.configure(), Paragraph.configure(), Text.configure()]; 37 38 if (placeholder) { 39 extensions.push( 40 Placeholder.configure({ 41 placeholder: placeholder 42 }) 43 ); 44 } 45 46 editor = new Editor({ 47 element: element, 48 extensions: extensions, 49 onTransaction: () => { 50 editor = editor; 51 }, 52 onUpdate: () => { 53 update(); 54 }, 55 56 content: contentDict[key] ?? defaultContent, 57 58 editorProps: { 59 attributes: { 60 class: 'outline-none pointer-events-auto' 61 }, 62 handleKeyDown: (_view, event) => { 63 // Prevent newlines by blocking Enter key 64 if (event.key === 'Enter') { 65 return true; 66 } 67 return false; 68 } 69 } 70 }); 71 }); 72 73 onDestroy(() => { 74 if (editor) { 75 editor.destroy(); 76 } 77 }); 78</script> 79 80<span class={className} bind:this={element}></span> 81 82<style> 83 :global(.tiptap p.is-editor-empty:first-child::before) { 84 color: var(--color-base-500); 85 content: attr(data-placeholder); 86 opacity: 100%; 87 float: left; 88 height: 0; 89 pointer-events: none; 90 } 91</style>