[READ-ONLY] Mirror of https://github.com/flo-bit/ui-kit. 🦊 fox ui, svelte 5 and tailwind 4 flo-bit.dev/ui-kit/
svelte tailwindcss ui-components
0

Configure Feed

Select the types of activity you want to include in your feed.

fix ssr issue

Florian (Mar 1, 2026, 7:55 PM +0100) 3de59aec df199333

+76 -74
+76 -74
packages/text/src/lib/components/rich-text-editor/RichTextEditor.svelte
··· 1 1 <script lang="ts"> 2 - import { onDestroy } from 'svelte'; 2 + import { onDestroy, onMount } from 'svelte'; 3 3 import { type Editor as CoreEditor, mergeAttributes, type Content } from '@tiptap/core'; 4 4 import { type Editor, createEditor, EditorContent } from 'svelte-tiptap'; 5 5 import StarterKit from '@tiptap/starter-kit'; ··· 105 105 } 106 106 } 107 107 108 - editor = createEditor({ 109 - extensions: [ 110 - StarterKit.configure({ 111 - dropcursor: { 112 - class: 'text-accent-500/30 rounded-2xl', 113 - width: 2 114 - }, 115 - codeBlock: false, 116 - heading: { 117 - levels: [1, 2, 3] 118 - } 119 - }), 120 - Placeholder.configure({ 121 - placeholder: ({ node }) => { 122 - if (node.type.name === 'paragraph' || node.type.name === 'heading') { 123 - return placeholder; 108 + onMount(() => { 109 + editor = createEditor({ 110 + extensions: [ 111 + StarterKit.configure({ 112 + dropcursor: { 113 + class: 'text-accent-500/30 rounded-2xl', 114 + width: 2 115 + }, 116 + codeBlock: false, 117 + heading: { 118 + levels: [1, 2, 3] 124 119 } 125 - return ''; 126 - } 127 - }), 128 - CustomImage.configure({ 129 - HTMLAttributes: { 130 - class: 'max-w-full object-contain relative rounded-2xl' 131 - }, 132 - allowBase64: true 133 - }), 134 - CodeBlockLowlight.configure({ 135 - lowlight, 136 - defaultLanguage: 'js' 137 - }), 138 - Underline.configure({}), 139 - RichTextLink.configure({ 140 - openOnClick: false, 141 - autolink: true, 142 - defaultProtocol: 'https' 143 - }), 144 - Slash.configure({ 145 - suggestion: suggestion({ 146 - char: '/', 147 - pluginKey: 'slash', 148 - switchTo, 149 - processImageFile 150 - }) 151 - }), 152 - Typography.configure(), 153 - Markdown.configure(), 154 - ImageUploadNode.configure({ 155 - upload: async (file, onProgress, abortSignal) => { 156 - console.log('uploading image', file); 157 - for (let i = 0; i < 10; i++) { 158 - await new Promise((resolve) => setTimeout(resolve, 200)); 159 - onProgress?.({ progress: i / 10 }); 120 + }), 121 + Placeholder.configure({ 122 + placeholder: ({ node }) => { 123 + if (node.type.name === 'paragraph' || node.type.name === 'heading') { 124 + return placeholder; 125 + } 126 + return ''; 160 127 } 128 + }), 129 + CustomImage.configure({ 130 + HTMLAttributes: { 131 + class: 'max-w-full object-contain relative rounded-2xl' 132 + }, 133 + allowBase64: true 134 + }), 135 + CodeBlockLowlight.configure({ 136 + lowlight, 137 + defaultLanguage: 'js' 138 + }), 139 + Underline.configure({}), 140 + RichTextLink.configure({ 141 + openOnClick: false, 142 + autolink: true, 143 + defaultProtocol: 'https' 144 + }), 145 + Slash.configure({ 146 + suggestion: suggestion({ 147 + char: '/', 148 + pluginKey: 'slash', 149 + switchTo, 150 + processImageFile 151 + }) 152 + }), 153 + Typography.configure(), 154 + Markdown.configure(), 155 + ImageUploadNode.configure({ 156 + upload: async (file, onProgress, abortSignal) => { 157 + console.log('uploading image', file); 158 + for (let i = 0; i < 10; i++) { 159 + await new Promise((resolve) => setTimeout(resolve, 200)); 160 + onProgress?.({ progress: i / 10 }); 161 + } 161 162 162 - return 'https://picsum.photos/200/300'; 163 + return 'https://picsum.photos/200/300'; 164 + } 165 + }) 166 + ], 167 + editorProps: { 168 + attributes: { 169 + class: 'outline-none' 163 170 } 164 - }) 165 - ], 166 - editorProps: { 167 - attributes: { 168 - class: 'outline-none' 169 - } 170 - }, 171 - onUpdate: (ctx) => { 172 - content = ctx.editor.getJSON(); 173 - onupdate?.(content, ctx); 174 - }, 175 - onFocus: () => { 176 - hasFocus = true; 177 - }, 178 - onBlur: () => { 179 - hasFocus = false; 180 - }, 181 - onTransaction: () => { 182 - ontransaction?.(); 183 - }, 184 - content 171 + }, 172 + onUpdate: (ctx) => { 173 + content = ctx.editor.getJSON(); 174 + onupdate?.(content, ctx); 175 + }, 176 + onFocus: () => { 177 + hasFocus = true; 178 + }, 179 + onBlur: () => { 180 + hasFocus = false; 181 + }, 182 + onTransaction: () => { 183 + ontransaction?.(); 184 + }, 185 + content 186 + }); 185 187 }); 186 188 187 189 const handlePaste = (event: ClipboardEvent) => {