Files
image-studio/view/inpaint/CandidateReviewPanel.tsx
syntaxbullet ff762b8f17 feat: add inpaint region functionality and related tools
- Enhanced cursor behavior for new tools: semantic select, mask lasso, and mask rectangle.
- Updated mask edit state to include mask asset ID and kind.
- Implemented inpaint region commands for adding, applying, and removing inpaint regions.
- Introduced new operations for lasso and semantic selection tools.
- Created UI components for candidate review and inpaint region management.
- Added tests for inpaint region commands to ensure functionality.
- Updated various components to support new inpaint features and improve user experience.
2026-07-11 16:41:22 +02:00

26 lines
2.0 KiB
TypeScript

import { Star } from "@phosphor-icons/react";
import { commandIds } from "@commands/ids";
import type { GenerationState } from "@editor/state";
import type { AppStore } from "@editor/store";
export function CandidateReviewPanel({ generation, dispatch }: { generation: GenerationState; dispatch: AppStore["dispatch"] }) {
if (generation.candidates.length === 0) return null;
const selectedId = generation.selectedCandidateId ?? generation.candidates[0]?.id;
return (
<section className="grid gap-2 border-b border-white/[0.07] pb-3">
<div className="flex items-center justify-between px-1"><strong className="text-sm text-white/85">Results</strong><span className="text-xs text-white/35">{generation.candidates.length} candidates</span></div>
<div className="grid grid-cols-2 gap-2">
{generation.candidates.map((candidate) => (
<div key={candidate.id} className={`group relative overflow-hidden rounded-lg border ${candidate.id === selectedId ? "border-sky-300" : "border-white/10"}`}>
<button type="button" className="block w-full" onClick={() => dispatch(commandIds.generationSelectCandidate, { candidateId: candidate.id })}>
<img src={candidate.source} alt={`Candidate seed ${candidate.seed}`} className="aspect-square w-full bg-black/25 object-cover" />
<span className="flex items-center justify-between px-2 py-1 text-[0.65rem] text-white/45"><span>Seed {candidate.seed}</span><span>{candidate.settings.inpaint.profile}</span></span>
</button>
<button type="button" aria-label={candidate.favorite ? "Remove favorite" : "Favorite candidate"} aria-pressed={candidate.favorite} className={`absolute right-1.5 top-1.5 rounded-md bg-black/65 p-1.5 ${candidate.favorite ? "text-amber-300" : "text-white/60 opacity-0 group-hover:opacity-100"}`} onClick={() => dispatch(commandIds.generationToggleCandidateFavorite, { candidateId: candidate.id })}><Star size={16} weight={candidate.favorite ? "fill" : "regular"} /></button>
</div>
))}
</div>
</section>
);
}