Skip to content

Feature/tooltip system clean#2973

Open
desireddymohithreddy0925 wants to merge 16 commits into
Karanjot786:mainfrom
desireddymohithreddy0925:feature/tooltip-system-clean
Open

Feature/tooltip system clean#2973
desireddymohithreddy0925 wants to merge 16 commits into
Karanjot786:mainfrom
desireddymohithreddy0925:feature/tooltip-system-clean

Conversation

@desireddymohithreddy0925

@desireddymohithreddy0925 desireddymohithreddy0925 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Description

This PR implements a global Tooltip System to provide extended descriptions when users hover over or focus on terminal UI elements. It introduces a TooltipManager in @termuijs/core, extends the base Widget with an optional tooltip property, and provides a TooltipOverlay component in @termuijs/ui that correctly measures wide characters and emoji using stringWidth().

Related Issue

Closes #2861

Which package(s)?

@termuijs/core, @termuijs/widgets, @termuijs/ui

Type of Change

  • 🐛 Bug fix (type:bug)
  • ✨ Feature (type:feature)
  • 📝 Docs (type:docs)
  • 🧪 Tests (type:testing)
  • ♻️ Refactor (type:refactor)
  • 🎨 Design / UX (type:design)
  • ♿ Accessibility (type:accessibility)
  • ⚡ Performance (type:performance)
  • 🔧 DevOps / CI (type:devops)
  • 🔒 Security (type:security)

Checklist

  • ⭐ You starred the repo. The never rules are respected.
  • 🧪 Tests are included or updated.
  • 🏗️ bun run build passes locally.
  • 🧹 bun run lint and bun run typecheck pass locally.
  • 📦 The scope is strictly confined to the packages specified.

Summary by CodeRabbit

  • New Features
    • Added tooltips for widgets when hovered or focused.
    • Tooltips appear after a brief hover delay and automatically reposition near screen edges.
    • Added support for styled tooltip overlays, including Unicode and emoji text.
    • Exposed tooltip functionality through the core and UI packages.
  • Tests
    • Added coverage for tooltip visibility, positioning, closing, and text rendering.

@github-actions github-actions Bot added area:widgets @termuijs/widgets area:core @termuijs/core area:ui @termuijs/ui type:testing +10 pts. Tests. labels Jul 24, 2026
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds tooltip metadata to widgets, manages hover and focus tooltip state in App, exposes tooltip APIs, and renders tooltips through a new UI overlay with bounds-aware positioning and tests.

Changes

Tooltip system

Layer / File(s) Summary
Tooltip contracts and state
packages/widgets/src/base/Widget.ts, packages/core/src/app/TooltipManager.ts, packages/core/src/index.ts
Widgets accept an optional tooltip string, while TooltipManager exposes nullable state, change events, and open/close methods through the core API.
Hover and focus activation
packages/core/src/app/App.ts
App resolves tooltip text from widgets or ancestors, delays hover activation by 500 ms, positions focus tooltips from widget rectangles, and clears tooltips on transitions or blur.
Overlay rendering and validation
packages/ui/src/TooltipOverlay.ts, packages/ui/src/TooltipOverlay.test.ts, packages/ui/src/index.ts
Adds a tooltip overlay with width calculation, screen-bound clamping, styled background rendering, public exports, and tests for visibility, overflow, Unicode width, and closing.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant App
  participant TooltipManager
  participant TooltipOverlay
  participant Text
  App->>TooltipManager: open resolved tooltip text and position
  TooltipManager-->>TooltipOverlay: emit tooltip state change
  TooltipOverlay->>Text: create or update tooltip text
  TooltipOverlay-->>Text: render clamped rectangle
  App->>TooltipManager: close tooltip on widget change or blur
  TooltipManager-->>TooltipOverlay: emit null state
Loading

Possibly related PRs

Suggested labels: type:feature, level:intermediate

Suggested reviewers: karanjot786

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and clearly points to the tooltip system changes.
Description check ✅ Passed The description covers the feature, linked issue, affected packages, change type, and checklist items.
Linked Issues check ✅ Passed The changes implement the requested tooltip system for hover and focus, including the Widget tooltip field and App/overlay behavior for #2861.
Out of Scope Changes check ✅ Passed The diff stays focused on the tooltip feature, tests, and public re-exports, with no unrelated changes apparent.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (1)
packages/ui/src/TooltipOverlay.ts (1)

34-38: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Avoid any on fallback colors.

this.style.fg/bg are typed as Color | undefined, so this can assign string to Text/styleToCellAttrs. Use the shared Color fallback type (for example { type: 'named', name: 'black' } / { type: 'named', name: 'yellow' }) or normalize the fallback to Color consistently.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/TooltipOverlay.ts` around lines 34 - 38, Update the Text
construction in TooltipOverlay’s _textWidget initialization to remove the any
casts and ensure both fg and bg fallbacks are valid Color values. Use the shared
named-color fallback representation consistently while preserving the existing
black and yellow defaults.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core/src/app/App.ts`:
- Around line 711-728: The focused-widget tooltip logic in the event handler
currently runs before _widgetById is available and is lost during pending-state
replay. Update the changed === null replay path to resolve the focused widget
from _widgetById, walk its parent chain for tooltip text, and open the tooltip
using the widget rectangle once the map is built, while preserving the existing
focus styling behavior.
- Around line 311-313: Update the hover timer handling in App so a pending
tooltip hover cannot overwrite a tooltip opened by focus: clear
_tooltipHoverTimer before focus-triggered opens, clear it during teardown, and
set the handle to null inside the timer callback before opening. Apply the same
behavior to the related logic around the additional referenced section,
preserving existing tooltip behavior otherwise.

In `@packages/ui/src/TooltipOverlay.ts`:
- Around line 63-66: Update the text-widget cleanup block in TooltipOverlay to
call removeChild(this._textWidget) instead of filtering _children directly, then
clear _textWidget as before so Text.destroy() and parent cleanup run through the
lifecycle API.
- Around line 22-28: Store the unsubscribe callback returned by the tooltip
manager’s events.on listener in TooltipOverlay, then invoke it during unmount()
or destroy() before the overlay is disposed. Ensure teardown removes the
listener so later tooltip events cannot call _open or _close on the destroyed
overlay.
- Around line 52-56: Update the tooltip positioning and sizing logic in
TooltipOverlay so widths exceeding screenW never produce a negative _tooltipX or
an off-screen rectangle: clamp the horizontal position to a non-negative value,
constrain the rendered width to the available screen width, and truncate or wrap
the tooltip content accordingly. Add coverage for text wider than the terminal,
preserving normal positioning for content that fits.

---

Nitpick comments:
In `@packages/ui/src/TooltipOverlay.ts`:
- Around line 34-38: Update the Text construction in TooltipOverlay’s
_textWidget initialization to remove the any casts and ensure both fg and bg
fallbacks are valid Color values. Use the shared named-color fallback
representation consistently while preserving the existing black and yellow
defaults.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e39c5df2-e446-470e-9857-b7ef0e114023

📥 Commits

Reviewing files that changed from the base of the PR and between 61eaa4e and 8b8c369.

📒 Files selected for processing (7)
  • packages/core/src/app/App.ts
  • packages/core/src/app/TooltipManager.ts
  • packages/core/src/index.ts
  • packages/ui/src/TooltipOverlay.test.ts
  • packages/ui/src/TooltipOverlay.ts
  • packages/ui/src/index.ts
  • packages/widgets/src/base/Widget.ts

Comment thread packages/core/src/app/App.ts
Comment thread packages/core/src/app/App.ts
Comment thread packages/ui/src/TooltipOverlay.ts
Comment thread packages/ui/src/TooltipOverlay.ts
Comment thread packages/ui/src/TooltipOverlay.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:core @termuijs/core area:ui @termuijs/ui area:widgets @termuijs/widgets type:testing +10 pts. Tests.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feature] Tooltip System for Hover and Focus

1 participant