From 7e454e257fd135bdec67c600d91955128951b3c8 Mon Sep 17 00:00:00 2001 From: Oksamies Date: Thu, 9 Nov 2023 21:50:36 +0200 Subject: [PATCH] temp6 --- .../Forms/CreateTeamForm/CreateTeamForm.tsx | 6 +- .../components/NewToast/NewToast.module.css | 131 +++++++++++------- .../src/components/NewToast/NewToast.tsx | 67 ++------- .../components/NewToast/NewToastContainer.tsx | 4 +- .../components/NewToast/NewToastContext.tsx | 14 +- .../cyberstorm/src/components/Providers.tsx | 2 +- 6 files changed, 108 insertions(+), 116 deletions(-) diff --git a/packages/cyberstorm/src/components/Forms/CreateTeamForm/CreateTeamForm.tsx b/packages/cyberstorm/src/components/Forms/CreateTeamForm/CreateTeamForm.tsx index 5c9fdbe5d..0fec6fc16 100644 --- a/packages/cyberstorm/src/components/Forms/CreateTeamForm/CreateTeamForm.tsx +++ b/packages/cyberstorm/src/components/Forms/CreateTeamForm/CreateTeamForm.tsx @@ -60,7 +60,7 @@ export function CreateTeamForm() { "danger", , "Team name cannot start or end with underscore.", - true + 30000 ); } else if ( errors.teamName && @@ -70,14 +70,14 @@ export function CreateTeamForm() { "danger", , "Team name can contain the following characters: a-z A-Z 0-9 _", - true + 30000 ); } else if (errors.teamName && errors.teamName.type === "required") { toast?.addToast( "danger", , "Team name is required", - true + 30000 ); } } diff --git a/packages/cyberstorm/src/components/NewToast/NewToast.module.css b/packages/cyberstorm/src/components/NewToast/NewToast.module.css index c3c92d415..5d7b440ee 100644 --- a/packages/cyberstorm/src/components/NewToast/NewToast.module.css +++ b/packages/cyberstorm/src/components/NewToast/NewToast.module.css @@ -27,6 +27,34 @@ padding: 1rem 3.25rem calc(1rem - 0.125rem) 1.5rem; } +.closeIconWrapper { + position: absolute; + top: 0.5rem; + right: 0.5rem; + background-color: transparent; +} + +.closeIcon { + display: flex; + align-items: center; + justify-content: center; + width: 1em; + height: 1em; + color: var(--color-text--tertiary); +} + +.toastProgress { + width: 100%; + height: 0.125rem; + background-color: rgb(0 0 0 / 0.3); +} + +.toastProgressBar { + height: 100%; + background-color: var(--feature-color); + animation: progress-bar var(--bar-timer) linear forwards; +} + /* Styles for Toast's text */ .message { display: flex; @@ -70,35 +98,6 @@ --text-color: var(--alert-danger-text-color); } -.closeIconWrapper { - position: absolute; - top: 0.5rem; - right: 0.5rem; -} - -.closeIcon { - display: flex; - align-items: center; - justify-content: center; - width: 1.875rem; - height: 1.875rem; -} - -.toastProgress { - width: 100%; - height: 0.125rem; - background-color: rgb(0 0 0 / 0.3); -} - -.toastProgressBar { - height: 100%; - background-color: var(--feature-color); -} - -.toastProgressBarTimer { - animation: progress-bar 10s linear forwards; -} - @keyframes progress-bar { 0% { width: 100%; @@ -109,40 +108,74 @@ } } +/* CSS for the Toast container */ .toastContainer { + --viewport-padding: 25px; + position: fixed; - bottom: 1rem; - left: 1rem; - z-index: 9999; + bottom: 0; + left: 0; + z-index: 2147483647; display: flex; flex-direction: column; - row-gap: 1rem; + gap: 10px; + width: 390px; + max-width: 100vw; + margin: 0; + padding: var(--viewport-padding); + list-style: none; + outline: none; + + --radix-toast-swipe-end-x: -25px; +} + +.root[data-state="open"] { + animation: slide-in 600ms cubic-bezier(0.16, 1, 0.3, 1); } -.rootFadeIn { - animation: fadein 0.3s linear forwards; +.root[data-state="closed"] { + animation: hide 200ms ease-in; } -.rootFadeOut { - animation: fadeout 0.3s linear forwards; +.root[data-swipe="move"] { + transform: translateX(var(--radix-toast-swipe-move-x)); } -@keyframes fadein { - 0% { opacity: 0; } - 100% { opacity: 1; } +.root[data-swipe="cancel"] { + transform: translateX(0); + transition: transform 200ms ease-out; } -@keyframes fadein { - 0% { opacity: 0; } - 100% { opacity: 1; } +.root[data-swipe="end"] { + animation: swipe-out 600ms ease-out; } -@keyframes fadeout { - 0% { opacity: 1; } - 100% { opacity: 0; } +@keyframes hide { + from { + opacity: 1; + } + + to { + opacity: 0; + } } -@keyframes fadeout { - 0% { opacity: 1; } - 100% { opacity: 0; } +@keyframes slide-in { + from { + transform: translateX(calc(-100% - var(--viewport-padding))); + } + + to { + transform: translateX(0); + } +} + +@keyframes swipe-out { + from { + transform: translateX(var(--radix-toast-swipe-end-x)); + } + + to { + transform: translateX(calc(-100% - var(--viewport-padding))); + } } diff --git a/packages/cyberstorm/src/components/NewToast/NewToast.tsx b/packages/cyberstorm/src/components/NewToast/NewToast.tsx index 8d0a51b81..df2c9aad5 100644 --- a/packages/cyberstorm/src/components/NewToast/NewToast.tsx +++ b/packages/cyberstorm/src/components/NewToast/NewToast.tsx @@ -1,12 +1,10 @@ "use client"; -import React, { ReactNode, useContext, useState } from "react"; +import React, { CSSProperties, ReactNode } from "react"; import styles from "./NewToast.module.css"; import { Icon } from "../Icon/Icon"; import { classnames } from "../../utils/utils"; -import { Button } from "../.."; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faXmarkLarge } from "@fortawesome/pro-solid-svg-icons"; -import { ToastContext } from "./NewToastContext"; import * as RadixToast from "@radix-ui/react-toast"; type _ToastProps = { @@ -14,44 +12,20 @@ type _ToastProps = { content: ReactNode; icon?: JSX.Element; variant?: "info" | "danger" | "warning" | "success"; - noTimer?: boolean; + timer?: number; }; export type ToastProps = _ToastProps & Omit, keyof _ToastProps>; export function Toast(props: ToastProps) { - const { id, content, icon, variant = "info", noTimer = false } = props; - const useToast = () => useContext(ToastContext); - const toast = useToast(); - const [isFadingOut, setIsFadingOut] = useState(false); - const [isFadingIn, setIsFadingIn] = useState(true); - - // Fade in - setTimeout(() => setIsFadingIn(false), 300); - - const removeToast = () => { - toast?.remove(id); - setIsFadingOut(false); - }; - const fadeOut = () => { - setIsFadingOut(true); - setTimeout(() => removeToast(), 300); - }; - - // Auto remove after 10 seconds - if (!noTimer) { - setTimeout(() => fadeOut(), 10000); - } + const { content, icon, variant = "info", timer = 10000 } = props; + const timerCSS = { + "--bar-timer": `${timer / 1000}s`, + } as CSSProperties; return ( - -
+ +
@@ -60,27 +34,12 @@ export function Toast(props: ToastProps) {
-
+
- -
- - - - - -
+ + + +
diff --git a/packages/cyberstorm/src/components/NewToast/NewToastContainer.tsx b/packages/cyberstorm/src/components/NewToast/NewToastContainer.tsx index c6b2b3387..35233e58f 100644 --- a/packages/cyberstorm/src/components/NewToast/NewToastContainer.tsx +++ b/packages/cyberstorm/src/components/NewToast/NewToastContainer.tsx @@ -9,7 +9,7 @@ export function ToastContainer(props: { variant?: "info" | "danger" | "warning" | "success"; icon?: JSX.Element; message?: string; - noTimer?: boolean; + timer?: number; }[]; }) { const { toasts } = props; @@ -24,7 +24,7 @@ export function ToastContainer(props: { icon={toast.icon} content={toast.message} variant={toast.variant} - noTimer={toast.noTimer} + timer={toast.timer} /> ))}
diff --git a/packages/cyberstorm/src/components/NewToast/NewToastContext.tsx b/packages/cyberstorm/src/components/NewToast/NewToastContext.tsx index 91dbf1662..198b57a45 100644 --- a/packages/cyberstorm/src/components/NewToast/NewToastContext.tsx +++ b/packages/cyberstorm/src/components/NewToast/NewToastContext.tsx @@ -9,7 +9,7 @@ const initState: { variant?: "info" | "danger" | "warning" | "success"; icon?: JSX.Element; message?: string; - noTimer?: boolean; + timer?: number; }[]; } = { toasts: [] }; @@ -20,7 +20,7 @@ const toastReducer = ( variant?: "info" | "danger" | "warning" | "success"; icon?: JSX.Element; message?: string; - noTimer?: boolean; + timer?: number; }[]; }, action: { @@ -30,7 +30,7 @@ const toastReducer = ( variant?: "info" | "danger" | "warning" | "success"; icon?: JSX.Element; message?: string; - noTimer?: boolean; + timer?: number; }; } ) => { @@ -58,7 +58,7 @@ interface ContextInterface { variant?: "info" | "danger" | "warning" | "success", icon?: JSX.Element, message?: string, - noTimer?: boolean + timer?: number ) => void; remove: (id: string) => void; } @@ -72,10 +72,10 @@ export function ToastProvider(props: PropsWithChildren) { variant?: "info" | "danger" | "warning" | "success", icon?: JSX.Element, message?: string, - noTimer?: boolean + timer?: number ) => { const id = uuid(); - dispatch({ type: "add", toast: { id, variant, icon, message, noTimer } }); + dispatch({ type: "add", toast: { id, variant, icon, message, timer } }); }; const remove = (id: string) => { @@ -89,7 +89,7 @@ export function ToastProvider(props: PropsWithChildren) { return ( - + {props.children} diff --git a/packages/cyberstorm/src/components/Providers.tsx b/packages/cyberstorm/src/components/Providers.tsx index 99cf7f543..56a140f03 100644 --- a/packages/cyberstorm/src/components/Providers.tsx +++ b/packages/cyberstorm/src/components/Providers.tsx @@ -1,7 +1,7 @@ "use client"; import * as RadixTooltip from "@radix-ui/react-tooltip"; import { ReactNode } from "react"; -import { ToastProvider } from "./Toast/ToastContext"; +import { ToastProvider } from "./NewToast/NewToastContext"; interface CyberstormProvidersProps { children: ReactNode | ReactNode[];