diff --git a/app/playground/page.tsx b/app/playground/page.tsx index f6a7bde..9f01998 100644 --- a/app/playground/page.tsx +++ b/app/playground/page.tsx @@ -1,5 +1,5 @@ import { TerminalApp } from '@/components/terminal-app' -import { Terminal, TerminalCommand, TerminalDiff, TerminalOutput, TerminalSpinner, TerminalBadge, ThemeSwitcher } from '@/components/terminal' +import { Terminal, TerminalCommand, TerminalDiff, TerminalOutput, TerminalSpinner, TerminalBadge, ThemeSwitcher, TerminalProgressGroup } from '@/components/terminal' import { TerminalProgress } from '@/components/terminal-progress' import { LogDemo } from './log-demo' import { PromptDemo } from './prompt-demo' @@ -52,6 +52,40 @@ export default function PlaygroundPage() { +
+

+ TerminalProgressGroup +

+

+ Display multiple related progress bars for multi-step tasks. +

+ + run-build + + + + deploy --verbose + + +
+

TerminalSpinner diff --git a/components/terminal-progress-group.tsx b/components/terminal-progress-group.tsx new file mode 100644 index 0000000..8725324 --- /dev/null +++ b/components/terminal-progress-group.tsx @@ -0,0 +1,150 @@ +'use client' + +import { useState } from 'react' +import { TerminalProgress } from './terminal-progress' + +export interface ProgressItem { + /** Label for this step */ + label: string + /** Progress percentage (0-100) */ + percent: number + /** Variant color */ + variant?: 'green' | 'blue' | 'yellow' | 'red' | 'purple' | 'cyan' + /** Step status (determines icon) */ + status?: 'pending' | 'active' | 'complete' | 'error' +} + +export interface TerminalProgressGroupProps { + /** Array of progress items */ + items: ProgressItem[] + /** Show overall progress (default: true) */ + showTotal?: boolean + /** Collapsible (default: false) */ + collapsible?: boolean + /** Title for the progress group */ + title?: string + /** Additional CSS classes */ + className?: string +} + +const statusIcons: Record, string> = { + pending: '○', + active: '⟳', + complete: '✓', + error: '✗', +} + +const statusColors: Record, string> = { + pending: 'var(--term-fg-dim)', + active: 'var(--term-blue)', + complete: 'var(--term-green)', + error: 'var(--term-red)', +} + +/** + * Display multiple related progress bars for multi-step tasks. + * Calculates and shows overall progress with optional collapsible details. + * + * @param items - Array of progress items with labels, percentages, and status + * @param showTotal - Display overall progress bar at top (default: true) + * @param collapsible - Allow expanding/collapsing details (default: false) + * @param title - Optional title for the progress group + * @param className - Additional classes applied to the root element + * + * @example + * ```tsx + * + * ``` + */ +export function TerminalProgressGroup({ + items, + showTotal = true, + collapsible = false, + title, + className = '', +}: TerminalProgressGroupProps) { + const [expanded, setExpanded] = useState(!collapsible) + + // Calculate overall progress (average) + const totalPercent = items.length > 0 + ? Math.round(items.reduce((sum, item) => sum + item.percent, 0) / items.length) + : 0 + + // Determine overall variant based on status + const hasError = items.some((item) => item.status === 'error') + const allComplete = items.every((item) => item.status === 'complete' || item.percent === 100) + const overallVariant = hasError ? 'red' : allComplete ? 'green' : 'blue' + + return ( +
+ {/* Title */} + {title && ( +
+ {title} +
+ )} + + {/* Overall progress */} + {showTotal && ( +
+ {collapsible && ( + + )} +
+ +
+
+ )} + + {/* Individual progress items */} + {expanded && items.length > 0 && ( +
+ {items.map((item, i) => { + const status = item.status || (item.percent === 100 ? 'complete' : item.percent > 0 ? 'active' : 'pending') + const icon = statusIcons[status] + const iconColor = statusColors[status] + const variant = item.variant || (status === 'error' ? 'red' : status === 'complete' ? 'green' : 'blue') + + return ( +
+ + {icon} + +
+ +
+
+ ) + })} +
+ )} +
+ ) +} diff --git a/components/terminal.tsx b/components/terminal.tsx index 56c9e1f..4d1bcad 100644 --- a/components/terminal.tsx +++ b/components/terminal.tsx @@ -249,6 +249,7 @@ export function TerminalSpinner({ text }: TerminalSpinnerProps) { } export { TerminalProgress } from './terminal-progress' +export { TerminalProgressGroup, type ProgressItem } from './terminal-progress-group' export { TerminalPrompt } from './terminal-prompt' export { TerminalTree } from './terminal-tree' export type { TreeNode, TreeRenderContext, TerminalTreeProps } from './terminal-tree'