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

50.68% Statements 37/73
100% Branches 1/1
0% Functions 0/1
50.68% Lines 37/73

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 741x 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, Image} from '../primereact/index.js';
 
import type {IWidgetProps} from '@feasibleone/blong';
 
// PrimeReact 8 declares chooseOptions via defaultProps which React 19 no longer merges.
const FILE_UPLOAD_OPTIONS = {
    label: undefined,
    icon: undefined,
    iconOnly: false,
    className: undefined,
    style: undefined,
} as const;
 
/**
 * ImageUploadWidget — advanced FileUpload with image preview.
 * `value` can be a string URL or an array of File objects `[{objectURL: string}]`.
 */
export function ImageUploadWidget({
    name: _name,
    schema,
    value,
    onChange,
    readOnly,
    disabled,
}: IWidgetProps) {
    const {maxSize = 2_000_000, basePath = ''} = schema.widget ?? {};
 
    let src: string | null = null;
    if (Array.isArray(value)) {
        src = (value[0] as {objectURL?: string})?.objectURL ?? null;
    } else if (value) {
        src = basePath + String(value);
    }
 
    const imagePreview = src ? (
        <Image
            imageClassName="w-full"
            preview
            src={src}
        />
    ) : (
        <div>No picture...</div>
    );

    if (readOnly || disabled) {
        return src ? (
            <Image
                imageClassName="w-full"
                preview
                src={src}
            />
        ) : null;
    }

    return (
        <FileUpload
            accept="image/*"
            multiple={false}
            maxFileSize={maxSize}
            onSelect={e => onChange([...e.files])}
            chooseOptions={FILE_UPLOAD_OPTIONS}
            uploadOptions={FILE_UPLOAD_OPTIONS}
            cancelOptions={FILE_UPLOAD_OPTIONS}
            headerTemplate={options => {
                const {className, chooseButton} = options;
                return <div className={className}>{chooseButton}</div>;
            }}
            itemTemplate={() => imagePreview}
            emptyTemplate={() => imagePreview}
            className="blong-image-upload"
        />
    );
}