Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion app/playground/page.tsx
Original file line number Diff line number Diff line change
@@ -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, TerminalMarker, ThemeSwitcher } from '@/components/terminal'
import { TerminalProgress } from '@/components/terminal-progress'
import { LogDemo } from './log-demo'
import { PromptDemo } from './prompt-demo'
Expand Down Expand Up @@ -161,6 +161,28 @@ export default function PlaygroundPage() {
</Terminal>
</section>

<section className="flex flex-col gap-2">
<h2 className="text-lg font-semibold font-mono text-[var(--term-fg)]">
TerminalMarker
</h2>
<p className="text-sm text-[var(--term-fg-dim)] font-mono">
Phase separators for visual boundaries in terminal feeds.
</p>
<Terminal title="deploy-pipeline.sh">
<TerminalCommand>npm run deploy:full</TerminalCommand>
<TerminalMarker label="BUILD" timestamp="10:23:45" variant="info" />
<TerminalOutput type="success">✓ Compiled 42 modules</TerminalOutput>
<TerminalOutput type="normal"> dist/main.js 124 KB</TerminalOutput>
<TerminalMarker label="TEST" timestamp="10:24:01" variant="success" />
<TerminalOutput type="success">✓ 24 tests passed</TerminalOutput>
<TerminalOutput type="normal"> coverage: 94%</TerminalOutput>
<TerminalMarker label="DEPLOY" timestamp="10:24:30" variant="warning" />
<TerminalOutput type="info">→ Deploying to production...</TerminalOutput>
<TerminalOutput type="success">✓ Deployed successfully</TerminalOutput>
<TerminalMarker label="DONE" timestamp="10:24:45" variant="success" />
</Terminal>
</section>

<section className="flex flex-col gap-2">
<h2 className="text-lg font-semibold font-mono text-[var(--term-fg)]">
Typing Animation
Expand Down
92 changes: 92 additions & 0 deletions components/terminal-marker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
'use client'

export interface TerminalMarkerProps {
/** Label text displayed as the phase marker. */
label: string
/** Optional timestamp to display after the label. */
timestamp?: string
/** Visual style variant (default: 'neutral'). */
variant?: 'info' | 'success' | 'warning' | 'error' | 'neutral'
/** Additional classes for layout tweaks. */
className?: string
}

/**
* Per-variant Tailwind classes for border, background tint, label, and timestamp.
* Background tints use `color-mix` for consistent translucency across themes.
*/
const variantClasses: Record<
NonNullable<TerminalMarkerProps['variant']>,
{ root: string; label: string; timestamp: string }
> = {
neutral: {
root: 'border-[var(--glass-border)] bg-[rgba(255,255,255,0.03)]',
label: 'text-[var(--term-fg)]',
timestamp: 'text-[var(--term-fg-dim)]',
},
info: {
root: 'border-[var(--term-blue)]/40 bg-[color-mix(in_oklab,var(--term-blue)_8%,transparent)]',
label: 'text-[var(--term-blue)]',
timestamp: 'text-[var(--term-blue)]/60',
},
success: {
root: 'border-[var(--term-green)]/40 bg-[color-mix(in_oklab,var(--term-green)_8%,transparent)]',
label: 'text-[var(--term-green)]',
timestamp: 'text-[var(--term-green)]/60',
},
warning: {
root: 'border-[var(--term-yellow)]/40 bg-[color-mix(in_oklab,var(--term-yellow)_8%,transparent)]',
label: 'text-[var(--term-yellow)]',
timestamp: 'text-[var(--term-yellow)]/60',
},
error: {
root: 'border-[var(--term-red)]/40 bg-[color-mix(in_oklab,var(--term-red)_8%,transparent)]',
label: 'text-[var(--term-red)]',
timestamp: 'text-[var(--term-red)]/60',
},
}

/**
* Displays a terminal-style phase separator for visual boundaries in feeds.
* Used to mark different phases like "Build", "Test", "Deploy" in sequential outputs.
*
* Renders a left-bordered row with a semantic background tint, a bold phase label,
* and an optional timestamp. Fully theme-aware via CSS custom properties and
* naturally responsive at any width.
*
* @param label - Phase label text (e.g., "Build", "Test", "Deploy")
* @param timestamp - Optional timestamp to display after the label
* @param variant - Visual style for semantic coloring (default: 'neutral')
* @param className - Additional CSS classes for layout overrides
*
* @example
* ```tsx
* <TerminalMarker label="BUILD" timestamp="10:23:45" variant="info" />
* <TerminalMarker label="TEST" timestamp="10:24:01" variant="success" />
* <TerminalMarker label="DEPLOY" timestamp="10:24:30" variant="warning" />
* <TerminalMarker label="DONE" timestamp="10:24:45" variant="success" />
* ```
*/
export function TerminalMarker({
label,
timestamp,
variant = 'neutral',
className = '',
}: TerminalMarkerProps) {
const cls = variantClasses[variant]

return (
<div
className={`flex min-w-0 items-center gap-3 border-l-2 pl-3 py-1.5 my-2 rounded-r ${cls.root} ${className}`.trim()}
>
<span
className={`shrink-0 font-mono text-xs font-semibold tracking-widest uppercase ${cls.label}`}
>
{label}
</span>
{timestamp && (
<span className={`font-mono text-xs truncate ${cls.timestamp}`}>{timestamp}</span>
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

truncate on the timestamp span won’t reliably prevent overflow in a flex row unless the timestamp element is allowed to shrink (e.g., min-w-0 + a flexible width such as flex-1 or an explicit/max width). As written, the timestamp can still force the row wider on narrow viewports, undermining the responsive goal mentioned in the description.

Suggested change
<span className={`font-mono text-xs truncate ${cls.timestamp}`}>{timestamp}</span>
<span className={`flex-1 min-w-0 font-mono text-xs truncate ${cls.timestamp}`}>{timestamp}</span>

Copilot uses AI. Check for mistakes.
)}
</div>
)
}
1 change: 1 addition & 0 deletions components/terminal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -264,3 +264,4 @@ export { TerminalAutocomplete, useAutocomplete, COMMON_COMMANDS, COMMON_FLAGS, f
export { TerminalGhosttyTheme, GhosttyThemePicker } from './terminal-ghostty'
export { ThemeSwitcher } from './theme-switcher'
export { TerminalBadge } from './terminal-badge'
export { TerminalMarker } from './terminal-marker'
Loading