KeyboardShortcut | CoUI
LogoCoUI

KeyboardShortcut

키보드 단축키 키 조합을 시각적으로 표시하는 컴포넌트

KeyboardShortcut#

키보드 단축키의 키 조합을 시각적으로 표시하는 컴포넌트입니다. 메뉴 / 도움말 / 사이드바 등에서 단축키를 안내할 때 사용합니다. 내부적으로 Kbd 를 사용해 양쪽 플랫폼 동일한 키 박스 spec 으로 렌더됩니다.

Live Preview#

Web
Ctrl+Shift+K
Flutter
Loading Flutter...
class KeyboardShortcutDefaultExample extends StatelessComponent {
  const KeyboardShortcutDefaultExample({super.key});

  @override
  Component build(BuildContext context) {
    return const KeyboardShortcut(keys: ['Ctrl', 'Shift', 'K']);
  }
}
class KeyboardShortcutDefaultExample extends StatelessWidget {
  const KeyboardShortcutDefaultExample({super.key});

  @override
  Widget build(BuildContext context) {
    return const KeyboardShortcut(keys: ['Ctrl', 'Shift', 'K']);
  }
}

사용 시기 (When to Use)#

이 컴포넌트를 사용하세요:

  • 메뉴 항목 옆에 해당 키보드 단축키를 안내할 때
  • 설정 / 도움말 페이지의 단축키 목록을 표시할 때
  • 커맨드 팔레트의 단축키 힌트를 표시할 때

대신 다른 컴포넌트를 사용하세요:

  • Kbd: 단축키 wrapper 없이 단일 키 박스만 필요할 때 (KeyboardShortcut 의 내부 building block)
  • Tooltip: 단축키가 아닌 일반 설명 텍스트를 호버 시 보여줄 때

기본 사용법 (Basic Usage)#

// 단축키 키 조합
const KeyboardShortcut(keys: ['Ctrl', 'S'])

// 복잡한 단축키
const KeyboardShortcut(keys: ['Ctrl', 'Shift', 'P'])

// macOS 표기
const KeyboardShortcut(keys: ['⌘', 'K'])

// Flutter ShortcutActivator 에서 자동 변환
KeyboardShortcut.fromActivator(
  activator: SingleActivator(LogicalKeyboardKey.keyS, control: true),
)
const KeyboardShortcut(keys: ['Ctrl', 'S'])
const KeyboardShortcut(keys: ['Ctrl', 'Shift', 'P'])
const KeyboardShortcut(keys: ['⌘', 'K'])

Props / Parameters#

속성타입기본값설명
keys List<String> 필수 표시할 키 목록 (+ 구분자로 자동 join)
spacing double? null 키 사이 간격 override (null = 토큰 기본값)

Flutter 전용#

속성타입설명
KeyboardShortcut.fromActivator ShortcutActivator Flutter SingleActivator / CharacterActivator / LogicalKeySet 에서 자동 추출

스타일 시스템 (Style System)#

CoreKeyboardShortcutStyle 필드#

필드타입설명
spacing double? Spacing (logical px) between key boxes and the + separator — forwarded straight to CoreKbdStyle.keySeparatorSpacing . null defers to CoreKbdStyle.defaultKeySeparatorSpacing . No default, and must not have one. The baseline for this value belongs to Kbd , which draws the keys; this wrapper only splits a shortcut string and hands them over. Both platforms turn the null into "send no override at all" — spacing == null ? null : CoreKbdStyle(keySeparatorSpacing: …) — so Kbd(kbdStyle: null) resolves its own default, and there is exactly one place the number lives. A constant here would break that branch twice over. It would be a second copy of Kbd 's default, free to drift from it; and on Flutter it would be scaled twice, because this resolver multiplies by theme.scaling before forwarding and Kbd 's resolver multiplies again — today only an explicit caller override travels that path, and a default would put every shortcut on it.

동작 스펙#

표시 전용. 인터랙션 없음. 키 박스 spec 은 Kbd 와 동일 토큰 사용 (labelSmall + sans + surfaceContainer + outline + field radius).

사용 가이드라인 (Usage Guidelines)#

✅ Do#

실제 단축키 처리 로직과 항상 짝지어 사용

// 표시는 KeyboardShortcut, 실제 키 처리는 별도로 등록
Shortcuts(
  shortcuts: <ShortcutActivator, Intent>{
    SingleActivator(LogicalKeyboardKey.keyS, control: true): SaveIntent(),
  },
  child: MenuItem(
    trailing: const KeyboardShortcut(keys: ['Ctrl', 'S']),
    child: const Text('저장'),
  ),
)

이유: KeyboardShortcut 은 키 조합을 표시만 하며 어떤 키 이벤트도 등록하거나 가로채지 않습니다. 실제 단축키 동작은 호출자가 Shortcuts/Actions 같은 별도 메커니즘으로 등록해야 안내와 실제 동작이 일치합니다.


❌ Don't#

접근성 단축키 안내의 대체 수단으로 사용 금지

// ❌ KeyboardShortcut 만 붙이면 스크린 리더에도 단축키가 안내된다고 오해
Button(
  variant: CoreButtonVariant.plain,
  onPressed: save,
  child: const KeyboardShortcut(keys: ['Ctrl', 'S']),
)

이유: KeyboardShortcutaria-keyshortcuts 를 내보내지 않고, 키 조합 전체에 대한 접근 가능한 이름도 없습니다(캡마다 별도 텍스트 노드). 스크린 리더에 단축키를 안내하려면 그 컨트롤에 aria-keyshortcuts 를 직접 넣어야 합니다.

접근성 (Accessibility)#

이름과 달리 KeyboardShortcut 은 단축키를 표시만 합니다. 키를 등록하지도, 가로채지도, 실행하지도 않습니다.

역할 / Semantics#

없습니다. Web 은 <span> 을 내보내고 그 안의 Kbd 도 키 캡과 구분자를 각각 <span> 으로 렌더합니다 — 네이티브 <kbd> 요소가 아니며 role 이나 aria-* 도 설정하지 않습니다. Flutter 는 Kbd → Row/Container/Text 로 내려가며 Semantics 를 붙이지 않습니다. 리더 입장에서는 상자로 그려진 평범한 텍스트입니다.

키보드#

없습니다. KeyboardShortcut.fromActivator 는 Flutter ShortcutActivator표시 문자열로 변환할 뿐이고, 어떤 키 이벤트도 수신하지 않습니다.

포커스#

없습니다. 포커스 대상이 아니며 tab 으로 도달하지 않습니다.

스크린 리더#

키 라벨을 순서대로 평범한 텍스트로 읽습니다. + 구분자는 양쪽 플랫폼 모두 실제 텍스트 노드라 키 사이에서 문자 그대로 읽힙니다. fromActivator 가 만들어내는 기호 치환( )은 대체 텍스트 없이 그 글리프 그대로 나가므로, 어떻게 발음되는지는 리더에 달려 있습니다.

알려진 제약#

  • aria-keyshortcuts 를 내보내지 않고, <kbd> 요소의 시맨틱도 없으며, 키 조합 전체에 대한 접근 가능한 이름도 없습니다(캡마다 별도 텍스트 노드입니다).
  • 실제 키 바인딩은 호출자 몫입니다. 이 표시를 붙인 컨트롤이 단축키를 알리게 하려면 aria-keyshortcuts 를 그 컨트롤 쪽에 직접 넣고, 키 처리도 직접 등록해야 합니다.
  • KeyboardShortcutDisplayMapper 는 Flutter 전용이며 키별 display builder 를 주입하는 표시 plumbing 입니다 — 키 바인딩이 아니고 Web 대응도 없습니다.

관련 컴포넌트#

  • Kbd: 단일 키 박스 컴포넌트 — KeyboardShortcut 의 내부 building block
  • Tooltip: 호버 시 단축키 안내
  • Menu: 메뉴 항목 trailing 으로 단축키 표시