Kbd
Displays a keyboard key or shortcut.
Installation
Included in poetry-ui — available as
poetry_kbd
the moment you've installed Poetry,
with no per-component step. To own the source and edit it, copy it into your app:
bin/rails g poetry:add kbd
Default
Open Default standalone
⌘
⇧
⌥
⌃
Ctrl
+
B
<%# Upstream kbd-demo: the modifier row and a Ctrl+B chord - a group is
a plain inline-flex wrapper (the house grouping idiom, cf. Chord). %>
<div class="flex flex-col items-center gap-4">
<div class="inline-flex items-center gap-1">
<%= poetry_kbd { "⌘" } %>
<%= poetry_kbd { "⇧" } %>
<%= poetry_kbd { "⌥" } %>
<%= poetry_kbd { "⌃" } %>
</div>
<div class="inline-flex items-center gap-1">
<%= poetry_kbd { "Ctrl" } %>
<span>+</span>
<%= poetry_kbd { "B" } %>
</div>
</div>
Chord
Open Chord standalone
⌘
K
<div class="inline-flex items-center gap-1">
<%= poetry_kbd { "⌘" } %>
<%= poetry_kbd { "K" } %>
</div>
Command
Open Command standalone
⌘
<%= poetry_kbd { "⌘" } %>
Group
Open Group standalone
Use Ctrl + B Ctrl + K to open the command palette
<%# Upstream kbd-group: key chords inline in prose - the muted sentence
carries the two Kbds. %>
<p class="text-sm text-muted-foreground">
Use
<%= poetry_kbd_group do %>
<%= poetry_kbd { "Ctrl + B" } %>
<%= poetry_kbd { "Ctrl + K" } %>
<% end %>
to open the command palette
</p>
In button
Open In button standalone
<%# A Kbd rides the button's trailing slot to advertise the action's
shortcut. Kbd is a non-interactive <kbd>, so nesting it in a Button is
fine - the visible label stays the content block. %>
<%= poetry_button(variant: :outline) do |button| %>
<% button.with_trailing { poetry_kbd { "⌘S" } } %>
Save changes
<% end %>
In tooltip
Open In tooltip standalone
Save Changes
⌘
S
Print Document
⌘
P
<%# Upstream kbd-tooltip: each tooltip names its action and shows the
chord - the command symbol makes the shortcut read at a glance.
Poetry's tooltip root is a wrapper span, so the two triggers sit in
a plain row rather than a ButtonGroup. %>
<div class="flex flex-wrap gap-2">
<%= poetry_tooltip do |tooltip| %>
<% tooltip.with_trigger(variant: :outline) { "Save" } %>
<span class="inline-flex items-center gap-2">
Save Changes
<span class="inline-flex items-center gap-1">
<%= poetry_kbd { "⌘" } %>
<%= poetry_kbd { "S" } %>
</span>
</span>
<% end %>
<%= poetry_tooltip do |tooltip| %>
<% tooltip.with_trigger(variant: :outline) { "Print" } %>
<span class="inline-flex items-center gap-2">
Print Document
<span class="inline-flex items-center gap-1">
<%= poetry_kbd { "⌘" } %>
<%= poetry_kbd { "P" } %>
</span>
</span>
<% end %>
</div>
Search hint
Open Search hint standalone
⌘K
<%# A Kbd inside an input-group addon hints the key that opens the field -
the group wears the border and focus ring, the control stays borderless
(a plain poetry_input would double-chrome the surface). %>
<div class="w-80">
<%= poetry_label(for_id: "kbd-command-search", class: "sr-only") { "Search commands" } %>
<%= poetry_input_group do %>
<%= poetry_input_group_addon do %>
<%= poetry_icon(name: :search) %>
<% end %>
<%= poetry_input_group_input(id: "kbd-command-search", name: "command", placeholder: "Search commands…") %>
<%= poetry_input_group_addon(align: :"inline-end") do %>
<%= poetry_kbd { "⌘K" } %>
<% end %>
<% end %>
</div>
Styling
Every part carries a stable data-slot attribute — target
[data-slot=…] from your own CSS to restyle it. State rides
data attributes on the parts below. This contract is verified against rendered DOM in CI.
| Part | Description |
|---|---|
| [data-slot=kbd] | The <kbd> element itself - the key text renders here |