Kbd#
키보드 키를 시각적으로 표현하는 컴포넌트입니다. 단축키 안내, 도움말 페이지, 커맨드 팔레트 등에서 활용합니다. 양쪽 플랫폼이 동일한 토큰 (labelSmall + mono 패밀리, surfaceContainer 배경, outline 보더,
CoreRadius.radius4) 으로 렌더됩니다.
Live Preview#
class KbdDefaultExample extends StatelessComponent {
const KbdDefaultExample({super.key});
@override
Component build(BuildContext context) {
return const Kbd(keys: ['Ctrl', 'C']);
}
}
class KbdDefaultExample extends StatelessWidget {
const KbdDefaultExample({super.key});
@override
Widget build(BuildContext context) {
return const Kbd(keys: ['Ctrl', 'C']);
}
}
class KbdComboExample extends StatelessComponent {
const KbdComboExample({super.key});
@override
Component build(BuildContext context) {
return const Kbd(keys: ['Ctrl', 'Shift', 'P']);
}
}
class KbdComboExample extends StatelessWidget {
const KbdComboExample({super.key});
@override
Widget build(BuildContext context) {
return const Kbd(keys: ['Ctrl', 'Shift', 'P']);
}
}
class KbdChainExample extends StatelessComponent {
const KbdChainExample({super.key});
@override
Component build(BuildContext context) {
return const Kbd(keys: ['Ctrl', 'C']).withStyle(
const CoreKbdStyle(
keyRadius: CoreBorderRadius.all(CoreRadius.radius9999),
keyBackgroundColor: CoreColor.token(CoreColors.primaryContainer),
keyBorderColor: CoreColor.token(CoreColors.primary),
keyBorderWidth: CoreStrokeWidth.stroke2,
keyPadding: CoreEdgeInsets.symmetric(
horizontal: CoreSpace.space12,
vertical: CoreSpace.space6,
),
keyTextStyle: CoreTextStyle.token(
CoreTextStyles.labelMedium,
color: CoreColor.token(CoreColors.onPrimaryContainer),
),
),
);
}
}
class KbdChainExample extends StatelessWidget {
const KbdChainExample({super.key});
@override
Widget build(BuildContext context) {
return const Kbd(keys: ['Ctrl', 'C']).withStyle(
const CoreKbdStyle(
keyRadius: CoreBorderRadius.all(CoreRadius.radius9999),
keyBackgroundColor: CoreColor.token(CoreColors.primaryContainer),
keyBorderColor: CoreColor.token(CoreColors.primary),
keyBorderWidth: CoreStrokeWidth.stroke2,
keyPadding: CoreEdgeInsets.symmetric(
horizontal: CoreSpace.space12,
vertical: CoreSpace.space6,
),
keyTextStyle: CoreTextStyle.token(
CoreTextStyles.labelMedium,
color: CoreColor.token(CoreColors.onPrimaryContainer),
),
),
);
}
}
사용 시기 (When to Use)#
이 컴포넌트를 사용하세요:
- 단축키나 키보드 조합을 사용자에게 시각적으로 안내할 때
- 도움말 페이지나 온보딩에서 키보드 인터랙션을 설명할 때
- 커맨드 팔레트의 항목 옆에 단축키를 표시할 때
- 접근성 안내 문서에서 키보드 탐색 방법을 설명할 때
대신 다른 컴포넌트를 사용하세요:
CodeSnippet: 여러 줄의 코드나 명령어를 표시할 때Text: 단순 텍스트로 키 이름을 표현해도 충분할 때KeyboardShortcut: 라벨/플랫폼별 표기와 함께 단축키를 표시할 때 (별도 컴포넌트)
기본 사용법 (Basic Usage)#
// 단일 키
const Kbd(keys: ['Ctrl'])
// 키 조합
const Kbd(keys: ['Ctrl', 'C'])
// 복잡한 단축키
const Kbd(keys: ['Ctrl', 'Shift', 'P'])
// 맥 스타일
const Kbd(keys: ['⌘', 'K'])
// 방향키
const Kbd(keys: ['↑'])
// 단일 키 named ctor
Kbd.single(keyText: '⌘')
// 아이콘 글리프 키 named ctor
const Kbd.icon(keyContent: Icon(LucideIcons.cornerDownLeft))
// 단일 키
const Kbd(keys: ['Ctrl'])
// 키 조합
const Kbd(keys: ['Ctrl', 'C'])
// 복잡한 단축키
const Kbd(keys: ['Ctrl', 'Shift', 'P'])
// 맥 스타일
const Kbd(keys: ['⌘', 'K'])
// 단일 키 named ctor
Kbd.single(keyText: '⌘')
// 아이콘 글리프 키 named ctor
const Kbd.icon(keyContent: Icon(LucideIcons.cornerDownLeft))
빠른 오버라이드 (Chain)#
이미 만든 Kbd 인스턴스에 스타일을 빠르게 덧붙이고 싶다면 withStyle 체인을 쓸 수 있습니다. 생성자의 style 슬롯 인자와 동일하게 동작하지만, 이미 구성된 위젯 위에서 바로 이어 쓸 수 있습니다.
class KbdChainExample extends StatelessWidget {
const KbdChainExample({super.key});
@override
Widget build(BuildContext context) {
return const Kbd(keys: ['Ctrl', 'C']).withStyle(
const CoreKbdStyle(
keyRadius: CoreBorderRadius.all(CoreRadius.radius9999),
keyBackgroundColor: CoreColor.token(CoreColors.primaryContainer),
keyBorderColor: CoreColor.token(CoreColors.primary),
keyBorderWidth: CoreStrokeWidth.stroke2,
keyPadding: CoreEdgeInsets.symmetric(
horizontal: CoreSpace.space12,
vertical: CoreSpace.space6,
),
keyTextStyle: CoreTextStyle.token(
CoreTextStyles.labelMedium,
color: CoreColor.token(CoreColors.onPrimaryContainer),
),
),
);
}
}
class KbdChainExample extends StatelessComponent {
const KbdChainExample({super.key});
@override
Component build(BuildContext context) {
return const Kbd(keys: ['Ctrl', 'C']).withStyle(
const CoreKbdStyle(
keyRadius: CoreBorderRadius.all(CoreRadius.radius9999),
keyBackgroundColor: CoreColor.token(CoreColors.primaryContainer),
keyBorderColor: CoreColor.token(CoreColors.primary),
keyBorderWidth: CoreStrokeWidth.stroke2,
keyPadding: CoreEdgeInsets.symmetric(
horizontal: CoreSpace.space12,
vertical: CoreSpace.space6,
),
keyTextStyle: CoreTextStyle.token(
CoreTextStyles.labelMedium,
color: CoreColor.token(CoreColors.onPrimaryContainer),
),
),
);
}
}
Props / Parameters#
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
keys |
List<String> |
필수 | 표시할 키 목록. 여러 키는 + 구분자로 렌더링 |
kbdStyle |
CoreKbdStyle? |
null |
padding / spacing / radius / 색 / 텍스트 chrome override |
keyContent (Widget? / Component?) 는 기본 생성자에는 없고 Kbd.icon(keyContent: …) 전용입니다 — 단일 칩에 아이콘 글리프를 넣어 심볼 텍스트 글리프의 플랫폼별 폰트 fallback 을 피할 때 씁니다.
keys 와 상호배타이며 (Kbd.icon 은 keys 가 빈 목록), copyWith 로도 교체되지 않습니다.
스타일 시스템 (Style System)#
모든 chrome / dimensional / 텍스트 override 는 kbdStyle 슬롯 하나로 흐릅니다.
CoreKbdStyle 필드#
| 필드 | 타입 | 설명 |
|---|---|---|
keyPadding |
CoreEdgeInsets? |
Padding inside each key box. |
keySeparatorSpacing |
double? |
Spacing (logical px) between each key and the
+
separator — rendered as
Row.spacing
(Flutter) / flex container
gap
inline CSS (Web). N-sibling 균등 분포 (Key, +, Key, +, Key) 패턴.
|
keyMinSize |
double? |
Minimum key-box square extent — see [defaultKeyMinSize]. |
keyRadius |
CoreBorderRadius? |
Border radius of key boxes. |
keyBackgroundColor |
CoreColor? |
Background colour of each key box. |
keyBorderColor |
CoreColor? |
Border colour of each key box. |
keyBorderWidth |
double? |
Border stroke width of each key box — see [defaultKeyBorderWidth]. |
keyTextStyle |
CoreTextStyle? |
Text style applied to the key label characters. |
separatorTextStyle |
CoreTextStyle? |
Text style applied to the + separator between keys. |
Resolve chain#
design system default (CoreKbdStyle.defaultX static const)
→ CoreKbdTheme.style // 프로젝트 공통
→ parent component slot override
→ widget.kbdStyle // 인스턴스별
동작 스펙 (Behavior)#
인터랙션#
- 표시 전용 컴포넌트 — 클릭/호버 인터랙션 없음.
레이아웃#
- 루트는
inline-flexrow —key + (sep + spacing) * (n-1)순서로 나열. -
각 키 박스: 최소 정사각
CoreSpace.space20(keyMinSize) + paddingCoreSpace.space4(수직) /CoreSpace.space6(수평). 높이는 내용 + padding 이 하한을 넘으면 그만큼 커집니다. -
보더 1px (
outline), 배경surfaceContainer, 라운드CoreRadius.radius4. -
separator (
+) 는labelMedium토큰 + 좌우CoreSpace.space2간격 (keySeparatorSpacing).
토큰#
| 항목 | Flutter | Web |
|---|---|---|
| 키 폰트 | labelSmall 역할 + CoreFontFamily.mono |
labelSmall 역할 + CoreFontFamily.mono |
| 키 폰트 굵기 | CoreFontWeight.medium |
CoreFontWeight.medium |
| 키 색 | colorScheme.onSurfaceVariant |
text-${cs.onSurfaceVariant} |
| 키 배경 | colorScheme.surfaceContainer |
bg-${cs.surfaceContainer} |
| 키 보더 | colorScheme.outline 1px |
border border-${cs.outline} |
| 키 radius | BorderRadius.circular(CoreRadius.radius4) |
inline border-radius |
| separator 폰트 | labelMedium 역할 |
text-${ts.labelMedium} |
예시 단축키#
// 복사
const Kbd(keys: ['Ctrl', 'C'])
// 붙여넣기
const Kbd(keys: ['Ctrl', 'V'])
// 전체 선택
const Kbd(keys: ['Ctrl', 'A'])
// 커맨드 팔레트 (macOS)
const Kbd(keys: ['⌘', 'K'])
// 저장
const Kbd(keys: ['Ctrl', 'S'])
// 실행 취소
const Kbd(keys: ['Ctrl', 'Z'])
사용 가이드라인 (Usage Guidelines)#
✅ Do#
플랫폼에 따라 다른 키 표기를 사용하세요:
const Kbd(keys: ['⌘', 'K']) // macOS
const Kbd(keys: ['Ctrl', 'K']) // Windows / Linux
KeyboardShortcut 컴포넌트는 platform-aware 자동 매핑을 제공하므로 사용자 OS 자동 분기에는 그쪽이 더 편합니다.
❌ Don't#
4개 이상의 키 조합을 단일 Kbd 에 넣지 마세요. 가독성이 급격히 저하됩니다 (최대 3개 권장).
// ❌
const Kbd(keys: ['Ctrl', 'Alt', 'Shift', 'F5'])
Kbd 를 클릭 가능한 버튼처럼 사용하지 마세요. 표시 전용입니다 — 클릭이 필요하면 Button 을 쓰세요.
접근성 (Accessibility)#
- 표시 전용 — 키보드 포커스 / 인터랙션 대상 아님.
- 스크린 리더는 텍스트로 "Ctrl + C" 처럼 읽도록 의미있는 라벨이 필요하면 부모 컨테이너에
Semantics(label: ...)를 적용하세요.
관련 컴포넌트 (Related Components)#
- CodeSnippet: 여러 줄 코드나 명령어 블록 표시
- KeyboardShortcut: 단축키 + 라벨, platform-aware 매핑
- Tooltip: 아이콘 버튼의 단축키 안내에 함께 사용