1
0
mirror of https://github.com/checktheroads/hyperglass synced 2024-05-11 05:55:08 +00:00

start adding response parsing & ui elements

This commit is contained in:
checktheroads
2020-04-24 11:41:43 -07:00
parent 7ad435fdf2
commit a562c90094
37 changed files with 1791 additions and 453 deletions

View File

@@ -0,0 +1,39 @@
/*@jsx jsx*/
import { jsx } from "@emotion/core";
import { Box, css, useTheme, useColorMode } from "@chakra-ui/core";
const scrollbar = { dark: "whiteAlpha.300", light: "blackAlpha.300" };
const scrollbarHover = { dark: "whiteAlpha.400", light: "blackAlpha.400" };
const scrollbarBg = { dark: "whiteAlpha.50", light: "blackAlpha.50" };
const MainTable = ({ children, ...props }) => {
const theme = useTheme();
const { colorMode } = useColorMode();
return (
<Box
css={css({
"&::-webkit-scrollbar": { height: "5px" },
"&::-webkit-scrollbar-track": {
backgroundColor: scrollbarBg[colorMode]
},
"&::-webkit-scrollbar-thumb": {
backgroundColor: scrollbar[colorMode]
},
"&::-webkit-scrollbar-thumb:hover": {
backgroundColor: scrollbarHover[colorMode]
},
"-ms-overflow-style": { display: "none" }
})(theme)}
overflow="auto"
borderRadius="md"
boxSizing="border-box"
{...props}
>
{children}
</Box>
);
};
MainTable.displayName = "MainTable";
export default MainTable;

View File

@@ -0,0 +1,24 @@
import * as React from "react";
import { Box } from "@chakra-ui/core";
import css from "@styled-system/css";
const TableBody = ({ children, ...props }) => {
return (
<Box
as="tbody"
overflowY="scroll"
css={css({
"&::-webkit-scrollbar": { display: "none" },
"&": { "-ms-overflow-style": "none" }
})}
overflowX="hidden"
{...props}
>
{children}
</Box>
);
};
TableBody.displayName = "TableBody";
export default TableBody;

View File

@@ -0,0 +1,52 @@
import * as React from "react";
import { Box, useColorMode } from "@chakra-ui/core";
// export const TableCell = styled("div")`
// ${space};
// ${color};
// ${justifyContent};
// flex: 1;
// display: flex;
// min-width: 150px;
// align-items: center;
// border-bottom-width: 1px;
// overflow: hidden;
// text-overflow: ellipsis;
// `;
const cellBorder = {
dark: { borderLeft: "1px", borderLeftColor: "whiteAlpha.100" },
light: { borderLeft: "1px", borderLeftColor: "blackAlpha.100" }
};
const TableCell = ({
bordersVertical = [false, 0, 0],
align,
cell,
children,
...props
}) => {
const { colorMode } = useColorMode();
const [doVerticalBorders, index] = bordersVertical;
let borderProps = {};
if (doVerticalBorders && index !== 0) {
borderProps = cellBorder[colorMode];
}
return (
<Box
as="td"
p={4}
m={0}
w="1%"
whiteSpace="nowrap"
{...borderProps}
{...props}
>
{children}
</Box>
);
};
TableCell.displayName = "TableCell";
export default TableCell;

View File

@@ -0,0 +1,29 @@
import * as React from "react";
import { Box, useColorMode } from "@chakra-ui/core";
// export const TableHead = styled.div`
// ${space};
// display: flex;
// flex-direction: row;
// `;
const bg = { dark: "whiteAlpha.100", light: "blackAlpha.100" };
const TableHead = ({ children, ...props }) => {
const { colorMode } = useColorMode();
return (
<Box
as="thead"
overflowX="hidden"
overflowY="auto"
bg={bg[colorMode]}
{...props}
>
{children}
</Box>
);
};
TableHead.displayName = "TableHead";
export default TableHead;

View File

@@ -0,0 +1,51 @@
import * as React from "react";
import { IconButton } from "@chakra-ui/core";
// export const TableIconButton = ({ icon, onClick, isDisabled, children, variantColor, ...rest }) => {
// return (
// <IconButton
// size="sm"
// {...rest}
// icon={icon}
// borderWidth={1}
// onClick={onClick}
// variantColor={variantColor}
// isDisabled={isDisabled}
// aria-label="Table Icon button"
// >
// {children}
// </IconButton>
// );
// };
// TableIconButton.defaultProps = {
// variantColor: "gray",
// };
const TableIconButton = ({
icon,
onClick,
isDisabled,
color,
children,
...props
}) => {
return (
<IconButton
size="sm"
icon={icon}
borderWidth={1}
onClick={onClick}
variantColor={color}
isDisabled={isDisabled}
aria-label="Table Icon Button"
{...props}
>
{children}
</IconButton>
);
};
TableIconButton.displayName = "TableIconButton";
export default TableIconButton;

View File

@@ -0,0 +1,65 @@
import * as React from "react";
import { PseudoBox, useColorMode, useTheme } from "@chakra-ui/core";
import { opposingColor } from "~/util";
// export const TableRow = styled(Flex)`
// &:hover {
// cursor: pointer;
// background-color: rgba(0, 0, 0, 0.01);
// }
// `;
const hoverBg = { dark: "whiteAlpha.100", light: "blackAlpha.100" };
const bgStripe = { dark: "whiteAlpha.50", light: "blackAlpha.50" };
const rowBorder = {
dark: { borderTop: "1px", borderTopColor: "whiteAlpha.100" },
light: { borderTop: "1px", borderTopColor: "blackAlpha.100" }
};
const alphaMap = { dark: "200", light: "100" };
const alphaMapHover = { dark: "100", light: "200" };
const TableRow = ({
highlight = false,
highlightBg = "primary",
doStripe = false,
doHorizontalBorders = false,
index = 0,
children = false,
...props
}) => {
const { colorMode } = useColorMode();
const theme = useTheme();
let bg = null;
if (highlight) {
bg = `${highlightBg}.${alphaMap[colorMode]}`;
} else if (doStripe && index % 2 !== 0) {
bg = bgStripe[colorMode];
}
const color = highlight ? opposingColor(theme, bg) : null;
const borderProps =
doHorizontalBorders && index !== 0 ? rowBorder[colorMode] : {};
return (
<PseudoBox
as="tr"
_hover={{
cursor: "pointer",
backgroundColor: highlight
? `${highlightBg}.${alphaMapHover[colorMode]}`
: hoverBg[colorMode]
}}
bg={bg}
color={color}
fontWeight={highlight ? "bold" : null}
{...borderProps}
{...props}
>
{children}
</PseudoBox>
);
};
TableRow.displayName = "TableRow";
export default TableRow;

View File

@@ -0,0 +1,32 @@
import * as React from "react";
import { Select } from "@chakra-ui/core";
{
/* <select
value={pageSize}
onChange={e => {setPageSize(Number(e.target.value))}}
>
{[5, 10, 20, 30, 40, 50].map(pageSize => (
<option key={pageSize} value={pageSize}>
Show {pageSize}
</option>
))}
</select> */
}
const TableSelectShow = ({ value, onChange, children, ...props }) => {
return (
<Select onChange={onChange} {...props}>
{[5, 10, 20, 30, 40, 50].map(value => (
<option key={value} value={value}>
Show {value}
</option>
))}
{children}
</Select>
);
};
TableSelectShow.displayName = "TableSelectShow";
export default TableSelectShow;

View File

@@ -0,0 +1,191 @@
import * as React from "react";
import { useMemo } from "react";
import { Flex, Icon, Text } from "@chakra-ui/core";
import useMedia from "~/components/MediaProvider";
import { usePagination, useSortBy, useTable } from "react-table";
import Card from "~/components/Card";
import BottomSection from "~/components/Card/CardFooter";
import TopSection from "~/components/Card/CardHeader";
import MainTable from "./MainTable";
import TableCell from "./TableCell";
import TableHead from "./TableHead";
import TableRow from "./TableRow";
import TableBody from "./TableBody";
import TableIconButton from "./TableIconButton";
import TableSelectShow from "./TableSelectShow";
const Table = ({
columns,
data,
tableHeading,
initialPageSize = 10,
onRowClick,
striped = false,
bordersVertical = false,
bordersHorizontal = false,
cellRender = null,
rowHighlightProp,
rowHighlightBg,
rowHighlightColor
}) => {
const tableColumns = useMemo(() => columns, [columns]);
const { isSm, isMd } = useMedia();
const isTabletOrMobile = isSm ? true : isMd ? true : false;
const defaultColumn = useMemo(
() => ({
minWidth: 100,
width: 150,
maxWidth: 300
}),
[]
);
const {
getTableProps,
headerGroups,
prepareRow,
page,
canPreviousPage,
canNextPage,
pageOptions,
pageCount,
gotoPage,
nextPage,
previousPage,
setPageSize,
state: { pageIndex, pageSize }
} = useTable(
{
columns: tableColumns,
defaultColumn,
data,
initialState: { pageIndex: 0, pageSize: initialPageSize }
},
useSortBy,
usePagination
);
return (
<Card>
{!!tableHeading && <TopSection>{tableHeading}</TopSection>}
<MainTable {...getTableProps()}>
<TableHead>
{headerGroups.map(headerGroup => (
<TableRow
key={headerGroup.id}
{...headerGroup.getHeaderGroupProps()}
>
{headerGroup.headers.map(column => (
<TableCell
as="th"
align={column.align}
key={column.id}
{...column.getHeaderProps()}
{...column.getSortByToggleProps()}
>
<Text fontSize="sm" fontWeight="bold" display="inline-block">
{column.render("Header")}
</Text>
{column.isSorted ? (
column.isSortedDesc ? (
<Icon name="chevron-down" size={4} ml={1} />
) : (
<Icon name="chevron-up" size={4} ml={1} />
)
) : (
""
)}
</TableCell>
))}
</TableRow>
))}
</TableHead>
<TableBody>
{page.map(
(row, key) =>
prepareRow(row) || (
<TableRow
index={key}
doStripe={striped}
doHorizontalBorders={bordersHorizontal}
onClick={() => onRowClick && onRowClick(row)}
key={key}
highlight={row.values[rowHighlightProp] ?? false}
highlightBg={rowHighlightBg}
highlightColor={rowHighlightColor}
{...row.getRowProps()}
>
{row.cells.map((cell, i) => {
return (
<TableCell
align={cell.column.align}
cell={cell}
bordersVertical={[bordersVertical, i]}
key={cell.row.index}
{...cell.getCellProps()}
>
{cell.render(cellRender ?? "Cell")}
</TableCell>
);
})}
</TableRow>
)
)}
</TableBody>
</MainTable>
<BottomSection>
<Flex direction="row">
<TableIconButton
mr={2}
onClick={() => gotoPage(0)}
isDisabled={!canPreviousPage}
icon={() => <Icon name="arrow-left" size={3} />}
/>
<TableIconButton
mr={2}
onClick={() => previousPage()}
isDisabled={!canPreviousPage}
icon={() => <Icon name="chevron-left" size={6} />}
/>
</Flex>
<Flex justifyContent="center" alignItems="center">
<Text mr={4} whiteSpace="nowrap">
Page{" "}
<strong>
{pageIndex + 1} of {pageOptions.length}
</strong>{" "}
</Text>
{!isTabletOrMobile && (
<TableSelectShow
value={pageSize}
onChange={e => {
setPageSize(Number(e.target.value));
}}
/>
)}
</Flex>
<Flex direction="row">
<TableIconButton
ml={2}
isDisabled={!canNextPage}
onClick={() => nextPage()}
icon={() => <Icon name="chevron-right" size={6} />}
/>
<TableIconButton
ml={2}
onClick={() => gotoPage(pageCount ? pageCount - 1 : 1)}
isDisabled={!canNextPage}
icon={() => <Icon name="arrow-right" size={3} />}
/>
</Flex>
</BottomSection>
</Card>
);
};
Table.displayName = "Table";
export default Table;

View File

@@ -0,0 +1,35 @@
import { generate } from "namor";
const range = (len) => {
const arr = [];
for (let i = 0; i < len; i++) {
arr.push(i);
}
return arr;
};
export const newPerson = () => {
const statusChance = Math.random();
return {
name: generate({ words: 2, numbers: 0 }),
age: Math.floor(Math.random() * 30),
visits: Math.floor(Math.random() * 100),
progress: Math.floor(Math.random() * 100),
status:
statusChance > 0.66 ? "relationship" : statusChance > 0.33 ? "complicated" : "single",
};
};
export default function makeData(...lens) {
const makeDataLevel = (depth = 0) => {
const len = lens[depth];
return range(len).map((d) => {
return {
...newPerson(),
subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined,
};
});
};
return makeDataLevel();
}

View File

@@ -0,0 +1,70 @@
import React from "react";
import { Flex, IconButton } from "@chakra-ui/core";
import styled from "@emotion/styled";
import {
color,
ColorProps,
justifyContent,
JustifyContentProps,
space,
SpaceProps,
} from "styled-system";
export const StyledTable = styled.div`
${space};
flex: 1;
width: 100%;
display: flex;
max-width: 100%;
overflow-x: auto;
border-radius: 4px;
flex-direction: column;
box-sizing: border-box;
`;
export const TableHead = styled.div`
${space};
display: flex;
flex-direction: row;
`;
export const TableCell = styled("div")`
${space};
${color};
${justifyContent};
flex: 1;
display: flex;
min-width: 150px;
align-items: center;
border-bottom-width: 1px;
overflow: hidden;
text-overflow: ellipsis;
`;
export const TableRow = styled(Flex)`
&:hover {
cursor: pointer;
background-color: rgba(0, 0, 0, 0.01);
}
`;
export const TableIconButton = ({ icon, onClick, isDisabled, children, variantColor, ...rest }) => {
return (
<IconButton
size="sm"
{...rest}
icon={icon}
borderWidth={1}
onClick={onClick}
variantColor={variantColor}
isDisabled={isDisabled}
aria-label="Table Icon button"
>
{children}
</IconButton>
);
};
TableIconButton.defaultProps = {
variantColor: "gray",
};