Files
simple-react-app-kit/packages/lexical/src/file-utils.ts
T
Maofeng 263b400860 feat(lexical): support local image data URLs
Allow the image insertion dialog to select a local image and embed it as a Base64 data URL, while retaining URL-based insertion and leaving video URL-only.

Extract shared abortable FileReader handling for clipboard uploads and dialog selection; add English and Simplified Chinese messages plus an interaction test covering file selection through insertion.
2026-07-31 16:03:54 +08:00

69 lines
1.6 KiB
TypeScript

export interface ReadFileAsDataUrlOptions {
onProgress?: (progress: number) => void
signal?: AbortSignal
}
export function readFileAsDataUrl(
file: File,
{ onProgress, signal }: ReadFileAsDataUrlOptions = {}
): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader()
const handleSignalAbort = () => reader.abort()
const cleanUp = () =>
signal?.removeEventListener("abort", handleSignalAbort)
if (signal?.aborted) {
reject(new DOMException("The image read was aborted.", "AbortError"))
return
}
signal?.addEventListener("abort", handleSignalAbort, { once: true })
reader.addEventListener(
"error",
() => {
const error =
reader.error ?? new Error(`Unable to read "${file.name}".`)
cleanUp()
reject(error)
},
{ once: true }
)
reader.addEventListener(
"abort",
() => {
cleanUp()
reject(new DOMException("The image read was aborted.", "AbortError"))
},
{ once: true }
)
reader.addEventListener("progress", (event) => {
if (event.lengthComputable && event.total > 0) {
onProgress?.(event.loaded / event.total)
}
})
reader.addEventListener(
"load",
() => {
const result = reader.result
cleanUp()
if (typeof result === "string") {
resolve(result)
} else {
reject(new Error(`Unable to read "${file.name}" as a data URL.`))
}
},
{ once: true }
)
try {
reader.readAsDataURL(file)
} catch (error) {
cleanUp()
reject(error)
}
})
}