import * as SliderPrimitive from "@radix-ui/react-slider"; import { useEffect, useState } from "react"; import type { FormEvent } from "react"; type ReadAsMethod = "readAsText" | "readAsDataURL" | "readAsArrayBuffer" | "readAsBinaryString"; type UseFileReaderProps = { method: ReadAsMethod; onLoad?: (result: unknown) => void; }; export const useFileReader = (options: UseFileReaderProps) => { const { method = "readAsText", onLoad } = options; const [file, setFile] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [result, setResult] = useState(null); useEffect(() => { if (!file && result) { setResult(null); } }, [file, result]); useEffect(() => { if (!file) { return; } const reader = new FileReader(); reader.onloadstart = () => setLoading(true); reader.onloadend = () => setLoading(false); reader.onerror = () => setError(reader.error); reader.onload = (e: ProgressEvent) => { setResult(e.target?.result ?? null); if (onLoad) { onLoad(e.target?.result ?? null); } }; reader[method](file); }, [file, method, onLoad]); return [{ result, error, file, loading }, setFile] as const; }; export const createImage = (url: string) => new Promise((resolve, reject) => { const image = new Image(); image.addEventListener("load", () => resolve(image)); image.addEventListener("error", (error) => reject(error)); image.setAttribute("crossOrigin", "anonymous"); // needed to avoid cross-origin issues on CodeSandbox image.src = url; }); export const Slider = ({ value, label, changeHandler, ...props }: Omit & { value: number; label: string; changeHandler: (value: number) => void; }) => ( changeHandler(value[0] ?? value)} {...props}> ); export interface FileEvent extends FormEvent { target: EventTarget & T; } export type Area = { width: number; height: number; x: number; y: number; };