~james/core

core/web/src/lib/components/search/SearchSidebar.svelte -rw-r--r-- 2.1 KiB
452f17b7 — james chore(import): snapshot james.dad.town/core at f70c71c7696a 16 hours ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<script lang="ts">
	import type { Snippet } from "svelte";
	import {
		LANGUAGE_COLORS,
		LANGUAGE_COLOR_FALLBACK
	} from "#lib/components/repo/languageColors.ts";
	import ColorBall from "#lib/components/ui/ColorBall.svelte";
	import QueryToken from "#lib/components/search/QueryToken.svelte";
	import SearchTabs, { searchUrl } from "#lib/components/search/SearchTabs.svelte";
	import { POPULAR_LANGUAGES } from "#lib/repoQuery.ts";
	import { quoteValue } from "#lib/ticketQuery.ts";

	interface Props {
		query: string;
		active: string;
		class?: string;
		/** tab-specific result metadata, rendered under the filters */
		children?: Snippet;
	}

	let { query, active, class: className, children }: Props = $props();

	const languageKey = $derived(active === "code" ? "lang" : "language");

	const withLang = (lang: string) => {
		const token = `${languageKey}:${quoteValue(lang)}`;
		return query.split(/\s+/).includes(token) ? query.trim() : `${token} ${query}`.trim();
	};
	const langColor = (lang: string) => LANGUAGE_COLORS[lang] ?? LANGUAGE_COLOR_FALLBACK;
</script>

<div class={["flex flex-col gap-xl md:sticky md:top-2 md:self-start", className]}>
	<div>
		<h2 class="mb-sm typography-paragraph-small font-semibold text-foreground-muted">
			Filter by
		</h2>
		<SearchTabs {query} {active} />
	</div>

	<div>
		<h2 class="mb-sm typography-paragraph-small font-semibold text-foreground-muted">
			Languages
		</h2>
		<div class="flex flex-wrap gap-xs">
			{#each POPULAR_LANGUAGES as lang (lang)}
				<a
					href={searchUrl(active, withLang(lang))}
					class="flex w-fit shrink-0 items-center gap-xs rounded-md border border-border-default bg-background-default px-xs py-2xs typography-paragraph-regular text-foreground-default transition-colors hover:bg-background-subtle"
				>
					<ColorBall color={langColor(lang)} class="size-2.5" />
					<span>{lang}</span>
				</a>
			{/each}
		</div>
		<p class="mt-sm typography-paragraph-small text-foreground-subtle">
			Selecting a language adds <QueryToken>{languageKey}:Rust</QueryToken> to your search.
		</p>
	</div>

	{@render children?.()}
</div>