diff --git a/ui/src/components/FilterBar.tsx b/ui/src/components/FilterBar.tsx index 96a05cb..6822d6b 100644 --- a/ui/src/components/FilterBar.tsx +++ b/ui/src/components/FilterBar.tsx @@ -15,6 +15,8 @@ import { total, } from "../stores/messages"; +const TAG_SEARCH_THRESHOLD = 8; + function Chip(props: { label: string; active: boolean; @@ -42,9 +44,16 @@ function Chip(props: { function TagDropdown() { const [open, setOpen] = createSignal(false); const [pos, setPos] = createSignal({ top: 0, left: 0 }); + const [tagQuery, setTagQuery] = createSignal(""); let triggerRef: HTMLButtonElement | undefined; let dropdownRef: HTMLDivElement | undefined; + const visibleTags = () => { + const q = tagQuery().trim().toLowerCase(); + const tags = allTags(); + return q ? tags.filter((t) => t.toLowerCase().includes(q)) : tags; + }; + function updatePosition() { if (!triggerRef) return; const rect = triggerRef.getBoundingClientRect(); @@ -74,6 +83,7 @@ function TagDropdown() { open, (isOpen) => { if (isOpen) { + setTagQuery(""); updatePosition(); window.addEventListener("scroll", updatePosition, true); window.addEventListener("resize", updatePosition); @@ -157,51 +167,72 @@ function TagDropdown() { } > + TAG_SEARCH_THRESHOLD}> +
+ queueMicrotask(() => el.focus())} + value={tagQuery()} + onInput={(e) => setTagQuery(e.currentTarget.value)} + placeholder="Filter tags..." + class="w-full rounded-md border border-zinc-200 dark:border-zinc-700 bg-zinc-50 dark:bg-zinc-800/50 px-2 py-1 text-xs text-zinc-700 dark:text-zinc-300 placeholder-zinc-400 dark:placeholder-zinc-500 outline-none focus:border-zinc-400 dark:focus:border-zinc-600" + /> +
+
- - {(tag) => { - const isSelected = () => filters().tags.includes(tag); - return ( - - ); - }} - +
+ + + + + +
+ + {tag} + + + ); + }} + +
0}>
diff --git a/ui/src/index.css b/ui/src/index.css index 8cfbb61..fb2cfc7 100644 --- a/ui/src/index.css +++ b/ui/src/index.css @@ -12,6 +12,11 @@ font-family: var(--font-brand); } +.theme-switching, +.theme-switching * { + transition: none !important; +} + .mesh-glow { position: fixed; top: 0; diff --git a/ui/src/stores/theme.ts b/ui/src/stores/theme.ts index 4dde554..e6424ce 100644 --- a/ui/src/stores/theme.ts +++ b/ui/src/stores/theme.ts @@ -21,7 +21,11 @@ function resolve(t: Theme): "dark" | "light" { } function applyTheme(t: Theme) { - document.documentElement.classList.toggle("dark", resolve(t) === "dark"); + const root = document.documentElement; + root.classList.add("theme-switching"); + root.classList.toggle("dark", resolve(t) === "dark"); + void root.offsetHeight; + root.classList.remove("theme-switching"); } applyTheme(theme());