Skip to main content

keycaps 0.1.1 copy "keycaps: ^0.1.1" to clipboard
keycaps: ^0.1.1 copied to clipboard

Keycap and keyboard-shortcut widgets for Flutter. Draws ⌘⇧P or Ctrl+Shift+P from a string, a LogicalKeyboardKey or a ShortcutActivator, themed and labelled per platform.

keycaps #

CI

Keycaps and keyboard shortcuts as Flutter widgets.

Write the shortcut once; the package prints it the way the platform does — ⌘⇧P on macOS, Ctrl+Shift+P on Windows, Super instead of Win on Linux.

import 'package:keycaps/keycaps.dart';

const Keycap('K');                                  // a single cap
Keycaps.parse('Cmd+Shift+P');                       // a chord
KeycapSequence.parse(const <String>['Ctrl+K', 'Ctrl+S']);  // chords in order

The same list, three platforms #

Nothing below changed but the platform the caps resolve against — same strings, same widgets. Apple sets modifiers solid as glyphs; Windows and Linux spell them out, join them with +, and wear their own logo on the meta key.

macOS Windows Linux
A shortcut list with macOS labels: command, shift and option glyphs, and esc. The same list with Windows labels: the Windows logo, Shift, Ctrl, Alt, Backspace and Esc, joined by plus signs. The same list with Linux labels: the Tux logo on the meta key, otherwise as Windows.

Both screenshots came out of the example app's platform switcher, on one machine.

Sources for a shortcut #

Source Widget
Text Keycaps.parse('Cmd+Shift+P')
A Flutter activator Keycaps.activator(const SingleActivator(LogicalKeyboardKey.keyP, meta: true))
Explicit tokens Keycaps(const <KeyToken>[KeyToken.key(LogicalKeyboardKey.meta), KeyToken.text('Fn')])
A single key const Keycap.logical(LogicalKeyboardKey.escape)
Anything else Keycap.child(child: Icon(Icons.keyboard_return))

Keycaps.activator also orders the modifiers conventionally: ⌃⌥⇧ then ⌘ on Apple, meta first on Windows and Linux.

Parsing rules #

Parts are separated by + and trimmed, so Ctrl + K and Ctrl+K are the same. A + in key position is the plus key, so Cmd++ is two caps. Names are matched case-insensitively against ShortcutParser.aliases (cmd, command, ⌘, opt, esc, pgdn, f7, …); a single unknown character becomes that key, and a longer unknown word is printed verbatim — handy for Fn.

Icons #

Some keys say more as a picture: the meta key wears the OS logo, arrows point. KeycapIcons decides how far that goes.

Mode Draws
auto (default) Windows/Linux logo on meta, plus the four arrow keys. Apple keeps its native glyphs — ⌘ is the convention there.
always Every key with an icon: ⌘ ⌥ ⌃ ⇧ ⇪ ⏎ ⌫ ⇥, Home/End, PgUp/PgDn
never Text only
Keycaps.parse('Cmd+Shift+P', style: const KeycapStyle(icons: KeycapIcons.always))

Icons come from phosphor_icons, referenced only through PhosphorIconsRegular static const fields so --tree-shake-icons can subset the font. Release builds should pass that flag.

The other five Phosphor weights are a subtler cost: the shaker only subsets a font it found references for, so weights nothing draws are copied whole — about 2 MB. Mount const KeycapIconFontGuard() anywhere in your tree to reference one glyph from each and cut them to a few hundred bytes apiece. Skip it if your app already draws from those weights.

Pressing and highlighting #

Caps are not static pictures.

  • Tap — a cap sinks under the finger and rises on release, whether or not you pass a handler. Keycap(onTap:) for one cap, Keycaps(onKeyTap:) for a row, which hands you the KeyToken that was hit. Turn the animation off with tapEffect: false.
  • Live highlight — a cap built from a LogicalKeyboardKey lights up in highlightColor while that key is actually held on the device, so a shortcut list doubles as a cheat sheet that answers as you type. Off with liveHighlight: false.
  • Forced — Keycap(pressed: true) holds a cap down regardless of input.

Highlighting shares one app-wide HardwareKeyboard handler (KeycapKeyboardWatcher), installed only while a highlighting cap is mounted and never swallowing an event, so your own shortcuts still fire. Left/right variants count: a cap for LogicalKeyboardKey.shift lights up for shiftLeft.

Styling #

Appearance comes from the nearest KeycapTheme, falling back to one derived from the ambient Material theme. Style a whole subtree:

KeycapTheme(
  data: KeycapThemeData.fromTheme(Theme.of(context), size: KeycapSize.small)
      .copyWith(variant: KeycapVariant.outlined),
  child: child,
)

…or one widget, with a KeycapStyle (all fields optional, applied over the inherited theme):

Keycaps.parse(
  'Cmd+K',
  style: const KeycapStyle(size: KeycapSize.large, variant: KeycapVariant.flat),
)
Knob Values
variant raised (default, with a bottom edge), flat, outlined, bare
size KeycapSize.small / medium / large, or set metrics individually
join auto (+ off Apple, nothing on Apple), plus, none, tight
platform Force KeycapPlatform.apple / windows / linux labels
icons auto, always, never (see above), plus iconSize
liveHighlight / tapEffect Turn the two reactions off

KeycapThemeData also exposes faceColor, edgeColor, borderColor, foregroundColor, highlightColor, highlightForegroundColor, height, minWidth, padding, radius, depth, borderWidth, spacing, pressDuration, textStyle and separatorStyle, plus lerp for animating between themes.

Accessibility #

Printed labels are glyphs (⌘, ⌫) or clipped words (PgDn), which read badly aloud. Caps announce full words instead — a Keycaps.parse('Cmd+Shift+P') row reads as “Command Shift P”. Override with Keycap(semanticLabel: …).

Example #

cd example
flutter run

A gallery of every variant, size and icon mode, a platform switcher, tap feedback, and a live keyboard mirror.

1
likes
160
points
127
downloads
screenshot

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Keycap and keyboard-shortcut widgets for Flutter. Draws ⌘⇧P or Ctrl+Shift+P from a string, a LogicalKeyboardKey or a ShortcutActivator, themed and labelled per platform.

Repository (GitHub)
View/report issues

Topics

#keyboard #shortcuts #widget #ui

License

MIT (license)

Dependencies

flutter, phosphor_icons

More

Packages that depend on keycaps