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

49.25% Statements 33/67
100% Branches 1/1
0% Functions 0/1
49.25% Lines 33/67

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 681x 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 {InputTextarea} from '../primereact/index.js';
 
import type {IWidgetProps} from '@feasibleone/blong';
import {useState} from 'react';
import {Button} from '../components/Button/Button.js';
 
export function JsonWidget({
    name,
    value,
    onChange,
    onBlur,
    error,
    readOnly,
    disabled,
}: IWidgetProps) {
    const serialized =
        value == null ? '' : typeof value === 'string' ? value : JSON.stringify(value, null, 2);
    const [parseError, setParseError] = useState<string | null>(null);
    const [raw, setRaw] = useState(serialized);
 
    const handleChange = (text: string) => {
        setRaw(text);
        try {
            onChange(JSON.parse(text));
            setParseError(null);
        } catch {
            setParseError('Invalid JSON');
        }
    };
 
    const format = () => {
        try {
            const parsed = JSON.parse(raw);
            const pretty = JSON.stringify(parsed, null, 2);
            setRaw(pretty);
            setParseError(null);
        } catch {
            setParseError('Invalid JSON');
        }
    };

    return (
        <div className="blong-json-widget">
            <InputTextarea
                id={name}
                value={raw}
                onChange={e => handleChange(e.target.value)}
                onBlur={onBlur}
                readOnly={readOnly}
                disabled={disabled}
                className={`blong-json-input ${error || parseError ? 'p-invalid' : ''}`}
                rows={6}
                autoResize
            />
            {!readOnly && !disabled && (
                <Button
                    icon="pi pi-align-left"
                    className="p-button-text p-button-sm blong-json-format"
                    onClick={format}
                    type="button"
                    tooltip="Format JSON"
                />
            )}
            {parseError && <small className="p-error">{parseError}</small>}
        </div>
    );
}