From 2cd7fb27b259dad2221943aaf1dea20b047bcde9 Mon Sep 17 00:00:00 2001 From: Toshimitsu Watanabe Date: Mon, 7 Feb 2022 12:39:38 +0900 Subject: [PATCH] Add Toast --- ...p_toast_ToastHavingDetailModal_Default.png | Bin 0 -> 1399 bytes .../chrome_laptop_toast_Toast_Default.png | Bin 0 -> 1399 bytes src/components/toast/Toast.stories.tsx | 18 +++++++ src/components/toast/Toast.test.tsx | 14 ++++++ src/components/toast/Toast.tsx | 13 ++++++ .../toast/ToastHavingDetailInfo.stories.tsx | 36 ++++++++++++++ .../toast/ToastHavingDetailInfo.test.tsx | 19 ++++++++ .../toast/ToastHavingDetailInfo.tsx | 44 ++++++++++++++++++ src/components/toast/Toaster.tsx | 27 +++++++++++ 9 files changed, 171 insertions(+) create mode 100644 .loki/reference/chrome_laptop_toast_ToastHavingDetailModal_Default.png create mode 100644 .loki/reference/chrome_laptop_toast_Toast_Default.png create mode 100644 src/components/toast/Toast.stories.tsx create mode 100644 src/components/toast/Toast.test.tsx create mode 100644 src/components/toast/Toast.tsx create mode 100644 src/components/toast/ToastHavingDetailInfo.stories.tsx create mode 100644 src/components/toast/ToastHavingDetailInfo.test.tsx create mode 100644 src/components/toast/ToastHavingDetailInfo.tsx create mode 100644 src/components/toast/Toaster.tsx diff --git a/.loki/reference/chrome_laptop_toast_ToastHavingDetailModal_Default.png b/.loki/reference/chrome_laptop_toast_ToastHavingDetailModal_Default.png new file mode 100644 index 0000000000000000000000000000000000000000..361e567220cdd09ec044f41ab649250005d8c550 GIT binary patch literal 1399 zcmeAS@N?(olHy`uVBq!ia0y~yU=0JZB{C*x-X^CG9B|n4*=J^fg^yR3 zR%mGG$37*92F-&lw{G34J2S^}vWJS$d!1lC4kkBu_m#i?ey?z!2r+ev!=y#=`&3c_ zMHPfP1$x~c%Q{1B2x{`In(DCs|9|uKaeKSUSs+GwavnRq8s?r!I%~WjiZ7}7uGnzv z>eZvW%ik|E^@xv`_n&7o^O_}0rIyc%4ONehaI&$pFE{n5uD0I0ckgAZcBr&(YrI%k z`I{RDH>aP!u`O3RH#e6dW^dKht=ZQ%rJa@P>h9iI`1n}G|KH!=2L}ZmIyF`M3Xq`uC0xZ*;g|YXr`QP zm5Z}8^Y?dmm94F3FZZ7>)ai2KZ4?eL6`yL$DiYhNT?LKEuI~7{jlbptgwkH z;kkD1oZq_G-EKN!$|77JpPiN7SO1^yz{|_aEz94@u=C43`TF|$l4DRKBdvo*3_3Od$@#k-E&%e2|SpDqTvs<=o`C}3X z3@&alodxUHzpsDB(dsn0R}UIg!AVZ;j4JBt#x^!Q2bTHHe(~5I&x|qa_jE?j3?LWW0ZLTzt1DG%wQc_YTOr7c)6m)6+GYu^* zC8^$`&(C}rjvYH@QS^l4?%lh=J4&FI{rd0oqWfxB7uTv)t8Q$~7I*KLTe@^<>#J8; zNgE|JH8o@QR7^}gJ#AybLnkY1YfTM}1fVZN!o!23qrHQJg}cRcA0239esh2Sd|;Ar zS}3qOZ0(~93!NEq?(LbmYnN43Rn?B#-)7g>$3Oq@@UV%gDPurPjE|@1$uDnPV3{Xi z#kzIx+?}1B_Z0ige)cSF*1sRh_Y9%3suMV6SruT8HRoOpivUm0{~Ya)=O#v}{`v(~ z`}galpx_{mCWU*J%UlImmMmLx#JUY4w}eIbmzCMK#fuj=>tEDhW@i3)&N%hZLj%o~ sD?>sC*x-X^CG9B|n4*=J^fg^yR3 zR%mGG$37*92F-&lw{G34J2S^}vWJS$d!1lC4kkBu_m#i?ey?z!2r+ev!=y#=`&3c_ zMHPfP1$x~c%Q{1B2x{`In(DCs|9|uKaeKSUSs+GwavnRq8s?r!I%~WjiZ7}7uGnzv z>eZvW%ik|E^@xv`_n&7o^O_}0rIyc%4ONehaI&$pFE{n5uD0I0ckgAZcBr&(YrI%k z`I{RDH>aP!u`O3RH#e6dW^dKht=ZQ%rJa@P>h9iI`1n}G|KH!=2L}ZmIyF`M3Xq`uC0xZ*;g|YXr`QP zm5Z}8^Y?dmm94F3FZZ7>)ai2KZ4?eL6`yL$DiYhNT?LKEuI~7{jlbptgwkH z;kkD1oZq_G-EKN!$|77JpPiN7SO1^yz{|_aEz94@u=C43`TF|$l4DRKBdvo*3_3Od$@#k-E&%e2|SpDqTvs<=o`C}3X z3@&alodxUHzpsDB(dsn0R}UIg!AVZ;j4JBt#x^!Q2bTHHe(~5I&x|qa_jE?j3?LWW0ZLTzt1DG%wQc_YTOr7c)6m)6+GYu^* zC8^$`&(C}rjvYH@QS^l4?%lh=J4&FI{rd0oqWfxB7uTv)t8Q$~7I*KLTe@^<>#J8; zNgE|JH8o@QR7^}gJ#AybLnkY1YfTM}1fVZN!o!23qrHQJg}cRcA0239esh2Sd|;Ar zS}3qOZ0(~93!NEq?(LbmYnN43Rn?B#-)7g>$3Oq@@UV%gDPurPjE|@1$uDnPV3{Xi z#kzIx+?}1B_Z0ige)cSF*1sRh_Y9%3suMV6SruT8HRoOpivUm0{~Ya)=O#v}{`v(~ z`}galpx_{mCWU*J%UlImmMmLx#JUY4w}eIbmzCMK#fuj=>tEDhW@i3)&N%hZLj%o~ sD?>s { + return ( +
+ + +
+ ); +}; diff --git a/src/components/toast/Toast.test.tsx b/src/components/toast/Toast.test.tsx new file mode 100644 index 00000000..95affea6 --- /dev/null +++ b/src/components/toast/Toast.test.tsx @@ -0,0 +1,14 @@ +import "@testing-library/jest-dom/extend-expect"; +import { screen } from "@testing-library/react"; +import React from "react"; +import { render } from "../../test-utils"; +import { Default } from "./Toast.stories"; + +describe("Toast", () => { + test("should toast alert", async () => { + render(); + expect(screen.queryAllByRole("alert")).toHaveLength(0); + screen.getByRole("button").click(); + await expect(screen.findAllByRole("alert")).resolves.toBeDefined(); + }); +}); diff --git a/src/components/toast/Toast.tsx b/src/components/toast/Toast.tsx new file mode 100644 index 00000000..f9060f8a --- /dev/null +++ b/src/components/toast/Toast.tsx @@ -0,0 +1,13 @@ +import Alert, { AlertProps } from "@mui/material/Alert"; +import React from "react"; + +export type ToastProps = AlertProps; +export const Toast = ({ sx, ...delegated }: ToastProps): JSX.Element => { + return ( + + ); +}; diff --git a/src/components/toast/ToastHavingDetailInfo.stories.tsx b/src/components/toast/ToastHavingDetailInfo.stories.tsx new file mode 100644 index 00000000..0ad55e1f --- /dev/null +++ b/src/components/toast/ToastHavingDetailInfo.stories.tsx @@ -0,0 +1,36 @@ +import React from "react"; +import { toast } from "react-toastify"; +import { ErrorMessage } from "../ErrorMessage"; +import { ToastHavingDetailModal } from "./ToastHavingDetailInfo"; +import { Toaster } from "./Toaster"; + +export default { + component: ToastHavingDetailModal, + title: "toast/ToastHavingDetailModal", +}; + +export const Default = (): JSX.Element => { + return ( +
+ + +
+ ); +}; diff --git a/src/components/toast/ToastHavingDetailInfo.test.tsx b/src/components/toast/ToastHavingDetailInfo.test.tsx new file mode 100644 index 00000000..f3675ab8 --- /dev/null +++ b/src/components/toast/ToastHavingDetailInfo.test.tsx @@ -0,0 +1,19 @@ +import "@testing-library/jest-dom/extend-expect"; +import { getByRole } from "@testing-library/dom"; +import { screen } from "@testing-library/react"; +import React from "react"; +import { render } from "../../test-utils"; +import { Default } from "./ToastHavingDetailInfo.stories"; + +describe("Toast", () => { + test("should toast alert having button that display alert dialog", async () => { + render(); + expect(screen.queryAllByRole("alert")).toHaveLength(0); + screen.getByRole("button").click(); + await expect(screen.findAllByRole("alert")).resolves.toBeDefined(); + + const toast = screen.getAllByRole("alert")[0]; + getByRole(toast, "button").click(); + expect(screen.getByRole("alertdialog")).toBeDefined(); + }); +}); diff --git a/src/components/toast/ToastHavingDetailInfo.tsx b/src/components/toast/ToastHavingDetailInfo.tsx new file mode 100644 index 00000000..f6062600 --- /dev/null +++ b/src/components/toast/ToastHavingDetailInfo.tsx @@ -0,0 +1,44 @@ +import Button, { ButtonProps } from "@mui/material/Button"; +import Dialog from "@mui/material/Dialog"; +import React, { useState, ReactNode } from "react"; +import { DialogCloseButton } from "../dialog/DialogCloseButton"; +import { DialogWrapper } from "../dialog/DialogWrapper"; +import { Toast, ToastProps } from "./Toast"; + +export type ToastHavingDetailModalProps = { + detailContent: ReactNode; + detailButtonProps?: Omit; +} & Omit; +export const ToastHavingDetailModal = ({ + detailContent, + detailButtonProps, + ...delegated +}: ToastHavingDetailModalProps): JSX.Element => { + const [open, setOpen] = useState(false); + return ( + <> + { + e.stopPropagation(); + setOpen(true); + }} + color="inherit" + variant="text" + {...detailButtonProps} + > + {detailButtonProps?.children ?? "Detail"} + + } + /> + setOpen(false)} role="alertdialog"> + + setOpen(false)} /> + {detailContent} + + + + ); +}; diff --git a/src/components/toast/Toaster.tsx b/src/components/toast/Toaster.tsx new file mode 100644 index 00000000..9edf856b --- /dev/null +++ b/src/components/toast/Toaster.tsx @@ -0,0 +1,27 @@ +import { useTheme } from "@mui/material/styles"; +import React from "react"; +import { ToastContainer, ToastContainerProps } from "react-toastify"; +import "react-toastify/dist/ReactToastify.css"; + +export type ToasterProps = ToastContainerProps; +export const Toaster = ({ + position, + theme, + progressStyle, + limit, + ...delegated +}: ToasterProps): JSX.Element => { + const muiTheme = useTheme(); + return ( + + ); +};