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());