Skip to content

Feat/terminal group#23

Open
himax12 wants to merge 7 commits intoclawgreen:mainfrom
himax12:feat/terminal-group
Open

Feat/terminal group#23
himax12 wants to merge 7 commits intoclawgreen:mainfrom
himax12:feat/terminal-group

Conversation

@himax12
Copy link
Copy Markdown

@himax12 himax12 commented Mar 1, 2026

#12
This pull request adds several new interactive demos to the playground for the terminal UI components, expanding coverage for structured logs, filtering, grouping, searching, and stack traces. It also improves the organization and clarity of the playground page by updating section headers and descriptions, and by integrating the new demos into the main showcase.

New playground demos:

  • Added FilterBarDemo to demonstrate terminal log filtering by source, level, and text, using the TerminalFilterBar and simulated log entries. (app/playground/filter-demo.tsx, app/playground/page.tsx) [1] [2]
  • Added StructuredLogDemo to showcase structured log streaming with badges, timestamps, and sources using the TerminalLog component in structured mode. (app/playground/log-demo.tsx, app/playground/page.tsx) [1] [2] [3]
  • Added GroupDemo to demonstrate collapsible terminal output sections via TerminalGroup, including controlled and uncontrolled open/close states and variant accents. (app/playground/group-demo.tsx, app/playground/page.tsx) [1] [2]
  • Integrated additional demos for search (SearchDemo) and stack traces (StackTraceDemo) into the playground page. (app/playground/page.tsx)

Playground page improvements:

  • Updated section headers and descriptions for clarity and consistency, and added new sections for each demo (e.g., "TerminalLog — structured mode", "TerminalGroup", "TerminalSearch", etc.). (app/playground/page.tsx) [1] [2] [3] [4] [5] [6] [7]

These changes make the playground a more comprehensive and interactive showcase for terminal UI features, helping developers understand and test each component in isolation.

himax12 added 7 commits March 2, 2026 02:34
…en#7)

- New `TerminalMarker` component with typed props and JSDoc
- Props: label, timestamp?, variant ('info'|'success'|'warning'|'error'|'neutral')
- Theme-aware via CSS custom properties (--term-* variables)
- Semantic background tint with color-mix for visual hierarchy (consistent with TerminalBadge)
- Responsive: min-w-0 + truncate on timestamp prevents overflow on narrow viewports
- Export added to components/terminal.tsx (no breaking changes)
- Playground demo added to app/playground/page.tsx
)

- New TerminalLogLine component with typed props and JSDoc
- Props: message (ReactNode), level, timestamp?, source?
- Level badge using 3-char uppercase labels (DBG/INF/WRN/ERR/OK) for consistent monospace alignment
- Theme-aware via CSS custom properties; error level colors message text red
- Responsive: min-w-0 + wrap-break-word on message prevents overflow
- Export added to components/terminal.tsx with re-exported type
- Playground demo added with 8 representative log lines
- Add color-mix background tints to level badges (consistent with TerminalBadge)
- Fix badge alignment: use w-[calc(3ch+0.5rem)] + justify-center so all 5 levels
  (DBG/INF/WRN/ERR/OK) render at identical pixel width in monospace layout
- Update levelClasses to Tailwind v4 CSS variable shorthand (text-/border-(--term-*))
- Remove 'OK ' trailing-space hack (HTML collapses whitespace); fixed-width badge
  container is the correct approach
…compat

- New LogEntry type { id?, message, level?, timestamp?, source? }
- New optional entries prop on TerminalLog — takes precedence over lines
- Existing lines?: string[] consumers continue to work with zero changes
- Internally reuses TerminalLogLine for structured rendering (level badges,
  timestamps, source labels, color-mix tints)
- maxLines and autoScroll work identically on both paths
- Export LogEntry from components/terminal.tsx
- Add StructuredLogDemo to playground (streaming entries with all 5 levels)
- Use Tailwind v4 CSS variable shorthand in terminal-log.tsx
…n#10)

- New TerminalFilterBar controlled component with typed props + JSDoc
- Level toggle buttons (DBG/INF/WRN/ERR/OK) with active color-mix tints
  matching TerminalLogLine badge palette; aria-pressed for a11y
- Text search input with inline SVG search icon + clear button (X)
- Source toggle buttons — row only rendered when sources prop is non-empty
- Clear-all pill shown only when any filter is active
- All controls are native <button>/<input> — fully keyboard accessible
- Exported pure helper filterEntries(entries, state) for composable use
- emptyFilterState() factory for clean initial state
- Exports: TerminalFilterBar, filterEntries, emptyFilterState,
  FilterBarState, TerminalFilterBarProps, LogLevel
- FilterBarDemo playground with 14 entries across 5 levels and 4 sources
- Entry count indicator: 'N / 14 entries shown'
Copilot AI review requested due to automatic review settings March 1, 2026 22:00
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR expands the terminal UI playground into a more comprehensive showcase by adding new terminal-feed primitives (grouping, structured log rows, search, filtering, markers) and wiring them into dedicated demos on the playground page.

Changes:

  • Add new terminal feed components: TerminalGroup, TerminalSearch (+ useTerminalSearch), TerminalFilterBar (+ filterEntries), TerminalMarker, TerminalLogLine, and structured-entry support in TerminalLog.
  • Update TerminalLog API to support entries: LogEntry[] (structured mode) while keeping lines as a backward-compatible path.
  • Add multiple new playground demos and reorganize the playground page sections accordingly.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
components/terminal.tsx Re-exports new terminal primitives (and updates TerminalLog export typings).
components/terminal-log.tsx Adds structured log entry mode (entries) and updates rendering/scroll behavior.
components/terminal-log-line.tsx Introduces a structured log row primitive with badges/timestamp/source.
components/terminal-group.tsx Adds collapsible grouping for command/output sections with ARIA semantics.
components/terminal-search.tsx Adds TerminalSearch UI + useTerminalSearch hook for in-feed search/navigation.
components/terminal-filter-bar.tsx Adds a controlled filter bar and a pure filtering helper for LogEntry[].
components/terminal-marker.tsx Adds phase/section marker rows for terminal feeds.
app/playground/page.tsx Integrates and documents new demos/sections in the playground page.
app/playground/log-demo.tsx Adds a structured-log demo alongside the existing string-log demo.
app/playground/group-demo.tsx Adds a demo showcasing controlled/uncontrolled TerminalGroup usage.
app/playground/search-demo.tsx Adds a search demo with highlighting and scroll-into-view behavior.
app/playground/filter-demo.tsx Adds a filter bar demo using TerminalFilterBar + filterEntries.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

<div
ref={containerRef}
className={`max-h-64 overflow-auto rounded border border-[var(--glass-border)] bg-[var(--term-bg)]/40 p-3 font-mono text-sm ${className}`.trim()}
className={`max-h-64 overflow-auto rounded border border-(--glass-border) bg-(--term-bg)/40 p-3 font-mono text-xs ${className}`.trim()}
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.

TerminalLog now renders with text-xs instead of the previous text-sm, which changes the default appearance for existing consumers even when they still use lines. If this wasn’t intended as a breaking visual change, consider keeping the previous default font size (or making the size configurable) and applying text-xs only where needed (e.g., inside TerminalLogLine).

Suggested change
className={`max-h-64 overflow-auto rounded border border-(--glass-border) bg-(--term-bg)/40 p-3 font-mono text-xs ${className}`.trim()}
className={`max-h-64 overflow-auto rounded border border-(--glass-border) bg-(--term-bg)/40 p-3 font-mono text-sm ${className}`.trim()}

Copilot uses AI. Check for mistakes.
Comment on lines +112 to 113
className={`max-h-64 overflow-auto rounded border border-(--glass-border) bg-(--term-bg)/40 p-3 font-mono text-xs ${className}`.trim()}
role="log"
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.

This file introduces Tailwind variable shorthand like border-(--glass-border) / bg-(--term-bg) / text-(--term-fg-dim), while most existing components use the ...[var(--...)] form (e.g., border-[var(--glass-border)], text-[var(--term-fg-dim)]). Mixing both styles makes the styling conventions harder to follow; consider standardizing on one syntax across the component library.

Copilot uses AI. Check for mistakes.
useTerminalSearch,
type LogEntry,
} from '@/components/terminal'
import { TerminalLog } from '@/components/terminal-log'
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.

TerminalLog is imported from @/components/terminal-log but never used. This can fail linting and should be removed (or use the component if intended).

Suggested change
import { TerminalLog } from '@/components/terminal-log'

Copilot uses AI. Check for mistakes.
Comment on lines +305 to +306
export { TerminalStackTrace, type TerminalStackTraceProps } from './terminal-stack-trace'
export { TerminalJsonLine, type TerminalJsonLineProps } from './terminal-json-line'
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.

TerminalStackTrace / TerminalJsonLine are exported from ./terminal-stack-trace and ./terminal-json-line, but those modules don’t exist in the repo (so this will fail at build/tsc time). Add the missing component files (and ensure they’re included in the PR) or remove these exports.

Suggested change
export { TerminalStackTrace, type TerminalStackTraceProps } from './terminal-stack-trace'
export { TerminalJsonLine, type TerminalJsonLineProps } from './terminal-json-line'

Copilot uses AI. Check for mistakes.
import { LogDemo } from './log-demo'
import { LogDemo, StructuredLogDemo } from './log-demo'
import { FilterBarDemo } from './filter-demo'
import { TerminalJsonLine } from '@/components/terminal'
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.

TerminalJsonLine is imported/used from @/components/terminal, but the underlying ./terminal-json-line module is not present in components/ (so this import/export chain will fail). Either include the missing component implementation in this PR or remove this demo section until it exists.

Suggested change
import { TerminalJsonLine } from '@/components/terminal'

Copilot uses AI. Check for mistakes.
import { SearchDemo } from './search-demo'
import { TreeDemo } from './tree-demo'
import { TreeKeyboardDemo } from './tree-keyboard-demo'
import { StackTraceDemo } from './stack-trace-demo'
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.

StackTraceDemo is imported from ./stack-trace-demo, but there is no app/playground/stack-trace-demo.tsx in the repo. This will break the playground page build; add the missing file or remove the import/section.

Suggested change
import { StackTraceDemo } from './stack-trace-demo'

Copilot uses AI. Check for mistakes.
Comment on lines +66 to +83
// Clamp currentIndex whenever matchIndices changes.
const safeCurrentIndex =
matchIndices.length === 0 ? -1 : Math.min(currentIndex, matchIndices.length - 1)

const setQuery = useCallback((q: string) => {
setQueryRaw(q)
setCurrentIndex(0)
}, [])

const next = useCallback(() => {
if (matchIndices.length === 0) return
setCurrentIndex((prev) => (prev + 1) % matchIndices.length)
}, [matchIndices.length])

const prev = useCallback(() => {
if (matchIndices.length === 0) return
setCurrentIndex((prev) => (prev - 1 + matchIndices.length) % matchIndices.length)
}, [matchIndices.length])
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.

In useTerminalSearch, safeCurrentIndex is derived but the currentIndex state is never clamped when matchIndices shrinks (e.g., when items changes). Because next/prev use the raw state value, navigation can get stuck on the wrong index when currentIndex is out of range. Consider clamping currentIndex in an effect when matchIndices changes, or compute the next/prev index from safeCurrentIndex instead of the stale state.

Copilot uses AI. Check for mistakes.
{source && <span className="shrink-0 text-(--term-fg-dim)">{source}</span>}

{/* Message */}
<span className={`min-w-0 wrap-break-word ${cls.message}`}>{message}</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.

wrap-break-word isn’t a standard Tailwind utility, so the message text likely won’t break long tokens and can overflow the container. Replace it with a valid wrapping strategy (e.g., break-words/break-all, optionally combined with whitespace-pre-wrap depending on desired formatting).

Suggested change
<span className={`min-w-0 wrap-break-word ${cls.message}`}>{message}</span>
<span className={`min-w-0 break-words ${cls.message}`}>{message}</span>

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants