Skip to content

feat(tui): redesign chrome, color system, picker + theme typography#96

Draft
kshivam14 wants to merge 6 commits into
parseablehq:mainfrom
kshivam14:feat/tui-redesign
Draft

feat(tui): redesign chrome, color system, picker + theme typography#96
kshivam14 wants to merge 6 commits into
parseablehq:mainfrom
kshivam14:feat/tui-redesign

Conversation

@kshivam14
Copy link
Copy Markdown

Summary

Complete TUI redesign for pb — palette + typography system, k9s-style chrome, picker view, and theme-aware components. Backward compatible: existing pb query -i and pb query --promql -i keep working; new pb tui is the greenfield entrypoint.

What's new

Design system (pkg/ui/)

  • Palette (dark + light) — surfaces, borders, text ramp, brand, semantic, syntax, interaction tokens
  • Typography — 19 named lipgloss styles (Label, Body, Accent, BadgeOk, StatusMode, etc.) built from palette
  • Card primitive — letter-spaced uppercase title + meta subtitle + subtle border
  • HeaderStrip — KV context + 3-col keybind grid + PB ASCII logo
  • Breadcrumbs row + segmented StatusBar
  • Chroma SQL/PromQL highlight, ASCII chart wrapper, PB ASCII wordmark
  • Icon set: PB_ICONS=ascii|nerd toggle
  • Theme loader: PB_THEME=dark|light|auto (auto via COLORFGBG)

Greenfield TUI (pb tui)

  • Root App model with view switching (1-7 keys, breadcrumbs)
  • pkg/ui/views/picker.go — fuzzy dataset picker with selection rail + pinning
  • Placeholders for results / metrics / time / saved / help (next PRs)

Existing views polished

  • Yellow ANSI 226/220 → brand indigo across cmd/style.go, pkg/model/{credential,defaultprofile,login,role}/
  • pkg/model/query.go + promql.go: theme-aware textarea, hidden vim tildes, uniform editor bg, no vertical column dividers, Faint headers, near-invisible nulls, HH:MM:SS timestamps, SelRow + Accent selection
  • pkg/model/status.go: segmented MODE/CLUSTER/ENV/LIVE/t/help
  • pkg/model/timeinput.go + timerange.go: redesigned modal with preset list, manual fields, now badge, summary chip
  • Esc in time modal cancels; Alt+Enter runs query
  • 15 ad-hoc styles migrated to ui.Type()

Stats

25 files changed, 3094 insertions(+), 404 deletions(-)
11 new files in pkg/ui/ + cmd/tui.go

Test plan

  • go build -o pb . && ./pb query -i — SQL editor, run query, table renders
  • ./pb query --promql -i — PromQL editor + dataset picker (ctrl-d)
  • ./pb tui — greenfield, picker fetches datasets, selecting jumps to query view
  • PB_THEME=light ./pb query -i — light palette readable
  • PB_THEME=dark ./pb query -i — dark palette readable
  • PB_ICONS=nerd ./pb tui — nerd glyphs render
  • Esc in time modal cancels without running
  • Alt+Enter runs query (with terminal meta config)

🤖 Generated with Claude Code

- New pkg/ui package: Palette (dark+light), Typography styles, Card primitive,
  HeaderStrip, Breadcrumbs, status bar, chroma SQL/PromQL highlight, ASCII chart,
  PB ASCII wordmark, icon set (PB_ICONS=ascii|nerd toggle).
- Theme loader: PB_THEME=dark|light|auto via COLORFGBG sniff.
- pkg/ui/views/: greenfield View interface + picker (fuzzy dataset list, pinning,
  selection rail) + EmptyView placeholders for remaining screens.
- cmd/tui.go: new `pb tui` cobra command (greenfield entry), leaves existing
  `pb query -i` untouched.
- Migrate yellow ANSI 226/220 references across cmd/style.go,
  pkg/model/{credential,defaultprofile,login,role}/*.go to brand indigo via
  ui.Adaptive.
- pkg/model/query.go + promql.go: theme-aware textarea styles, hidden vim
  tildes, uniform editor bg, dropped vertical column dividers, header in
  Faint, data in Body, null indicator near-invisible, timestamps trimmed to
  HH:MM:SS, selection on SelRow+Accent.
- pkg/model/status.go: segmented MODE/CLUSTER/ENV/LIVE/t/help bar.
- pkg/model/timeinput.go + timerange.go: redesigned modal with preset list +
  manual fields + now badge + summary chip.
- Esc in time modal closes without applying; Alt+Enter runs query
  (Cmd+Enter via terminal Meta config).
- Migrated 15 ad-hoc Foreground styles in pkg/model/* to ui.Type().

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

CLA Assistant Lite bot:
Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request

kshivam14 and others added 5 commits May 21, 2026 17:42
- Drop rounded chrome and inner rules. Each zone (editor / date / results
  / help / footer) is a flat NormalBorder rectangle with a single label
  row — matches the agreed wireframe.
- Tighten DATE sidebar width (20/24/28 by terminal size). Drop the
  start/end/now hint and span/step/samples summary in the modal picker
  to match the minimal main view.
- Replace customBorder's rounded outer box with column-divider-only.
  Outer border is drawn by renderResultsPane so the table no longer
  double-borders inside the Results zone.
- StatusBar: full NormalBorder rectangle (was BorderTop only). Drop
  Panel background — plain rectangle to match the four-zone system.
- Light theme: auto-detect via lipgloss.HasDarkBackground when
  $PB_THEME / $COLORFGBG are unset. Previously fell through to Dark
  unconditionally, leaving the editor's EditorBg painted near-black on
  light terminals.
- Bump Light palette Border / BorderSoft / BorderHi for legible chrome
  on white backgrounds (#D8D8DC was invisible on #FBFBFD).
- Fix editor pane height: textarea was hardcoded to 10 rows but the
  pane only allots topH-3. The overflow pushed the top border + EDITOR
  label off-screen. Size textarea to match the pane each render.

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

PromQL view
- Rebuild PromQL as the same four-zone layout SQL uses: editor (wide)
  + sidebar (narrow) on top, results below, single bottom bar.
- Sidebar holds from/to + step+mode + dataset as three sub-groups
  separated by blank lines. Active sub-section gets a 1-cell Accent
  bg rail on each of its rows; idle rows use 2-space leading. Rail is
  unambiguous active-state signaling — color alone read as just
  "another shade of purple" against the editor accent.
- Editor title carries a code|builder mode toggle with the same
  Accent rail in front of the active mode and a visible <ctrl-b>
  shortcut hint, so the affordance is discoverable.
- Empty state uses the same PARSEABLE wordmark + <ctrl+r> run query
  hint as SQL. Drops the rate(...) example block and the lowercase
  "p a r s e a b l e" logo.
- PromQL textarea picks up the SQL editor styling (line numbers,
  blank end-of-buffer, theme-aware colors).

Bottom bar
- Collapse help + status into one bordered strip in both SQL and
  PromQL (buildBottomBar / buildPromqlBottomBar). Drops the CLUSTER
  URL segment; keeps focus-aware key hints on the left and info ·
  MODE · LIVE on the right. Saves a row of vertical chrome.

Editor background
- Strip every Background() out of applyEditorStyles. The textarea
  now inherits the terminal background, so the editor blends in
  regardless of which theme the terminal is set to. Previously the
  palette's EditorBg painted a near-black box on light terminals and
  vice versa.

Modals
- Time picker, dataset spotlight, and PromQL builder all switch from
  rounded chrome with Panel/EditorBg fills to flat NormalBorder
  frames with no bg fills. Titles are UPPERCASE Accent bold.
- Spotlight grows a header row (SELECT DATASET · N datasets), a
  hairline BorderSoft rule, an inline filter prompt (no inner border
  box), and a 1-cell Accent rail on the selected row. Idle rows are
  Body fg with a 2-space leading prefix.
- Builder uses the same rail + UPPERCASE column titles + inline
  filter. Time picker preset list delegate uses the same rail
  pattern. SelRow backgrounds removed everywhere — they didn't pad
  cleanly past trailing ANSI resets, which is what caused the
  half-filled highlight rows.
- Textinput prompts (spotlight + builder) get Accent bold "> " and
  Ghost italic placeholders.

Bottom-bar wiring
- StatusBar's outer width was m.width-4 (rendered 2 cells narrower
  than the help bar above it); use m.width-2 for the bordered total
  and m.width-4 only for the inner gap math.
- Table customBorder: Top stays blank but Bottom is "─" so the
  header gets a real underline rule. Empty Top/Bottom chars rendered
  as phantom rows with BorderTop/BorderBottom still enabled, which
  caused the VALUE column header to wrap to the next visual line.

Editor and sidebar spacing
- Insert a 1-col gap between the editor pane and the sidebar pane in
  both views so the two `│` borders aren't flush against each other.
- Editor body height now tracks topH - 3 so the textarea matches the
  pane's inner content area exactly. Previously the textarea was
  hardcoded to 10 rows, overflowed the pane, and pushed the top
  border + EDITOR title off-screen.

Typography + key hints
- Keys everywhere render as <key> (was [key], or bare). Help-bar
  labels lowercased. Placeholders rewritten as concrete example
  queries (select * from "dataset" limit 100 / rate(...)).
- DATE pane title dropped (the lowercase from/to labels carry the
  meaning); focused state highlights the label only, value stays
  Body. Same pattern in PromQL sidebar.

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

Active-state color
- Add a dedicated Active palette atom (sky-400 #38BDF8 dark / sky-600
  #0284C7 light) reserved for "cursor here, will edit" + list
  selection. Routes through every focus/selection surface:
  - SQL DATE pane focus → Active rail + Active bold FROM/TO.
  - PromQL sidebar DATASET / FROM-TO / STEP-MODE focused group →
    same rail + label treatment.
  - Date picker preset list, dataset spotlight rows, builder
    columns (METRICS / LABELS / VALUES) → same convention.
- Code | Builder toggle: active mode in Active sky-blue, idle Faint,
  static " | " separator. Removed the inline <ctrl-b> hint — it now
  lives only in the bottom bar.

Sidebar parity
- Move the sidebar to the LEFT of the editor in both SQL and PromQL
  so the two views read identical.
- Reorder PromQL sidebar to DATASET first, then FROM/TO, then
  STEP/MODE. All labels UPPERCASE (DATASET, FROM, TO, STEP, MODE).
- Add DATASET row to the SQL sidebar (parsed read-only from the SQL
  FROM clause via extractDataset; Faint label, no focus highlight).
- SQL sidebar width bumped to match PromQL (26/30/34 by terminal
  size). Previously the dates wrapped to two lines on narrow widths.
- SQL topH locked to 11 so the extra DATASET rows never push the top
  border off-screen on small terminals.

Default dataset
- On dataset-list arrival, if no dataset is selected yet, pick the
  first entry and fire fetchCacheMetrics so the sidebar shows a real
  value out of the box instead of the "select-dataset" placeholder.

Editor pane
- Add a blank spacer row between the EDITOR title and the first line
  of code in both panes; reduce editorBodyH by 1 to keep the overall
  pane height unchanged.
- Empty state: drop the centered <ctrl+r> run query hint — the
  PARSEABLE wordmark alone marks the empty state, and the bottom bar
  still carries the shortcut.
- Both editors now use the same placeholder ("Write your queries
  here").

Tables
- Match PromQL results table to SQL Results: UPPERCASE column titles
  (TIMESTAMP / METRIC / VALUE), timestamp width 10 (was 20), and
  timestamps trimmed via shared trimTimestampToHMS. The header,
  divider, and row styling were already shared.

Light theme
- Lighten light-theme Border (#A8A8B0 → #D1D5DB) and BorderSoft
  (#C8C8CE → #E5E7EB) so idle pane borders sit back as chrome
  instead of competing with content. BorderHi (purple #5A5AC8) is
  unchanged, so the focused pane now pops cleanly against the
  lighter idle borders.

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

Login (`pb login`)
- Wrap every wizard step in a single NormalBorder card (Width 60).
- Title row "PARSEABLE LOGIN" Accent bold; step labels UPPERCASE
  (SERVER URL, USERNAME, PASSWORD, API KEY, AUTHENTICATION, etc.).
- Replace the `❯` cursor + Accent bg with a paired indicator: a
  1-cell Active sky-blue bg rail + `❯` arrow + Active bold label.
  Idle rows: 4-space prefix + Body label.
- New `hint(...)` helper renders `<key> action` pairs consistently
  across every step; drops the dashes-separator and breadcrumb.
- View() appends a trailing `\n` so the shell prompt doesn't
  overwrite the card's bottom border when the program quits (login
  runs without AltScreen).

Saved queries (`pb query list`)
- Split into two stacked NormalBorder cards, both Width = m.width,
  so the right edge always reaches the terminal border:
    1. Main card: UPPERCASE "SAVED QUERIES" title + the list.
    2. Footer card: `<a/enter> apply  <b> back  <ctrl-c> quit`.
- Item delegate rewritten: 1-cell Active rail + bold Active title on
  the focused row, idle rows Body bold title + Faint query desc +
  Faint from/to meta. Empty descs render as "(empty query)" instead
  of the literal `""` that fetchFilters produced.
- Long rows truncated with `…` to fit `m.Width()-4` so SELECTs no
  longer wrap and push the right border off-screen.
- list/viewport sized to (m.width-6, m.height-9) so the title and
  footer card always stay on screen. Item Height tightened from 4
  to 3 rows (+1 spacing).
- list.SetShowTitle/Status/Help all false — the card chrome carries
  the title and hints now.

Dark borders
- Idle pane borders read as too dim against the dark background.
  Bump Dark.Border #2A2A3D → #4A4A5C (visible gray), BorderSoft
  #1F1F2E → #2A2A3D (hairlines stay subtle), BorderHi #5050A8 →
  #7878E0 so the focused outline still pops against the brighter
  idle gray.

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

Both views — SQL and PromQL — now render the sidebar as two stacked
NormalBorder cards whose borders touch (zero-gap join, same as the
top section ↔ results pane join).

PromQL
- Move the sidebar to the right of the editor (was on the left).
- Top card (8 rows): DATASET, blank, STEP, MODE. Active rail + bold
  label on the focused sub-section (dataset focus highlights the
  DATASET pair; step focus highlights the STEP/MODE pair).
- Bottom card (6 rows): FROM, TO. Time focus lights the Active rail
  + bold label. Instant mode hides FROM.
- topH bumped to 14 so the editor pane matches the stacked sidebar
  height (8 + 6).
- Drop the unified renderPromqlSidebarPane; replaced by
  renderPromqlControlsBox + renderPromqlDateBox sharing a
  sidebarStyles() helper for label/value/rail styles.

SQL
- Move the sidebar to the right of the editor.
- Top card (4 rows): read-only DATASET parsed from the SQL FROM
  clause. SQL has no separate dataset focus, so this card never
  lights.
- Bottom card (7 rows): FROM, TO. Same Active rail + bold label
  treatment on time focus as PromQL.
- Drop renderTimePane; replaced by renderSQLDatasetBox +
  renderSQLDateBox. 4 + 7 = 11 = topH.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@kshivam14 kshivam14 marked this pull request as draft May 22, 2026 10:27
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