~sjm/starsmith

696d28b49aabd86829812180be1724fdfe8314b5 — Sam Marshall 2 years ago 88778fe main
feat: add search
M packages/moves/package.json => packages/moves/package.json +2 -0
@@ 5,6 5,7 @@
  "dependencies": {
    "@emotion/react": "^11.7.1",
    "@emotion/styled": "^11.6.0",
    "@mui/icons-material": "^5.3.1",
    "@mui/material": "^5.4.0",
    "@testing-library/jest-dom": "^5.16.2",
    "@testing-library/react": "^12.1.2",


@@ 14,6 15,7 @@
    "@types/react": "^17.0.39",
    "@types/react-dom": "^17.0.11",
    "fp-ts": "^2.11.8",
    "fuse.js": "^6.5.3",
    "markdown-it": "^12.3.2",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",

A packages/moves/src/components/move.tsx => packages/moves/src/components/move.tsx +34 -0
@@ 0,0 1,34 @@
import Card from "@mui/material/Card";
import CardContent from "@mui/material/CardContent";
import Typography from "@mui/material/Typography";
import MarkdownIt from "markdown-it";
import React from "react";

const md = new MarkdownIt();

export default function Move(props: { Name: string; Text: string }) {
  const [hidden, setHidden] = React.useState(true);
  const bodyText = md.render(props.Text);

  return (
    <Card>
      <CardContent>
        <Typography
          variant="h6"
          component="h1"
          onClick={() => setHidden((x) => !x)}
          sx={{ cursor: "pointer", width: "100%" }}
        >
          {props.Name}
        </Typography>
        {hidden ? (
          <div />
        ) : (
          <Typography sx={{ maxWidth: 600 }} variant="body1">
            <p dangerouslySetInnerHTML={{ __html: bodyText }}></p>
          </Typography>
        )}
      </CardContent>
    </Card>
  );
}

M packages/moves/src/moves.tsx => packages/moves/src/moves.tsx +35 -41
@@ 1,44 1,16 @@
import React from "react";
import Search from "@mui/icons-material/Search";
import Box from "@mui/material/Box";
import Paper from "@mui/material/Paper";
import Chip from "@mui/material/Chip";
import InputAdornment from "@mui/material/InputAdornment";
import Paper from "@mui/material/Paper";
import Stack from "@mui/material/Stack";
import Card from "@mui/material/Card";
import CardContent from "@mui/material/CardContent";
import Typography from "@mui/material/Typography";
import MarkdownIt from "markdown-it";
import moves from "./moves.json";
import TextField from "@mui/material/TextField";
import * as A from "fp-ts/Array";
import * as S from "fp-ts/string";

const md = new MarkdownIt();

function Move(props: { Name: string; Text: string }) {
  const [hidden, setHidden] = React.useState(true);
  const bodyText = md.render(props.Text);

  return (
    <Card>
      <CardContent>
        <Typography
          variant="h6"
          component="h1"
          onClick={() => setHidden((x) => !x)}
          sx={{ cursor: "pointer", width: "100%" }}
        >
          {props.Name}
        </Typography>
        {hidden ? (
          <div />
        ) : (
          <Typography sx={{ maxWidth: 600 }} variant="body1">
            <p dangerouslySetInnerHTML={{ __html: bodyText }}></p>
          </Typography>
        )}
      </CardContent>
    </Card>
  );
}
import Fuse from "fuse.js";
import React from "react";
import Move from "./components/move";
import moves from "./moves.json";

/**
 * TODO pull this stuff into a library.


@@ 69,13 41,37 @@ const MoveChip = ({
);

export default function Moves() {
  const [searchTerm, setSearchTerm] = React.useState(null as null | string);
  const [selectedCategories, setSelectedCategories] = React.useState(
    [] as Array<string>
  );

  const selectedMoves = moves.Moves.filter((mv) =>
    // display all moves when there are no categories selected
    selectedCategories.length === 0
      ? true
      : selectedCategories.includes(mv.Category)
  );

  const fuse = new Fuse(selectedMoves, { keys: ["Name", "Text"] });

  return (
    <Box sx={{ maxWidth: 800 }}>
      <Paper elevation={1}>
        <TextField
          sx={{ width: "100%" }}
          value={searchTerm === null ? "" : searchTerm}
          onChange={(e) =>
            setSearchTerm(e.target.value === "" ? null : e.target.value)
          }
          InputProps={{
            endAdornment: (
              <InputAdornment position="end">
                <Search />
              </InputAdornment>
            ),
          }}
        />
        <Stack
          spacing={1}
          direction="row"


@@ 97,11 93,9 @@ export default function Moves() {
          ))}
        </Stack>
        <Stack sx={{ p: 1 }} spacing={0.5}>
          {moves.Moves.filter((mv) =>
            // display all moves when there are no categories selected
            selectedCategories.length === 0
              ? true
              : selectedCategories.includes(mv.Category)
          {(searchTerm === null
            ? selectedMoves
            : fuse.search(searchTerm).map((res) => res.item)
          ).map((mv) => (
            <Move key={mv.Name} {...mv} />
          ))}

M yarn.lock => yarn.lock +12 -0
@@ 1735,6 1735,13 @@
    prop-types "^15.7.2"
    react-is "^17.0.2"

"@mui/icons-material@^5.3.1":
  version "5.3.1"
  resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.3.1.tgz#e0e0aecce5a86971dbaa46441d931a9c749a1c53"
  integrity sha512-8zBWCaE8DHjIGZhGgMod92p6Rm38EhXrS+cZtaV0+jOTMeWh7z+mvswXzb/rVKc0ZYqw6mQYBcn2uEs2yclI9w==
  dependencies:
    "@babel/runtime" "^7.16.7"

"@mui/material@^5.4.0":
  version "5.4.0"
  resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.4.0.tgz#b54d9fbcad5c4036b95c53906f0fc9c16c980f6e"


@@ 7406,6 7413,11 @@ fuse.js@^3.6.1:
  resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.6.1.tgz#7de85fdd6e1b3377c23ce010892656385fd9b10c"
  integrity sha512-hT9yh/tiinkmirKrlv4KWOjztdoZo1mx9Qh4KvWqC7isoXwdUY3PNWUxceF4/qO9R6riA2C29jdTOeQOIROjgw==

fuse.js@^6.5.3:
  version "6.5.3"
  resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-6.5.3.tgz#7446c0acbc4ab0ab36fa602e97499bdb69452b93"
  integrity sha512-sA5etGE7yD/pOqivZRBvUBd/NaL2sjAu6QuSaFoe1H2BrJSkH/T/UXAJ8CdXdw7DvY3Hs8CXKYkDWX7RiP5KOg==

gauge@^3.0.0:
  version "3.0.2"
  resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395"