Feedback

Edge Flip

A tooltip that never overflows: at the outer buttons it hugs its own side while the arrow slides to the trigger so the link is not lost.

  • tooltip
  • flip
  • arrow
  • edge

Preview

1440pxHost theme

Use it with AI

  1. 1. Copy the link.
  2. 2. Write to your agent in your own words and drop the link into the sentence.
  3. 3. The agent opens the link and installs the component from the registry.

put this in the header: https://vibeui.ru/c/tooltip-006?lang=en

Export to CSVExport to CSVExport to CSV

Наведите на крайние кнопки: подсказка прижимается к своей стороне, а стрелка съезжает к кнопке — за границу области ничего не выходит.

Show the full instructions

What the link says, spelled out. Use it when your agent cannot open links — paste this text instead.

# Install and place "tooltip-006" (Edge Flip) from VibeUI

## 1. Install first — do not skip, do not recreate
Run this exact command before writing any code:
npx shadcn@latest add https://vibeui.ru/r/tooltip-006.json

Registry item: https://vibeui.ru/r/tooltip-006.json
Installs to: components/vibeui/tooltip-006.tsx (the exact path follows this project's components.json aliases).
npm dependencies: none.
Registry dependencies: none.

Install it from the registry. Do not recreate it from the description,
do not substitute a similar component from another library, and do not
rewrite it to match the project's existing style.

## 2. What it is
A tooltip that never overflows: at the outer buttons it hugs its own side while the arrow slides to the trigger so the link is not lost.

An arrowed tooltip that flips at the edge of its area. Zero dependencies, one file, no client JS.

## 3. How to use it
import { Tooltip006 } from "@/components/vibeui/tooltip-006"

<Tooltip006
  tip="Export to CSV"
  labels={["At the left edge", "Centred", "At the right edge"]}
/>

Read the installed file for the full prop list.

## 4. Where to place it
This is a small inline component. Put it exactly where the user asked,
inside the existing markup. Do not create a new page, section or
wrapper for it. If a similar control already sits in that spot,
replace it instead of adding a second one.

Placement: ___
(The user fills this line in. If it is still blank, ask where to put it
instead of guessing.)

## 5. Keep exactly as installed
- the local --vibeui-tooltip-006-* palette — do not swap it for your theme tokens
- moving the arrow with the tooltip: a shifted tip with a centred arrow loses its link to the button
- the three alignment variants through data-align — without them the outer tips get clipped
- opening on :focus-within of the cell, not of the whole button row
- aria-describedby with a unique id on every button
- the card's own light surface: without it the dark text disappears on a dark background

## 6. You may change
- the tooltip copy through tip
- the button captions through labels — the first three are laid out at the edges and centre
- the side it opens on by swapping bottom for top in the tooltip rule
- the tooltip colour through the --vibeui-tooltip-006-tip variable

## 7. Rules
- Alignment is declared, not measured: real edge detection needs JS.
- The component lays out at most three buttons — extra ones fall back to centre alignment.
- The centre tooltip has an explicit width because the negative offset is computed from it.
- Do not lift the CSS variables into globals.css: the component has to stay a single file.

## 8. Verify
- it renders with no console errors;
- it looks like the preview on the VibeUI page you copied this from;
- if it does not, you changed something listed in section 5 — put it back.

For developers

npx shadcn@latest add https://vibeui.ru/r/tooltip-006.json
https://vibeui.ru/r/tooltip-006.json

Компонент самодостаточен: один файл, без зависимостей, собственная палитра в локальных переменных --vibeui-tooltip-006-*. Серверный: выравнивание объявлено атрибутом data-align на ячейке, и три правила задают left:0, центр и right:0. Хвостик позиционируется отдельно для каждого варианта, поэтому при переносе подсказки он остаётся под кнопкой. В демонстрации три кнопки расставлены по краям и центру области — так переворот виден без изменения размера окна.

Component source

The same file your agent installs. Here in case you would rather copy it by hand.

import type { ComponentPropsWithoutRef, CSSProperties } from "react"

export type Tooltip006Props = Omit<
  ComponentPropsWithoutRef<"div">,
  "children"
> & {
  tip?: string
  /** Подписи трёх кнопок: у края, по центру и снова у края. */
  labels?: string[]
}

// Идея компонента: подсказка, которая не вылезает за край. У крайних кнопок
// она прижимается к своей стороне, а стрелка съезжает к триггеру — поэтому
// связь подсказки с кнопкой не теряется и обрезки нет ни справа, ни слева.
const STYLES = `
:where([data-vibeui-block="tooltip-006"]){
--vibeui-tooltip-006-bg:oklch(1 0 0);
--vibeui-tooltip-006-fg:oklch(0.25 0.014 265);
--vibeui-tooltip-006-muted:oklch(0.55 0.014 265);
--vibeui-tooltip-006-border:oklch(0.9 0.006 265);
--vibeui-tooltip-006-tip:oklch(0.24 0.014 265);
--vibeui-tooltip-006-accent:oklch(0.57 0.17 265);
--vibeui-tooltip-006-font:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
}
[data-vibeui-block="tooltip-006"]{
display:flex;flex-direction:column;gap:0.75rem;
width:100%;max-width:26rem;box-sizing:border-box;
padding:1.5rem 1rem 1.125rem;
border:1px solid var(--vibeui-tooltip-006-border);border-radius:1rem;
background:var(--vibeui-tooltip-006-bg);color:var(--vibeui-tooltip-006-fg);
font-family:var(--vibeui-tooltip-006-font);
}
[data-vibeui-block="tooltip-006"] [data-part="row"]{display:flex;justify-content:space-between;gap:0.5rem}
[data-vibeui-block="tooltip-006"] [data-part="item"]{position:relative;display:inline-flex}
[data-vibeui-block="tooltip-006"] [data-part="button"]{
appearance:none;cursor:pointer;
height:2.125rem;padding:0 0.75rem;border-radius:0.625rem;
border:1px solid var(--vibeui-tooltip-006-border);
background:oklch(0.98 0.003 265);color:inherit;
font:inherit;font-size:0.8125rem;font-weight:620;white-space:nowrap;
}
[data-vibeui-block="tooltip-006"] [data-part="button"]:focus-visible{outline:2px solid var(--vibeui-tooltip-006-accent);outline-offset:2px}
[data-vibeui-block="tooltip-006"] [data-part="tip"]{
position:absolute;bottom:calc(100% + 0.5rem);z-index:20;
width:max-content;max-width:12rem;
padding:0.375rem 0.5625rem;border-radius:0.5rem;
background:var(--vibeui-tooltip-006-tip);color:oklch(0.98 0.002 265);
font-size:0.75rem;line-height:1.4;
pointer-events:none;opacity:0;translate:0 0.25rem;
transition:opacity .13s ease,translate .13s ease;
}
[data-vibeui-block="tooltip-006"] [data-part="tip"]::after{
content:"";position:absolute;bottom:-0.1875rem;width:0.5rem;height:0.5rem;
background:inherit;transform:rotate(45deg);
}
/* Переворот у края: подсказка прижата к своей стороне, стрелка едет к кнопке. */
[data-vibeui-block="tooltip-006"] [data-part="item"][data-align="start"] [data-part="tip"]{left:0}
[data-vibeui-block="tooltip-006"] [data-part="item"][data-align="start"] [data-part="tip"]::after{left:1rem}
[data-vibeui-block="tooltip-006"] [data-part="item"][data-align="center"] [data-part="tip"]{left:50%;margin-left:-6rem;width:12rem;text-align:center}
[data-vibeui-block="tooltip-006"] [data-part="item"][data-align="center"] [data-part="tip"]::after{left:50%;margin-left:-0.25rem}
[data-vibeui-block="tooltip-006"] [data-part="item"][data-align="end"] [data-part="tip"]{right:0;text-align:right}
[data-vibeui-block="tooltip-006"] [data-part="item"][data-align="end"] [data-part="tip"]::after{right:1rem}
[data-vibeui-block="tooltip-006"] [data-part="item"]:hover [data-part="tip"],
[data-vibeui-block="tooltip-006"] [data-part="item"]:focus-within [data-part="tip"]{opacity:1;translate:0 0}
[data-vibeui-block="tooltip-006"] [data-part="note"]{
margin:0;font-size:0.75rem;line-height:1.5;color:var(--vibeui-tooltip-006-muted);
}
@media (prefers-reduced-motion:reduce){[data-vibeui-block="tooltip-006"] *{animation:none!important;transition:none!important}}
`

const ALIGNMENTS = ["start", "center", "end"] as const
const DEFAULT_LABELS = ["У левого края", "По центру", "У правого края"]

/**
 * Подсказка со стрелкой, которая переворачивается у края области.
 * Один файл, ноль зависимостей, собственная палитра.
 */
export function Tooltip006({
  tip = "Экспорт в CSV",
  labels = DEFAULT_LABELS,
  className,
  style,
  ...props
}: Tooltip006Props) {
  return (
    <>
      <style href="vibeui-tooltip-006" precedence="medium">
        {STYLES}
      </style>
      <div
        {...props}
        data-vibeui-block="tooltip-006"
        className={className}
        style={style as CSSProperties}
      >
        <div data-part="row">
          {labels.slice(0, 3).map((label, index) => (
            <span
              data-part="item"
              data-align={ALIGNMENTS[index] ?? "center"}
              key={label}
            >
              <button
                data-part="button"
                type="button"
                aria-describedby={`vibeui-tooltip-006-${index}`}
              >
                {label}
              </button>
              <span
                data-part="tip"
                role="tooltip"
                id={`vibeui-tooltip-006-${index}`}
              >
                {tip}
              </span>
            </span>
          ))}
        </div>
        <p data-part="note">
          Наведите на крайние кнопки: подсказка прижимается к своей стороне, а
          стрелка съезжает к кнопке — за границу области ничего не выходит.
        </p>
      </div>
    </>
  )
}