> For AI agents: the complete documentation index is available at https://wallarm.github.io/design-system/llms.txt, the full documentation bundle is available at https://wallarm.github.io/design-system/llms-full.txt.

# OverflowTooltip

Shows the full value only when it is actually truncated, so a reader who can already see the text is not given a tooltip that repeats it. It finds the truncating element itself, so wrap the content rather than pointing it at a node.

[Source](https://github.com/wallarm/design-system/tree/main/packages/design-system/src/components/OverflowTooltip) · [Storybook](https://wallarm.github.io/design-system/storybook/?path=/docs/overlay-overflowtooltip--overview)

```tsx
import { OverflowTooltip, OverflowTooltipContent, OverflowTooltipTrigger } from '@wallarm-org/design-system/OverflowTooltip';

export const AutoDetection = () => {
  return (
    <div className='font-sans flex flex-col gap-16 w-300'>
      <div>
        <OverflowTooltip>
          <OverflowTooltipTrigger>
            <div className='truncate'>Short text</div>
          </OverflowTooltipTrigger>
          <OverflowTooltipContent>
            This won't show because text isn't overflowing
          </OverflowTooltipContent>
        </OverflowTooltip>
      </div>
      <div>
        <OverflowTooltip>
          <OverflowTooltipTrigger>
            <div className='truncate'>
              This is a very long text that will be truncated and automatically show a tooltip when
              hovered
            </div>
          </OverflowTooltipTrigger>
          <OverflowTooltipContent>
            This is a very long text that will be truncated and automatically show a tooltip when
            hovered
          </OverflowTooltipContent>
        </OverflowTooltip>
      </div>
    </div>
  );
};
```

## Usage

```tsx
import { OverflowTooltip, OverflowTooltipContent, OverflowTooltipTrigger } from '@wallarm-org/design-system/OverflowTooltip';
```

## Examples

### Multi line auto detection

The same with `line-clamp`, where truncation happens at the block rather than the line.

```tsx
import { OverflowTooltip, OverflowTooltipContent, OverflowTooltipTrigger } from '@wallarm-org/design-system/OverflowTooltip';

export const MultiLineAutoDetection = () => {
  const longText =
    'This is a very long text that demonstrates multi-line truncation. It keeps going and going to show how the component handles text that exceeds multiple lines. The tooltip will appear when you hover over the truncated content. And it continues even more to ensure we have enough content for demonstration purposes.';
  return (
    <div className='font-sans flex flex-col gap-16 w-300'>
      <div>
        <OverflowTooltip>
          <OverflowTooltipTrigger>
            <div className='line-clamp-2'>{longText}</div>
          </OverflowTooltipTrigger>
          <OverflowTooltipContent>{longText}</OverflowTooltipContent>
        </OverflowTooltip>
      </div>
      <div>
        <OverflowTooltip>
          <OverflowTooltipTrigger>
            <div className='line-clamp-3'>{longText}</div>
          </OverflowTooltipTrigger>
          <OverflowTooltipContent>{longText}</OverflowTooltipContent>
        </OverflowTooltip>
      </div>
      <div>
        <OverflowTooltip>
          <OverflowTooltipTrigger>
            <div className='line-clamp-4'>{longText}</div>
          </OverflowTooltipTrigger>
          <OverflowTooltipContent>{longText}</OverflowTooltipContent>
        </OverflowTooltip>
      </div>
    </div>
  );
};
```

### Nested elements

The truncating element is somewhere inside the children, which is the usual case — it is
found rather than declared.

```tsx
import { OverflowTooltip, OverflowTooltipContent, OverflowTooltipTrigger } from '@wallarm-org/design-system/OverflowTooltip';

export const NestedElements = () => {
  return (
    <div className='font-sans flex flex-col gap-16 w-300'>
      <div>
        <OverflowTooltip>
          <OverflowTooltipTrigger>
            <div className='border p-4'>
              <h3 className='font-bold mb-2'>Card Title</h3>
              <p className='truncate'>
                This is a nested element with truncate that will be automatically detected for
                overflow
              </p>
            </div>
          </OverflowTooltipTrigger>
          <OverflowTooltipContent>
            This is a nested element with truncate that will be automatically detected for overflow
          </OverflowTooltipContent>
        </OverflowTooltip>
      </div>
      <div>
        <OverflowTooltip>
          <OverflowTooltipTrigger>
            <div className='border p-4'>
              <h3 className='font-bold mb-2 truncate'>
                This is a very long title that might be truncated
              </h3>
              <p className='line-clamp-2'>
                And this is a description that can span multiple lines but will be clamped to just
                two lines. The component will detect if either of these elements overflow.
              </p>
            </div>
          </OverflowTooltipTrigger>
          <OverflowTooltipContent>
            <div>
              <strong>Title:</strong> This is a very long title that might be truncated
              <br />
              <strong>Description:</strong> And this is a description that can span multiple lines
              but will be clamped to just two lines. The component will detect if either of these
              elements overflow.
            </div>
          </OverflowTooltipContent>
        </OverflowTooltip>
      </div>
    </div>
  );
};
```

### Custom tooltip content

Overriding the content, for when the full value needs formatting the truncated one does not
have.

```tsx
import { OverflowTooltip, OverflowTooltipContent, OverflowTooltipTrigger } from '@wallarm-org/design-system/OverflowTooltip';

export const CustomTooltipContent = () => {
  return (
    <div className='font-sans flex flex-col gap-16 w-300'>
      <div>
        <OverflowTooltip>
          <OverflowTooltipTrigger>
            <div className='truncate'>
              /api/v1/users/1234567890/sessions/abc-def-ghi-jkl-mno/tokens/refresh
            </div>
          </OverflowTooltipTrigger>
          <OverflowTooltipContent>
            <div className='flex flex-col gap-2'>
              <div className='font-medium text-sm'>API Endpoint</div>
              <code className='rounded-6 bg-component-kbi-tooltip-bg px-4 py-2 font-mono text-text-primary-alt text-xs'>
                /api/v1/users/1234567890/sessions/abc-def-ghi-jkl-mno/tokens/refresh
              </code>
              <div className='text-xs text-text-secondary-alt'>
                Method: POST
                <br />
                Auth: Bearer Token
              </div>
            </div>
          </OverflowTooltipContent>
        </OverflowTooltip>
      </div>
      <div>
        <OverflowTooltip>
          <OverflowTooltipTrigger>
            <div className='truncate'>
              user@example.com - Administrator - Last login: 2024-01-15
            </div>
          </OverflowTooltipTrigger>
          <OverflowTooltipContent>
            <div className='grid grid-cols-2 gap-2 text-sm'>
              <span className='font-medium'>Email:</span>
              <span>user@example.com</span>
              <span className='font-medium'>Role:</span>
              <span>Administrator</span>
              <span className='font-medium'>Last Login:</span>
              <span>2024-01-15</span>
            </div>
          </OverflowTooltipContent>
        </OverflowTooltip>
      </div>
    </div>
  );
};
```

### Force tooltip

Forcing it on regardless of truncation. Reach for a plain `Tooltip` instead if the answer is
always yes — this prop exists for the case that switches.

```tsx
import { Button } from '@wallarm-org/design-system/Button';
import { OverflowTooltip, OverflowTooltipContent, OverflowTooltipTrigger } from '@wallarm-org/design-system/OverflowTooltip';

export const ForceTooltip = () => {
  return (
    <div className='font-sans flex flex-col gap-16 w-300'>
      <div>
        <OverflowTooltip forceTooltip>
          <OverflowTooltipTrigger>
            <div className='truncate w-fit'>Short text</div>
          </OverflowTooltipTrigger>
          <OverflowTooltipContent>
            This tooltip is forced to show even though the text isn't truncated
          </OverflowTooltipContent>
        </OverflowTooltip>
      </div>
      <div>
        <OverflowTooltip forceTooltip>
          <OverflowTooltipTrigger>
            <Button variant='outline' color='neutral'>
              Click for info
            </Button>
          </OverflowTooltipTrigger>
          <OverflowTooltipContent>
            <div className='flex flex-col gap-2'>
              <strong>Additional Information</strong>
              <span className='text-sm'>
                This tooltip provides extra context even when the trigger element doesn't have
                overflow.
              </span>
            </div>
          </OverflowTooltipContent>
        </OverflowTooltip>
      </div>
    </div>
  );
};
```

### Different sides

Placement around the trigger. In a table, keep it off the side the reader is scanning.

```tsx
import { OverflowTooltip, OverflowTooltipContent, OverflowTooltipTrigger } from '@wallarm-org/design-system/OverflowTooltip';

export const DifferentSides = () => {
  const text = 'This is a text that will be truncated and show tooltips on different sides';
  return (
    <div className='font-sans flex flex-col gap-32 w-300 py-32'>
      <div>
        <OverflowTooltip positioning={{ placement: 'top' }}>
          <OverflowTooltipTrigger>
            <div className='truncate'>{text}</div>
          </OverflowTooltipTrigger>
          <OverflowTooltipContent>{text}</OverflowTooltipContent>
        </OverflowTooltip>
      </div>
      <div>
        <OverflowTooltip positioning={{ placement: 'bottom' }}>
          <OverflowTooltipTrigger>
            <div className='truncate'>{text}</div>
          </OverflowTooltipTrigger>
          <OverflowTooltipContent>{text}</OverflowTooltipContent>
        </OverflowTooltip>
      </div>
      <div>
        <OverflowTooltip positioning={{ placement: 'left' }}>
          <OverflowTooltipTrigger>
            <div className='truncate'>{text}</div>
          </OverflowTooltipTrigger>
          <OverflowTooltipContent>{text}</OverflowTooltipContent>
        </OverflowTooltip>
      </div>
      <div>
        <OverflowTooltip positioning={{ placement: 'right' }}>
          <OverflowTooltipTrigger>
            <div className='truncate'>{text}</div>
          </OverflowTooltipTrigger>
          <OverflowTooltipContent>{text}</OverflowTooltipContent>
        </OverflowTooltip>
      </div>
    </div>
  );
};
```

### Dynamic content

Content that changes after mount. The measurement is re-taken rather than cached from first
render, so text that grows past its box gains a tooltip without being remounted.

```tsx
import { useState } from 'react';
import { Button } from '@wallarm-org/design-system/Button';
import { OverflowTooltip, OverflowTooltipContent, OverflowTooltipTrigger } from '@wallarm-org/design-system/OverflowTooltip';

export const DynamicContent = () => {
  const [text, setText] = useState('Click the button to change this text');

  return (
    <div className='font-sans flex flex-col gap-16 w-300'>
      <div>
        <OverflowTooltip>
          <OverflowTooltipTrigger>
            <div className='truncate'>{text}</div>
          </OverflowTooltipTrigger>
          <OverflowTooltipContent>{text}</OverflowTooltipContent>
        </OverflowTooltip>
      </div>

      <Button
        variant='outline'
        color='neutral'
        onClick={() => {
          const texts = [
            'Short text',
            'This is a medium length text that might overflow',
            'This is a very long text that will definitely overflow and show a tooltip when you hover over it',
            'Another short one',
            'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt',
          ];
          setText(texts[Math.floor(Math.random() * texts.length)] ?? 'Short text');
        }}
      >
        Change Text
      </Button>
    </div>
  );
};
```

## Props

| Prop         | Type                              | Default | Description |
| ------------ | --------------------------------- | ------- | ----------- |
| forceTooltip | `boolean \| undefined`            | `false` |             |
| positioning  | `PositioningOptions \| undefined` |         |             |

### OverflowTooltipContent

| Prop     | Type                  | Default | Description |
| -------- | --------------------- | ------- | ----------- |
| maxWidth | `number \| undefined` | `400`   |             |

### OverflowTooltipTrigger

| Prop    | Type                   | Default | Description |
| ------- | ---------------------- | ------- | ----------- |
| asChild | `boolean \| undefined` | `true`  |             |

## Explorer

