Tooltip

Square hover and focus hint in the default button surface, with an optional arrow.

Usage

svelte
<script lang="ts">
  import { Pin } from "@lucide/svelte";
  import { Tooltip } from "@milandekruijf/ui/svelte";
</script>

<Tooltip text="Pin navigation" side="bottom">
  {#snippet trigger(tooltipProps)}
    <button {...tooltipProps} type="button" aria-label="Pin navigation">
      <Pin />
    </button>
  {/snippet}
</Tooltip>

Examples

Icon buttons with hints
<script lang="ts">
  import { css } from "@milandekruijf/pandacss/css";
  import { Pin, Settings, Sun } from "@lucide/svelte";
  import { Tooltip } from "@milandekruijf/ui/svelte";

  /** Mirrors the nav cluster: icon-only controls sharing one slate.3 bar. */
  const clusterClass = css({
    display: "flex",
    alignItems: "center",
    w: "fit-content",
    bg: "slate.3",
  });

  const buttonClass = css({
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    h: 12,
    px: 4,
    color: "slate.12",
    cursor: "pointer",
    transitionProperty: "color, background-color",
    transitionDuration: "0.2s",
    transitionTimingFunction: "ease-in-out",
    _hover: { bg: "slate.4" },
    _focusVisible: { outline: "none", bg: "slate.5" },
  });

  const iconClass = css({
    w: 4,
    h: 4,
    flexShrink: 0,
    strokeWidth: "0.15em",
  });
</script>

<!-- Spread the snippet argument onto the trigger; the hint portals itself. -->
<div class={clusterClass}>
  <Tooltip text="Pin navigation" side="bottom">
    {#snippet trigger(tooltipProps)}
      <button
        {...tooltipProps}
        type="button"
        class={buttonClass}
        aria-label="Pin navigation"
      >
        <Pin class={iconClass} aria-hidden="true" />
      </button>
    {/snippet}
  </Tooltip>
  <Tooltip text="Appearance" side="bottom">
    {#snippet trigger(tooltipProps)}
      <button
        {...tooltipProps}
        type="button"
        class={buttonClass}
        aria-label="Appearance"
      >
        <Sun class={iconClass} aria-hidden="true" />
      </button>
    {/snippet}
  </Tooltip>
  <Tooltip text="Settings" side="bottom">
    {#snippet trigger(tooltipProps)}
      <button
        {...tooltipProps}
        type="button"
        class={buttonClass}
        aria-label="Settings"
      >
        <Settings class={iconClass} aria-hidden="true" />
      </button>
    {/snippet}
  </Tooltip>
</div>

Props

PropTypeDefaultDescription
textstring—
Hint text; keep it short enough to read at a glance.
triggerSnippet<[Record<string, unknown>]>—
The interactive element; spread the snippet argument onto it so hover, focus, and ARIA wire up.
side?"top" | "right" | "bottom" | "left""top"
Preferred side of the trigger; the bubble flips when there is no room.
sideOffset?number4
Gap in pixels between the trigger and the bubble.
delayDuration?number300
Milliseconds the pointer must rest on the trigger before the hint opens.
disabled?booleanfalse
Keeps the hint from opening (e.g. while the control is busy).
arrow?booleantrue
Points an arrow at the trigger, filled like the bubble.
class?string—
Extra classes merged on the bubble.

Square, borderless surface in the default `Button` colors (`slate.3` behind `slate.11`). It renders no wrapper: the element you spread the snippet props onto is the trigger, and the hint portals above dialogs and menus.