your personal website on atproto - mirror blento.app
at small-event-card-fixes 115 lines 2.2 kB view raw
1import { Node, mergeAttributes } from '@tiptap/core'; 2import { SvelteNodeViewRenderer } from 'svelte-tiptap'; 3 4import ImageUploadComponent from './ImageUploadComponent.svelte'; 5 6export type UploadFunction = ( 7 file: File, 8 onProgress?: (event: { progress: number }) => void, 9 abortSignal?: AbortSignal 10) => Promise<string>; 11 12export interface ImageUploadNodeOptions { 13 /** 14 * Acceptable file types for upload. 15 * @default 'image/*' 16 */ 17 accept?: string; 18 /** 19 * Maximum number of files that can be uploaded. 20 * @default 1 21 */ 22 limit?: number; 23 /** 24 * Maximum file size in bytes (0 for unlimited). 25 * @default 0 26 */ 27 maxSize?: number; 28 29 /** 30 * Preview image URL. 31 */ 32 preview?: string; 33 /** 34 * Function to handle the upload process. 35 */ 36 upload?: UploadFunction; 37 /** 38 * Callback for upload errors. 39 */ 40 onError?: (error: Error) => void; 41 /** 42 * Callback for successful uploads. 43 */ 44 onSuccess?: (url: string) => void; 45} 46 47declare module '@tiptap/core' { 48 interface Commands<ReturnType> { 49 imageUpload: { 50 setImageUploadNode: (options?: ImageUploadNodeOptions) => ReturnType; 51 }; 52 } 53} 54 55export const ImageUploadNode = Node.create<ImageUploadNodeOptions>({ 56 name: 'imageUpload', 57 group: 'block', 58 atom: true, 59 draggable: true, 60 selectable: false, 61 inline: false, 62 63 addAttributes() { 64 return { 65 accept: { 66 default: this.options.accept 67 }, 68 limit: { 69 default: this.options.limit 70 }, 71 maxSize: { 72 default: this.options.maxSize 73 }, 74 preview: { 75 default: this.options.preview 76 } 77 }; 78 }, 79 80 addOptions() { 81 return { 82 accept: 'image/*', 83 limit: 1, 84 maxSize: 0, 85 upload: undefined, 86 onError: undefined, 87 onSuccess: undefined 88 }; 89 }, 90 91 addCommands() { 92 return { 93 setImageUploadNode: 94 (options = {}) => 95 ({ commands }) => { 96 return commands.insertContent({ 97 type: this.name, 98 attrs: options 99 }); 100 } 101 }; 102 }, 103 104 parseHTML() { 105 return [{ tag: 'div[data-type="image-upload"]' }]; 106 }, 107 108 renderHTML({ HTMLAttributes }) { 109 return ['div', mergeAttributes({ 'data-type': 'image-upload' }, HTMLAttributes)]; 110 }, 111 112 addNodeView() { 113 return SvelteNodeViewRenderer(ImageUploadComponent); 114 } 115});