noogle/components/basicList/basicList.tsx

234 lines
5.9 KiB
TypeScript
Raw Normal View History

2022-12-09 18:41:59 +03:00
import React, { useState, useMemo } from "react";
2022-11-26 12:36:08 +03:00
import {
Box,
IconButton,
List,
ListItem,
Pagination,
Stack,
Typography,
Grid,
2022-12-03 20:20:07 +03:00
Slide,
Collapse,
Grow,
2022-11-26 12:36:08 +03:00
} from "@mui/material";
2022-12-03 20:20:07 +03:00
import { BasicDataItem, BasicDataViewProps } from "../../types/basicDataView";
2022-11-26 12:36:08 +03:00
import { SearchInput } from "../searchInput";
import Radio from "@mui/material/Radio";
import RadioGroup from "@mui/material/RadioGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import FormControl from "@mui/material/FormControl";
import FormLabel from "@mui/material/FormLabel";
import ClearIcon from "@mui/icons-material/Clear";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
2022-11-27 16:40:17 +03:00
import { NixType, nixTypes } from "../../types/nix";
2022-11-26 12:36:08 +03:00
export type BasicListItem = {
item: React.ReactNode;
key: string;
};
export type BasicListProps = BasicDataViewProps & {
handleFilter: (t: NixType, mode: "from" | "to") => void;
preview: React.ReactNode;
2022-12-03 19:48:36 +03:00
selected?: string | null;
2022-12-09 18:51:33 +03:00
itemsPerPage: number;
2022-11-26 12:36:08 +03:00
};
interface SelectOptionProps {
label: string;
handleChange: (value: string) => void;
2022-12-03 19:43:52 +03:00
2022-11-26 12:36:08 +03:00
options: {
value: string;
label: string;
}[];
}
const SelectOption = (props: SelectOptionProps) => {
const { label, handleChange, options } = props;
const [value, setValue] = React.useState<NixType>("any");
const _handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const newVal = (event.target as HTMLInputElement).value as NixType;
setValue(newVal);
handleChange(newVal);
};
const handleClear = () => {
setValue("any");
handleChange("any");
};
return (
2022-12-03 19:38:50 +03:00
<FormControl
sx={{
// pl: 1.5,
flexDirection: "row",
}}
>
<FormLabel sx={{ width: "11rem", wordWrap: "unset" }}>
<Typography>
2022-11-30 18:45:12 +03:00
<IconButton aria-label="clear-button" onClick={handleClear}>
2022-11-26 12:36:08 +03:00
<ClearIcon />
</IconButton>
{label}
2022-12-03 19:38:50 +03:00
</Typography>
2022-11-26 12:36:08 +03:00
</FormLabel>
2022-12-03 19:38:50 +03:00
<RadioGroup
sx={{
// pl: 1.5,
width: "100%",
"&.MuiFormGroup-root": {
flexDirection: "row",
},
}}
value={value}
onChange={_handleChange}
>
2022-11-26 12:36:08 +03:00
{options.map(({ value, label }) => (
<FormControlLabel
key={value}
value={value}
control={<Radio />}
label={label}
/>
))}
</RadioGroup>
</FormControl>
);
};
export function BasicList(props: BasicListProps) {
2022-12-03 19:38:50 +03:00
const {
items,
pageCount = 1,
2022-12-09 18:41:59 +03:00
itemsPerPage,
2022-12-03 19:38:50 +03:00
handleSearch,
handleFilter,
preview,
selected = "",
} = props;
2022-11-26 12:36:08 +03:00
// const [from, setFrom] = useState<NixType>("any");
// const [to, setTo] = useState<NixType>("any");
const [page, setPage] = useState(1);
2022-12-09 18:41:59 +03:00
const pageItems = useMemo(() => {
const startIdx = (page - 1) * itemsPerPage;
const endIdx = page * itemsPerPage;
return items.slice(startIdx, endIdx);
}, [page, items, itemsPerPage]);
2022-11-26 12:36:08 +03:00
const [searchTerm, setSearchTerm] = useState("");
const handlePageChange = (
_event: React.ChangeEvent<unknown>,
value: number
) => {
setPage(value);
};
const _handleFilter = (t: NixType, mode: "from" | "to") => {
handleFilter(t, mode);
setPage(1);
};
const _handleSearch = (term: string) => {
handleSearch && handleSearch(term);
setSearchTerm(term);
setPage(1);
};
2022-11-27 16:16:52 +03:00
2022-11-26 12:36:08 +03:00
return (
<Stack>
<SearchInput
placeholder="search nix functions"
handleSearch={_handleSearch}
clearSearch={() => _handleSearch("")}
/>
<Box>
2022-12-03 19:38:50 +03:00
{/* <Stack direction="row"> */}
2022-11-26 12:36:08 +03:00
<Grid container>
2022-12-03 19:38:50 +03:00
<Grid item xs={12} md={5}>
<SelectOption
label="from type"
handleChange={(value) => {
_handleFilter(value as NixType, "from");
}}
options={nixTypes.map((v) => ({ value: v, label: v }))}
/>
</Grid>
<Grid
item
md={2}
sx={{
display: {
md: "flex",
xs: "none",
},
justifyContent: "center",
alignItems: "center",
}}
>
<Typography
// sx={{
// width: "100%",
// display: "flex",
// justifyContent: "center",
// alignItems: "center",
// // flexDirection: "column",
// }}
>
<ChevronRightIcon />
</Typography>
2022-11-26 12:36:08 +03:00
</Grid>
2022-12-03 19:38:50 +03:00
<Grid item xs={12} md={5}>
<SelectOption
label="to type"
handleChange={(value) => {
_handleFilter(value as NixType, "to");
}}
options={nixTypes.map((v) => ({ value: v, label: v }))}
/>
2022-11-26 12:36:08 +03:00
</Grid>
</Grid>
2022-12-03 19:38:50 +03:00
{/* </Stack> */}
2022-11-26 12:36:08 +03:00
</Box>
<List aria-label="basic-list" sx={{ pt: 0 }}>
2022-12-09 18:41:59 +03:00
{pageItems.map(({ item, key }, idx) => (
2022-12-08 01:10:58 +03:00
<Box key={`${key}-${idx}`}>
2022-12-03 20:20:07 +03:00
<Slide
direction="up"
in={key === selected}
mountOnEnter
unmountOnExit
>
2022-12-03 19:38:50 +03:00
<ListItem
key={`${key}-preview`}
aria-label={`item-${key}`}
sx={{ px: 0 }}
>
{preview}
</ListItem>
2022-12-03 20:20:07 +03:00
{/* )} */}
</Slide>
2022-12-09 18:41:59 +03:00
<ListItem sx={{ px: 0 }} key={key} aria-label={`item-${key}`}>
2022-12-03 19:38:50 +03:00
{item}
</ListItem>
2022-12-03 20:20:07 +03:00
</Box>
2022-11-26 12:36:08 +03:00
))}
</List>
<Pagination
hideNextButton
hidePrevButton
2022-11-26 12:36:08 +03:00
sx={{ display: "flex", justifyContent: "center", mt: 1, mb: 10 }}
2022-12-09 18:41:59 +03:00
count={Math.ceil(items.length / itemsPerPage) || 1}
2022-11-26 12:36:08 +03:00
color="primary"
page={page}
onChange={handlePageChange}
/>
</Stack>
);
}