mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-22 06:06:42 +02:00
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>
This commit is contained in:
parent
1ff172fc8d
commit
9e7113982e
8 changed files with 849 additions and 11 deletions
174
packages/shared-ui/src/quick-input/InputBarContextMenu.svelte
Normal file
174
packages/shared-ui/src/quick-input/InputBarContextMenu.svelte
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
<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} />
|
||||
Loading…
Add table
Add a link
Reference in a new issue