Display

Key Chord Separator

A key chord with an explicit separator: "⌘ + K" and "⌘ then K" are different actions, and the word between the keys removes the guesswork.

  • kbd
  • shortcut
  • chord
  • keyboard

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/kbd-002?lang=en

+ + P

Command palette

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 "kbd-002" (Key Chord Separator) 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/kbd-002.json

Registry item: https://vibeui.ru/r/kbd-002.json
Installs to: components/vibeui/kbd-002.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 key chord with an explicit separator: "⌘ + K" and "⌘ then K" are different actions, and the word between the keys removes the guesswork.

A key chord with the separator in markup: plus, then, or an arrow. Zero dependencies, one file, no client JS.

## 3. How to use it
import { Kbd002 } from "@/components/vibeui/kbd-002"

<Kbd002 keys={["⌘", "⇧", "P"]} separator="plus" caption="Command palette" />

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-kbd-002-* palette — do not swap it for your theme tokens
- the kbd tag for keys: a screen reader announces them as input rather than plain text
- the separator in markup — a pseudo-element is not read aloud and breaks the chord's meaning
- the difference between plus and then: simultaneous and sequential presses are different actions
- the 2px bottom edge of the key: it gives the key depth without shadows or gradients
- the component's own light surface: keys and caption are dark and vanish on a dark background

## 6. You may change
- the separator style through separator: plus, then or arrow
- the action caption through caption
- the chord contents through keys
- the key radius through the --vibeui-kbd-002-* variables

## 7. Rules
- The ⌘ and ⇧ glyphs are missing from some fonts: certain Windows setups show a box.
- A chord longer than four keys wraps — check it on narrow widths.
- The "then" separator is Russian in the default: substitute your own word for other locales.
- 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/kbd-002.json
https://vibeui.ru/r/kbd-002.json

Серверный компонент, хуков нет. Клавиши набраны тегом kbd — это его прямое назначение, скринридер объявит их как ввод. Разделитель лежит в разметке отдельным узлом, а не рисуется псевдоэлементом: содержимое ::before не попадает в поток чтения, и вслух сочетание превратилось бы в две несвязанные клавиши. Вариант разделителя переключается атрибутом data-separator, набор вариантов вынесен в объект: plus для одновременного нажатия, then для последовательного, arrow для перехода. Подложка светлая, потому что и клавиши, и подпись тёмные.

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 Kbd002Props = Omit<ComponentPropsWithoutRef<"div">, "children"> & {
  keys?: string[]
  separator?: "plus" | "then" | "arrow"
  caption?: string
}

// Идея компонента: сочетание клавиш с явным разделителем. «⌘ + K» и «⌘ затем
// K» — разные действия: первое нажимают вместе, второе по очереди, и без
// слова между клавишами пользователь угадывает. Разделитель лежит в разметке
// отдельным элементом, поэтому его слышно при чтении вслух, а не только видно.
const STYLES = `
:where([data-vibeui-block="kbd-002"]){
--vibeui-kbd-002-surface:oklch(1 0 0);
--vibeui-kbd-002-fg:oklch(0.24 0.014 265);
--vibeui-kbd-002-muted:oklch(0.55 0.014 265);
--vibeui-kbd-002-border:oklch(0.88 0.008 265);
--vibeui-kbd-002-key:oklch(0.985 0.002 265);
--vibeui-kbd-002-font:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
}
/* Своя светлая подложка: клавиши и подпись тёмные. */
[data-vibeui-block="kbd-002"]{
display:inline-flex;flex-direction:column;gap:0.5rem;
box-sizing:border-box;padding:0.875rem 1rem;
background:var(--vibeui-kbd-002-surface);
border:1px solid var(--vibeui-kbd-002-border);border-radius:0.875rem;
font-family:var(--vibeui-kbd-002-font);color:var(--vibeui-kbd-002-fg);
}
[data-vibeui-block="kbd-002"] [data-part="caption"]{
margin:0;font-size:0.75rem;color:var(--vibeui-kbd-002-muted);
}
[data-vibeui-block="kbd-002"] [data-part="chord"]{
display:inline-flex;align-items:center;gap:0.375rem;flex-wrap:wrap;
}
[data-vibeui-block="kbd-002"] kbd{
display:inline-flex;align-items:center;justify-content:center;
min-width:1.75rem;height:1.75rem;padding:0 0.5rem;box-sizing:border-box;
background:var(--vibeui-kbd-002-key);
border:1px solid var(--vibeui-kbd-002-border);border-bottom-width:2px;
border-radius:0.4375rem;
font-family:inherit;font-size:0.8125rem;font-weight:650;line-height:1;
}
/* Разделитель — отдельный узел: его слышно при чтении вслух, а не только видно. */
[data-vibeui-block="kbd-002"] [data-part="sep"]{
font-size:0.75rem;color:var(--vibeui-kbd-002-muted);
}
[data-vibeui-block="kbd-002"][data-separator="then"] [data-part="sep"]{
font-size:0.6875rem;text-transform:lowercase;letter-spacing:0.02em;
}
@media (prefers-reduced-motion:reduce){[data-vibeui-block="kbd-002"] *{animation:none!important;transition:none!important}}
`

const SEPARATORS: Record<NonNullable<Kbd002Props["separator"]>, string> = {
  plus: "+",
  then: "затем",
  arrow: "→",
}

/**
 * Сочетание клавиш с разделителем, который читается вслух.
 * Один файл, ноль зависимостей, собственная палитра.
 */
export function Kbd002({
  keys = ["⌘", "⇧", "P"],
  separator = "plus",
  caption = "Палитра команд",
  className,
  style,
  ...props
}: Kbd002Props) {
  const glue = SEPARATORS[separator]

  return (
    <>
      <style href="vibeui-kbd-002" precedence="medium">
        {STYLES}
      </style>
      <div
        {...props}
        data-vibeui-block="kbd-002"
        data-separator={separator}
        className={className}
        style={style as CSSProperties}
      >
        <span data-part="chord">
          {keys.map((key, index) => (
            <span key={key} data-part="unit">
              {index > 0 ? <span data-part="sep"> {glue} </span> : null}
              <kbd>{key}</kbd>
            </span>
          ))}
        </span>
        <p data-part="caption">{caption}</p>
      </div>
    </>
  )
}