Toaster
This commit is contained in:
parent
0d9eb149c2
commit
2953bd37de
@ -7,6 +7,7 @@ import Button, { EButtonSize, EButtonstyletype, EButtonVariant, IButtonProps } f
|
||||
import classNames from "classnames";
|
||||
import IconButton from "../IconButton";
|
||||
import useOpenable from "@Front/Hooks/useOpenable";
|
||||
import BadgeIcon, { EBadgeColor } from "../BadgeIcon";
|
||||
|
||||
type IProps = {
|
||||
variant: EAlertVariant;
|
||||
@ -35,6 +36,14 @@ const variantButtonMap: Record<EAlertVariant, EButtonVariant> = {
|
||||
[EAlertVariant.NEUTRAL]: EButtonVariant.NEUTRAL,
|
||||
};
|
||||
|
||||
const variantColorMap: Record<EAlertVariant, EBadgeColor> = {
|
||||
[EAlertVariant.INFO]: EBadgeColor.INFO,
|
||||
[EAlertVariant.SUCCESS]: EBadgeColor.SUCCESS,
|
||||
[EAlertVariant.WARNING]: EBadgeColor.WARNING,
|
||||
[EAlertVariant.ERROR]: EBadgeColor.ERROR,
|
||||
[EAlertVariant.NEUTRAL]: EBadgeColor.NEUTRAL,
|
||||
};
|
||||
|
||||
export default function Alert(props: IProps) {
|
||||
const { isOpen, close } = useOpenable({ defaultOpen: true });
|
||||
const { variant = EAlertVariant.INFO, title, description, firstButton, secondButton, closeButton, icon, fullWidth } = props;
|
||||
@ -43,7 +52,7 @@ export default function Alert(props: IProps) {
|
||||
|
||||
return (
|
||||
<div className={classNames(classes["root"], classes[variant], fullWidth && classes["fullwidth"])}>
|
||||
<span className={classes["icon"]}>{icon ?? <InformationCircleIcon />}</span>
|
||||
<BadgeIcon icon={icon ?? <InformationCircleIcon />} color={variantColorMap[variant]} />
|
||||
<div className={classes["content"]}>
|
||||
<div className={classes["text-container"]}>
|
||||
<Typography typo={ETypo.TEXT_LG_SEMIBOLD} color={ETypoColor.COLOR_NEUTRAL_950}>
|
||||
|
@ -0,0 +1,46 @@
|
||||
@import "@Themes/constants.scss";
|
||||
|
||||
.root {
|
||||
display: flex;
|
||||
padding: var(--spacing-1, 8px);
|
||||
align-items: center;
|
||||
align-self: flex-start;
|
||||
|
||||
border-radius: var(--alerts-badge-radius, 360px);
|
||||
border: 1px solid var(--alerts-badge-border, rgba(0, 0, 0, 0));
|
||||
background: var(--alerts-badge-background, #fff);
|
||||
box-shadow: 0px 4px 16px 0px rgba(0, 0, 0, 0.1);
|
||||
|
||||
svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
min-width: 24px;
|
||||
min-height: 24px;
|
||||
|
||||
stroke: var(--alerts-badge-contrast-info);
|
||||
}
|
||||
|
||||
&.error {
|
||||
svg {
|
||||
stroke: var(--alerts-badge-contrast-error);
|
||||
}
|
||||
}
|
||||
|
||||
&.warning {
|
||||
svg {
|
||||
stroke: var(--alerts-badge-contrast-warning);
|
||||
}
|
||||
}
|
||||
|
||||
&.success {
|
||||
svg {
|
||||
stroke: var(--alerts-badge-contrast-success);
|
||||
}
|
||||
}
|
||||
|
||||
&.neutral {
|
||||
svg {
|
||||
stroke: var(--alerts-badge-contrast-neutral);
|
||||
}
|
||||
}
|
||||
}
|
23
src/front/Components/DesignSystem/BadgeIcon/index.tsx
Normal file
23
src/front/Components/DesignSystem/BadgeIcon/index.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
|
||||
import classes from "./classes.module.scss";
|
||||
|
||||
export enum EBadgeColor {
|
||||
INFO = "info",
|
||||
SUCCESS = "success",
|
||||
WARNING = "warning",
|
||||
ERROR = "error",
|
||||
NEUTRAL = "neutral",
|
||||
}
|
||||
|
||||
type IProps = {
|
||||
icon: React.ReactNode;
|
||||
color: EBadgeColor;
|
||||
};
|
||||
|
||||
export default function BadgeIcon(props: IProps) {
|
||||
const { icon, color } = props;
|
||||
|
||||
return <div className={classNames(classes["root"], classes[color])}>{icon}</div>;
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
.root {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-lg, 24px);
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
import React from "react";
|
||||
|
||||
import Typography, { ETypo, ETypoColor } from "../../Typography";
|
||||
import classes from "./classes.module.scss";
|
||||
|
||||
type IProps = {
|
||||
title: string;
|
||||
description?: string;
|
||||
icon?: React.ReactNode;
|
||||
};
|
||||
|
||||
export default function ToastContent(props: IProps) {
|
||||
const { icon, title, description } = props;
|
||||
|
||||
return (
|
||||
<div className={classes["root"]}>
|
||||
{icon}
|
||||
<div className={classes["content"]}>
|
||||
<Typography typo={ETypo.TEXT_MD_SEMIBOLD} color={ETypoColor.TOASTER_CONTRAST_TITLE}>
|
||||
{title}
|
||||
</Typography>
|
||||
<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.TOASTER_CONTRAST_TEXT}>
|
||||
{description}
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
.root {
|
||||
width: fit-content !important;
|
||||
.wrapper {
|
||||
width: 387px;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
padding: var(--spacing-2, 16px);
|
||||
border-radius: var(--toaster-radius, 0px);
|
||||
border: 1px solid var(--toaster-border, #e5eefa);
|
||||
background: var(--toaster-background, #fff);
|
||||
/* shadow/sm */
|
||||
box-shadow: 0px 4px 16px 0px rgba(0, 0, 0, 0.1);
|
||||
|
||||
.body {
|
||||
}
|
||||
|
||||
.progress {
|
||||
height: 2px;
|
||||
}
|
||||
}
|
||||
}
|
111
src/front/Components/DesignSystem/Toaster/index.tsx
Normal file
111
src/front/Components/DesignSystem/Toaster/index.tsx
Normal file
@ -0,0 +1,111 @@
|
||||
import { ArrowLeftStartOnRectangleIcon, CheckIcon, ExclamationTriangleIcon, InformationCircleIcon, XMarkIcon } from "@heroicons/react/24/outline";
|
||||
import React from "react";
|
||||
import { toast, ToastContainer } from "react-toastify";
|
||||
|
||||
import BadgeIcon, { EBadgeColor } from "../BadgeIcon";
|
||||
import IconButton from "../IconButton";
|
||||
import Loader from "../Loader";
|
||||
import classes from "./classes.module.scss";
|
||||
import ToastContent from "./ToastContent";
|
||||
|
||||
import "react-toastify/dist/ReactToastify.css";
|
||||
|
||||
export default function Toaster() {
|
||||
return (
|
||||
<ToastContainer
|
||||
className={classes["root"]}
|
||||
toastClassName={classes["wrapper"]}
|
||||
bodyClassName={classes["body"]}
|
||||
progressClassName={classes["progress"]}
|
||||
closeButton={<IconButton icon={<XMarkIcon />} />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export class ToasterService {
|
||||
private static instance: ToasterService;
|
||||
private constructor() {}
|
||||
|
||||
public static getInstance() {
|
||||
return (this.instance ??= new this());
|
||||
}
|
||||
|
||||
public text({ title, description }: { title: string; description?: string }) {
|
||||
toast.info(<ToastContent title={title} description={description} />, {
|
||||
icon: false,
|
||||
progressStyle: { backgroundColor: "var(--primary-default-base)" },
|
||||
});
|
||||
}
|
||||
|
||||
public info({ title, description }: { title: string; description?: string }) {
|
||||
toast.info(
|
||||
<ToastContent
|
||||
title={title}
|
||||
description={description}
|
||||
icon={<BadgeIcon icon={<InformationCircleIcon />} color={EBadgeColor.INFO} />}
|
||||
/>,
|
||||
{
|
||||
icon: false,
|
||||
progressStyle: { backgroundColor: "var(--info-default-base)" },
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
public success({ title, description }: { title: string; description?: string }) {
|
||||
toast.info(
|
||||
<ToastContent title={title} description={description} icon={<BadgeIcon icon={<CheckIcon />} color={EBadgeColor.SUCCESS} />} />,
|
||||
{
|
||||
icon: false,
|
||||
progressStyle: { backgroundColor: "var(--success-default-base)" },
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
public error({ title, description }: { title: string; description?: string }) {
|
||||
toast.info(
|
||||
<ToastContent title={title} description={description} icon={<BadgeIcon icon={<XMarkIcon />} color={EBadgeColor.ERROR} />} />,
|
||||
{
|
||||
icon: false,
|
||||
progressStyle: { backgroundColor: "var(--error-default-base)" },
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
public warning({ title, description }: { title: string; description?: string }) {
|
||||
toast.info(
|
||||
<ToastContent
|
||||
title={title}
|
||||
description={description}
|
||||
icon={<BadgeIcon icon={<ExclamationTriangleIcon />} color={EBadgeColor.WARNING} />}
|
||||
/>,
|
||||
{
|
||||
icon: false,
|
||||
progressStyle: { backgroundColor: "var(--warning-default-base)" },
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
public loading({ title, description }: { title: string; description?: string }) {
|
||||
toast.info(
|
||||
<ToastContent title={title} description={description} icon={<BadgeIcon icon={<Loader />} color={EBadgeColor.INFO} />} />,
|
||||
{
|
||||
icon: false,
|
||||
autoClose: false,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
public loggedOut({ title, description }: { title: string; description?: string }) {
|
||||
toast.info(
|
||||
<ToastContent
|
||||
title={title}
|
||||
description={description}
|
||||
icon={<BadgeIcon icon={<ArrowLeftStartOnRectangleIcon />} color={EBadgeColor.NEUTRAL} />}
|
||||
/>,
|
||||
{
|
||||
icon: false,
|
||||
autoClose: false,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
@ -169,6 +169,9 @@ export enum ETypoColor {
|
||||
TAG_SUCCESS_CONTRAST = "--tag-success-contrast",
|
||||
TAG_WARNING_CONTRAST = "--tag-warning-contrast",
|
||||
TAG_ERROR_CONTRAST = "--tag-error-contrast",
|
||||
|
||||
TOASTER_CONTRAST_TITLE = "--toaster-contrast-title",
|
||||
TOASTER_CONTRAST_TEXT = "--toaster-contrast-text",
|
||||
}
|
||||
|
||||
export default function Typography(props: IProps) {
|
||||
|
@ -1,8 +1,9 @@
|
||||
import Head from "next/head";
|
||||
import { ReactNode } from "react";
|
||||
import Toaster from "../DesignSystem/Toaster";
|
||||
|
||||
type DefaultLayoutProps = { children: ReactNode };
|
||||
import { ToastContainer } from "react-toastify";
|
||||
import "react-toastify/dist/ReactToastify.css";
|
||||
|
||||
export const DefaultLayout = ({ children }: DefaultLayoutProps) => {
|
||||
return (
|
||||
<>
|
||||
@ -12,7 +13,7 @@ export const DefaultLayout = ({ children }: DefaultLayoutProps) => {
|
||||
</Head>
|
||||
<main>
|
||||
{children}
|
||||
<ToastContainer />
|
||||
<Toaster />
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
|
@ -2,7 +2,9 @@ import Alert, { EAlertVariant } from "@Front/Components/DesignSystem/Alert";
|
||||
import Autocomplete from "@Front/Components/DesignSystem/Autocomplete";
|
||||
import AutocompleteMultiSelect from "@Front/Components/DesignSystem/AutocompleteMultiSelect";
|
||||
import Button, { EButtonSize, EButtonstyletype, EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||
import CheckboxesInputElement from "@Front/Components/DesignSystem/CheckBox";
|
||||
import CircleProgress from "@Front/Components/DesignSystem/CircleProgress";
|
||||
import DragAndDrop from "@Front/Components/DesignSystem/DragAndDrop";
|
||||
import Dropdown from "@Front/Components/DesignSystem/Dropdown";
|
||||
import Footer from "@Front/Components/DesignSystem/Footer";
|
||||
import Form from "@Front/Components/DesignSystem/Form";
|
||||
@ -12,10 +14,13 @@ import IconButton, { EIconButtonVariant } from "@Front/Components/DesignSystem/I
|
||||
import Menu from "@Front/Components/DesignSystem/Menu";
|
||||
import Modal from "@Front/Components/DesignSystem/Modal";
|
||||
import Newsletter from "@Front/Components/DesignSystem/Newsletter";
|
||||
import RadioBox from "@Front/Components/DesignSystem/RadioBox";
|
||||
import SearchBlockList from "@Front/Components/DesignSystem/SearchBlockList";
|
||||
import DropdownNavigation from "@Front/Components/DesignSystem/SearchBlockList/DropdownNavigation";
|
||||
import Separator, { ESeperatorColor, ESeperatorDirection } from "@Front/Components/DesignSystem/Separator";
|
||||
import Table from "@Front/Components/DesignSystem/Table";
|
||||
import Tag, { ETagColor, ETagVariant } from "@Front/Components/DesignSystem/Tag";
|
||||
import Toggle, { EToggleSize } from "@Front/Components/DesignSystem/Toggle";
|
||||
import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography";
|
||||
import NumberPicker from "@Front/Components/Elements/NumberPicker";
|
||||
import Tabs from "@Front/Components/Elements/Tabs";
|
||||
@ -33,11 +38,7 @@ import {
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
|
||||
import classes from "./classes.module.scss";
|
||||
import CheckboxesInputElement from "@Front/Components/DesignSystem/CheckBox";
|
||||
import RadioBox from "@Front/Components/DesignSystem/RadioBox";
|
||||
import Toggle, { EToggleSize } from "@Front/Components/DesignSystem/Toggle";
|
||||
import Separator, { ESeperatorColor, ESeperatorDirection } from "@Front/Components/DesignSystem/Separator";
|
||||
import DragAndDrop from "@Front/Components/DesignSystem/DragAndDrop";
|
||||
import { ToasterService } from "@Front/Components/DesignSystem/Toaster";
|
||||
|
||||
export default function DesignSystem() {
|
||||
const { isOpen, open, close } = useOpenable();
|
||||
@ -89,6 +90,46 @@ export default function DesignSystem() {
|
||||
<div className={classes["root"]}>
|
||||
<Typography typo={ETypo.DISPLAY_LARGE}>DesignSystem</Typography>
|
||||
<div className={classes["components"]}>
|
||||
<Typography typo={ETypo.TEXT_LG_BOLD}>Toast</Typography>
|
||||
<div className={classes["rows"]}>
|
||||
<Button
|
||||
size={EButtonSize.SM}
|
||||
onClick={() => ToasterService.getInstance().text({ title: "Title toaster", description: "Description" })}>
|
||||
Send Toast
|
||||
</Button>
|
||||
<Button
|
||||
size={EButtonSize.SM}
|
||||
onClick={() => ToasterService.getInstance().info({ title: "Title toaster", description: "Description" })}>
|
||||
Send Toast Info
|
||||
</Button>
|
||||
<Button
|
||||
size={EButtonSize.SM}
|
||||
onClick={() => ToasterService.getInstance().success({ title: "Title toaster", description: "Description" })}>
|
||||
Send Toast Success
|
||||
</Button>
|
||||
</div>
|
||||
<div className={classes["rows"]}>
|
||||
<Button
|
||||
size={EButtonSize.SM}
|
||||
onClick={() => ToasterService.getInstance().warning({ title: "Title toaster", description: "Description" })}>
|
||||
Send Toast Warning
|
||||
</Button>
|
||||
<Button
|
||||
size={EButtonSize.SM}
|
||||
onClick={() => ToasterService.getInstance().error({ title: "Title toaster", description: "Description" })}>
|
||||
Send Toast Error
|
||||
</Button>
|
||||
<Button
|
||||
size={EButtonSize.SM}
|
||||
onClick={() => ToasterService.getInstance().loading({ title: "Title toaster", description: "Description" })}>
|
||||
Send Toast Loading
|
||||
</Button>
|
||||
</div>
|
||||
<Button
|
||||
size={EButtonSize.SM}
|
||||
onClick={() => ToasterService.getInstance().loggedOut({ title: "Title toaster", description: "Description" })}>
|
||||
Logged Out
|
||||
</Button>
|
||||
<Typography typo={ETypo.TEXT_LG_BOLD}>Drag and Drop</Typography>
|
||||
<DragAndDrop name="test" title="Upload de document" description="Description" />
|
||||
<Typography typo={ETypo.TEXT_LG_BOLD}>Separators</Typography>
|
||||
|
Loading…
x
Reference in New Issue
Block a user