SPB Git forge
3commits 1branches 0releases
417.0 KBsize
maindefault branch
10 days agolast push
TypeScript 66.5% Python 30.9% JavaScript 1.4% CSS 0.7%
2.0 KB · 61 lines tsx
Raw Blame History
1'use client';2import { Search, X } from 'lucide-react';3import { useRouter, useSearchParams } from 'next/navigation';4import { useState } from 'react';5import { routes } from '@/lib/site';67/** Compact search that navigates to `?q=` while keeping the other filters. Degrades to a plain GET form without JS. */8export function SearchBox({ initial = '' }: { initial?: string }) {9  const router = useRouter();10  const sp = useSearchParams();11  const [value, setValue] = useState(initial);1213  const go = (q: string) => {14    const p = new URLSearchParams(sp.toString());15    p.delete('page');16    if (q.trim()) p.set('q', q.trim());17    else p.delete('q');18    const s = p.toString();19    router.push(routes.satellites(s || undefined));20  };2122  return (23    <form24      method="get"25      action={routes.satellites()}26      role="search"27      className="relative flex w-full max-w-md items-center"28      onSubmit={(e) => {29        e.preventDefault();30        go(value);31      }}32    >33      {Array.from(sp.entries()).filter(([k]) => k !== 'q' && k !== 'page').map(([k, v]) => <input key={k} type="hidden" name={k} value={v} />)}34      <Search className="pointer-events-none absolute left-3 size-4 text-ink-3" aria-hidden />35      <input36        type="search"37        name="q"38        value={value}39        onChange={(e) => setValue(e.target.value)}40        placeholder="Name, NORAD or COSPAR id…"41        aria-label="Search satellites by name, NORAD or COSPAR id"42        className="h-11 w-full rounded-md border border-rule bg-plane-2 pl-9 pr-10 text-sm text-ink placeholder:text-ink-3 focus:border-accent/60"43        autoComplete="off"44      />45      {value && (46        <button47          type="button"48          onClick={() => {49            setValue('');50            go('');51          }}52          className="absolute right-1 inline-flex size-9 items-center justify-center rounded text-ink-3 hover:text-ink"53          aria-label="Clear search"54        >55          <X className="size-4" aria-hidden />56        </button>57      )}58    </form>59  );60}61