import { useRef, type ReactNode } from "react"; import Button from "@moduletrace/twui/layout/Button"; import Row from "@moduletrace/twui/layout/Row"; import Span from "@moduletrace/twui/layout/Span"; import Stack from "@moduletrace/twui/layout/Stack"; import imageInputToBase64 from "@moduletrace/twui/utils/form/imageInputToBase64"; type Props = { /** * The avatar as it looks now (or will, with the picked picture). */ preview: ReactNode; has_image: boolean; onPick: (params: { data_url: string }) => void; onRemove: () => void; loading?: boolean; disabled?: boolean; note?: string; }; /** * An avatar preview with Upload/Change and Remove. The picked picture comes * back as a data URL; saving is up to the caller. */ export default function ImagePickField({ preview, has_image, onPick, onRemove, loading, disabled, note = "PNG, JPG or WebP. A square picture looks best.", }: Props) { const input_ref = useRef(null); return ( {preview} {has_image ? ( ) : null} {note} {/* * Raw on purpose: twui `Input` writes `value` on change, which * browsers forbid on file inputs, and `ImageUpload` is a full * card widget. This is only the hidden picker behind the button. */} { if (!e.target.files?.[0]) return; imageInputToBase64({ imageInput: e.target }).then((res) => { if (res?.imageBase64Full) onPick({ data_url: res.imageBase64Full }); }); }} /> ); }