Web: Components: added story for Toast

This commit is contained in:
Artem Tarasov 2021-03-11 19:03:17 +03:00
parent 277f803f12
commit 23b4cd5380
6 changed files with 243 additions and 281 deletions

View File

@ -53,6 +53,7 @@ module.exports = {
"../text-input/*.stories.@(js|mdx)",
"../textarea/*.stories.@(js|mdx)",
"../theme-provider/*.stories.@(js|mdx)",
"../toast/*.stories.@(js|mdx)",
],
addons: [
"@storybook/addon-links",

View File

@ -92,95 +92,3 @@ const DarkTemplate = (args) => {
);
};
export const DarkTheme = DarkTemplate.bind({});
/*
import { storiesOf } from "@storybook/react";
import ThemeProvider from ".";
import withReadme from "storybook-readme/with-readme";
import Readme from "./README.md";
import { BooleanValue } from "react-values";
import Box from "../Box";
import Text from "../Text";
import JSONPretty from "react-json-pretty";
import Base from "../themes/base";
import Heading from "../Heading";
import Checkbox from "../Checkbox";
const LightTheme = {
backgroundColor: "#FFF",
fontFamily: "sans-serif",
text: { color: "#333" },
};
const DarkTheme = {
backgroundColor: "#1F2933",
fontFamily: "Open Sans",
text: { color: "#E4E7EB" },
};
storiesOf("Components|ThemeProvider", module)
.addDecorator(withReadme(Readme))
.add("Default", () => (
<BooleanValue>
{({ value, toggle }) => (
<Box displayProp="flex" paddingProp="16px" alignItems="center">
<ThemeProvider theme={value ? DarkTheme : LightTheme}>
<Checkbox
checked={value}
onChange={(e) => toggle(e.target.value)}
label={value ? "Dark" : "Light"}
/>
</ThemeProvider>
</Box>
)}
</BooleanValue>
));
storiesOf("Components|ThemeProvider", module)
.addParameters({ options: { showAddonPanel: false } })
.add("Base theme", () => {
const jsonTheme = {
main: "line-height:1.5;background:#FFF;overflow:auto;",
error: "line-height:1.5;background:#FFF;overflow:auto;",
key: "color:#444;",
string: "color:#00873D;",
};
return (
<ThemeProvider theme={LightTheme}>
<Box paddingProp={"16px"}>
<Heading>Base theme:</Heading>
<Text as="div" bold fontSize="14px">
<JSONPretty
id="json-pretty"
data={JSON.stringify(Base)}
theme={jsonTheme}
/>
</Text>
</Box>
</ThemeProvider>
);
});
storiesOf("Components|ThemeProvider", module)
.addParameters({ options: { showAddonPanel: false } })
.add("Dark theme", () => {
const jsonTheme = {
main: "line-height:1.5;background:#1F2933;overflow:auto;",
error: "line-height:1.5;background:#1F2933;overflow:auto;",
key: "color:#1F97CA;",
string: "color:#00873D;",
};
return (
<ThemeProvider theme={DarkTheme}>
<Box paddingProp={"16px"}>
<Heading>Dark theme:</Heading>
<Text as="div" bold color="#1F97CA" fontSize="14px">
<JSONPretty
id="json-pretty"
data={JSON.stringify(Dark)}
theme={jsonTheme}
/>
</Text>
</Box>
</ThemeProvider>
);
});
*/

View File

@ -1,139 +0,0 @@
import React from "react";
import ReactDOM from "react-dom";
import { storiesOf } from "@storybook/react";
import Toast from ".";
import toastr from "./toastr";
import Link from "../link";
class TostWrapper extends React.Component {
componentDidMount() {
this.toastContainer = document.createElement("div");
this.toastContainer.setAttribute("id", "toast-container");
document.body.appendChild(this.toastContainer);
ReactDOM.render(
<Toast />,
document.getElementById("toast-container"),
() => {
toastr.success(
"Demo text for success Toast closes in 30 seconds or on click",
null,
30000
);
toastr.error(
"Demo text for error Toast closes in 28 seconds or on click",
null,
28000
);
toastr.warning(
"Demo text for warning Toast closes in 25 seconds or on click",
null,
25000
);
toastr.info(
"Demo text for info Toast closes in 15 seconds or on click",
null,
15000
);
toastr.success(
"Demo text for success Toast with title closes in 12 seconds or on click",
"Demo title",
12000
);
toastr.error(
"Demo text for error Toast with title closes in 10 seconds or on click",
"Demo title",
10000
);
toastr.warning(
"Demo text for warning Toast with title closes in 8 seconds or on click",
"Demo title",
8000
);
toastr.info(
"Demo text for info Toast with title closes in 6 seconds or on click",
"Demo title",
6000
);
toastr.success(
"Demo text for success manual closed Toast",
null,
0,
true,
true
);
toastr.error(
"Demo text for error manual closed Toast",
null,
0,
true,
true
);
toastr.warning(
"Demo text for warning manual closed Toast",
null,
0,
true,
true
);
toastr.info(
"Demo text for info manual closed Toast",
null,
0,
true,
true
);
toastr.success(
<>
Demo text for success manual closed Toast with title and contains{" "}
<Link
type="page"
color="gray"
href="https://github.com"
text="gray link"
/>
</>,
"Demo title",
0,
true,
true
);
toastr.error(
"Demo text for error manual closed Toast with title",
"Demo title",
0,
true,
true
);
toastr.warning(
"Demo text for warning manual closed Toast with title",
"Demo title",
0,
true,
true
);
toastr.info(
"Demo text for info manual closed Toast with title",
"Demo title",
0,
true,
true
);
}
);
}
componentWillUnmount() {
toastr.clear();
ReactDOM.unmountComponentAtNode(this.toastContainer);
document.body.removeChild(this.toastContainer);
}
render() {
return <></>;
}
}
storiesOf("Components|Toast", module)
.addParameters({ options: { showAddonPanel: false } })
.add("all", () => <TostWrapper />);

View File

@ -37,11 +37,16 @@ const Toast = (props) => {
Toast.propTypes = {
autoClosed: PropTypes.bool,
/** Accepts class */
className: PropTypes.string,
/** Accepts id */
id: PropTypes.string,
/** Accepts css style */
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
text: PropTypes.string,
/** Title inside a toast */
title: PropTypes.string,
/** Define color and icon of toast */
type: PropTypes.oneOf(["success", "error", "warning", "info"]).isRequired,
};

View File

@ -1,34 +1,18 @@
import React from "react";
import { storiesOf } from "@storybook/react";
import Toast from ".";
import React, { useEffect } from "react";
import ReactDOM from "react-dom";
import Toast from "./";
import toastr from "./toastr";
import Readme from "./README.md";
import {
text,
boolean,
withKnobs,
select,
number,
} from "@storybook/addon-knobs/react";
import withReadme from "storybook-readme/with-readme";
import Section from "../../../.storybook/decorators/section";
import Button from "../button";
import Link from "../link";
const typeToast = ["success", "error", "warning", "info"];
storiesOf("Components|Toast", module)
.addDecorator(withKnobs)
.addDecorator(withReadme(Readme))
.add("base", () => {
const type = `${select("type", typeToast, "success")}`;
const data = `${text("data", "Demo text for Toast")}`;
const title = `${text("title", "Demo title")}`;
const withCross = boolean("withCross", false);
const timeout = number("timeout", "5000");
const BaseTemplate = ({ type, data, title, timeout, withCross, ...args }) => {
return (
<>
<Toast />
<Section>
<button
<Toast {...args} />
<Button
label="Show toast"
primary
size="medium"
onClick={() => {
switch (type) {
case "error":
@ -45,10 +29,132 @@ storiesOf("Components|Toast", module)
break;
}
}}
>
Show toast
</button>
</Section>
/>
</>
);
});
};
export const basic = BaseTemplate.bind({});
basic.args = {
type: "success",
data: "Demo text for Toast",
title: "Demo title",
withCross: false,
timeout: 5000,
};
const AllTemplate = (args) => {
const renderAllToast = () => {
toastr.success(
"Demo text for success Toast closes in 30 seconds or on click",
null,
30000
);
toastr.error(
"Demo text for error Toast closes in 28 seconds or on click",
null,
28000
);
toastr.warning(
"Demo text for warning Toast closes in 25 seconds or on click",
null,
25000
);
toastr.info(
"Demo text for info Toast closes in 15 seconds or on click",
null,
15000
);
toastr.success(
"Demo text for success Toast with title closes in 12 seconds or on click",
"Demo title",
12000
);
toastr.error(
"Demo text for error Toast with title closes in 10 seconds or on click",
"Demo title",
10000
);
toastr.warning(
"Demo text for warning Toast with title closes in 8 seconds or on click",
"Demo title",
8000
);
toastr.info(
"Demo text for info Toast with title closes in 6 seconds or on click",
"Demo title",
6000
);
toastr.success(
"Demo text for success manual closed Toast",
null,
0,
true,
true
);
toastr.error(
"Demo text for error manual closed Toast",
null,
0,
true,
true
);
toastr.warning(
"Demo text for warning manual closed Toast",
null,
0,
true,
true
);
toastr.info("Demo text for info manual closed Toast", null, 0, true, true);
toastr.success(
<>
Demo text for success manual closed Toast with title and contains{" "}
<Link
type="page"
color="gray"
href="https://github.com"
text="gray link"
/>
</>,
"Demo title",
0,
true,
true
);
toastr.error(
"Demo text for error manual closed Toast with title",
"Demo title",
0,
true,
true
);
toastr.warning(
"Demo text for warning manual closed Toast with title",
"Demo title",
0,
true,
true
);
toastr.info(
"Demo text for info manual closed Toast with title",
"Demo title",
0,
true,
true
);
};
return (
<>
<Toast />
<Button
label="Show all toast"
primary
size="medium"
onClick={() => renderAllToast()}
/>
</>
);
};
export const all = AllTemplate.bind({});

View File

@ -0,0 +1,81 @@
import { Story, ArgsTable, Canvas, Meta } from "@storybook/addon-docs/blocks";
import * as stories from "./toast.stories.js";
import Toast from "./";
<Meta
title="Components/Toast"
component={Toast}
parameters={{
source: {
code: stories.basic,
},
}}
argTypes={{
timeout: {
description: `Time (in milliseconds) for showing your toast. Setting in \`0\` let you to show toast constantly until clicking on it`,
},
data: { description: "Any components or data inside a toast" },
withCross: {
description: `If \`false\`: toast disappeared after clicking on any area of toast. If \`true\`: toast disappeared after clicking on close button`,
},
}}
/>
# Toast
Toast allow you to add notification to your page with ease.
`<Toast />` is container for your notification. Remember to render the `<Toast />` _once_ in your application tree. If you can't figure out where to put it, rendering it in the application root would be the best bet.
`toastr` is a function for showing notifications.
<Canvas>
<Story story={stories.basic} name="Default" />
</Canvas>
<ArgsTable story="Default" />
<Canvas>
<Story story={stories.all} name="All" />
</Canvas>
### Usage
```js
import Toast from "@appserver/components/toast";
import toastr from "@appserver/components/toast/toastr";
```
```jsx
<Toast />
<button onClick={() => toastr.success('Some text for toast', 'Some text for title', true)}>Click</button>
```
or
```jsx
<Toast>{toastr.success("Some text for toast")}</Toast>
```
You can use simple html tags. For this action you should wrap your message by empty tags:
```jsx
<Toast />
<button onClick={() => toastr.success(<>You have <b>bold text</b></>)}>Click</button>
```
If your notification include only text in html tags or data in JSX tags, you can omit empty tags:
```jsx
<Toast />
<button onClick={() => toastr.success(<b>Bold text</b>)}>Click</button>
```
#### Other Options
```js
<Toast/>
// Remove all toasts in your page programmatically
<button onClick = {()=> { toastr.clear() }}>Clear</button>
```