Add table header with arrow

This commit is contained in:
dominik-zeglen 2019-09-02 11:02:56 +02:00
parent 2b0f2933ec
commit 3827f8b8c1
4 changed files with 422 additions and 0 deletions

View file

@ -0,0 +1,83 @@
import Card from "@material-ui/core/Card";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
import { storiesOf } from "@storybook/react";
import React from "react";
import Decorator from "../../storybook/Decorator";
import TableCellHeader, {
TableCellHeaderArrowDirection
} from "./TableCellHeader";
type Field = "name" | "type";
interface StoryProps {
direction: TableCellHeaderArrowDirection;
field?: Field;
onHeaderClick?: (field: Field) => void;
}
const Story: React.FC<StoryProps> = ({
direction,
field = "name",
onHeaderClick = () => undefined
}) => (
<Card style={{ margin: "auto", width: 400 }}>
<Table>
<TableHead>
<TableRow>
<TableCellHeader
arrowPosition="right"
direction={field === "name" ? direction : undefined}
onClick={() => onHeaderClick("name")}
>
Name
</TableCellHeader>
<TableCellHeader
direction={field === "type" ? direction : undefined}
onClick={() => onHeaderClick("type")}
>
Type
</TableCellHeader>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>Apple Juice</TableCell>
<TableCell>Juice</TableCell>
</TableRow>
</TableBody>
</Table>
</Card>
);
const InteractiveStory: React.FC = () => {
const [direction, setDirection] = React.useState<
TableCellHeaderArrowDirection
>("asc");
const [field, setField] = React.useState<Field>("name");
const handleHeaderClick = (selectedField: Field) => {
if (field === selectedField) {
setDirection(direction === "asc" ? "desc" : "asc");
} else {
setField(selectedField);
setDirection("asc");
}
};
return (
<Story
direction={direction}
field={field}
onHeaderClick={handleHeaderClick}
/>
);
};
storiesOf("Generics / Table header", module)
.addDecorator(Decorator)
.add("ascending", () => <Story direction="asc" />)
.add("descending", () => <Story direction="desc" />)
.add("interactive", () => <InteractiveStory />);

View file

@ -0,0 +1,70 @@
import { Theme } from "@material-ui/core/styles";
import TableCell, { TableCellProps } from "@material-ui/core/TableCell";
import makeStyles from "@material-ui/styles/makeStyles";
import classNames from "classnames";
import React from "react";
import ArrowSort from "../../icons/ArrowSort";
const useStyles = makeStyles((theme: Theme) => ({
arrow: {
transition: theme.transitions.duration.short + "ms"
},
arrowLeft: {
marginLeft: -24
},
arrowUp: {
transform: "rotate(180deg)"
},
label: {
alignSelf: "center",
display: "inline-block"
},
labelContainer: {
display: "flex",
height: 24
},
root: {
cursor: "pointer"
}
}));
export type TableCellHeaderArrowDirection = "asc" | "desc";
export type TableCellHeaderArrowPosition = "left" | "right";
export interface TableCellHeader extends TableCellProps {
arrowPosition?: TableCellHeaderArrowPosition;
direction?: TableCellHeaderArrowDirection;
}
const TableCellHeader: React.FC<TableCellHeader> = props => {
const classes = useStyles(props);
const { arrowPosition, children, className, direction, ...rest } = props;
return (
<TableCell {...rest} className={classNames(className, classes.root)}>
<div className={classes.labelContainer}>
{!!direction && arrowPosition === "left" && (
<ArrowSort
className={classNames(classes.arrow, classes.arrowLeft, {
[classes.arrowUp]: direction === "asc"
})}
/>
)}
<div className={classes.label}>{children}</div>
{!!direction && arrowPosition === "right" && (
<ArrowSort
className={classNames(classes.arrow, {
[classes.arrowUp]: direction === "asc"
})}
/>
)}
</div>
</TableCell>
);
};
TableCellHeader.displayName = "TableCellHeader";
TableCellHeader.defaultProps = {
arrowPosition: "left"
};
export default TableCellHeader;

View file

@ -0,0 +1,2 @@
export { default } from "./TableCellHeader";
export * from "./TableCellHeader";

View file

@ -4591,6 +4591,273 @@ exports[`Storyshots Generics / StatusLabel when success 1`] = `
</div>
`;
exports[`Storyshots Generics / Table header ascending 1`] = `
<div
style="padding:24px"
>
<div
class="MuiPaper-root-id MuiPaper-elevation1-id MuiPaper-rounded-id MuiCard-root-id"
style="margin:auto;width:400px"
>
<table
class="MuiTable-root-id"
>
<thead
class="MuiTableHead-root-id"
>
<tr
class="MuiTableRow-root-id MuiTableRow-head-id"
>
<th
class="MuiTableCell-root-id MuiTableCell-head-id Hook-root-id"
scope="col"
>
<div
class="Hook-labelContainer-id"
>
<div
class="Hook-label-id"
>
Name
</div>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-id Hook-arrow-id Hook-arrowUp-id"
focusable="false"
role="presentation"
viewBox="0 0 24 24"
>
<rect
fill="transparent"
height="24"
width="24"
/>
<path
clip-rule="evenodd"
d="M11.0328 17.1401V4H12.9672V17.1401L14.6322 15.4751L16 16.8429L12 20.8429L8 16.8429L9.36782 15.4751L11.0328 17.1401Z"
fill="currentColor"
fill-rule="evenodd"
/>
</svg>
</div>
</th>
<th
class="MuiTableCell-root-id MuiTableCell-head-id Hook-root-id"
scope="col"
>
<div
class="Hook-labelContainer-id"
>
<div
class="Hook-label-id"
>
Type
</div>
</div>
</th>
</tr>
</thead>
<tbody
class="MuiTableBody-root-id"
>
<tr
class="MuiTableRow-root-id"
>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
Apple Juice
</td>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
Juice
</td>
</tr>
</tbody>
</table>
</div>
</div>
`;
exports[`Storyshots Generics / Table header descending 1`] = `
<div
style="padding:24px"
>
<div
class="MuiPaper-root-id MuiPaper-elevation1-id MuiPaper-rounded-id MuiCard-root-id"
style="margin:auto;width:400px"
>
<table
class="MuiTable-root-id"
>
<thead
class="MuiTableHead-root-id"
>
<tr
class="MuiTableRow-root-id MuiTableRow-head-id"
>
<th
class="MuiTableCell-root-id MuiTableCell-head-id Hook-root-id"
scope="col"
>
<div
class="Hook-labelContainer-id"
>
<div
class="Hook-label-id"
>
Name
</div>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-id Hook-arrow-id"
focusable="false"
role="presentation"
viewBox="0 0 24 24"
>
<rect
fill="transparent"
height="24"
width="24"
/>
<path
clip-rule="evenodd"
d="M11.0328 17.1401V4H12.9672V17.1401L14.6322 15.4751L16 16.8429L12 20.8429L8 16.8429L9.36782 15.4751L11.0328 17.1401Z"
fill="currentColor"
fill-rule="evenodd"
/>
</svg>
</div>
</th>
<th
class="MuiTableCell-root-id MuiTableCell-head-id Hook-root-id"
scope="col"
>
<div
class="Hook-labelContainer-id"
>
<div
class="Hook-label-id"
>
Type
</div>
</div>
</th>
</tr>
</thead>
<tbody
class="MuiTableBody-root-id"
>
<tr
class="MuiTableRow-root-id"
>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
Apple Juice
</td>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
Juice
</td>
</tr>
</tbody>
</table>
</div>
</div>
`;
exports[`Storyshots Generics / Table header interactive 1`] = `
<div
style="padding:24px"
>
<div
class="MuiPaper-root-id MuiPaper-elevation1-id MuiPaper-rounded-id MuiCard-root-id"
style="margin:auto;width:400px"
>
<table
class="MuiTable-root-id"
>
<thead
class="MuiTableHead-root-id"
>
<tr
class="MuiTableRow-root-id MuiTableRow-head-id"
>
<th
class="MuiTableCell-root-id MuiTableCell-head-id Hook-root-id"
scope="col"
>
<div
class="Hook-labelContainer-id"
>
<div
class="Hook-label-id"
>
Name
</div>
<svg
aria-hidden="true"
class="MuiSvgIcon-root-id Hook-arrow-id Hook-arrowUp-id"
focusable="false"
role="presentation"
viewBox="0 0 24 24"
>
<rect
fill="transparent"
height="24"
width="24"
/>
<path
clip-rule="evenodd"
d="M11.0328 17.1401V4H12.9672V17.1401L14.6322 15.4751L16 16.8429L12 20.8429L8 16.8429L9.36782 15.4751L11.0328 17.1401Z"
fill="currentColor"
fill-rule="evenodd"
/>
</svg>
</div>
</th>
<th
class="MuiTableCell-root-id MuiTableCell-head-id Hook-root-id"
scope="col"
>
<div
class="Hook-labelContainer-id"
>
<div
class="Hook-label-id"
>
Type
</div>
</div>
</th>
</tr>
</thead>
<tbody
class="MuiTableBody-root-id"
>
<tr
class="MuiTableRow-root-id"
>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
Apple Juice
</td>
<td
class="MuiTableCell-root-id MuiTableCell-body-id"
>
Juice
</td>
</tr>
</tbody>
</table>
</div>
</div>
`;
exports[`Storyshots Generics / TablePagination both previous and next pages are available 1`] = `
<div
style="padding:24px"