This commit is contained in:
Max S 2024-08-09 17:42:52 +02:00
parent 0d9eb149c2
commit 2953bd37de
10 changed files with 299 additions and 9 deletions

View File

@ -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}>

View File

@ -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);
}
}
}

View 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>;
}

View File

@ -0,0 +1,5 @@
.root {
display: flex;
align-items: center;
gap: var(--spacing-lg, 24px);
}

View File

@ -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>
);
}

View File

@ -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;
}
}
}

View 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,
},
);
}
}

View File

@ -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) {

View File

@ -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>
</>
);

View File

@ -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>