Skip to main content
Urbicon UI
Back to Recipes

Help Tooltip

Glossary trigger for domain terms — small info icon next to a label, tooltip with the definition. Pattern for domain apps with specialist vocabulary (heating-cost billing, tax, payroll, insurance). Combines Tooltip + Button (ghost, 2xs) + InfoCircleIcon.

Live Preview

Recommended: ≥ 60 °C

System efficiency is reported via the Jahresarbeitszahl Seasonal performance factor — the ratio of heat energy produced to electrical energy consumed. A JAZ of 3.5 means 1 kWh of electricity yields 3.5 kWh of heat. Averaged over the whole year. — values of 3.0 or higher are considered energy-efficient.

Table header

ApartmentWMZ reading Heat meter — measures the heat energy delivered, in kWh. Mandatory in multi-unit buildings for heating and hot water, so consumption can be billed to each apartment by actual use. Consumption
Unit 112,420 kWh8,150 kWh
Unit 29,880 kWh6,230 kWh

Features

  • Consistent trigger across value types — form labels, table headers, inline text
  • Tooltip with Floating-UI positioning (placement="top", auto-flip)
  • Glossary map as the single source of truth (i18n-ready, centrally maintained)
  • A11y: aria-label on the trigger ("Explanation: HeizKV § 7"), tooltip also reachable via focus
  • Keyboard: Tab focuses, tooltip appears, Escape closes

Code

HelpTooltip.svelte (Wrapper)

<script lang="ts">
  import { Tooltip, Button, InfoCircleIcon } from '@urbicon-ui/blocks';

  interface Props {
    /** Definition text shown in the tooltip. */
    text: string;
    /** Aria-label term — what is being explained here? */
    term: string;
    /** Optional: warning, danger for legally or safety-relevant hints. */
    intent?: 'neutral' | 'warning' | 'danger';
  }

  const { text, term, intent = 'neutral' }: Props = $props();
</script>

<Tooltip label={text} placement="top" {intent} size="md">
  <Button
    size="2xs"
    variant="ghost"
    intent="neutral"
    aria-label="Explanation: {term}"
  >
    <InfoCircleIcon class="h-3.5 w-3.5" />
  </Button>
</Tooltip>

lib/glossary.ts (central map)

export const glossary = {
  'heizkv-7': {
    term: 'HeizKV § 7',
    text: 'The German Heating Costs Ordinance requires that at least 50% and at most 70% of heating costs are billed by consumption.'
  },
  jaz: {
    term: 'Jahresarbeitszahl (JAZ)',
    text: 'Seasonal performance factor — the ratio of heat energy produced to electrical energy consumed.'
  },
  wmz: {
    term: 'Wärmemengenzähler (WMZ)',
    text: 'Heat meter — measures the heat energy delivered, in kWh.'
  }
} as const;

export type GlossaryKey = keyof typeof glossary;

Usage in a form label

<label class="flex items-center gap-1 text-sm font-medium">
  Consumption share
  <HelpTooltip
    term={glossary['heizkv-7'].term}
    text={glossary['heizkv-7'].text}
  />
</label>

Best Practices

Keep the glossary central

A glossary.ts map with term + text as the single source of truth. With i18n: one map per locale. That keeps the wording consistent across form labels, tables, and tooltips.

Don't forget the aria-label

The trigger is an icon-only button — screen readers need the term in the aria-label ("Explanation: HeizKV § 7"). Otherwise the user only hears "button" with no context.

Intent for risk hints

For legally or safety-relevant explanations (intent="warning" for mandatory values, intent="danger" for consequences). Default neutral for purely informational tips.

Inline variant for running text

Instead of a separate icon button, the term itself can act as the tooltip trigger: a subtle border-bottom dotted signals "hover for more". Saves space, avoids icon sprawl in running text.

Don't misuse it for mandatory documentation

Tooltips are not suited to compliance texts or legal notices — those must be permanently visible. HelpTooltip is only for supporting explanations the user could also do without.