aboutsummaryrefslogtreecommitdiff
path: root/src/lib/CommandPalette
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-03-01 16:04:11 -0800
committerFuwn <[email protected]>2026-03-01 16:04:11 -0800
commit48f0c30d47d62e4f35706edb93a1bb2f97eba14c (patch)
tree44866d7a61adfdf01a780e0108c370294d3db78b /src/lib/CommandPalette
parentchore(biome): re-enable useAltText rule (diff)
downloaddue.moe-48f0c30d47d62e4f35706edb93a1bb2f97eba14c.tar.xz
due.moe-48f0c30d47d62e4f35706edb93a1bb2f97eba14c.zip
chore(biome): enable svelte formatting
Diffstat (limited to 'src/lib/CommandPalette')
-rw-r--r--src/lib/CommandPalette/CommandPalette.svelte216
1 files changed, 108 insertions, 108 deletions
diff --git a/src/lib/CommandPalette/CommandPalette.svelte b/src/lib/CommandPalette/CommandPalette.svelte
index 735941fb..a42fab1a 100644
--- a/src/lib/CommandPalette/CommandPalette.svelte
+++ b/src/lib/CommandPalette/CommandPalette.svelte
@@ -1,137 +1,137 @@
<script lang="ts">
- 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 filtered: (CommandPaletteAction & { id?: string })[] = [];
- let selectedIndex = -1;
- let inputRef: HTMLInputElement;
- let isVisible = false;
- 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))
- );
+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 filtered: (CommandPaletteAction & { id?: string })[] = [];
+let selectedIndex = -1;
+let inputRef: HTMLInputElement;
+let isVisible = false;
+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));
};
- filtered = [];
+ return (
+ doesActionIncludePattern(action.name, search) ||
+ action.tags?.some((tag) => doesActionIncludePattern(tag, search))
+ );
+ };
- items.forEach((action, idx) => {
- const actionMatches = doesActionMatch(action);
- let matchedParent = false;
+ filtered = [];
- if (actionMatches) {
- filtered.push({ ...action, id: `action-${idx}` });
+ items.forEach((action, idx) => {
+ const actionMatches = doesActionMatch(action);
+ let matchedParent = false;
- matchedParent = true;
- }
+ if (actionMatches) {
+ filtered.push({ ...action, id: `action-${idx}` });
- 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}`
- });
- });
- });
+ matchedParent = true;
+ }
- filtered = filtered.slice(0, 10);
- }
+ 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}`
+ });
+ });
+ });
- $: if (selectedIndex >= filtered.length) selectedIndex = filtered.length - 1;
- $: if (selectedIndex < 0 && filtered.length > 0) selectedIndex = 0;
+ filtered = filtered.slice(0, 10);
+}
- $: if (open && !isVisible) {
- isVisible = true;
+$: if (selectedIndex >= filtered.length) selectedIndex = filtered.length - 1;
+$: if (selectedIndex < 0 && filtered.length > 0) selectedIndex = 0;
- if (timeoutID !== null) {
- clearTimeout(timeoutID);
+$: if (open && !isVisible) {
+ isVisible = true;
+ if (timeoutID !== null) {
+ clearTimeout(timeoutID);
+
+ timeoutID = null;
+ }
+} else if (!open && isVisible) {
+ if (timeoutID === null) {
+ timeoutID = setTimeout(() => {
+ isVisible = false;
timeoutID = null;
- }
- } else if (!open && isVisible) {
- if (timeoutID === null) {
- timeoutID = setTimeout(() => {
- isVisible = false;
- timeoutID = null;
- }, 200);
- }
+ }, 200);
}
+}
- const executeItem = (item: CommandPaletteAction) => {
- if (item.onClick) item.onClick();
- if (!item.preventDefault) window.location.href = item.url;
+const executeItem = (item: CommandPaletteAction) => {
+ 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;
- }
- };
+const handleKey = (e: KeyboardEvent) => {
+ if (e.key === 'ArrowDown') {
+ e.preventDefault();
- onMount(() => {
- window.addEventListener('keydown', handleGlobalKey);
+ selectedIndex = (selectedIndex + 1) % filtered.length;
+ } else if (e.key === 'ArrowUp') {
+ e.preventDefault();
- return () => {
- window.removeEventListener('keydown', handleGlobalKey);
+ 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 (timeoutID !== null) clearTimeout(timeoutID);
- };
- });
+onMount(() => {
+ window.addEventListener('keydown', handleGlobalKey);
- const handleClickOutside = (event: MouseEvent) => {
- const target = event.target as HTMLElement;
+ return () => {
+ window.removeEventListener('keydown', handleGlobalKey);
- if (target.classList.contains('command-palette-overlay') || !target.closest('.dropdown'))
- open = false;
+ if (timeoutID !== null) clearTimeout(timeoutID);
};
+});
- const handleGlobalKey = (e: KeyboardEvent) => {
- if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
- e.preventDefault();
+const handleClickOutside = (event: MouseEvent) => {
+ const target = event.target as HTMLElement;
- open = !open;
+ if (target.classList.contains('command-palette-overlay') || !target.closest('.dropdown'))
+ open = false;
+};
- if (open) requestAnimationFrame(() => inputRef?.focus());
- }
- };
+const handleGlobalKey = (e: KeyboardEvent) => {
+ if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
+ e.preventDefault();
+
+ open = !open;
+
+ if (open) requestAnimationFrame(() => inputRef?.focus());
+ }
+};
</script>
<svelte:window onclick={handleClickOutside} />