Skip to content

CAMEL-23839: camel-jbang TUI - switchable light/dark CSS theme#24322

Open
ammachado wants to merge 18 commits into
apache:mainfrom
ammachado:CAMEL-23839
Open

CAMEL-23839: camel-jbang TUI - switchable light/dark CSS theme#24322
ammachado wants to merge 18 commits into
apache:mainfrom
ammachado:CAMEL-23839

Conversation

@ammachado

@ammachado ammachado commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Description

Introduces a switchable, CSS-backed theme for the Camel JBang TUI (camel tui), replacing the previously hard-coded inline colors with a central semantic Theme.

What's new

  • Central Theme is the single semantic source of truth for TUI styles (borders, status colors, accents, zebra rows, selection, empty-state, MCP indicator, key-hint chips, ...).
  • CSS stylesheets (dark.tcss / light.tcss, backed by tamboui-css) define the palettes. Two ship: dark (default) and light.
  • Runtime toggle with F4 on any screen; the choice is persisted as camel.tui.theme (dark/light) in .camel-jbang-user.properties and restored on the next launch.
  • The brand orange accent is identical in both themes; status colors (success/warning/error), borders, and the MCP indicator adapt for readability on light and dark terminals.
  • A built-in fallback palette (mirroring the dark theme) keeps the TUI usable if a stylesheet is missing or malformed (logged once, never crashes).

Visual polish included

  • Active-tab highlight, zebra-striped rows, focus-aware shell panel border.
  • Shared empty / no-selection state with a refined camel and orange key-hint chips.
  • Overview empty-state now draws its border consistently with the other panels.

Screenshots

image image image

Notes for reviewers

  • Theme-token migration covers the chrome and status colors (header, tabs, footer, MCP indicator, Overview row status). Some secondary tabs still use direct colors for table-content cells; these can be migrated incrementally.
  • The black-on-orange key-hint chip now resolves through Theme.hintKey() / a #hint-key CSS token instead of a hard-coded HINT_KEY_STYLE constant (addresses review feedback). It was a static final that could never track a runtime theme toggle; behavior is unchanged today (black-on-orange in both palettes) but it is now wired through the engine like every other color.
  • Tab labels are plain text. Emoji tab icons were trialed but added ~3 columns per tab and overflowed the tuned tab-bar width budget (compact labels fit at MIN_WIDTH=88, full at TABS_FULL_MIN_WIDTH=126) on small/medium terminals, so they were removed. A themed per-tab icon rendered on the content border is a possible follow-up.
  • Documentation: the TUI manual page and the 4.21 upgrade guide are updated; the documented shortcut (F4) matches the implementation.
  • ThemeTest covers token resolution for both palettes (including the new hint-key token), the theme toggle, and persistence to user config.

Target

  • I checked that the commit is targeting the correct branch (Camel 4 uses the main branch)

Tracking

  • If this is a large change, bug fix, or code improvement, I checked there is a JIRA issue filed for the change (usually before you start working on it).

JIRA: https://issues.apache.org/jira/browse/CAMEL-23839

Apache Camel coding standards and style

  • I checked that each commit in the pull request has a meaningful subject line and body.
  • I have run mvn clean install -DskipTests locally from root folder and I have committed all auto-generated changes.

AI-assisted contributions

  • If this PR includes AI-generated code, commits have proper co-authorship attribution (e.g., Co-authored-by trailers) and the PR description identifies the AI tool used.

AI tool used: Claude Code (Opus 4.8), on behalf of Adriano Machado.

@ammachado ammachado requested review from davsclaus and gnodet June 30, 2026 05:56
@github-actions

Copy link
Copy Markdown
Contributor

🌟 Thank you for your contribution to the Apache Camel project! 🌟
🤖 CI automation will test this PR automatically.

🐫 Apache Camel Committers, please review the following items:

  • First-time contributors require MANUAL approval for the GitHub Actions to run
  • You can use the command /component-test (camel-)component-name1 (camel-)component-name2.. to request a test from the test bot although they are normally detected and executed by CI.
  • You can label PRs using skip-tests and test-dependents to fine-tune the checks executed by this PR.
  • Build and test logs are available in the summary page. Only Apache Camel committers have access to the summary.

⚠️ Be careful when sharing logs. Review their contents before sharing them publicly.

@ammachado ammachado marked this pull request as ready for review June 30, 2026 06:04

@davsclaus davsclaus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice work on the CSS-backed theming! The Theme class design is solid — semantic token names, graceful CSS fallback with a single log warning (never crashes), and proper test coverage including persistence roundtrip.

A few observations:

  • The PR bundles some unrelated changes with the theme feature (tamboui API migration ke.character()ke.string().charAt(0), @SuppressWarnings cleanup, stream API refactoring in DataRefreshService, Size constructor migration, test cleanup). Each is individually correct, but splitting them into separate commits would make the git history easier to navigate.
  • HINT_KEY_STYLE is a non-theme-switchable constant (black-on-orange in both themes). Intentional? Or should it also resolve through Theme?
  • CI: JDK 25 build failed on mvn test, JDK 17 was cancelled. Likely pre-existing but worth confirming.

Overall the core feature is well-designed and well-documented (upgrade guide, TUI manual, help text all updated). LGTM.

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

Claude Code on behalf of Claus Ibsen

ammachado and others added 18 commits July 1, 2026 09:10
…t, zebra rows, Overview empty state

- Add emoji glyphs to tab labels and an orange-background highlight for the active tab
- Zebra-stripe Overview integration/infra rows for readability
- Add an empty-state instructions page when no integrations are running

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

# Conflicts:
#	dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

^ Conflicts:
^	dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The theme toggle was bound to Shift+T while the help text, the TUI doc
page, and the upgrade guide all advertised F4. Shift+T also collided
with the RoutesTab "top mode" toggle (isCharIgnoreCase('t')), which the
global handler shadowed. Bind the toggle to the free F4 key so the code
matches the documented shortcut and frees Shift+T.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The MCP footer indicator still emitted raw ANSI colors for its
active/idle/down dot, so it did not follow the light stylesheet. Add
dedicated mcp-active / mcp-idle / mcp-down tokens to both stylesheets
and Theme accessors (with built-in fallbacks mirroring the dark theme),
and point the indicator at them.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The integration and infra status cells still used raw ANSI colors, so
they did not adapt to the light stylesheet. Map them to the semantic
Theme tokens (success/warning/error), matching the header chrome.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the placeholder camel with a clearer silhouette: a smaller head,
a distinct hump, and three legs with feet, so the empty/no-selection
state reads as a camel rather than a big-headed horse.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The emoji tab icons added ~3 columns per tab, overflowing the tab-bar
width budget that was tuned to the cell (compact labels fit at MIN_WIDTH
88, full labels at TABS_FULL_MIN_WIDTH 126). Remove the emoji to restore
the fit on small and medium terminals; a themed per-tab icon can be
reintroduced on the content border later.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The empty/no-selection panel built a rounded Block but never set
borders(Borders.ALL), so no border was drawn (every other panel sets
it). Add the borders, and render the F6/?/F1 key hints as orange
HINT_KEY_STYLE chips instead of literal [F6]/[?]/[F1] text, matching the
footers and the other tabs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add inner spacing to the F1/? and arrow key chips in the help overlay
footer so they match the chip styling used elsewhere.
Move the black-on-orange key-hint chip into the CSS-backed Theme like
every other token. Adds a #hint-key token to dark.tcss/light.tcss and a
Theme.hintKey() accessor, replacing the hardcoded HINT_KEY_STYLE
constant in MonitorContext and its call sites. This makes the chip
theme-resolved (it was a static final, frozen at class load) and
corrects the accentBg() javadoc that no longer covers hint keys.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

ℹ️ CI did not run targeted module tests (skip-tests label detected).


⚙️ View full build and test results

@davsclaus davsclaus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Clean, well-structured PR. The theme centralization replaces scattered inline colors with semantic Theme accessors backed by CSS stylesheets — a clear improvement. The fallback palette is defensive (cosmetic failure never crashes the TUI), and ThemeTest covers both palettes, toggle, persistence round-trip, and null safety. Documentation (upgrade guide + TUI manual) is updated and matches the implementation.

A few minor observations (none blocking):

  • Several non-theme cleanups are bundled (deprecated API migration, @SuppressWarnings removals, noneMatchallMatch, DataRefreshService null check fix). The commit e51d09db groups them intentionally, which is reasonable.
  • Theme thread safety is pragmatically fine — accent() and zebra() resolve outside the synchronized block, but the TUI event loop is single-threaded so there's no real race.

Note: CI was running a full 673-module build because the root pom.xml .tcss formatter entry triggered Scalpel to cascade. The incremental-skip-tests label has been applied to unblock.

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment