UNPKG

@limetech/lime-elements

Version:
127 lines (122 loc) 5.73 kB
import { r as registerInstance, h, H as Host } from './index-DBTJNfo7.js'; import { t as tokenizeHotkeyString } from './hotkeys-BxrRWYts.js'; import { c as isAppleDevice } from './device-B-tmXAXV.js'; // Note: this function handles the same key aliases as `KEY_ALIASES` in // `../../util/hotkeys.ts`, but maps them to display strings rather than // canonical names. Keep both in sync when adding new aliases. /** * Maps a single hotkey token to its display representation. * * @param token - A single token from `tokenizeHotkeyString` (e.g. `"meta"`, `"k"`, `"+"`). * @param isApple - Whether the current device is an Apple device. * @returns The display string, whether it is a glyph (for styling), * and a human-readable name for screen readers. */ function formatDisplayToken(token, isApple) { const trimmed = (token !== null && token !== void 0 ? token : '').trim(); if (!trimmed) { return { display: '', isGlyph: false, ariaName: '' }; } if (trimmed === '+') { return { display: '+', isGlyph: false, ariaName: 'plus' }; } const lower = trimmed.toLowerCase(); switch (lower) { case 'meta': case 'win': case 'windows': { return isApple ? { display: '⌘', isGlyph: true, ariaName: 'Command' } : { display: '⊞ Win', isGlyph: false, ariaName: 'Windows' }; } case 'cmd': case 'command': { return { display: '⌘', isGlyph: true, ariaName: 'Command' }; } case 'alt': case 'option': { return isApple ? { display: '⌥', isGlyph: true, ariaName: 'Option' } : { display: 'Alt', isGlyph: false, ariaName: 'Alt' }; } case 'shift': { return { display: '⇧', isGlyph: true, ariaName: 'Shift' }; } case 'enter': case 'return': { return { display: '↩', isGlyph: true, ariaName: 'Enter' }; } case 'tab': { return { display: '⇥', isGlyph: true, ariaName: 'Tab' }; } case 'delete': case 'del': case 'backspace': { if (isApple) { return { display: '⌫', isGlyph: true, ariaName: 'Delete' }; } return lower === 'backspace' ? { display: 'Backspace', isGlyph: false, ariaName: 'Backspace', } : { display: 'Del', isGlyph: false, ariaName: 'Delete' }; } case 'ctrl': case 'control': { return isApple ? { display: '⌃', isGlyph: true, ariaName: 'Control' } : { display: 'Ctrl', isGlyph: false, ariaName: 'Control' }; } case 'escape': case 'esc': { return { display: 'Esc', isGlyph: false, ariaName: 'Escape' }; } case 'space': case 'spacebar': { return { display: '␣', isGlyph: true, ariaName: 'Space' }; } case 'arrowup': case 'up': { return { display: '↑', isGlyph: true, ariaName: 'Up' }; } case 'arrowdown': case 'down': { return { display: '↓', isGlyph: true, ariaName: 'Down' }; } case 'arrowleft': case 'left': { return { display: '←', isGlyph: true, ariaName: 'Left' }; } case 'arrowright': case 'right': { return { display: '→', isGlyph: true, ariaName: 'Right' }; } } return { display: trimmed, isGlyph: false, ariaName: trimmed }; } const hotkeyCss = () => `@charset "UTF-8";kbd{display:inline-block;font-family:ui-monospace, "Cascadia Code", "Source Code Pro", Menlo, Consolas, "DejaVu Sans Mono", monospace;font-weight:600;color:rgb(var(--contrast-1100));white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:normal;border-radius:0.125rem;border-style:solid;border-color:rgb(var(--contrast-500));border-width:0 1px 0.1875rem 1px;padding:0.0625rem 0.375rem;margin:0 0.25rem;background-color:rgb(var(--contrast-200));box-shadow:var(--button-shadow-normal), 0 0.625rem 0.375rem -0.5rem rgb(var(--color-black), 0.02), 0 0.025rem 0.5rem 0 rgb(var(--contrast-100)) inset}:host(limel-hotkey){display:flex;align-items:center;justify-content:center;gap:0.25rem}:host(limel-hotkey[disabled]:not([disabled=false])){opacity:0.5}kbd{text-transform:var(--hotkey-text-transform, uppercase);margin:0;font-size:0.75rem;box-shadow:var(--button-shadow-pressed), 0 0.625rem 0.375px -0.5rem rgb(var(--color-black), 0.02), 0 0.025rem 0.5rem 0 rgb(var(--contrast-100)) inset}span{display:inline-block}kbd.is-glyph span{transform:scale(1.2)}`; const Hotkey = class { constructor(hostRef) { registerInstance(this, hostRef); /** * When `true`, the hotkey is rendered in a visually disabled state. */ this.disabled = false; } componentWillLoad() { this.isApple = isAppleDevice(); } render() { const parts = tokenizeHotkeyString(this.value); const displayParts = parts.map((part) => formatDisplayToken(part, this.isApple)); const ariaLabel = displayParts .map((p) => p.ariaName) .filter(Boolean) .join(' '); return (h(Host, { key: 'ab1b9d31080740d19a4633c8c5bc92b02625c111', "aria-label": ariaLabel || undefined }, displayParts.map(({ display, isGlyph }, index) => (h("kbd", { key: `${parts[index]}-${index}`, class: isGlyph ? 'is-glyph' : undefined }, h("span", null, display)))))); } }; Hotkey.style = hotkeyCss(); export { Hotkey as limel_hotkey };