UI Tooltip System
The unified tooltip system provides consistent styling and behavior across all UI panels in Hyperscape. Centralized style utilities ensure visual consistency for inventory, equipment, bank, spells, prayer, skills, trade, store, and loot panels.Overview
Previously, each panel implemented its own tooltip styling, leading to ~500 lines of duplicated code and inconsistent visual appearance. The new system provides a set of style utility functions that generate consistent ReactCSSProperties objects based on the current theme.
Key Features
- Centralized Styling: Single source of truth for tooltip appearance
- Theme-Aware: All styles adapt to current theme (Hyperscape, Dark, Light)
- Consistent Hierarchy: Clear visual distinction between titles, metadata, body text, and status indicators
- Tone Support: Status indicators support success/danger/warning tones
- Zero Duplication: Eliminates ~500 lines of duplicated styling code
API Reference
Module: packages/client/src/ui/core/tooltip/tooltipStyles.ts
getTooltipTitleStyle()
Generate title text styling for tooltip headers.
theme- Current theme objectaccentColor- Optional accent color (defaults totheme.colors.accent.secondary)
color: Accent color (default: theme.colors.accent.secondary)fontWeight: 700 (bold)fontSize: “13px”lineHeight: 1.2
getTooltipMetaStyle()
Generate metadata/secondary text styling.
theme- Current theme object
color: theme.colors.text.mutedfontSize: “11px”lineHeight: 1.3
- Item quantities (“x5”, “x100”)
- Level requirements (“Level 40 Attack”)
- Contextual hints (“Drag to reorder”)
getTooltipBodyStyle()
Generate body content styling for descriptions and details.
theme- Current theme object
color: theme.colors.text.secondaryfontSize: “11px”lineHeight: 1.45
- Item descriptions
- Spell effects
- Stat bonuses
- Detailed information
getTooltipDividerStyle()
Generate section divider styling with optional accent color.
theme- Current theme objectaccentColor- Optional accent color for divider (defaults totheme.colors.border.default)
borderTop:1px solid ${accentColor}33marginTop: “8px”paddingTop: “8px”
- Separating tooltip sections
- Visual hierarchy between content blocks
- Grouping related information
getTooltipTagStyle()
Generate tag/badge styling for labels and categories.
theme- Current theme object
display: “inline-flex”alignItems: “center”padding: “2px 6px”borderRadius: theme.borderRadius.smbackground:${theme.colors.background.tertiary}ccborder:1px solid ${theme.colors.border.default}33color: theme.colors.text.secondaryfontSize: “10px”lineHeight: 1.2
- Rune costs (“5x Air Rune”, “3x Fire Rune”)
- Item categories (“Weapon”, “Armor”, “Food”)
- Skill requirements
getTooltipStatusStyle()
Generate status indicator styling with tone-based coloring.
theme- Current theme objecttone- Status tone (default/success/danger/warning)
marginTop: “8px”padding: “5px 8px”borderRadius: theme.borderRadius.smbackground: Tone-specific background color with transparencyborder: Tone-specific border colorcolor: Tone-specific text colorfontSize: “10px”lineHeight: 1.3textAlign: “center”fontWeight: 600
success: Green (theme.colors.state.success)danger: Red (theme.colors.state.danger)warning: Yellow (theme.colors.state.warning)default: Accent (theme.colors.accent.secondary)
- Level requirements (“Requires level 60 Attack”)
- Active states (“Currently Active”)
- Warnings (“Not enough runes”)
- Success messages (“Quest Complete!”)
Usage Patterns
Basic Item Tooltip
Equipment Tooltip with Bonuses
Spell Tooltip with Rune Costs
Integration with CursorTooltip
The style utilities are designed to work with theCursorTooltip component:
Performance Considerations
Hover State Management
Each tooltip-enabled component manages its own hover state:onMouseMove fires at 60+ Hz, creating a new object on every event. For performance-critical components (e.g., bank slots with hundreds of items):
- Throttle position updates: Only update when position changes by >2px
- Lift state to parent: Parent manages hover state, children call
onHoverStart/onHoverMove/onHoverEnd - Use
React.memo: Wrap slot components to prevent unnecessary re-renders
Migration Guide
From Inline Styles
Before:From Custom Tooltip Components
Before:Panels Using Unified Tooltips
The following panels have been migrated to use the unified tooltip system:- ActionBarPanel - Action bar slots and rubbish bin
- ActionPanel - Draggable action slots
- BankPanel - Bank items, tabs, and equipment sidebar
- EquipmentPanel - Equipment slots and paperdoll
- InventoryPanel - Inventory slots and coin pouch
- LootWindowPanel - Loot items
- PrayerPanel - Prayer icons and descriptions
- SkillsPanel - Skill icons and XP progress
- SpellsPanel - Spell icons and rune costs
- StorePanel - Store items
- TradePanel - Trade slots and inventory items
Customization
Adding New Tone Colors
To add a new tone (e.g., “info”), updategetToneColors():
Extending Style Functions
To add new style utilities, follow the existing pattern:Best Practices
1. Use Semantic Style Functions
Choose the style function that matches the content’s semantic meaning:2. Avoid Redundant Spreads
When the style function is the only property source, use it directly:3. Combine Styles Appropriately
When combining with custom styles, spread the utility function first:4. Use Consistent Spacing
Follow the established spacing patterns:Troubleshooting
Tooltip styles not applying: Cause: Theme not passed correctly or style function not imported. Fix: Verify imports and theme access:See Also
packages/client/src/ui/core/tooltip/CursorTooltip.tsx- Tooltip componentpackages/client/src/ui/theme/themes.ts- Theme definitionspackages/client/src/game/panels/- Panel implementations using unified tooltips