AddFilter

tcmts.studio.AddFilter · #juob7rcf · term · runs in the browser

uses location

Narrow a table's rows to those whose field equals a value (as find has it): asked which field and what value, it goes to the page so filtered (href the page as it is, its query kept).

import { navigate } from "#codebase/tcmts/react";
import { useState } from "react";
import {
  Button, Input, Label, ListBox, ListBoxItem, Popover, Select, SelectValue, TextField,
} from "react-aria-components";

export function AddFilter({ fields, href }: { fields: string[]; href: string }) {
  const [open, setOpen] = useState(false);
  const [field, setField] = useState(fields[0] ?? "");
  const [value, setValue] = useState("");
  if (!fields.length) return null;
  if (!open)
    return (
      <Button className="linkbtn" onPress={() => setOpen(true)}>
        Filter
      </Button>
    );
  const go = () => {
    const u = new URL(href, location.origin);
    u.searchParams.set(`f.${field}`, value);
    u.searchParams.delete("page");
    navigate(`${u.pathname}${u.search}`);
    setOpen(false);
    setValue("");
  };
  return (
    <form
      className="addfilter"
      onSubmit={(e) => {
        e.preventDefault();
        go();
      }}
    >
      <Select aria-label="Field" selectedKey={field} onSelectionChange={(k) => setField(String(k))}>
        <Button className="btn small">
          <SelectValue />
        </Button>
        <Popover className="menu-pop">
          <ListBox className="menu">
            {fields.map((f) => (
              <ListBoxItem key={f} id={f} className="opt">
                {f}
              </ListBoxItem>
            ))}
          </ListBox>
        </Popover>
      </Select>
      <span className="muted">is</span>
      <TextField aria-label="Value" value={value} onChange={setValue} autoFocus>
        <Label className="sr-only">Value</Label>
        <Input className="field small mono" placeholder="a value (true, 3, null, text)" />
      </TextField>
      <Button className="btn small primary" type="submit">
        Filter
      </Button>
      <Button className="linkbtn" onPress={() => setOpen(false)}>
        Cancel
      </Button>
    </form>
  );
}

uses

used by