-
- (commandBarOpen = false)}
- onSearch={handleCommandBarSearch}
- onSelect={handleCommandBarSelect}
- quickActions={commandBarQuickActions}
- placeholder="Termin suchen oder erstellen..."
+
+
@@ -371,12 +375,37 @@
transition: all 300ms ease;
position: relative;
z-index: 0;
+ /* Space for QuickInputBar at bottom */
+ padding-bottom: calc(80px + env(safe-area-inset-bottom));
}
.main-content.floating-mode {
padding-top: 70px;
}
+ /* Extra padding when DateStrip + Toolbar are at bottom */
+ .main-content.floating-mode.has-toolbar {
+ padding-top: 0;
+ padding-bottom: calc(
+ 280px + env(safe-area-inset-bottom)
+ ); /* DateStrip + Toolbar + PillNav + QuickInputBar */
+ }
+
+ @media (max-width: 768px) {
+ /* On mobile, toolbars are at bottom, extra padding at bottom instead */
+ .main-content {
+ padding-bottom: calc(150px + env(safe-area-inset-bottom)); /* PillNav + QuickInputBar */
+ }
+ .main-content.has-toolbar {
+ padding-bottom: calc(
+ 250px + env(safe-area-inset-bottom)
+ ); /* DateStrip + Toolbar + BottomNav + QuickInputBar */
+ }
+ .main-content.floating-mode.has-toolbar {
+ padding-top: 70px;
+ }
+ }
+
.main-content.sidebar-mode {
padding-left: 180px;
}
diff --git a/apps/contacts/apps/web/src/lib/components/ContactsToolbar.svelte b/apps/contacts/apps/web/src/lib/components/ContactsToolbar.svelte
new file mode 100644
index 000000000..2e30f283e
--- /dev/null
+++ b/apps/contacts/apps/web/src/lib/components/ContactsToolbar.svelte
@@ -0,0 +1,274 @@
+
+
+
+
+ goto('/contacts/new')} title={$_('contacts.new')}>
+
+ {$_('contacts.new')}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {#if favoritesCount > 0}
+ {favoritesCount}
+ {/if}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/contacts/apps/web/src/routes/(app)/+layout.svelte b/apps/contacts/apps/web/src/routes/(app)/+layout.svelte
index 0a8871350..df28a0743 100644
--- a/apps/contacts/apps/web/src/routes/(app)/+layout.svelte
+++ b/apps/contacts/apps/web/src/routes/(app)/+layout.svelte
@@ -3,11 +3,11 @@
import { page } from '$app/stores';
import { onMount } from 'svelte';
import { locale } from 'svelte-i18n';
- import { PillNavigation, CommandBar } from '@manacore/shared-ui';
+ import { PillNavigation, QuickInputBar } from '@manacore/shared-ui';
import type {
PillNavItem,
PillDropdownItem,
- CommandBarItem,
+ QuickInputItem,
QuickAction,
CreatePreview,
} from '@manacore/shared-ui';
@@ -39,9 +39,6 @@
formatParsedContactPreview,
} from '$lib/utils/contact-parser';
- // Search modal state
- let searchModalOpen = $state(false);
-
// Tags state for Quick-Create
let availableTags = $state<{ id: string; name: string }[]>([]);
@@ -130,13 +127,6 @@
function handleKeydown(event: KeyboardEvent) {
const target = event.target as HTMLElement;
- // Cmd/Ctrl+K to open search (works even in inputs)
- if ((event.ctrlKey || event.metaKey) && event.key === 'k') {
- event.preventDefault();
- searchModalOpen = true;
- return;
- }
-
if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {
return;
}
@@ -188,8 +178,8 @@
goto('/', { replaceState: false });
}
- // CommandBar search function
- async function handleCommandBarSearch(query: string): Promise {
+ // QuickInputBar search function
+ async function handleSearch(query: string): Promise {
const response = await contactsApi.list({ search: query, limit: 10 });
return (response.contacts || []).map((contact: any) => ({
id: contact.id,
@@ -204,25 +194,25 @@
}));
}
- // CommandBar item selection
- function handleCommandBarSelect(item: CommandBarItem) {
+ // QuickInputBar item selection
+ function handleSelect(item: QuickInputItem) {
goto(`/contacts/${item.id}`);
}
- // CommandBar Quick-Create handlers
- function handleCommandBarParseCreate(query: string): CreatePreview | null {
+ // QuickInputBar Quick-Create handlers
+ function handleParseCreate(query: string): CreatePreview | null {
if (!query.trim()) return null;
const parsed = parseContactInput(query);
if (!parsed.displayName) return null;
return {
- title: parsed.displayName,
+ title: `"${parsed.displayName}" erstellen`,
subtitle: formatParsedContactPreview(parsed),
};
}
- async function handleCommandBarCreate(query: string): Promise {
+ async function handleCreate(query: string): Promise {
const parsed = parseContactInput(query);
if (!parsed.displayName) return;
@@ -250,18 +240,11 @@
}
}
- // CommandBar quick actions
- const commandBarQuickActions: QuickAction[] = [
- {
- id: 'new',
- label: 'Neuen Kontakt erstellen',
- icon: 'plus',
- href: '/contacts/new',
- shortcut: 'N',
- },
- { id: 'favorites', label: 'Favoriten anzeigen', icon: 'heart', href: '/favorites' },
- { id: 'tags', label: 'Tags verwalten', icon: 'tag', href: '/tags' },
- { id: 'import', label: 'Kontakte importieren', icon: 'upload', href: '/data?tab=import' },
+ // QuickInputBar quick actions
+ const quickActions: QuickAction[] = [
+ { id: 'favorites', label: 'Favoriten', icon: 'heart', href: '/favorites' },
+ { id: 'tags', label: 'Tags', icon: 'tag', href: '/tags' },
+ { id: 'settings', label: 'Einstellungen', icon: 'settings', href: '/settings' },
];
onMount(async () => {
@@ -360,20 +343,20 @@
{/if}
-
- (searchModalOpen = false)}
- onSearch={handleCommandBarSearch}
- onSelect={handleCommandBarSelect}
- quickActions={commandBarQuickActions}
- placeholder="Kontakt suchen oder erstellen..."
+
+
diff --git a/apps/todo/apps/web/src/lib/components/TodoToolbar.svelte b/apps/todo/apps/web/src/lib/components/TodoToolbar.svelte
new file mode 100644
index 000000000..01dce8b12
--- /dev/null
+++ b/apps/todo/apps/web/src/lib/components/TodoToolbar.svelte
@@ -0,0 +1,848 @@
+
+
+
+
+
+
+ e.stopPropagation()}>
+
+
+
+ {#if showQuickAddOptions || inputValue.trim()}
+
+
+
+
+
+ {#if showDatePicker}
+
e.stopPropagation()}>
+ {#each dateOptions as option}
+
+ {/each}
+
+ {/if}
+
+
+
+
+
+
+ {#if showPriorityPicker}
+
e.stopPropagation()}>
+ {#each PRIORITY_OPTIONS as priority}
+
+ {/each}
+
+ {/if}
+
+
+
+
+
+
+ {#if showProjectPicker}
+
e.stopPropagation()}>
+
+ {#each projectsStore.activeProjects as project}
+
+ {/each}
+
+ {/if}
+
+
+
+
+
+ {/if}
+
+
+
+
+
+ goto('/kanban')} title="Kanban-Ansicht">
+
+
+
+
+
+
+ e.stopPropagation()}>
+
{
+ showFilterDropdown = !showFilterDropdown;
+ closeAllDropdowns();
+ }}
+ active={activeFilterCount > 0}
+ title="Filter"
+ >
+
+ {#if activeFilterCount > 0}
+ {activeFilterCount}
+ {/if}
+
+
+ {#if showFilterDropdown}
+
e.stopPropagation()}>
+
+
+
+ {#each priorities as priority}
+
+ {/each}
+
+
+
+
+
+
+
+
+ {#if activeFilterCount > 0}
+
+ {/if}
+
+ {/if}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/todo/apps/web/src/routes/(app)/+layout.svelte b/apps/todo/apps/web/src/routes/(app)/+layout.svelte
index 8b909f30a..dad2bb8c9 100644
--- a/apps/todo/apps/web/src/routes/(app)/+layout.svelte
+++ b/apps/todo/apps/web/src/routes/(app)/+layout.svelte
@@ -3,11 +3,11 @@
import { page } from '$app/stores';
import { onMount } from 'svelte';
import { locale } from 'svelte-i18n';
- import { PillNavigation, CommandBar } from '@manacore/shared-ui';
+ import { PillNavigation, QuickInputBar } from '@manacore/shared-ui';
import type {
PillNavItem,
PillDropdownItem,
- CommandBarItem,
+ QuickInputItem,
QuickAction,
CreatePreview,
} from '@manacore/shared-ui';
@@ -38,19 +38,15 @@
let { children } = $props();
- // CommandBar state
- let commandBarOpen = $state(false);
-
- // CommandBar quick actions
- const commandBarQuickActions: QuickAction[] = [
- { id: 'new', label: 'Neue Aufgabe erstellen', icon: 'plus', href: '/task/new', shortcut: 'N' },
- { id: 'kanban', label: 'Kanban-Board', icon: 'list', href: '/kanban' },
- { id: 'stats', label: 'Statistiken', icon: 'chart', href: '/statistics' },
+ // QuickInputBar quick actions
+ const quickActions: QuickAction[] = [
+ { id: 'kanban', label: 'Kanban', icon: 'kanban', href: '/kanban' },
+ { id: 'stats', label: 'Statistik', icon: 'chart', href: '/statistics' },
{ id: 'settings', label: 'Einstellungen', icon: 'settings', href: '/settings' },
];
- // CommandBar search - search tasks
- async function handleCommandBarSearch(query: string): Promise {
+ // QuickInputBar search - search tasks
+ async function handleSearch(query: string): Promise {
if (!query.trim()) return [];
try {
@@ -69,25 +65,25 @@
}
}
- function handleCommandBarSelect(item: CommandBarItem) {
+ function handleSelect(item: QuickInputItem) {
goto(`/task/${item.id}`);
}
- // CommandBar create - parse input and show preview
- function handleCommandBarParseCreate(query: string): CreatePreview | null {
+ // QuickInputBar create - parse input and show preview
+ function handleParseCreate(query: string): CreatePreview | null {
if (!query.trim()) return null;
const parsed = parseTaskInput(query);
const preview = formatParsedTaskPreview(parsed);
return {
- title: `"${parsed.title}" als Aufgabe erstellen`,
+ title: `"${parsed.title}" erstellen`,
subtitle: preview || 'Neue Aufgabe',
};
}
- // CommandBar create - actually create the task
- async function handleCommandBarCreate(query: string): Promise {
+ // QuickInputBar create - actually create the task
+ async function handleCreate(query: string): Promise {
if (!query.trim()) return;
const parsed = parseTaskInput(query);
@@ -192,13 +188,6 @@
function handleKeydown(event: KeyboardEvent) {
const target = event.target as HTMLElement;
- // Cmd/Ctrl+K to open command bar (works even in inputs)
- if ((event.ctrlKey || event.metaKey) && event.key === 'k') {
- event.preventDefault();
- commandBarOpen = true;
- return;
- }
-
if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {
return;
}
@@ -366,20 +355,20 @@
-
-