@limetech/lime-elements
Version:
127 lines (122 loc) • 5.73 kB
JavaScript
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 = () => ` "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 };