All files / blong-browser/src/widgets ImageWidget.tsx

50.63% Statements 40/79
100% Branches 1/1
0% Functions 0/1
50.63% Lines 40/79

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 801x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x                                                                                
import {FileUpload} from '../primereact/index.js';
 
import type {IWidgetProps} from '@feasibleone/blong';
import {useRef, useState} from 'react';
 
// PrimeReact 8 declares chooseOptions/uploadOptions/cancelOptions via defaultProps,
// which React 19 no longer merges — pass them explicitly to prevent crashes.
const FILE_UPLOAD_OPTIONS = {
    label: undefined,
    icon: undefined,
    iconOnly: false,
    className: undefined,
    style: undefined,
} as const;
 
export function ImageWidget({
    name: _name,
    schema,
    value,
    onChange,
    error: _error,
    readOnly,
    disabled,
}: IWidgetProps) {
    const uploadRef = useRef<FileUpload>(null);
    const {maxSize = 2_000_000} = schema.widget ?? {};
    const [preview, setPreview] = useState<string | null>(typeof value === 'string' ? value : null);
 
    if (readOnly || disabled) {
        return preview ? (
            <img
                src={preview}
                alt=""
                className="blong-image-preview"
                style={{maxWidth: 240, maxHeight: 160}}
            />
        ) : null;
    }
 
    const handleUpload = (e: {files: File[]}) => {
        const file = e.files[0];
        if (!file) return;
        const reader = new FileReader();
        reader.onload = ev => {
            const dataUrl = ev.target?.result as string;
            setPreview(dataUrl);
            onChange(dataUrl);
        };
        reader.readAsDataURL(file);
        uploadRef.current?.clear();
    };

    return (
        <div className="blong-image-widget">
            {preview && (
                <img
                    src={preview}
                    alt=""
                    className="blong-image-preview"
                    style={{maxWidth: 240, maxHeight: 160, display: 'block', marginBottom: 8}}
                />
            )}
            <FileUpload
                ref={uploadRef}
                mode="basic"
                accept="image/*"
                maxFileSize={maxSize}
                customUpload
                uploadHandler={handleUpload}
                className="blong-image"
                auto
                chooseLabel="Upload image"
                chooseOptions={FILE_UPLOAD_OPTIONS}
                uploadOptions={FILE_UPLOAD_OPTIONS}
                cancelOptions={FILE_UPLOAD_OPTIONS}
            />
        </div>
    );
}