tooltip

A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.

PreviousNext
import { ChangeDetectionStrategy, Component } from '@angular/core';

import { ZardButtonComponent } from '@/shared/components/button';
import { ZardTooltipImports } from '@/shared/components/tooltip/tooltip.imports';

@Component({
  selector: 'z-demo-tooltip-preview',
  imports: [ZardButtonComponent, ZardTooltipImports],
  template: `
    <button type="button" z-button zType="outline" zTooltip="Tooltip content">Hover</button>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoTooltipPreviewComponent {}

Installation

Copy
npx zard-cli@latest add tooltip

Usage

import { ZardTooltipImports } from '@/shared/components/tooltip/tooltip.imports';
Copy
<button z-button zType="outline" zTooltip="Add to library">Hover</button>
Copy

Examples

side

Set zPosition (shadcn calls this input side) to top, bottom, left or right to choose which side of the trigger the tooltip opens on.
import { ChangeDetectionStrategy, Component } from '@angular/core';

import { ZardButtonComponent } from '@/shared/components/button';
import { ZardTooltipImports } from '@/shared/components/tooltip/tooltip.imports';

@Component({
  selector: 'z-demo-tooltip-side',
  imports: [ZardButtonComponent, ZardTooltipImports],
  template: `
    <div class="flex flex-col space-y-2">
      <button type="button" z-button zType="outline" zTooltip="Tooltip content" zPosition="top">Top</button>

      <div class="flex space-x-2">
        <button type="button" z-button zType="outline" zTooltip="Tooltip content" zPosition="left">Left</button>
        <button type="button" z-button zType="outline" zTooltip="Tooltip content" zPosition="right">Right</button>
      </div>

      <button type="button" z-button zType="outline" zTooltip="Tooltip content" zPosition="bottom">Bottom</button>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoTooltipSideComponent {}

with keyboard shortcut

Compose a z-kbd inside the zTooltip template to show the shortcut for the action it labels.
import { ChangeDetectionStrategy, Component } from '@angular/core';

import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideSave } from '@ng-icons/lucide';

import { ZardButtonComponent } from '@/shared/components/button';
import { ZardKbdComponent } from '@/shared/components/kbd';
import { ZardTooltipDirective } from '@/shared/components/tooltip/tooltip';

@Component({
  selector: 'z-demo-tooltip-with-kbd',
  imports: [NgIcon, ZardButtonComponent, ZardTooltipDirective, ZardKbdComponent],
  template: `
    <button type="button" z-button [zTooltip]="shortcutTip" zType="outline" zSize="icon-sm">
      <ng-icon name="lucideSave" />
    </button>

    <ng-template #shortcutTip>
      Save changes
      <z-kbd>S</z-kbd>
    </ng-template>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
  viewProviders: [provideIcons({ lucideSave })],
})
export class ZardDemoTooltipWithKbdComponent {}

disabled button

A disabled <button> fires no pointer events, so [zTooltip] placed on it never triggers. Wrap the button in a focusable <span tabindex="0"> and put [zTooltip] on the wrapper instead.
import { ChangeDetectionStrategy, Component } from '@angular/core';

import { ZardButtonComponent } from '@/shared/components/button';
import { ZardTooltipImports } from '@/shared/components/tooltip/tooltip.imports';

@Component({
  selector: 'z-demo-tooltip-disabled-button',
  imports: [ZardButtonComponent, ZardTooltipImports],
  template: `
    <span zTooltip="This feature is currently unavailable" class="block" tabindex="0">
      <button type="button" z-button zType="outline" [zDisabled]="true">Disabled</button>
    </span>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoTooltipDisabledButtonComponent {}

click

Set zTrigger="click" to open the tooltip on click instead of hover. Keep click-triggered tooltips to a single short label; for a click-opened panel of interactive content, reach for [zPopover] instead.
import { ChangeDetectionStrategy, Component } from '@angular/core';

import { ZardButtonComponent } from '@/shared/components/button';
import { ZardTooltipImports } from '@/shared/components/tooltip/tooltip.imports';

@Component({
  selector: 'z-demo-tooltip-click',
  imports: [ZardButtonComponent, ZardTooltipImports],
  template: `
    <button type="button" z-button zType="outline" zTooltip="Tooltip content" zTrigger="click">Click</button>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoTooltipClickComponent {}

on show hide

Listen to (zShow) and (zHide) to react to the tooltip opening and closing, for example to sync external state.
Event: none
import { ChangeDetectionStrategy, Component } from '@angular/core';

import { ZardButtonComponent } from '@/shared/components/button';
import { ZardTooltipImports } from '@/shared/components/tooltip/tooltip.imports';

@Component({
  selector: 'z-demo-tooltip-on-show-hide',
  imports: [ZardButtonComponent, ZardTooltipImports],
  template: `
    <div class="flex w-25 flex-col gap-4">
      <button type="button" z-button zType="outline" zTooltip="Tooltip content" (zShow)="onShow()" (zHide)="onHide()">
        Events
      </button>

      <span class="text-sm">Event: {{ event }}</span>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoTooltipOnShowHideComponent {
  protected event = 'none';

  protected onShow() {
    this.event = '(zShow)';
  }

  protected onHide() {
    this.event = '(zHide)';
  }
}

rtl

To enable RTL support in zard/ui, see the RTL configuration guide.
// You will notice this example is rendered inside a wrapper that sets the dir and data-lang attributes, and
// reads its text from a translations helper. This is because this site is not RTL by default.
// In your application you won't need either: set dir="rtl" on <html> (or use the CDK Dir directive on a subtree)
// and write the text of your own language. See the RTL guide: https://zardui.com/docs/rtl

import { ChangeDetectionStrategy, Component } from '@angular/core';

import { ZardButtonComponent } from '@/shared/components/button';
import type { ZardTooltipSide } from '@/shared/components/tooltip/tooltip-positions';
import { ZardTooltipImports } from '@/shared/components/tooltip/tooltip.imports';
import { injectRtlTranslation, type ZardRtlTranslations } from '@/shared/demo-utils/rtl-translation';

interface TooltipRtlValues {
  content: string;
  'inline-start': string;
  left: string;
  top: string;
  bottom: string;
  right: string;
  'inline-end': string;
}

const translations: ZardRtlTranslations<TooltipRtlValues> = {
  en: {
    dir: 'ltr',
    values: {
      content: 'Add to library',
      'inline-start': 'Inline Start',
      left: 'Left',
      top: 'Top',
      bottom: 'Bottom',
      right: 'Right',
      'inline-end': 'Inline End',
    },
  },
  ar: {
    dir: 'rtl',
    values: {
      content: 'إضافة إلى المكتبة',
      'inline-start': 'بداية السطر',
      left: 'يسار',
      top: 'أعلى',
      bottom: 'أسفل',
      right: 'يمين',
      'inline-end': 'نهاية السطر',
    },
  },
  he: {
    dir: 'rtl',
    values: {
      content: 'הוסף לספרייה',
      'inline-start': 'תחילת השורה',
      left: 'שמאל',
      top: 'למעלה',
      bottom: 'למטה',
      right: 'ימין',
      'inline-end': 'סוף השורה',
    },
  },
};

@Component({
  selector: 'z-demo-tooltip-rtl',
  imports: [ZardButtonComponent, ZardTooltipImports],
  template: `
    <div class="grid gap-4">
      <div class="flex flex-wrap justify-center gap-2">
        @for (side of physicalSides; track side) {
          <button type="button" z-button zType="outline" [zTooltip]="i18n.t().content" [zPosition]="side">
            {{ i18n.t()[side] }}
          </button>
        }
      </div>
      <div class="flex flex-wrap justify-center gap-2">
        @for (side of logicalSides; track side) {
          <button type="button" z-button zType="outline" [zTooltip]="i18n.t().content" [zPosition]="side">
            {{ i18n.t()[side] }}
          </button>
        }
      </div>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ZardDemoTooltipRtlComponent {
  protected readonly i18n = injectRtlTranslation(translations);

  protected readonly physicalSides: ZardTooltipSide[] = ['left', 'top', 'bottom', 'right'];
  protected readonly logicalSides: ZardTooltipSide[] = ['inline-start', 'inline-end'];
}

API Reference

[zTooltip]Component

The directive that shows a tooltip popup when its host is hovered, focused, or clicked.

PropertyDescriptionTypeDefault
[zTooltip] The tooltip content: a string, or a template for richer content such as a `z-kbd` string | TemplateRef<void> -
[zPosition] Side of the trigger the tooltip opens on (shadcn calls this input `side`). `left` and `right` are physical sides; `inline-start` and `inline-end` follow the direction of the trigger, so they flip in RTL. 'top' | 'bottom' | 'left' | 'right' | 'inline-start' | 'inline-end' 'top'
[zPositionOffset] Distance in pixels between the tooltip and the trigger number 4
[zTrigger] How the tooltip is triggered 'hover' | 'click' 'hover'
[zShowDelay] Delay in milliseconds before showing the tooltip number 150
[zHideDelay] Delay in milliseconds before hiding the tooltip number 100
(zShow) Emits when the tooltip is shown EventEmitter<void> -
(zHide) Emits when the tooltip is hidden EventEmitter<void> -

z-tooltipComponent

The tooltip content. Mounted automatically by `[zTooltip]` — never placed directly in a template. Exposes `role="tooltip"`, `data-side` and `data-state` while mounted.

github iconwhatsapp icondiscord iconX icon

Made with ❤ in Brazil. Open source and available on GitHub .