From 332c6c08d73ebdbffc18e1f196962eaa76e7a8dc Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 31 Oct 2024 19:14:15 +0500 Subject: [PATCH] feat(Kbd): special keys for macOS and other systems (#2494) Co-authored-by: Benjamin Canac --- docs/content/3.components/kbd.md | 3 +- src/runtime/composables/defineShortcuts.ts | 8 - src/runtime/composables/useKbd.ts | 32 +++- .../CommandPalette-vue.spec.ts.snap | 162 +++++++++--------- .../__snapshots__/CommandPalette.spec.ts.snap | 162 +++++++++--------- .../DropdownMenu-vue.spec.ts.snap | 90 +++++----- .../__snapshots__/DropdownMenu.spec.ts.snap | 90 +++++----- .../__snapshots__/Tooltip-vue.spec.ts.snap | 2 +- .../__snapshots__/Tooltip.spec.ts.snap | 2 +- 9 files changed, 283 insertions(+), 268 deletions(-) diff --git a/docs/content/3.components/kbd.md b/docs/content/3.components/kbd.md index 0f8375f7..0f7b41f9 100644 --- a/docs/content/3.components/kbd.md +++ b/docs/content/3.components/kbd.md @@ -31,7 +31,7 @@ props: --- :: -You can pass special keys to the `value` prop that goes through the [`useKbd`](https://github.com/nuxt/ui/blob/v3/src/runtime/composables/useKbd.ts) composable. For example, the `meta` key displays as `⌘` on macOS and `Ctrl` on other platforms. +You can pass special keys to the `value` prop that goes through the [`useKbd`](https://github.com/nuxt/ui/blob/v3/src/runtime/composables/useKbd.ts) composable. For example, the `meta` key displays as `⌘` on macOS and `⊞` on other platforms. ::component-code --- @@ -40,6 +40,7 @@ props: items: value: - meta + - win - command - shift - ctrl diff --git a/src/runtime/composables/defineShortcuts.ts b/src/runtime/composables/defineShortcuts.ts index dcbf5f3c..d990e7b6 100644 --- a/src/runtime/composables/defineShortcuts.ts +++ b/src/runtime/composables/defineShortcuts.ts @@ -3,7 +3,6 @@ import { ref, computed, toValue } from 'vue' import type { MaybeRef } from 'vue' import { useEventListener, useActiveElement, useDebounceFn } from '@vueuse/core' -import { useKbd } from '../composables/useKbd' type Handler = (e?: any) => void @@ -67,7 +66,6 @@ export function defineShortcuts(config: MaybeRef, options: Shor } const debouncedClearChainedInput = useDebounceFn(clearChainedInput, options.chainDelay ?? 800) - const { macOS } = useKbd() const activeElement = useActiveElement() const onKeyDown = (e: KeyboardEvent) => { @@ -180,12 +178,6 @@ export function defineShortcuts(config: MaybeRef, options: Shor } shortcut.chained = chained - // Convert Meta to Ctrl for non-MacOS - if (!macOS.value && shortcut.metaKey && !shortcut.ctrlKey) { - shortcut.metaKey = false - shortcut.ctrlKey = true - } - // Retrieve handler function if (typeof shortcutConfig === 'function') { shortcut.handler = shortcutConfig diff --git a/src/runtime/composables/useKbd.ts b/src/runtime/composables/useKbd.ts index f393fafc..ab1173d4 100644 --- a/src/runtime/composables/useKbd.ts +++ b/src/runtime/composables/useKbd.ts @@ -1,13 +1,20 @@ import { createSharedComposable } from '@vueuse/core' import { ref, computed, onMounted } from 'vue' +type KbdSpecificMap = { + meta: string + alt: string + ctrl: string +} + export const kbdKeysMap = { meta: '', + ctrl: '', + alt: '', + win: '⊞', command: '⌘', shift: '⇧', - ctrl: '⌃', option: '⌥', - alt: '⎇', enter: '↵', delete: '⌦', backspace: '⌫', @@ -24,7 +31,21 @@ export const kbdKeysMap = { end: '↘' } +export const kbdKeysSpecificMap: Record<'macOS' | 'other', KbdSpecificMap> = { + macOS: { + meta: kbdKeysMap.command, + alt: kbdKeysMap.option, + ctrl: '⌃' + }, + other: { + meta: kbdKeysMap.win, + alt: 'alt', + ctrl: 'ctrl' + } +} + export type KbdKey = keyof typeof kbdKeysMap +export type KbdKeySpecific = keyof KbdSpecificMap const _useKbd = () => { const macOS = computed(() => import.meta.client && navigator && navigator.userAgent && navigator.userAgent.match(/Macintosh;/)) @@ -32,15 +53,16 @@ const _useKbd = () => { const metaSymbol = ref(' ') onMounted(() => { - metaSymbol.value = macOS.value ? kbdKeysMap.command : kbdKeysMap.ctrl + metaSymbol.value = getKbdKey('meta')! }) function getKbdKey(value?: KbdKey | string) { if (!value) { return } - if (value === 'meta') { - return metaSymbol.value + + if (['meta', 'alt', 'ctrl'].includes(value)) { + return kbdKeysSpecificMap[macOS.value ? 'macOS' : 'other'][value as KbdKeySpecific] } return kbdKeysMap[value as KbdKey] || value.toUpperCase() diff --git a/test/components/__snapshots__/CommandPalette-vue.spec.ts.snap b/test/components/__snapshots__/CommandPalette-vue.spec.ts.snap index d8a2f3d8..55e947dd 100644 --- a/test/components/__snapshots__/CommandPalette-vue.spec.ts.snap +++ b/test/components/__snapshots__/CommandPalette-vue.spec.ts.snap @@ -11,16 +11,16 @@ exports[`CommandPalette > renders with as correctly 1`] = `