PullIn

tcmts.studio.PullIn · #ga54rdc7 · term · runs in the browser

uses useState

Find a definition in the codebase by name (findDefinitions: its letters in order) and pull it into the scratch file (onPick, its name).

import { findDefinitions } from "#codebase/tcmts/studio";
import { useEffect, useState } from "react";
import {
  Button, Dialog, DialogTrigger, Input, ListBox, ListBoxItem, Popover, SearchField,
} from "react-aria-components";

export function PullIn({ onPick }: { onPick: (name: string) => void }) {
  const [q, setQ] = useState("");
  const [found, setFound] = useState<{ path: string; kind: string; signature: string }[]>([]);
  useEffect(() => {
    let live = true;
    const t = setTimeout(async () => {
      const r = await findDefinitions(q).catch(() => []);
      if (live) setFound(r);
    }, 150);
    return () => {
      live = false;
      clearTimeout(t);
    };
  }, [q]);
  return (
    <DialogTrigger onOpenChange={(open) => !open && setQ("")}>
      <Button className="btn">Pull in…</Button>
      <Popover className="menu-pop pullpop" placement="bottom end" offset={6}>
        <Dialog className="getit-body" aria-label="Pull a definition into this file">
          {({ close }) => (
            <>
              <SearchField aria-label="A definition's name" value={q} onChange={setQ} autoFocus>
                <Input className="field" placeholder="A definition's name" />
              </SearchField>
              {found.length > 0 ? (
                <ListBox
                  className="menu pulllist"
                  aria-label="Definitions"
                  items={found.map((f) => ({ id: f.path, ...f }))}
                  onAction={(k) => {
                    close();
                    onPick(String(k));
                  }}
                >
                  {(f) => (
                    <ListBoxItem id={f.id} className="opt" textValue={f.path}>
                      <span className="mono">{f.path}</span>
                      <span className="muted sig">{f.kind === "type" ? "type" : f.signature}</span>
                    </ListBoxItem>
                  )}
                </ListBox>
              ) : (
                <p className="muted">
                  {q.trim()
                    ? "No definition is named like that."
                    : "Its name, or letters of it in order."}
                </p>
              )}
            </>
          )}
        </Dialog>
      </Popover>
    </DialogTrigger>
  );
}

uses

used by