BlueSky & more on desktop
lazurite.stormlightlabs.org/
tauri
rust
typescript
bluesky
appview
atproto
solid
1import { Icon, SearchModeIcon } from "$/components/shared/Icon";
2import type { SearchMode } from "$/lib/api/types/search";
3import { createSignal } from "solid-js";
4
5function SearchModeButton(props: { active: boolean; disabled?: boolean; mode: SearchMode; onClick: () => void }) {
6 return (
7 <button
8 type="button"
9 disabled={props.disabled}
10 class="inline-flex items-center justify-center gap-2 rounded-xl border-0 px-3 py-2 text-xs font-medium transition duration-150 disabled:cursor-not-allowed disabled:opacity-40"
11 classList={{
12 "bg-primary/15 text-primary": props.active,
13 "tone-muted text-on-surface-variant hover:bg-surface-bright hover:text-on-surface": !props.active
14 && !props.disabled,
15 }}
16 onClick={() => props.onClick()}>
17 <SearchModeIcon mode={props.mode} class="text-sm" />
18 <span class="capitalize">{props.mode}</span>
19 </button>
20 );
21}
22
23export function SearchPicker(props: { onSubmit: (query: string, mode: SearchMode) => void }) {
24 const [mode, setMode] = createSignal<SearchMode>("network");
25 const [query, setQuery] = createSignal("");
26
27 function handleSubmit(event: Event) {
28 event.preventDefault();
29 const trimmed = query().trim();
30 if (!trimmed) {
31 return;
32 }
33
34 props.onSubmit(trimmed, mode());
35 }
36
37 return (
38 <form onSubmit={handleSubmit} class="grid gap-3">
39 <label class="grid gap-1.5">
40 <span class="text-xs font-medium uppercase tracking-wide text-on-surface-variant">Search query</span>
41 <input
42 type="text"
43 class="ui-input ui-input-strong rounded-xl px-4 py-2.5"
44 placeholder="from:alice at protocol"
45 value={query()}
46 onInput={(event) => setQuery(event.currentTarget.value)} />
47 </label>
48
49 <div class="grid gap-1.5">
50 <span class="text-xs font-medium uppercase tracking-wide text-on-surface-variant">Search mode</span>
51 <div class="grid grid-cols-2 gap-2">
52 <SearchModeButton active={mode() === "network"} mode="network" onClick={() => setMode("network")} />
53 <SearchModeButton active={mode() === "keyword"} mode="keyword" onClick={() => setMode("keyword")} />
54 <SearchModeButton active={mode() === "semantic"} mode="semantic" onClick={() => setMode("semantic")} />
55 <SearchModeButton active={mode() === "hybrid"} mode="hybrid" onClick={() => setMode("hybrid")} />
56 </div>
57 </div>
58
59 <button
60 type="submit"
61 disabled={!query().trim()}
62 class="flex items-center justify-center gap-2 rounded-xl border-0 bg-primary/15 px-4 py-2.5 text-sm font-medium text-primary transition duration-150 hover:-translate-y-px hover:bg-primary/25 disabled:cursor-not-allowed disabled:opacity-40">
63 <Icon kind="search" />
64 Open search column
65 </button>
66 </form>
67 );
68}