Skip to content

Commit abf6934

Browse files
feat: Add Section component (#863)
* feat: Add Section component * fix: add Section.Action example
1 parent 6b034ec commit abf6934

File tree

3 files changed

+127
-0
lines changed

3 files changed

+127
-0
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { makeStyles } from "@material-ui/core/styles"
2+
import React from "react"
3+
4+
const useStyles = makeStyles((theme) => ({
5+
root: {
6+
marginTop: theme.spacing(3),
7+
},
8+
}))
9+
10+
/**
11+
* SectionAction is a content box that call to actions should be placed
12+
* within
13+
*/
14+
export const SectionAction: React.FC = ({ children }) => {
15+
const styles = useStyles()
16+
return <div className={styles.root}>{children}</div>
17+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import Button from "@material-ui/core/Button"
2+
import TextField from "@material-ui/core/TextField"
3+
import { Story } from "@storybook/react"
4+
import React from "react"
5+
import { Section, SectionProps } from "./"
6+
7+
export default {
8+
title: "Page/Section",
9+
component: Section,
10+
argTypes: {
11+
title: { type: "string" },
12+
description: { type: "string" },
13+
children: { control: { disable: true } },
14+
},
15+
}
16+
17+
const Template: Story<SectionProps> = (args: SectionProps) => <Section {...args} />
18+
19+
export const Example = Template.bind({})
20+
Example.args = {
21+
title: "User Settings",
22+
description: "Add your personal info",
23+
children: (
24+
<>
25+
<form style={{ display: "grid", gridAutoFlow: "row", gap: 12 }}>
26+
<TextField label="Name" variant="filled" fullWidth />
27+
<TextField label="Email" variant="filled" fullWidth />
28+
</form>
29+
30+
<Section.Action>
31+
<Button variant="contained" color="primary">
32+
Submit
33+
</Button>
34+
</Section.Action>
35+
</>
36+
),
37+
}

site/src/components/Section/index.tsx

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { makeStyles } from "@material-ui/core/styles"
2+
import { fade } from "@material-ui/core/styles/colorManipulator"
3+
import Typography from "@material-ui/core/Typography"
4+
import React from "react"
5+
import { SectionAction } from "./Action"
6+
7+
type SectionLayout = "fixed" | "fluid"
8+
9+
export interface SectionProps {
10+
title?: React.ReactNode | string
11+
description?: React.ReactNode
12+
toolbar?: React.ReactNode
13+
alert?: React.ReactNode
14+
layout?: SectionLayout
15+
children?: React.ReactNode
16+
}
17+
18+
type SectionFC = React.FC<SectionProps> & { Action: typeof SectionAction }
19+
20+
export const Section: SectionFC = ({ title, description, toolbar, alert, children, layout = "fixed" }) => {
21+
const styles = useStyles({ layout })
22+
return (
23+
<div className={styles.root}>
24+
<div className={styles.inner}>
25+
{(title || description) && (
26+
<div className={styles.header}>
27+
<div>
28+
{title && <Typography variant="h4">{title}</Typography>}
29+
{description && typeof description === "string" && (
30+
<Typography className={styles.description}>{description}</Typography>
31+
)}
32+
{description && typeof description !== "string" && (
33+
<div className={styles.description}>{description}</div>
34+
)}
35+
</div>
36+
{toolbar && <div>{toolbar}</div>}
37+
</div>
38+
)}
39+
{alert && <div className={styles.alert}>{alert}</div>}
40+
{children}
41+
</div>
42+
</div>
43+
)
44+
}
45+
46+
// Sub-components
47+
Section.Action = SectionAction
48+
49+
const useStyles = makeStyles((theme) => ({
50+
root: {
51+
backgroundColor: theme.palette.background.paper,
52+
boxShadow: `0px 18px 12px 6px ${fade(theme.palette.common.black, 0.02)}`,
53+
marginBottom: theme.spacing(1),
54+
padding: theme.spacing(6),
55+
},
56+
inner: ({ layout }: { layout: SectionLayout }) => ({
57+
maxWidth: layout === "fluid" ? "100%" : 500,
58+
}),
59+
alert: {
60+
marginBottom: theme.spacing(1),
61+
},
62+
header: {
63+
marginBottom: theme.spacing(4),
64+
display: "flex",
65+
flexDirection: "row",
66+
justifyContent: "space-between",
67+
},
68+
description: {
69+
color: theme.palette.text.secondary,
70+
fontSize: 16,
71+
marginTop: theme.spacing(2),
72+
},
73+
}))

0 commit comments

Comments
 (0)