-
Notifications
You must be signed in to change notification settings - Fork 79
Closed
Description
It would be handy for my use case if support for pasting and dropping images and other files were built-in.
Here's what I would envision the API to look like. There would be a callback in the configuration object that takes a File object and returns (async, so we can use axios or fetch to upload it) the text to insert in the textarea.
const [editor] = new OverType('#editor', {
...
onInsertFile: async (file: File): Promise<string> => {
const url = await uploadFile(file)
return file.type.startsWith('image/')
? ``
: `[${fileName}](${url})`
},
...
});Here's some code of mine to do this on a plain textarea to get you started:
const textAreaPaste = (event: React.ClipboardEvent<HTMLTextAreaElement>) => {
const clipboardData = event.clipboardData
// Let the default handler handle plain text
if (!clipboardData || !clipboardData.files || clipboardData.files.length == 0) return
event.preventDefault()
const textarea = event.currentTarget as HTMLTextAreaElement
textarea.focus()
for (const file of clipboardData.files) {
console.log('Pasted file:', file)
uploadFile(file)
.then((url) => {
const fileName = file.name
const text = file.type.startsWith('image/')
? ``
: `[${fileName}](${url})`
insertTextAtCursor(textarea, text)
})
.catch((error) => {
console.error('Error uploading pasted file:', error)
})
}
}
const textAreaDrop = (event: React.DragEvent<HTMLTextAreaElement>) => {
const dataTransfer = event.dataTransfer
// Let the default handler handle plain text
if (!dataTransfer || !dataTransfer.files || dataTransfer.files.length == 0) return
event.preventDefault()
const textarea = event.currentTarget as HTMLTextAreaElement
textarea.focus()
for (const file of dataTransfer.files) {
console.log('Dropped file:', file)
uploadFile(file)
.then((url) => {
const fileName = file.name
const text = file.type.startsWith('image/')
? ``
: `[${fileName}](${url})`
insertTextAtCursor(textarea, text)
})
.catch((error) => {
console.error('Error uploading dropped file:', error)
})
}
}
const insertTextAtCursor = (textarea: HTMLTextAreaElement, text: string) => {
textarea.focus()
if (document.queryCommandSupported && document.queryCommandSupported('insertText')) {
document.execCommand('insertText', false, text)
} else {
const start = textarea.selectionStart
const end = textarea.selectionEnd
const value = textarea.value
textarea.value = value.slice(0, start) + text + value.slice(end)
textarea.setSelectionRange(start + text.length, start + text.length)
}
} <textarea
onPaste={textAreaPaste}
onDrop={textAreaDrop}
></textarea>r0bbie, itsjavi and rognoni
Metadata
Metadata
Assignees
Labels
No labels