From abf6934ebba17cb90553a78fb947e7c968f1246a Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Tue, 5 Apr 2022 14:01:21 -0300 Subject: [PATCH] feat: Add Section component (#863) * feat: Add Section component * fix: add Section.Action example --- site/src/components/Section/Action.tsx | 17 +++++ .../Section/SectionView.stories.tsx | 37 ++++++++++ site/src/components/Section/index.tsx | 73 +++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 site/src/components/Section/Action.tsx create mode 100644 site/src/components/Section/SectionView.stories.tsx create mode 100644 site/src/components/Section/index.tsx diff --git a/site/src/components/Section/Action.tsx b/site/src/components/Section/Action.tsx new file mode 100644 index 0000000000..8a40c90fb9 --- /dev/null +++ b/site/src/components/Section/Action.tsx @@ -0,0 +1,17 @@ +import { makeStyles } from "@material-ui/core/styles" +import React from "react" + +const useStyles = makeStyles((theme) => ({ + root: { + marginTop: theme.spacing(3), + }, +})) + +/** + * SectionAction is a content box that call to actions should be placed + * within + */ +export const SectionAction: React.FC = ({ children }) => { + const styles = useStyles() + return
{children}
+} diff --git a/site/src/components/Section/SectionView.stories.tsx b/site/src/components/Section/SectionView.stories.tsx new file mode 100644 index 0000000000..13f5a1486a --- /dev/null +++ b/site/src/components/Section/SectionView.stories.tsx @@ -0,0 +1,37 @@ +import Button from "@material-ui/core/Button" +import TextField from "@material-ui/core/TextField" +import { Story } from "@storybook/react" +import React from "react" +import { Section, SectionProps } from "./" + +export default { + title: "Page/Section", + component: Section, + argTypes: { + title: { type: "string" }, + description: { type: "string" }, + children: { control: { disable: true } }, + }, +} + +const Template: Story = (args: SectionProps) =>
+ +export const Example = Template.bind({}) +Example.args = { + title: "User Settings", + description: "Add your personal info", + children: ( + <> +
+ + + + + + + + + ), +} diff --git a/site/src/components/Section/index.tsx b/site/src/components/Section/index.tsx new file mode 100644 index 0000000000..e51ad892df --- /dev/null +++ b/site/src/components/Section/index.tsx @@ -0,0 +1,73 @@ +import { makeStyles } from "@material-ui/core/styles" +import { fade } from "@material-ui/core/styles/colorManipulator" +import Typography from "@material-ui/core/Typography" +import React from "react" +import { SectionAction } from "./Action" + +type SectionLayout = "fixed" | "fluid" + +export interface SectionProps { + title?: React.ReactNode | string + description?: React.ReactNode + toolbar?: React.ReactNode + alert?: React.ReactNode + layout?: SectionLayout + children?: React.ReactNode +} + +type SectionFC = React.FC & { Action: typeof SectionAction } + +export const Section: SectionFC = ({ title, description, toolbar, alert, children, layout = "fixed" }) => { + const styles = useStyles({ layout }) + return ( +
+
+ {(title || description) && ( +
+
+ {title && {title}} + {description && typeof description === "string" && ( + {description} + )} + {description && typeof description !== "string" && ( +
{description}
+ )} +
+ {toolbar &&
{toolbar}
} +
+ )} + {alert &&
{alert}
} + {children} +
+
+ ) +} + +// Sub-components +Section.Action = SectionAction + +const useStyles = makeStyles((theme) => ({ + root: { + backgroundColor: theme.palette.background.paper, + boxShadow: `0px 18px 12px 6px ${fade(theme.palette.common.black, 0.02)}`, + marginBottom: theme.spacing(1), + padding: theme.spacing(6), + }, + inner: ({ layout }: { layout: SectionLayout }) => ({ + maxWidth: layout === "fluid" ? "100%" : 500, + }), + alert: { + marginBottom: theme.spacing(1), + }, + header: { + marginBottom: theme.spacing(4), + display: "flex", + flexDirection: "row", + justifyContent: "space-between", + }, + description: { + color: theme.palette.text.secondary, + fontSize: 16, + marginTop: theme.spacing(2), + }, +}))