managarten/packages/shared-ui/src/quick-input/InputBarContextMenu.svelte
Till-JS 9e7113982e feat(shared-ui): add InputBar context menu with settings
- Add InputBarContextMenu with settings toggles (syntax highlighting, auto-focus)
- Add InputBarHelpModal for keyboard shortcuts and syntax help
- Add inputBarSettings store with localStorage persistence
- Add recentInputHistory store for tracking used tags/references
- Integrate context menu in calendar app with default calendar selection
- Right-click on InputBar opens settings menu

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 22:20:00 +01:00

174 lines
3.8 KiB
Svelte

<script lang="ts">
import { ContextMenu, type ContextMenuItem } from '../context-menu';
import {
HighlighterCircle,
Target,
Calendar,
Trash,
Keyboard,
Question,
} from '@manacore/shared-icons';
import { getInputBarSettingsStore } from './inputBarSettings.svelte';
import { clearRecentHistory } from './recentInputHistory';
interface DefaultOption {
id: string;
label: string;
}
interface Props {
visible: boolean;
x: number;
y: number;
onClose: () => void;
/** Callback when settings change (to update parent component) */
onSettingsChange?: () => void;
/** Callback to show keyboard shortcuts help */
onShowShortcuts?: () => void;
/** Callback to show syntax help */
onShowSyntaxHelp?: () => void;
/** App-specific default options (e.g., calendars for calendar app) */
defaultOptions?: DefaultOption[];
/** Currently selected default option ID */
selectedDefaultId?: string;
/** Label for the default option (e.g., "Standard-Kalender") */
defaultOptionLabel?: string;
/** Callback when default option changes */
onDefaultChange?: (id: string) => void;
}
let {
visible,
x,
y,
onClose,
onSettingsChange,
onShowShortcuts,
onShowSyntaxHelp,
defaultOptions = [],
selectedDefaultId,
defaultOptionLabel = 'Standard',
onDefaultChange,
}: Props = $props();
// Get settings store
const settingsStore = getInputBarSettingsStore();
// Toggle handlers
function toggleSyntaxHighlighting() {
settingsStore.toggle('syntaxHighlighting');
onSettingsChange?.();
}
function toggleAutoFocus() {
settingsStore.toggle('autoFocus');
onSettingsChange?.();
}
function handleClearHistory() {
clearRecentHistory();
onSettingsChange?.();
}
function handleDefaultChange(id: string) {
onDefaultChange?.(id);
}
// Build menu items dynamically
let menuItems = $derived.by((): ContextMenuItem[] => {
const items: ContextMenuItem[] = [];
// === Appearance Settings ===
items.push({
id: 'syntax-highlighting',
label: 'Syntax Highlighting',
icon: HighlighterCircle,
toggle: true,
checked: settingsStore.syntaxHighlighting,
action: toggleSyntaxHighlighting,
});
items.push({
id: 'auto-focus',
label: 'Auto-Focus',
icon: Target,
toggle: true,
checked: settingsStore.autoFocus,
action: toggleAutoFocus,
});
// === App-specific Default Option ===
if (defaultOptions.length > 0 && onDefaultChange) {
items.push({
id: 'divider-defaults',
label: '',
type: 'divider',
});
// Show current selection with submenu-like display
const selectedOption = defaultOptions.find((o) => o.id === selectedDefaultId);
items.push({
id: 'default-option-header',
label: defaultOptionLabel,
icon: Calendar,
disabled: true,
});
// Show options as selectable items
defaultOptions.forEach((option) => {
items.push({
id: `default-${option.id}`,
label: option.label,
toggle: true,
checked: option.id === selectedDefaultId,
action: () => handleDefaultChange(option.id),
});
});
}
// === History ===
items.push({
id: 'divider-history',
label: '',
type: 'divider',
});
items.push({
id: 'clear-history',
label: 'Verlauf löschen',
icon: Trash,
variant: 'danger',
action: handleClearHistory,
});
// === Help ===
items.push({
id: 'divider-help',
label: '',
type: 'divider',
});
if (onShowShortcuts) {
items.push({
id: 'shortcuts',
label: 'Tastenkürzel',
icon: Keyboard,
shortcut: '?',
action: onShowShortcuts,
});
}
if (onShowSyntaxHelp) {
items.push({
id: 'syntax-help',
label: 'Syntax-Hilfe',
icon: Question,
action: onShowSyntaxHelp,
});
}
return items;
});
</script>
<ContextMenu {visible} {x} {y} items={menuItems} {onClose} />