Skip to content

feat: inline Settings & History panels, fix tool-call contrast, add pill width scale#49

Open
okletstryitnow wants to merge 10 commits intolcoutodemos:mainfrom
okletstryitnow:feat/ui-panel-improvements
Open

feat: inline Settings & History panels, fix tool-call contrast, add pill width scale#49
okletstryitnow wants to merge 10 commits intolcoutodemos:mainfrom
okletstryitnow:feat/ui-panel-improvements

Conversation

@okletstryitnow
Copy link
Copy Markdown

Summary

Refactors the Settings and Recent Sessions (History) panels from createPortal-based popovers into inline panels rendered above the main card — matching the existing Marketplace panel pattern. Also fixes tool-call text visibility and adds a configurable pill width scale.

What changed

Panel Refactoring:

  • Settings panel: extracted SettingsContent (panel body) + SettingsPopover (trigger button) — renders inline above card with glass-surface styling
  • History panel: extracted HistoryContent + HistoryTrigger — same inline pattern
  • Single AnimatePresence with mode="wait" for clean panel-to-panel transitions
  • Mutual exclusion: only one panel (Settings/History/Marketplace) open at a time
  • Click-outside-to-close via data-*-panel / data-*-trigger attributes
  • Chat collapses when Settings or History opens (prevents overflow), Marketplace keeps chat open

Settings Enhancements:

  • Width slider (75-150%) for adjustable pill scale
  • Full Width toggle (synced with slider: ON=150%, OFF=100%)
  • Notification sound toggle
  • Dark/Light theme toggle
  • Terminal preference picker (UI ready — backend pending, see feat: Terminal app selector #19)
  • All settings persisted to localStorage

Visual Fixes:

  • Tool-call text contrast: textMutedtextTertiary for Result badges, "running..." status, and collapse header — was invisible against dark background (~1.3:1 → ~3.4:1 contrast ratio)
  • Right-edge content clipping: asymmetric padding (pl-4 pr-5) compensates for 4px custom scrollbar
  • History panel uses minHeight=maxHeight to prevent loading-state size jump
  • Settings panel fixed at 602px width (avoids jitter during width slider interaction)

Code Quality (from pre-PR audit):

  • Extracted PANEL_TRANSITION constant (was duplicated inline)
  • Removed dead variables and ternaries
  • Fixed as any casts with proper TypeScript narrowing
  • Fixed slider pointerUp leak (window-level listener with {once: true})
  • saveSettings reads from store after set() for consistency
  • Dock margin via CSS variable --clui-dock-margin (injected from main process)

Why

The portal-based popovers were inconsistent with the Marketplace's inline pattern, had complex position-calculation logic, and couldn't benefit from the content column's centering. The inline approach is simpler, more consistent, and works naturally with the dynamic window sizing (see companion PR).

The text contrast fix addresses a real accessibility issue — tool-call results were literally invisible in dark mode. The textMuted token (#353530) on containerBg (#242422) has a contrast ratio of ~1.3:1 (WCAG requires minimum 4.5:1).

Related PRs

  • Companion: fix/dock-display-binary (dynamic window sizing + Dock margin) — best merged first, but this PR works independently
  • Related: feat: Terminal app selector #19 (Terminal app selector) — our Settings panel includes the terminal picker UI; backend integration planned as a separate contribution

Test Plan

  • Click ... in TabStrip → Settings panel opens inline, centered above card
  • Width slider adjusts card width in real-time, Settings panel stays stable
  • Click 🕐 → Recent Sessions panel opens, sessions load
  • Open Settings → click 🕐 → Settings exits cleanly, History enters (no overlap)
  • Expand chat → open panel → chat collapses (except Marketplace)
  • Click outside any panel → closes
  • Tool-call "Result" badge and "Used X tools" text are readable in dark mode
  • At max width: content not clipped at right edge

🤖 Generated with Claude Code

okletstryitnow and others added 10 commits March 26, 2026 14:04
…ent clipping

UI Panel Refactoring:
- Refactor Settings from createPortal popover to inline panel above main card
- Refactor History (Recent Sessions) from createPortal popover to inline panel
- Split SettingsPopover into SettingsContent (panel) + SettingsPopover (trigger)
- Split HistoryPicker into HistoryContent (panel) + HistoryTrigger (trigger)
- Panels and expanded chat are mutually exclusive (prevents overflow beyond
  PILL_HEIGHT=720px window)
- Click-outside-to-close via data-*-panel / data-*-trigger attributes
- Mutual exclusion: only one of Settings/History/Marketplace open at a time

Settings Enhancements:
- Add pill width scale setting (75-150%) with live slider
- Add Full Width toggle synced with slider
- Add terminal preference picker (Auto/Terminal.app/Ghostty/iTerm2)
- Persist all settings to localStorage

Visual Fixes:
- Fix tool-call text contrast: textMuted → textTertiary for Result badges,
  running status, and collapse header (was invisible against dark background)
- Fix right-edge content clipping: asymmetric padding (pl-4 pr-5) to
  compensate for 4px custom scrollbar

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The terminal detection IPC is not registered when terminal-launcher
module is not included. Without optional chaining, the undefined
function call crashes the renderer when opening Settings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The width slider is inside the Settings panel — closing settings on
drag start made the slider unusable. Now only History panel closes
on scale-start; Settings stays open so users can adjust width live.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Settings panel width is frozen at drag-start and smoothly transitions
to the new size on release (0.2s ease-out). Prevents frame-by-frame
width recalculation that caused visual jitter during slider interaction.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…freeze

Replace unreliable pointerUp-based freeze mechanism with a simple CSS
transition (0.12s linear). CSS handles rapid value changes gracefully
by smoothly interpolating toward the latest target — no event-based
state management needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace dynamic width (tied to pillScale) with a fixed 602px width
(equivalent to 140% of collapsed card base). Eliminates all slider-
related jitter — the panel never resizes during width adjustment.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove contentWidth/cardWidth caps (dynamic window handles this)
- Remove bodyMaxHeight compression for marketplace
- Revert circle button spacing to original (56px/112px)
- Marketplace no longer collapses chat when opening
- History panel minHeight=maxHeight prevents loading size jump
- Add paddingBottom: var(--clui-dock-margin) for Dock clearance
- Fix drag code: window.innerHeight instead of hardcoded PILL_HEIGHT

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove dead windowHeight variable
- Extract PANEL_TRANSITION constant (was inline-duplicated)
- Remove dead ternary (expandedUI ? 15 : 15)
- Fix as-any casts in TerminalPicker with proper type narrowing
- Fix slider pointerUp leak with window-level {once:true} listener
- saveSettings reads from get() after set() for consistency

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

1 participant