Kbd
kbd.svelteA keycap badge for keyboard shortcuts and hotkey hints.
Demo
Default: ⌘ K Ctrl Shift P
Bracket: [Enter] [Esc] [:w]
Subtle: Tab Space
Usage
001 <script lang="ts">
002 import Kbd from '$lib/components/kbd.svelte';
003 </script>
004
005 <div class="flex flex-wrap items-center gap-4">
006 <div class="flex items-center gap-2">
007 <span class="opacity-70">Default:</span>
008 <Kbd>⌘</Kbd>
009 <Kbd>K</Kbd>
010 <Kbd>Ctrl</Kbd>
011 <Kbd>Shift</Kbd>
012 <Kbd>P</Kbd>
013 </div>
014
015 <div class="flex items-center gap-2">
016 <span class="opacity-70">Bracket:</span>
017 <Kbd variant="bracket">Enter</Kbd>
018 <Kbd variant="bracket">Esc</Kbd>
019 <Kbd variant="bracket">:w</Kbd>
020 </div>
021
022 <div class="flex items-center gap-2">
023 <span class="opacity-70">Subtle:</span>
024 <Kbd variant="subtle">Tab</Kbd>
025 <Kbd variant="subtle">Space</Kbd>
026 </div>
027 </div>
028
kbd.svelte
001 <script lang="ts" module>
002 import type { HTMLAttributes } from 'svelte/elements';
003
004 export type KbdProps = HTMLAttributes<HTMLElement> & {
005 ref?: HTMLElement | null;
006 variant?: 'default' | 'bracket' | 'subtle';
007 };
008 </script>
009
010 <script lang="ts">
011 let {
012 ref = $bindable(null),
013 variant = 'default',
014 class: className = '',
015 children,
016 ...restProps
017 }: KbdProps = $props();
018 </script>
019
020 <kbd bind:this={ref} class="kbd {variant} {className}" {...restProps}>
021 {#if variant === 'bracket'}[{/if}{@render children?.()}{#if variant === 'bracket'}]{/if}
022 </kbd>
023
024 <style>
025 .kbd {
026 display: inline-flex;
027 align-items: center;
028 justify-content: center;
029 font-family: var(--font-family-mono);
030 font-size: var(--font-size);
031 line-height: var(--line);
032 height: var(--line);
033 padding: 0 0.5ch;
034 color: var(--text-primary);
035 vertical-align: baseline;
036 user-select: none;
037 box-sizing: border-box;
038 }
039
040 .kbd.default {
041 background: color-mix(in srgb, var(--surface-base) 80%, var(--border-default) 20%);
042 box-shadow: inset 0 0 0 1px var(--border-default);
043 }
044
045 .kbd.bracket {
046 background: transparent;
047 box-shadow: none;
048 padding: 0 0.25ch;
049 color: var(--button-muted);
050 }
051
052 .kbd.subtle {
053 background: transparent;
054 box-shadow: inset 0 0 0 1px var(--border-muted);
055 opacity: 0.8;
056 }
057 </style>
058