HistoryFilter
uses useState
The history's filter: which branch (a select), and under which namespace (a search field).
import { navigate } from "#codebase/tcmts/react"; import { at, Chevron } from "#codebase/tcmts/share"; import { useState } from "react"; import { Button, Form, Input, ListBox, ListBoxItem, Popover, SearchField, Select, SelectValue, } from "react-aria-components"; export function HistoryFilter({ branches, branch, under, }: { branches: string[]; branch: string; under: string; }) { const [ns, setNs] = useState(under); const go = (b: string, u: string) => navigate(at(`/history?${new URLSearchParams({ branch: b, ...(u ? { under: u } : {}) })}`)); return ( <Form className="filters" onSubmit={(e) => (e.preventDefault(), go(branch, ns.trim()))}> <Select aria-label="Branch" className="select" value={branch} onChange={(k) => k !== null && go(String(k), ns.trim())} > <Button className="btn select-btn"> <SelectValue /> <Chevron /> </Button> <Popover className="menu-pop" placement="bottom start" offset={4}> <ListBox className="menu" items={branches.map((b) => ({ id: b }))}> {(b) => ( <ListBoxItem id={b.id} className="opt"> {b.id} </ListBoxItem> )} </ListBox> </Popover> </Select> <SearchField aria-label="Only under a namespace" className="searchfield ns" value={ns} onChange={setNs} onSubmit={(v) => go(branch, v.trim())} onClear={() => under && go(branch, "")} > <Input className="field" placeholder="Only under a namespace, e.g. tcmts.cli" /> <Button className="clear" aria-label="Clear"> × </Button> </SearchField> <Button type="submit" className="btn"> Filter </Button> </Form> ); }