diff --git a/apps/mana/apps/web/src/lib/search/engine.svelte.ts b/apps/mana/apps/web/src/lib/search/engine.svelte.ts
index 0ed7baa3b..d552b0ae3 100644
--- a/apps/mana/apps/web/src/lib/search/engine.svelte.ts
+++ b/apps/mana/apps/web/src/lib/search/engine.svelte.ts
@@ -6,8 +6,7 @@
import { SearchRegistry } from './registry';
import type { GroupedSearchResults } from './types';
-
-const DEBOUNCE_MS = 150;
+import { SEARCH_DEBOUNCE_MS as DEBOUNCE_MS } from '@mana/shared-ui';
export function createSearchEngine() {
const registry = new SearchRegistry();
diff --git a/packages/shared-ui/src/command-bar/CommandBar.svelte b/packages/shared-ui/src/command-bar/CommandBar.svelte
index 9a72b8446..c0162f40c 100644
--- a/packages/shared-ui/src/command-bar/CommandBar.svelte
+++ b/packages/shared-ui/src/command-bar/CommandBar.svelte
@@ -2,47 +2,9 @@
import { goto } from '$app/navigation';
import type { CommandBarItem, QuickAction, CreatePreview } from './CommandBar.types';
import { Heart, MagnifyingGlass, Plus } from '@mana/shared-icons';
+ import { getHighlightPatterns, highlightText, SEARCH_DEBOUNCE_MS } from '../search-core';
- // Syntax highlighting patterns for command keywords
- interface HighlightPattern {
- pattern: RegExp;
- className: string;
- }
-
- const HIGHLIGHT_PATTERNS: HighlightPattern[] = [
- // Priority keywords (Todo) - with specific colors per level
- { pattern: /(!{3,}|!?dringend)\b/gi, className: 'hl-priority-urgent' },
- { pattern: /(!{2}|!?wichtig)\b/gi, className: 'hl-priority-high' },
- { pattern: /!?normal\b/gi, className: 'hl-priority-medium' },
- { pattern: /!?sp[aä]ter\b/gi, className: 'hl-priority-low' },
- // Tags
- { pattern: /#\w+/g, className: 'hl-tag' },
- // Projects/Calendars/Companies (@reference)
- { pattern: /@\w+/g, className: 'hl-reference' },
- // Date keywords
- {
- pattern:
- /\b(heute|morgen|übermorgen|montag|dienstag|mittwoch|donnerstag|freitag|samstag|sonntag|nächsten?\s+\w+|in\s+\d+\s+tagen?)\b/gi,
- className: 'hl-date',
- },
- // Time patterns
- { pattern: /\b(\d{1,2}:\d{2}|um\s+\d{1,2}(\s*uhr)?|\d{1,2}\s*uhr)\b/gi, className: 'hl-time' },
- ];
-
- function highlightText(text: string): string {
- if (!text) return '';
-
- let result = text;
- // Escape HTML first
- result = result.replace(/&/g, '&').replace(//g, '>');
-
- // Apply highlights (process in order, avoiding double-highlighting)
- for (const { pattern, className } of HIGHLIGHT_PATTERNS) {
- result = result.replace(pattern, (match) => `${match}`);
- }
-
- return result;
- }
+ const HIGHLIGHT_PATTERNS = getHighlightPatterns('de');
interface Props {
open: boolean;
@@ -89,7 +51,7 @@
);
// Highlighted text for overlay
- let highlightedQuery = $derived(highlightText(searchQuery));
+ let highlightedQuery = $derived(highlightText(searchQuery, HIGHLIGHT_PATTERNS));
// Check if create option is selected (it's always first when available)
let isCreateSelected = $derived(selectedIndex === 0 && createPreview !== null);
@@ -126,7 +88,7 @@
} finally {
loading = false;
}
- }, 150);
+ }, SEARCH_DEBOUNCE_MS);
}
async function handleCreate() {
diff --git a/packages/shared-ui/src/index.ts b/packages/shared-ui/src/index.ts
index 40cadac0b..7abfb218b 100644
--- a/packages/shared-ui/src/index.ts
+++ b/packages/shared-ui/src/index.ts
@@ -185,13 +185,11 @@ export {
createInputBarSettingsStore,
getInputBarSettingsStore,
} from './quick-input';
-export type {
- QuickInputItem,
- QuickAction,
- CreatePreview,
- HighlightPattern,
- InputBarSettings,
-} from './quick-input';
+export type { QuickInputItem, QuickAction, CreatePreview, InputBarSettings } from './quick-input';
+
+// Shared search/command core — highlight patterns, debounce, common helpers.
+export { getHighlightPatterns, highlightText, SEARCH_DEBOUNCE_MS } from './search-core';
+export type { HighlightPattern } from './search-core';
// Pages
export { default as AppsPage } from './pages/AppsPage.svelte';
diff --git a/packages/shared-ui/src/navigation/GlobalSpotlight.svelte b/packages/shared-ui/src/navigation/GlobalSpotlight.svelte
index 574cbed14..1c246cabb 100644
--- a/packages/shared-ui/src/navigation/GlobalSpotlight.svelte
+++ b/packages/shared-ui/src/navigation/GlobalSpotlight.svelte
@@ -7,6 +7,7 @@
ContentSearcher,
} from './types';
import { createAppNavigationStore } from './appNavigationStore.svelte';
+ import { SEARCH_DEBOUNCE_MS } from '../search-core';
interface Props {
open: boolean;
@@ -160,7 +161,7 @@
contentLoading = false;
}
}
- }, 150);
+ }, SEARCH_DEBOUNCE_MS);
});
// Group results by category for display
diff --git a/packages/shared-ui/src/quick-input/InputBar.svelte b/packages/shared-ui/src/quick-input/InputBar.svelte
index b2d8145e9..e6edf99ed 100644
--- a/packages/shared-ui/src/quick-input/InputBar.svelte
+++ b/packages/shared-ui/src/quick-input/InputBar.svelte
@@ -1,29 +1,15 @@