mirror of
https://github.com/soybeanjs/soybean-admin.git
synced 2025-09-30 15:16:42 +08:00
feat: Add keyboard shortcuts for global search functionality
This commit is contained in:
parent
d08a3817d1
commit
cc345423c3
@ -4,6 +4,7 @@ import { NConfigProvider, darkTheme } from 'naive-ui';
|
|||||||
import { useAppStore } from './store/modules/app';
|
import { useAppStore } from './store/modules/app';
|
||||||
import { useThemeStore } from './store/modules/theme';
|
import { useThemeStore } from './store/modules/theme';
|
||||||
import { naiveDateLocales, naiveLocales } from './locales/naive';
|
import { naiveDateLocales, naiveLocales } from './locales/naive';
|
||||||
|
import { useKeyboardShortcuts } from './utils/keyboard-shortcut';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'App'
|
name: 'App'
|
||||||
@ -21,6 +22,8 @@ const naiveLocale = computed(() => {
|
|||||||
const naiveDateLocale = computed(() => {
|
const naiveDateLocale = computed(() => {
|
||||||
return naiveDateLocales[appStore.locale];
|
return naiveDateLocales[appStore.locale];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useKeyboardShortcuts();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -1,11 +1,34 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useBoolean } from '@sa/hooks';
|
import { useBoolean } from '@sa/hooks';
|
||||||
|
import { onMounted, onUnmounted } from 'vue';
|
||||||
import { $t } from '@/locales';
|
import { $t } from '@/locales';
|
||||||
|
import { useEventBus } from '@/utils/event-bus';
|
||||||
|
import { useAppStore } from '@/store/modules/app';
|
||||||
import SearchModal from './components/search-modal.vue';
|
import SearchModal from './components/search-modal.vue';
|
||||||
|
|
||||||
defineOptions({ name: 'GlobalSearch' });
|
defineOptions({ name: 'GlobalSearch' });
|
||||||
|
|
||||||
const { bool: show, toggle } = useBoolean();
|
const { bool: show, toggle } = useBoolean();
|
||||||
|
|
||||||
|
const eventBus = useEventBus();
|
||||||
|
|
||||||
|
const appStore = useAppStore();
|
||||||
|
|
||||||
|
const checkShow = () => {
|
||||||
|
if (show.value) return;
|
||||||
|
if (appStore.themeDrawerVisible) {
|
||||||
|
appStore.closeThemeDrawer();
|
||||||
|
}
|
||||||
|
toggle();
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
eventBus.on('searchShortcutKey', checkShow);
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
eventBus.off('searchShortcutKey', checkShow);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
34
src/utils/event-bus.ts
Normal file
34
src/utils/event-bus.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { reactive } from 'vue';
|
||||||
|
|
||||||
|
type EventCallback = (...args: any[]) => void;
|
||||||
|
|
||||||
|
interface EventBus {
|
||||||
|
on(event: string, callback: EventCallback): void;
|
||||||
|
off(event: string, callback: EventCallback): void;
|
||||||
|
emit(event: string, ...args: any[]): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventBus = reactive<{
|
||||||
|
events: { [key: string]: EventCallback[] };
|
||||||
|
}>({
|
||||||
|
events: {}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const useEventBus = (): EventBus => {
|
||||||
|
return {
|
||||||
|
on(event: string, callback: EventCallback) {
|
||||||
|
if (!eventBus.events[event]) {
|
||||||
|
eventBus.events[event] = [];
|
||||||
|
}
|
||||||
|
eventBus.events[event].push(callback);
|
||||||
|
},
|
||||||
|
off(event: string, callback: EventCallback) {
|
||||||
|
if (!eventBus.events[event]) return;
|
||||||
|
eventBus.events[event] = eventBus.events[event].filter(cb => cb !== callback);
|
||||||
|
},
|
||||||
|
emit(event: string, ...args: any[]) {
|
||||||
|
if (!eventBus.events[event]) return;
|
||||||
|
eventBus.events[event].forEach(callback => callback(...args));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
31
src/utils/keyboard-shortcut.ts
Normal file
31
src/utils/keyboard-shortcut.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { onMounted, onUnmounted } from 'vue';
|
||||||
|
import { useEventBus } from '@/utils/event-bus';
|
||||||
|
|
||||||
|
type ShortcutHandler = (event: KeyboardEvent) => void;
|
||||||
|
|
||||||
|
const useKeyboardShortcuts = () => {
|
||||||
|
const eventBus = useEventBus();
|
||||||
|
|
||||||
|
const shortcuts: { [key: string]: ShortcutHandler } = {
|
||||||
|
k: (event: KeyboardEvent) => {
|
||||||
|
event.preventDefault();
|
||||||
|
eventBus.emit('searchShortcutKey');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleKeyDown = (event: KeyboardEvent) => {
|
||||||
|
if (event.ctrlKey && shortcuts[event.key]) {
|
||||||
|
shortcuts[event.key](event);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
window.addEventListener('keydown', handleKeyDown);
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
window.removeEventListener('keydown', handleKeyDown);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export { useKeyboardShortcuts };
|
Loading…
Reference in New Issue
Block a user