/** * @license * Copyright 2025 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import type React from 'react'; import { Box, Text } from 'ink'; import { theme } from '../semantic-colors.js'; import { useMemo } from 'react'; import { ChecklistItem, type ChecklistItemData } from './ChecklistItem.js'; export interface ChecklistProps { title: string; items: ChecklistItemData[]; isExpanded: boolean; toggleHint?: string; } const ChecklistTitleDisplay: React.FC<{ title: string; items: ChecklistItemData[]; toggleHint?: string; }> = ({ title, items, toggleHint }) => { const score = useMemo(() => { let total = 0; let completed = 0; for (const item of items) { if (item.status !== 'cancelled') { total += 1; if (item.status === 'completed') { completed += 1; } } } return `${completed}/${total} completed`; }, [items]); return ( {title} {score} {toggleHint ? ` (${toggleHint})` : ''} ); }; const ChecklistListDisplay: React.FC<{ items: ChecklistItemData[] }> = ({ items, }) => ( {items.map((item, index) => ( ))} ); export const Checklist: React.FC = ({ title, items, isExpanded, toggleHint, }) => { const inProgress: ChecklistItemData | null = useMemo( () => items.find((item) => item.status === 'in_progress') || null, [items], ); const hasActiveItems = useMemo( () => items.some( (item) => item.status === 'pending' || item.status === 'in_progress', ), [items], ); if (items.length === 0 || (!isExpanded && !hasActiveItems)) { return null; } return ( {isExpanded ? ( ) : ( {inProgress && ( )} )} ); };