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

0% Statements 0/73
0% Branches 0/1
0% Functions 0/1
0% Lines 0/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 74                                                                                                                                                   
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"
        />
    );
}