Files
zeroclock/src/components/KeyboardShortcutsDialog.vue
Your Name 514090eed4 feat: tooltips, two-column timer, font selector, tray behavior, icons, readme
- Custom tooltip directive (WCAG AAA) on every button in the app
- Two-column timer layout with sticky hero and recent entries sidebar
- Timer font selector with 16 monospace Google Fonts and live preview
- UI font selector with 15+ Google Fonts
- Close-to-tray and minimize-to-tray settings
- New app icons (no-glow variants), platform icon set
- Mini timer pop-out window
- Favorites strip with drag-reorder and inline actions
- Comprehensive README with feature documentation
- Remove tracked files that belong in gitignore
2026-02-21 01:15:57 +02:00

96 lines
3.0 KiB
Vue

<script setup lang="ts">
import { watch, ref } from 'vue'
import { useFocusTrap } from '../utils/focusTrap'
const props = defineProps<{ show: boolean }>()
const emit = defineEmits<{ close: [] }>()
const { activate, deactivate } = useFocusTrap()
const dialogRef = ref<HTMLElement | null>(null)
watch(() => props.show, (val) => {
if (val) {
setTimeout(() => {
if (dialogRef.value) activate(dialogRef.value, { onDeactivate: () => emit('close') })
}, 50)
} else {
deactivate()
}
})
const groups = [
{
label: 'Global',
shortcuts: [
{ keys: '?', description: 'Show keyboard shortcuts' },
{ keys: 'Ctrl+Shift+T', description: 'Toggle timer' },
{ keys: 'Ctrl+Shift+Z', description: 'Show/focus app' },
{ keys: 'Ctrl+Shift+N', description: 'Quick entry' },
]
},
{
label: 'Timer',
shortcuts: [
{ keys: 'Space', description: 'Start/stop timer (when focused)' },
]
},
{
label: 'Navigation',
shortcuts: [
{ keys: 'Arrow keys', description: 'Navigate tabs, calendar, lists' },
{ keys: 'Enter', description: 'Open/select focused item' },
{ keys: 'Escape', description: 'Close dialog/popover' },
]
},
]
</script>
<template>
<Transition name="modal">
<div
v-if="show"
class="fixed inset-0 bg-black/70 backdrop-blur-[4px] flex items-center justify-center p-4 z-50"
@click.self="emit('close')"
>
<div
ref="dialogRef"
role="dialog"
aria-modal="true"
aria-labelledby="shortcuts-title"
class="bg-bg-surface border border-border-subtle rounded-lg shadow-[0_1px_3px_rgba(0,0,0,0.3)] w-full max-w-md p-6"
>
<h2 id="shortcuts-title" class="text-[1.125rem] font-semibold font-[family-name:var(--font-heading)] text-text-primary mb-4">
Keyboard Shortcuts
</h2>
<div class="space-y-4">
<div v-for="group in groups" :key="group.label">
<h3 class="text-[0.6875rem] text-text-tertiary uppercase tracking-[0.08em] font-medium mb-2">
{{ group.label }}
</h3>
<div class="space-y-1.5">
<div
v-for="shortcut in group.shortcuts"
:key="shortcut.keys"
class="flex items-center justify-between text-[0.8125rem]"
>
<span class="text-text-secondary">{{ shortcut.description }}</span>
<kbd class="px-2 py-0.5 bg-bg-elevated border border-border-subtle rounded text-[0.6875rem] font-mono text-text-primary">
{{ shortcut.keys }}
</kbd>
</div>
</div>
</div>
</div>
<div class="mt-6 flex justify-end">
<button
@click="emit('close')"
class="px-4 py-2 border border-border-subtle text-text-secondary text-[0.8125rem] rounded-lg hover:bg-bg-elevated transition-colors duration-150"
>
Close
</button>
</div>
</div>
</div>
</Transition>
</template>