Skip to content

Shared component: packages/components/src/ui/Tooltip.astro

  • CSS-only display, 4 positions (top/bottom/left/right), keyboard-accessible (tabindex + focus)
  • text prop accepts plain text or HTML — rendered via set:html
  • Smart viewport-aware positioning: JS measures getBoundingClientRect() on the visibility:hidden bubble before showing, tries positions in order (preferred → opposite → all 4), picks the first that fits within viewport bounds (6px gap)
  • Brand-themed via CSS variables (--foreground/--background); works in dark/light mode
  • Showcase: sites/template/src/components/showcase/TooltipShowcase.astro

MBR Focus page integration:

  • load-focus-content.ts: loadFASTTooltipHtml() reads Misc/Glossary.md at build time, extracts the F.A.S.T. section, converts **bold**<b>bold</b>, injects HTML into tooltip. Falls back to hardcoded HTML when Glossary unavailable.
  • injectFASTTooltip() wraps every F.A.S.T. occurrence in all content strings (mission body + plan intro) with .ft / .ft-tip tooltip HTML.
  • focus.astro: Added .ft / .ft-tip / .ft-bot CSS + inline JS positionTooltip() (vertical flip: top → bottom when trigger near viewport top).
FileChange
packages/components/src/ui/Tooltip.astroNew component
sites/template/src/components/showcase/TooltipShowcase.astroNew showcase
sites/template/src/pages/components.astroImport + register TooltipShowcase
sites/mbr/src/utils/load-focus-content.tsGlossary reader, HTML injection pipeline
sites/mbr/src/pages/focus.astroTooltip CSS + smart positioning JS
  • visibility:hidden is measurablegetBoundingClientRect() returns correct rect even when hidden. No need to temporarily show the bubble to measure it; just change the position class and call getBoundingClientRect() on the bubble directly.
  • Focus page can’t use Astro components inlineset:html rendered content is raw HTML strings; Astro components can’t be injected there. Workaround: inject HTML with matching CSS class names from the TypeScript build pipeline.
  • set:html bypasses Astro auto-escaping — document the text prop as accepting HTML; only safe because content is build-time KB-sourced, not user input.