HistoryFilter

tcmts.share.HistoryFilter · #gokyyggd · term · runs in the browser

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

uses

used by