use-vibes
Version:
Transform any DOM element into an AI-powered micro-app
109 lines • 6.84 kB
JavaScript
import * as React from 'react';
import { combineClasses, defaultClasses } from '../utils/style-utils';
import { logDebug } from '../utils/debug';
/**
* ControlsBar component - Displays controls for deleting, navigating between versions, and regenerating
*/
export function ControlsBar({ handleDeleteConfirm, handlePrevVersion, handleNextVersion, handleRegen, versionIndex, totalVersions, classes = defaultClasses, showControls = true, editedPrompt, promptText, progress = 100, showDelete = true, versionFlash = false, isRegenerating = false, }) {
// State for managing delete confirmation
const [showConfirmation, setShowConfirmation] = React.useState(false);
// Timer ref for automatic cancellation
const cancelTimerRef = React.useRef(null);
// Use external state if provided
const isConfirming = showConfirmation;
// Handle delete click
const onDeleteClick = () => {
if (isConfirming) {
// User clicked delete while confirmation is showing - confirm the delete
logDebug('ControlsBar: Delete confirmed, calling handleDeleteConfirm');
// Ensure we call handleDeleteConfirm with no arguments, it will handle the document ID
handleDeleteConfirm();
// Reset confirmation state
setShowConfirmation(false);
if (cancelTimerRef.current) {
window.clearTimeout(cancelTimerRef.current);
cancelTimerRef.current = null;
}
}
else {
// Show confirmation
logDebug('ControlsBar: Showing delete confirmation');
setShowConfirmation(true);
// Set timer to auto-hide confirmation after 6.5 seconds (allows 0.5s for fade)
cancelTimerRef.current = window.setTimeout(() => {
setShowConfirmation(false);
}, 6500);
}
};
// Clean up timer on unmount
React.useEffect(() => {
return () => {
if (cancelTimerRef.current) {
window.clearTimeout(cancelTimerRef.current);
}
};
}, []);
return (React.createElement(React.Fragment, null,
progress < 100 && (React.createElement("div", { className: "imggen-progress", style: {
width: `${progress}%`,
position: 'absolute',
top: 0,
left: 0,
height: 'var(--imggen-progress-height)',
zIndex: 20,
} })),
React.createElement("div", { className: combineClasses('imggen-controls', classes.controls) }, showControls ? (React.createElement(React.Fragment, null,
React.createElement("div", { style: { display: 'flex', gap: '6px', alignItems: 'center', flex: 1 } }, showDelete && (React.createElement("div", { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
React.createElement("button", { "aria-label": "Delete image", onClick: onDeleteClick, className: combineClasses('imggen-button imggen-delete-button', classes.button), style: {
position: 'static',
width: 'var(--imggen-button-size)',
height: 'var(--imggen-button-size)',
backgroundColor: isConfirming ? 'var(--imggen-error-border)' : undefined,
color: isConfirming ? 'white' : undefined,
opacity: isConfirming ? 1 : undefined,
} }, "\u2715"),
isConfirming && (React.createElement("div", { className: "fade-transition", style: { animationDelay: '6s' } },
React.createElement("button", { onClick: () => {
handleDeleteConfirm();
setShowConfirmation(false);
}, "aria-label": "Confirm delete", style: {
fontSize: 'var(--imggen-font-size)',
fontWeight: 'bold',
whiteSpace: 'nowrap',
border: '1px solid var(--imggen-error-border, #ff3333)',
background: 'var(--imggen-error-border, #ff3333)',
color: 'white',
borderRadius: '4px',
cursor: 'pointer',
padding: '2px 8px',
} }, "Delete image?"),
React.createElement("button", { onClick: () => {
logDebug('ControlsBar: Delete canceled');
setShowConfirmation(false);
if (cancelTimerRef.current) {
window.clearTimeout(cancelTimerRef.current);
}
}, "aria-label": "Cancel delete", style: {
fontSize: 'var(--imggen-font-size)',
whiteSpace: 'nowrap',
border: 'none',
background: 'none',
color: 'var(--imggen-font-color)',
cursor: 'pointer',
padding: '0 4px',
} }, "Cancel")))))),
React.createElement("div", { className: "imggen-control-group" },
totalVersions > 1 && (React.createElement("button", { "aria-label": "Previous version", disabled: versionIndex === 0, onClick: handlePrevVersion, className: combineClasses('imggen-button', classes.button) }, "\u25C0\uFE0E")),
totalVersions > 1 && (React.createElement("span", { className: `imggen-version-indicator version-indicator ${versionFlash ? 'imggen-version-flash' : ''}`, "aria-live": "polite" },
versionIndex + 1,
" / ",
totalVersions)),
totalVersions > 1 && (React.createElement("button", { "aria-label": "Next version", disabled: versionIndex >= totalVersions - 1, onClick: handleNextVersion, className: combineClasses('imggen-button', classes.button) }, "\u25B6\uFE0E")),
React.createElement("button", { "aria-label": "Regenerate image", onClick: () => {
handleRegen();
}, disabled: isRegenerating, className: combineClasses('imggen-button', classes.button, editedPrompt !== null && editedPrompt.trim() !== promptText
? 'imggen-button-highlight'
: '', isRegenerating ? 'imggen-button-disabled' : '') },
React.createElement("span", { className: isRegenerating ? 'imggen-regen-spinning' : '' }, "\u27F3"))))) : progress < 100 ? (React.createElement("div", { className: "imggen-status-text" }, "Generating...")) : null)));
}
//# sourceMappingURL=ControlsBar.js.map