docs: add tooltip hover implementation plan
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,228 @@
|
||||
# Tooltip Hover Implementation Plan
|
||||
|
||||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Add pixel-art styled hover tooltips to all abbreviated tab labels and stat abbreviations in the game UI.
|
||||
|
||||
**Architecture:** Create a shared tooltip utility function that creates/positions/removes tooltip divs on mouseenter/mouseleave. Both LeftPanel and NpcInfoPanel import and use it. Tooltip placement varies by context (left, right, or above).
|
||||
|
||||
**Tech Stack:** TypeScript, DOM API (no libraries)
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Create Tooltip Utility
|
||||
|
||||
**Files:**
|
||||
- Create: `client/src/ui/tooltip.ts`
|
||||
|
||||
**Step 1: Create the tooltip utility module**
|
||||
|
||||
```typescript
|
||||
// Tooltip positioning options
|
||||
type TooltipPosition = 'left' | 'right' | 'above';
|
||||
|
||||
const TOOLTIP_STYLE = `
|
||||
position: absolute;
|
||||
background: #1a1a2e;
|
||||
border: 2px solid #7878d8;
|
||||
color: #e0d0b0;
|
||||
font-family: 'Press Start 2P', monospace;
|
||||
font-size: 10px;
|
||||
padding: 4px 8px;
|
||||
white-space: nowrap;
|
||||
pointer-events: none;
|
||||
z-index: 10000;
|
||||
`;
|
||||
|
||||
/**
|
||||
* Attach a hover tooltip to an element.
|
||||
* Returns a cleanup function to remove the listeners.
|
||||
*/
|
||||
export function attachTooltip(
|
||||
element: HTMLElement,
|
||||
text: string,
|
||||
position: TooltipPosition = 'right',
|
||||
): () => void {
|
||||
let tooltip: HTMLDivElement | null = null;
|
||||
|
||||
const show = () => {
|
||||
tooltip = document.createElement('div');
|
||||
tooltip.style.cssText = TOOLTIP_STYLE;
|
||||
tooltip.textContent = text;
|
||||
document.body.appendChild(tooltip);
|
||||
|
||||
const rect = element.getBoundingClientRect();
|
||||
const tipRect = tooltip.getBoundingClientRect();
|
||||
|
||||
switch (position) {
|
||||
case 'right':
|
||||
tooltip.style.left = `${rect.right + 6}px`;
|
||||
tooltip.style.top = `${rect.top + (rect.height - tipRect.height) / 2}px`;
|
||||
break;
|
||||
case 'left':
|
||||
tooltip.style.left = `${rect.left - tipRect.width - 6}px`;
|
||||
tooltip.style.top = `${rect.top + (rect.height - tipRect.height) / 2}px`;
|
||||
break;
|
||||
case 'above':
|
||||
tooltip.style.left = `${rect.left + (rect.width - tipRect.width) / 2}px`;
|
||||
tooltip.style.top = `${rect.top - tipRect.height - 6}px`;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const hide = () => {
|
||||
if (tooltip) {
|
||||
tooltip.remove();
|
||||
tooltip = null;
|
||||
}
|
||||
};
|
||||
|
||||
element.addEventListener('mouseenter', show);
|
||||
element.addEventListener('mouseleave', hide);
|
||||
|
||||
return () => {
|
||||
element.removeEventListener('mouseenter', show);
|
||||
element.removeEventListener('mouseleave', hide);
|
||||
hide();
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Verify it compiles**
|
||||
|
||||
Run: `npx -w client tsc --noEmit`
|
||||
Expected: No errors
|
||||
|
||||
**Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add client/src/ui/tooltip.ts
|
||||
git commit -m "feat: add tooltip utility for hover labels"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2: Add Tooltips to Left Panel Tabs
|
||||
|
||||
**Files:**
|
||||
- Modify: `client/src/ui/LeftPanel.ts`
|
||||
|
||||
**Step 1: Import tooltip utility and attach tooltips to tabs**
|
||||
|
||||
At the top of `LeftPanel.ts`, add:
|
||||
```typescript
|
||||
import { attachTooltip } from './tooltip.js';
|
||||
```
|
||||
|
||||
After all tabs are created and appended to `tabContainer` (after line ~170), add:
|
||||
```typescript
|
||||
attachTooltip(this.statsTab, 'Superlatives', 'right');
|
||||
attachTooltip(this.eventsTab, 'Event Log', 'right');
|
||||
attachTooltip(this.inventionsTab, 'Inventions', 'right');
|
||||
attachTooltip(this.resourcesTab, 'Resources', 'right');
|
||||
```
|
||||
|
||||
**Step 2: Verify it compiles**
|
||||
|
||||
Run: `npx -w client tsc --noEmit`
|
||||
Expected: No errors
|
||||
|
||||
**Step 3: Manual verification**
|
||||
|
||||
Run: `npm -w client run dev`
|
||||
Hover over each left panel tab (S, E, I, R) and verify tooltips appear to the right with correct labels.
|
||||
|
||||
**Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add client/src/ui/LeftPanel.ts
|
||||
git commit -m "feat: add hover tooltips to left panel tabs"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 3: Add Tooltips to NPC Info Panel Tabs
|
||||
|
||||
**Files:**
|
||||
- Modify: `client/src/ui/NpcInfoPanel.ts`
|
||||
|
||||
**Step 1: Import tooltip utility and attach tooltips to tabs**
|
||||
|
||||
At the top of `NpcInfoPanel.ts`, add:
|
||||
```typescript
|
||||
import { attachTooltip } from './tooltip.js';
|
||||
```
|
||||
|
||||
After the tabs are created (after line ~96, before `tabColumn.appendChild`), add:
|
||||
```typescript
|
||||
attachTooltip(this.statusTab, 'Status', 'left');
|
||||
attachTooltip(this.relationshipsTab, 'Relationships', 'left');
|
||||
attachTooltip(this.historyTab, 'History', 'left');
|
||||
attachTooltip(this.inventoryTab, 'Inventory', 'left');
|
||||
```
|
||||
|
||||
**Step 2: Verify it compiles**
|
||||
|
||||
Run: `npx -w client tsc --noEmit`
|
||||
Expected: No errors
|
||||
|
||||
**Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add client/src/ui/NpcInfoPanel.ts
|
||||
git commit -m "feat: add hover tooltips to NPC info panel tabs"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 4: Add Tooltips to Stat Abbreviations
|
||||
|
||||
**Files:**
|
||||
- Modify: `client/src/ui/NpcInfoPanel.ts`
|
||||
|
||||
**Step 1: Add stat tooltip mapping and attach tooltips in setStatDisplay**
|
||||
|
||||
Add a constant at the top of the file (after the `EB` object):
|
||||
```typescript
|
||||
const STAT_FULL_NAMES: Record<string, string> = {
|
||||
STR: 'Strength', DEX: 'Dexterity', CON: 'Constitution', INT: 'Intelligence', PER: 'Perception',
|
||||
SOC: 'Sociability', COU: 'Courage', CUR: 'Curiosity', EMP: 'Empathy', TMP: 'Temperament',
|
||||
};
|
||||
```
|
||||
|
||||
In the `setStatDisplay` method, after the stat element is created (inside the `if (!el)` block, after `this.statElements.set(label, el);`), add:
|
||||
```typescript
|
||||
if (STAT_FULL_NAMES[label]) {
|
||||
attachTooltip(el, STAT_FULL_NAMES[label], 'above');
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Verify it compiles**
|
||||
|
||||
Run: `npx -w client tsc --noEmit`
|
||||
Expected: No errors
|
||||
|
||||
**Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add client/src/ui/NpcInfoPanel.ts
|
||||
git commit -m "feat: add hover tooltips to stat abbreviations"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 5: Visual QA
|
||||
|
||||
**Step 1: Start the client and server**
|
||||
|
||||
Run: `npm -w server run dev` and `npm -w client run dev`
|
||||
|
||||
**Step 2: Verify all tooltips**
|
||||
|
||||
- Hover over each left panel tab (S, E, I, R) — tooltips appear to the right
|
||||
- Follow an NPC, hover over each right panel tab (S, R, H, I) — tooltips appear to the left
|
||||
- Hover over each stat abbreviation (STR, DEX, etc.) — tooltips appear above
|
||||
- Verify tooltips disappear when mouse leaves
|
||||
- Verify tooltip styling matches the game aesthetic (pixel font, dark background, purple border)
|
||||
|
||||
**Step 3: Final commit if any fixes needed**
|
||||
Reference in New Issue
Block a user