diff options
| author | Fuwn <[email protected]> | 2026-03-01 16:20:51 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-03-01 16:21:02 -0800 |
| commit | eae5d24d9e79e59a19d4721caaeaa0ca650ecb33 (patch) | |
| tree | 1b685bb248e051dfa26d2bfdebe6689402dd93c5 /src/lib/CommandPalette/CommandPalette.svelte | |
| parent | chore(tooling): remove legacy eslint and prettier (diff) | |
| download | due.moe-eae5d24d9e79e59a19d4721caaeaa0ca650ecb33.tar.xz due.moe-eae5d24d9e79e59a19d4721caaeaa0ca650ecb33.zip | |
chore(biome): drop formatter style overrides
Diffstat (limited to 'src/lib/CommandPalette/CommandPalette.svelte')
| -rw-r--r-- | src/lib/CommandPalette/CommandPalette.svelte | 184 |
1 files changed, 94 insertions, 90 deletions
diff --git a/src/lib/CommandPalette/CommandPalette.svelte b/src/lib/CommandPalette/CommandPalette.svelte index a42fab1a..8ace0222 100644 --- a/src/lib/CommandPalette/CommandPalette.svelte +++ b/src/lib/CommandPalette/CommandPalette.svelte @@ -1,13 +1,13 @@ <script lang="ts"> -import { onMount } from 'svelte'; -import { fly, fade } from 'svelte/transition'; -import { flip } from 'svelte/animate'; -import type { CommandPaletteAction } from './actions'; +import { onMount } from "svelte"; +import { fly, fade } from "svelte/transition"; +import { flip } from "svelte/animate"; +import type { CommandPaletteAction } from "./actions"; export let items: CommandPaletteAction[] = []; export let open = false; -let search = ''; +let search = ""; let filtered: (CommandPaletteAction & { id?: string })[] = []; let selectedIndex = -1; let inputRef: HTMLInputElement; @@ -16,121 +16,125 @@ let timeoutID: ReturnType<typeof setTimeout> | null = null; let itemIDs = new Map<string, number>(); $: { - items.forEach((item, index) => { - if (!itemIDs.has(item.url)) itemIDs.set(item.url, index); - }); - - const doesActionMatch = (action: CommandPaletteAction) => { - const doesActionIncludePattern = (query: string, action: string) => { - const normalise = (input: string) => input.toLowerCase().replace(/\s+/g, ''); - - return normalise(query).includes(normalise(action)); - }; - - return ( - doesActionIncludePattern(action.name, search) || - action.tags?.some((tag) => doesActionIncludePattern(tag, search)) - ); - }; - - filtered = []; - - items.forEach((action, idx) => { - const actionMatches = doesActionMatch(action); - let matchedParent = false; - - if (actionMatches) { - filtered.push({ ...action, id: `action-${idx}` }); - - matchedParent = true; - } - - if (action.actions) - action.actions.forEach((nestedAction, nestedIdx) => { - if (doesActionMatch(nestedAction)) - filtered.push({ - ...nestedAction, - id: `action-${idx}-nested-${nestedIdx}`, - name: `${matchedParent ? '↳' : `${action.name} >`} ${nestedAction.name}` - }); - }); - }); - - filtered = filtered.slice(0, 10); + items.forEach((item, index) => { + if (!itemIDs.has(item.url)) itemIDs.set(item.url, index); + }); + + const doesActionMatch = (action: CommandPaletteAction) => { + const doesActionIncludePattern = (query: string, action: string) => { + const normalise = (input: string) => + input.toLowerCase().replace(/\s+/g, ""); + + return normalise(query).includes(normalise(action)); + }; + + return ( + doesActionIncludePattern(action.name, search) || + action.tags?.some((tag) => doesActionIncludePattern(tag, search)) + ); + }; + + filtered = []; + + items.forEach((action, idx) => { + const actionMatches = doesActionMatch(action); + let matchedParent = false; + + if (actionMatches) { + filtered.push({ ...action, id: `action-${idx}` }); + + matchedParent = true; + } + + if (action.actions) + action.actions.forEach((nestedAction, nestedIdx) => { + if (doesActionMatch(nestedAction)) + filtered.push({ + ...nestedAction, + id: `action-${idx}-nested-${nestedIdx}`, + name: `${matchedParent ? "↳" : `${action.name} >`} ${nestedAction.name}`, + }); + }); + }); + + filtered = filtered.slice(0, 10); } $: if (selectedIndex >= filtered.length) selectedIndex = filtered.length - 1; $: if (selectedIndex < 0 && filtered.length > 0) selectedIndex = 0; $: if (open && !isVisible) { - isVisible = true; + isVisible = true; - if (timeoutID !== null) { - clearTimeout(timeoutID); + if (timeoutID !== null) { + clearTimeout(timeoutID); - timeoutID = null; - } + timeoutID = null; + } } else if (!open && isVisible) { - if (timeoutID === null) { - timeoutID = setTimeout(() => { - isVisible = false; - timeoutID = null; - }, 200); - } + if (timeoutID === null) { + timeoutID = setTimeout(() => { + isVisible = false; + timeoutID = null; + }, 200); + } } const executeItem = (item: CommandPaletteAction) => { - if (item.onClick) item.onClick(); - if (!item.preventDefault) window.location.href = item.url; + if (item.onClick) item.onClick(); + if (!item.preventDefault) window.location.href = item.url; - open = false; + open = false; }; const handleKey = (e: KeyboardEvent) => { - if (e.key === 'ArrowDown') { - e.preventDefault(); - - selectedIndex = (selectedIndex + 1) % filtered.length; - } else if (e.key === 'ArrowUp') { - e.preventDefault(); - - selectedIndex = (selectedIndex - 1 + filtered.length) % filtered.length; - } else if (e.key === 'Enter') { - if (filtered.length === 1) { - executeItem(filtered[0]); - } else if (filtered.length > 1 && selectedIndex >= 0) { - executeItem(filtered[selectedIndex]); - } - } else if (e.key === 'Escape') { - open = false; - } + if (e.key === "ArrowDown") { + e.preventDefault(); + + selectedIndex = (selectedIndex + 1) % filtered.length; + } else if (e.key === "ArrowUp") { + e.preventDefault(); + + selectedIndex = (selectedIndex - 1 + filtered.length) % filtered.length; + } else if (e.key === "Enter") { + if (filtered.length === 1) { + executeItem(filtered[0]); + } else if (filtered.length > 1 && selectedIndex >= 0) { + executeItem(filtered[selectedIndex]); + } + } else if (e.key === "Escape") { + open = false; + } }; onMount(() => { - window.addEventListener('keydown', handleGlobalKey); + window.addEventListener("keydown", handleGlobalKey); - return () => { - window.removeEventListener('keydown', handleGlobalKey); + return () => { + window.removeEventListener("keydown", handleGlobalKey); - if (timeoutID !== null) clearTimeout(timeoutID); - }; + if (timeoutID !== null) clearTimeout(timeoutID); + }; }); const handleClickOutside = (event: MouseEvent) => { - const target = event.target as HTMLElement; + const target = event.target as HTMLElement; - if (target.classList.contains('command-palette-overlay') || !target.closest('.dropdown')) - open = false; + if ( + target.classList.contains("command-palette-overlay") || + !target.closest(".dropdown") + ) + open = false; }; const handleGlobalKey = (e: KeyboardEvent) => { - if ((e.metaKey || e.ctrlKey) && e.key === 'k') { - e.preventDefault(); + if ((e.metaKey || e.ctrlKey) && e.key === "k") { + e.preventDefault(); - open = !open; + open = !open; - if (open) requestAnimationFrame(() => inputRef?.focus()); - } + if (open) requestAnimationFrame(() => inputRef?.focus()); + } }; </script> |