Feedback

Shortcut Tooltip

A tooltip that also teaches the shortcut: the action on the left, the key combination on the right — it becomes a reference rather than a repeat of the label.

  • tooltip
  • shortcut
  • kbd
  • toolbar

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-003?lang=en

Open searchCtrlK
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-003" (Shortcut Tooltip) 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-003.json

Registry item: https://vibeui.ru/r/tooltip-003.json
Installs to: components/vibeui/tooltip-003.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 also teaches the shortcut: the action on the left, the key combination on the right — it becomes a reference rather than a repeat of the label.

A tooltip with a keyboard shortcut: action and combination on one line, keys marked up with <kbd>. Zero dependencies, one file, no client JS.

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

<Tooltip003 tip="Open search" keys={["Ctrl", "K"]} />

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-003-* palette — do not swap it for your theme tokens
- aria-keyshortcuts on the button: the combination must be available without hovering
- the spoken label on the key group — otherwise a screen reader reads a run of separate letters
- the <kbd> tags instead of a plain "Ctrl+K" string: keys are recognised by shape
- opening on :focus-within — the tooltip must appear from the keyboard too
- the button's own light surface: without it the dark text disappears on a dark background

## 6. You may change
- the action text through tip
- the combination through keys — the array is drawn one key at a time
- your own trigger through children instead of the default button
- the key colour through the --vibeui-tooltip-003-key variable

## 7. Rules
- macOS expects ⌘ and ⌥: substitute them yourself, the component does not detect the platform.
- The combination in the tooltip must match the real handler — the component listens to nothing.
- More than three keys in a row read poorly: long chords are better written out in words.
- 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-003.json
https://vibeui.ru/r/tooltip-003.json

Компонент самодостаточен: один файл, без зависимостей, собственная палитра в локальных переменных --vibeui-tooltip-003-*. Серверный: открытие держится на :hover и :focus-within. Клавиши нарисованы тегами <kbd> с полупрозрачной заливкой, а не текстом «Ctrl+K»: так их видно как клавиши. На кнопке стоит aria-keyshortcuts, поэтому сочетание доступно и без наведения, а группе клавиш дана словесная подпись через aria-label — иначе скринридер прочитает набор букв.

Component source

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

import type { ComponentPropsWithoutRef, CSSProperties, ReactNode } from "react"

export type Tooltip003Props = Omit<
  ComponentPropsWithoutRef<"span">,
  "children"
> & {
  tip?: string
  /** Клавиши сочетания: каждая рисуется отдельной клавишей. */
  keys?: string[]
  children?: ReactNode
}

// Идея компонента: подсказка, которая заодно учит горячей клавише. Название
// действия и сочетание разведены по краям, клавиши нарисованы как <kbd> —
// поэтому подсказка становится справочником, а не повтором подписи кнопки.
const STYLES = `
:where([data-vibeui-block="tooltip-003"]){
--vibeui-tooltip-003-bg:oklch(0.24 0.014 265);
--vibeui-tooltip-003-fg:oklch(0.97 0.002 265);
--vibeui-tooltip-003-key:oklch(1 0 0 / 14%);
--vibeui-tooltip-003-keyfg:oklch(0.88 0.008 265);
--vibeui-tooltip-003-accent:oklch(0.6 0.16 265);
--vibeui-tooltip-003-font:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
}
[data-vibeui-block="tooltip-003"]{
position:relative;display:inline-flex;font-family:var(--vibeui-tooltip-003-font);
}
[data-vibeui-block="tooltip-003"] [data-part="trigger"]{
appearance:none;cursor:pointer;
display:inline-flex;align-items:center;gap:0.375rem;
height:2.25rem;padding:0 0.875rem;border-radius:0.625rem;
border:1px solid oklch(0.89 0.006 265);
background:oklch(1 0 0);color:oklch(0.26 0.014 265);
font:inherit;font-size:0.8125rem;font-weight:620;
}
[data-vibeui-block="tooltip-003"] [data-part="trigger"]:hover{background:oklch(0.97 0.003 265)}
[data-vibeui-block="tooltip-003"] [data-part="trigger"]:focus-visible{outline:2px solid var(--vibeui-tooltip-003-accent);outline-offset:2px}
/* Название и сочетание разведены по краям одной строки. */
[data-vibeui-block="tooltip-003"] [data-part="tip"]{
position:absolute;bottom:calc(100% + 0.5rem);left:50%;z-index:20;
display:flex;align-items:center;gap:0.625rem;width:max-content;
padding:0.375rem 0.4375rem 0.375rem 0.625rem;border-radius:0.5rem;
background:var(--vibeui-tooltip-003-bg);color:var(--vibeui-tooltip-003-fg);
font-size:0.75rem;line-height:1.4;
pointer-events:none;opacity:0;
transform:translate(-50%,0.25rem);
transition:opacity .13s ease,transform .13s ease;
}
[data-vibeui-block="tooltip-003"] [data-part="tip"]::after{
content:"";position:absolute;left:50%;bottom:-0.1875rem;
width:0.5rem;height:0.5rem;margin-left:-0.25rem;
background:inherit;transform:rotate(45deg);
}
[data-vibeui-block="tooltip-003"]:hover [data-part="tip"],
[data-vibeui-block="tooltip-003"]:focus-within [data-part="tip"]{opacity:1;transform:translate(-50%,0)}
[data-vibeui-block="tooltip-003"] [data-part="keys"]{display:inline-flex;align-items:center;gap:0.1875rem;flex:none}
[data-vibeui-block="tooltip-003"] kbd{
display:inline-flex;align-items:center;justify-content:center;
min-width:1.25rem;height:1.25rem;padding:0 0.3125rem;box-sizing:border-box;
border-radius:0.3125rem;background:var(--vibeui-tooltip-003-key);
color:var(--vibeui-tooltip-003-keyfg);
font-family:inherit;font-size:0.6875rem;font-weight:650;line-height:1;
}
@media (prefers-reduced-motion:reduce){[data-vibeui-block="tooltip-003"] *{animation:none!important;transition:none!important}}
`

const DEFAULT_KEYS = ["Ctrl", "K"]

/**
 * Подсказка с горячей клавишей: название действия и сочетание в одной строке.
 * Один файл, ноль зависимостей, собственная палитра.
 */
export function Tooltip003({
  tip = "Открыть поиск",
  keys = DEFAULT_KEYS,
  children,
  className,
  style,
  ...props
}: Tooltip003Props) {
  const spoken = keys.join(" + ")

  return (
    <>
      <style href="vibeui-tooltip-003" precedence="medium">
        {STYLES}
      </style>
      <span
        {...props}
        data-vibeui-block="tooltip-003"
        className={className}
        style={style as CSSProperties}
      >
        {children ?? (
          <button
            data-part="trigger"
            type="button"
            aria-keyshortcuts={keys.join("+")}
            aria-describedby="vibeui-tooltip-003-tip"
          >
            Поиск
          </button>
        )}
        <span data-part="tip" role="tooltip" id="vibeui-tooltip-003-tip">
          <span>{tip}</span>
          <span data-part="keys" aria-label={spoken}>
            {keys.map((key) => (
              <kbd key={key}>{key}</kbd>
            ))}
          </span>
        </span>
      </span>
    </>
  )
}