Kbd

A component for displaying keyboard shortcuts and key combinations with proper platform-specific formatting. Automatically adapts the display to match the conventions of macOS (using symbols) or Windows/Linux (using text labels).

Install

#Import

use gpui_kit::component::kbd::Kbd;
use gpui_kit::Keystroke;
// Installed in ui/components. That directory is on the Slint include path, so import by file name:
import { Kbd, KbdSequence } from "kbd.slint";
use iced::widget::{column, container, mouse_area, row, scrollable, svg, text};
use iced::{Alignment, Element, Length, Task, Theme};

#Usage

#Shortcuts

// Command palette
Kbd::new(Keystroke::parse("cmd-shift-p").unwrap())

// New tab
Kbd::new(Keystroke::parse("cmd-t").unwrap())

// Zoom controls
Kbd::new(Keystroke::parse("cmd--").unwrap())  // Zoom out
Kbd::new(Keystroke::parse("cmd-+").unwrap())  // Zoom in

// Navigation
Kbd::new(Keystroke::parse("escape").unwrap())
Kbd::new(Keystroke::parse("enter").unwrap())
Kbd::new(Keystroke::parse("backspace").unwrap())
KbdSequence {
    Kbd {
        text: "⌘";
    }
    Kbd {
        text: "K";
    }
}
KbdSequence {
    Kbd {
        text: "Ctrl";
    }
    Kbd {
        text: "Shift";
    }
    Kbd {
        text: "P";
    }
}
// The Slint example's first box: a chord on the default cap, and a longer
// one whose words are spelled because the wasm face has no `⌘`.
let shortcuts = panel(
    column![sequence(["Cmd", "K"]), sequence(["Ctrl", "Shift", "P"]),]
        .spacing(8)
        .align_x(Alignment::Start),
);

#Basic Keyboard Shortcut

// Create from a keystroke
let kbd = Kbd::new(Keystroke::parse("cmd-shift-p").unwrap());

// Or convert directly from keystroke
let kbd: Kbd = Keystroke::parse("escape").unwrap().into();
SlintNo Slint version of this example yet.

#Multiple Modifiers

// Complex combinations
Kbd::new(Keystroke::parse("cmd-ctrl-shift-a").unwrap())
Kbd::new(Keystroke::parse("cmd-alt-backspace").unwrap())
Kbd::new(Keystroke::parse("ctrl-alt-shift-a").unwrap())
VerticalLayout {
    spacing: 8px;
    alignment: start;
    KbdSequence {
        Kbd {
            text: "⌘";
        }
        Kbd {
            text: "⇧";
        }
        Kbd {
            text: "P";
        }
    }
    KbdSequence {
        Kbd {
            text: "Ctrl";
        }
        Kbd {
            text: "Alt";
        }
        Kbd {
            text: "Delete";
        }
    }
    KbdSequence {
        Kbd {
            text: "⌘";
            size: ControlSize.small;
        }
        Kbd {
            text: "K";
            size: ControlSize.small;
        }
    }
}
// Three chords: marks the face carries beside words it does not, and the
// same chord again at the small step, which is what an inline hint uses.
let modifiers = panel(
    column![
        sequence(["Cmd", "⇧", "P"]),
        sequence(["Ctrl", "Alt", "Delete"]),
        row![
            Kbd::<Message>::new("Cmd").size(ControlSize::Small),
            Kbd::<Message>::new("K").size(ControlSize::Small),
        ]
        .spacing(4.0)
        .align_y(Alignment::Center),
    ]
    .spacing(8)
    .align_x(Alignment::Start),
);

#Arrow Keys and Function Keys

// Arrow keys
Kbd::new(Keystroke::parse("left").unwrap())
Kbd::new(Keystroke::parse("right").unwrap())
Kbd::new(Keystroke::parse("up").unwrap())
Kbd::new(Keystroke::parse("down").unwrap())

// Function keys
Kbd::new(Keystroke::parse("f12").unwrap())
Kbd::new(Keystroke::parse("secondary-f12").unwrap())

// Page navigation
Kbd::new(Keystroke::parse("pageup").unwrap())
Kbd::new(Keystroke::parse("pagedown").unwrap())
KbdSequence {
    Kbd {
        text: "↑";
    }
    Kbd {
        text: "↓";
    }
    Kbd {
        text: "←";
    }
    Kbd {
        text: "→";
    }
    Kbd {
        text: "Enter";
    }
    Kbd {
        text: "Esc";
    }
}
// The arrows are real glyphs in the wasm face; the named keys are spelled
// because `⎋` and `⏎` are not in it.
let arrows = panel(sequence(["↑", "↓", "←", "→", "Enter", "Esc"]));

#Without Visual Styling

// Display only the key text without the styled background
Kbd::new(Keystroke::parse("cmd-s").unwrap())
    .appearance(false)
SlintNo Slint version of this example yet.

#From Action Bindings

use gpui_kit::{Action, Window, FocusHandle};

// Get first keybinding for an action
if let Some(kbd) = Kbd::binding_for_action(&MyAction {}, None, window) {
    // Display the bound shortcut
}

// Get keybinding for action within a specific context
if let Some(kbd) = Kbd::binding_for_action(&MyAction {}, Some("Editor"), window) {
    // Display context-specific shortcut
}

// Get keybinding for action within a focus handle
if let Some(kbd) = Kbd::binding_for_action_in(&MyAction {}, &focus_handle, window) {
    // Display shortcut for focused element
}
SlintNo Slint version of this example yet.

#Keyboard Shortcut Help

use gpui_kit::{div, h_flex, v_flex};

// Display common shortcuts
v_flex()
    .gap_2()
    .child(
        h_flex()
            .gap_2()
            .items_center()
            .child("Open command palette:")
            .child(Kbd::new(Keystroke::parse("cmd-shift-p").unwrap()))
    )
    .child(
        h_flex()
            .gap_2()
            .items_center()
            .child("Save file:")
            .child(Kbd::new(Keystroke::parse("cmd-s").unwrap()))
    )
    .child(
        h_flex()
            .gap_2()
            .items_center()
            .child("Find in files:")
            .child(Kbd::new(Keystroke::parse("cmd-shift-f").unwrap()))
    )
SlintNo Slint version of this example yet.
h_flex()
    .justify_between()
    .items_center()
    .child("New File")
    .child(Kbd::new(Keystroke::parse("cmd-n").unwrap()))
SlintNo Slint version of this example yet.

#Inline Documentation

div()
    .child("Press ")
    .child(Kbd::new(Keystroke::parse("escape").unwrap()))
    .child(" to cancel or ")
    .child(Kbd::new(Keystroke::parse("enter").unwrap()))
    .child(" to confirm.")
SlintNo Slint version of this example yet.

#Custom Styling

Kbd::new(Keystroke::parse("cmd-k").unwrap())
    .text_color(cx.theme().accent)
    .border_color(cx.theme().accent)
    .bg(cx.theme().accent.opacity(0.1))
SlintNo Slint version of this example yet.

#Text-Only Format

// Get formatted text without styling
let shortcut_text = Kbd::format(&Keystroke::parse("cmd-shift-p").unwrap());
div().child(format!("Shortcut: {}", shortcut_text))
SlintNo Slint version of this example yet.

#Platform Differences

The Kbd component automatically formats shortcuts according to platform conventions:

#macOS

  • Uses symbols: ⌃ ⌥ ⇧ ⌘
  • No separators between modifiers
  • Order: Control, Option, Shift, Command
  • Special keys: ⌫ (backspace), ⎋ (escape), ⏎ (enter), ← → ↑ ↓ (arrows)

#Windows/Linux

  • Uses text labels: Ctrl, Alt, Shift, Win
  • Plus sign (+) separators
  • Order: Ctrl, Alt, Shift, Win
  • Special keys: Backspace, Esc, Enter, Left, Right, Up, Down

#Examples by Platform

InputmacOSWindows/Linux
cmd-a⌘AWin+A
ctrl-shift-a⌃⇧ACtrl+Shift+A
cmd-alt-backspace⌥⌘⌫Win+Alt+Backspace
escape⎋Esc
enter⏎Enter
left←Left

#Styling

The Kbd component uses the following default styles:

  • Border with theme border color
  • Muted foreground text color
  • Background with theme background color
  • Small rounded corners
  • Centered text alignment
  • Extra small font size
  • Minimal padding (0.5px vertical, 1px horizontal)
  • Minimum width of 5 units
  • Flex shrink disabled to maintain size

All styles can be customized using the Styled trait methods.