All files / blong-browser/src/components/Hint Hint.tsx

92.64% Statements 63/68
83.33% Branches 5/6
100% Functions 1/1
92.64% Lines 63/68

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 691x 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 7x 7x 7x 7x 1x           7x 7x 7x 7x 7x 7x 7x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x  
/**
 * Hint — transient success/error toast notifications.
 *
 * Also exports ActionHint — singleton OverlayPanel for ActionButton
 * success/error feedback anchored near the triggering button.
 */
import {OverlayPanel, Toast} from '../../primereact/index.js';
 
 
import {useEffect, useRef} from 'react';
import {useAppStore} from '../../state/appStore.js';
 
export function Hint() {
    const toastRef = useRef<Toast>(null);
    const toasts = useAppStore(s => s.toasts);
 
    useEffect(() => {
        if (toastRef.current && toasts.length > 0) {
            const latest = toasts[toasts.length - 1];
            toastRef.current.show({
                severity: latest.severity,
                summary: latest.summary,
                detail: latest.detail,
                life: latest.life,
            });
        }
    }, [toasts]);
 
    return (
        <Toast
            ref={toastRef}
            position="top-right"
        />
    );
}
 
/**
 * ActionHint — singleton OverlayPanel for button-level feedback.
 * Mount once in App. ActionButton calls showHint() to display a
 * success/error message anchored to the button. Auto-dismisses after 2 s.
 */
export function ActionHint() {
    const hint = useAppStore(s => s.hint);
    const clearHint = useAppStore(s => s.clearHint);
    const overlayRef = useRef<OverlayPanel>(null);

    useEffect(() => {
        if (hint?.target) {
            overlayRef.current?.show(null, hint.target);
            const t = setTimeout(() => {
                overlayRef.current?.hide();
                clearHint();
            }, 2000);
            return () => clearTimeout(t);
        } else {
            overlayRef.current?.hide();
        }
    }, [hint, clearHint]);
 
    return (
        <OverlayPanel
            ref={overlayRef}
            style={{maxWidth: 240}}
        >
            <span className={hint?.error ? 'text-red-500' : 'text-green-500'}>{hint?.message}</span>
        </OverlayPanel>
    );
}