Tooltip

Labels icon buttons and dense controls. One tooltip is shared across the page, so moving between triggers moves the open tooltip instead of opening a new one.

<script lang="ts">
    import Frame from '@lucide/svelte/icons/frame';
    import MessageCircle from '@lucide/svelte/icons/message-circle';
    import MousePointer2 from '@lucide/svelte/icons/mouse-pointer-2';
    import PenTool from '@lucide/svelte/icons/pen-tool';
    import Square from '@lucide/svelte/icons/square';
    import Type from '@lucide/svelte/icons/type';
    import Shortcut from '@sivir-ui/svelte/components/shortcut';
    import * as Tooltip from '@sivir-ui/svelte/components/tooltip';

    let activeTool = $state<string>('move');

    const tools = [
        { id: 'move', label: 'Move', shortcut: 'V', icon: MousePointer2 },
        { id: 'frame', label: 'Frame', shortcut: 'F', icon: Frame },
        { id: 'rectangle', label: 'Rectangle', shortcut: 'R', icon: Square },
        { id: 'pen', label: 'Pen', shortcut: 'P', icon: PenTool },
        { id: 'text', label: 'Text', shortcut: 'T', icon: Type },
        { id: 'comment', label: 'Comment', shortcut: 'C', icon: MessageCircle }
    ];
</script>

<div class="flex items-center justify-center p-10">
    <div class="flex gap-1 rounded-[var(--radius-lg)] border border-border bg-card p-1">
        {#each tools as tool (tool.id)}
            {@const Icon = tool.icon}
            <Tooltip.Root delay={300}>
                <Tooltip.Trigger>
                    <button
                        type="button"
                        class="inline-flex size-8 items-center justify-center rounded-[var(--radius-md)] transition-colors"
                        class:bg-secondary={activeTool === tool.id}
                        class:text-foreground={activeTool === tool.id}
                        class:text-foreground-muted={activeTool !== tool.id}
                        class:hover:bg-secondary={activeTool !== tool.id}
                        class:hover:text-foreground={activeTool !== tool.id}
                        onclick={() => {
                            activeTool = tool.id;
                        }}
                        aria-label={tool.label}
                    >
                        <Icon size={16} />
                    </button>
                </Tooltip.Trigger>
                <Tooltip.Content>
                    <div class="flex items-center gap-2">
                        <span>{tool.label}</span>
                        <Shortcut shortcut={tool.shortcut} />
                    </div>
                </Tooltip.Content>
            </Tooltip.Root>
        {/each}
    </div>
</div>

Installation

Copy the command below and run it in your terminal.

bunx @sivir-ui/svelte add tooltip

Usage

Wrap a focusable element in Tooltip.Trigger so keyboard users can open it too. Set placement to top (the default), right, bottom, or left. It opens after 125 ms; change this with delay.

import { Button } from '@sivir-ui/svelte/components/button';
import * as Tooltip from '@sivir-ui/svelte/components/tooltip';

<Tooltip.Root>
  <Tooltip.Trigger>
    <Button variant="outline">Share</Button>
  </Tooltip.Trigger>
  <Tooltip.Content>Copy a link to this page</Tooltip.Content>
</Tooltip.Root>

Content renders as plain text. Put a Shortcut after the label to show it as a keycap, as in the toolbar above.

Examples

Top placement

<script lang="ts">
    import Info from '@lucide/svelte/icons/info';
    import * as Tooltip from '@sivir-ui/svelte/components/tooltip';
</script>

<Tooltip.Root placement="top">
    <Tooltip.Trigger>
        <button
            type="button"
            class="inline-flex size-8 items-center justify-center rounded-[var(--radius-md)] text-foreground-muted transition-colors hover:bg-secondary hover:text-foreground"
            aria-label="More info"
        >
            <Info size={16} />
        </button>
    </Tooltip.Trigger>
    <Tooltip.Content>Required for team accounts</Tooltip.Content>
</Tooltip.Root>

Bottom placement

<script lang="ts">
    import HelpCircle from '@lucide/svelte/icons/help-circle';
    import * as Tooltip from '@sivir-ui/svelte/components/tooltip';
</script>

<Tooltip.Root placement="bottom">
    <Tooltip.Trigger>
        <button
            type="button"
            class="inline-flex size-8 items-center justify-center rounded-[var(--radius-md)] text-foreground-muted transition-colors hover:bg-secondary hover:text-foreground"
            aria-label="Help"
        >
            <HelpCircle size={16} />
        </button>
    </Tooltip.Trigger>
    <Tooltip.Content>Learn more about this setting</Tooltip.Content>
</Tooltip.Root>

Anatomy

Tooltip.Root - Sets placement and open and close delays.

Tooltip.Trigger - Opens the tooltip on hover or focus.

Tooltip.Content - Supplies the tooltip text.