From 675112079c5676a4dcce1cde3c1ceaed3f8083d5 Mon Sep 17 00:00:00 2001 From: Andre H Date: Thu, 22 Feb 2024 14:16:47 +0700 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20feat:=20implement=20toast?= =?UTF-8?q?=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shared/Toast/SimpleToast.theme.ts | 10 ++++ .../components/shared/Toast/SimpleToast.tsx | 51 ++++++++++++++++--- 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/packages/frontend/src/components/shared/Toast/SimpleToast.theme.ts b/packages/frontend/src/components/shared/Toast/SimpleToast.theme.ts index 0d8ae24b..bac805ce 100644 --- a/packages/frontend/src/components/shared/Toast/SimpleToast.theme.ts +++ b/packages/frontend/src/components/shared/Toast/SimpleToast.theme.ts @@ -5,6 +5,7 @@ export const simpleToastTheme = tv( slots: { wrapper: [ 'flex', + 'items-center', 'py-2', 'pl-2', 'pr-1.5', @@ -18,6 +19,15 @@ export const simpleToastTheme = tv( 'shadow-sm', ], icon: ['flex', 'items-center', 'justify-center', 'w-5', 'h-5'], + closeIcon: [ + 'cursor-pointer', + 'flex', + 'items-center', + 'justify-center', + 'w-6', + 'h-6', + 'text-elements-on-high-contrast', + ], title: ['text-sm', 'text-elements-on-high-contrast'], }, variants: { diff --git a/packages/frontend/src/components/shared/Toast/SimpleToast.tsx b/packages/frontend/src/components/shared/Toast/SimpleToast.tsx index e134d647..b3bafc21 100644 --- a/packages/frontend/src/components/shared/Toast/SimpleToast.tsx +++ b/packages/frontend/src/components/shared/Toast/SimpleToast.tsx @@ -2,41 +2,80 @@ import React, { useMemo } from 'react'; import * as ToastPrimitive from '@radix-ui/react-toast'; import { ToastProps } from '@radix-ui/react-toast'; import { simpleToastTheme, type SimpleToastTheme } from './SimpleToast.theme'; -import { CheckIcon, CheckRoundFilledIcon } from 'components/shared/CustomIcon'; +import { + LoadingIcon, + CheckRoundFilledIcon, + CrossIcon, + InfoRoundFilledIcon, + WarningIcon, +} from 'components/shared/CustomIcon'; +import { Button, ButtonBaseProps, ButtonTheme } from 'components/shared/Button'; import { cloneIcon } from 'utils/cloneIcon'; +import { cn } from 'utils/classnames'; +interface CtaProps extends ButtonBaseProps, ButtonTheme { + buttonLabel: string; +} export interface SimpleToastProps extends ToastProps { title: string; variant?: SimpleToastTheme['variant']; + cta?: CtaProps[]; + onDismiss: (id?: string) => void; } export const SimpleToast = ({ className, title, variant = 'success', + cta = [], + onDismiss, ...props }: SimpleToastProps) => { + const hasCta = cta.length > 0; const { wrapper: wrapperCls, icon: iconCls, + closeIcon: closeIconCls, title: titleCls, } = simpleToastTheme({ variant }); const Icon = useMemo(() => { if (variant === 'success') return ; - if (variant === 'error') return ; - if (variant === 'warning') return ; - if (variant === 'info') return ; - return ; // variant === 'loading' + if (variant === 'error') return ; + if (variant === 'warning') return ; + if (variant === 'info') return ; + return ; // variant === 'loading' }, [variant]); + const renderCta = useMemo( + () => + hasCta ? ( +
+ {cta.map(({ buttonLabel, ...props }, index) => ( + + ))} +
+ ) : null, + [], + ); + + const renderCloseButton = () => ( +
onDismiss(props.id)} className={closeIconCls()}> + +
+ ); + return ( -
+
{cloneIcon(Icon, { className: iconCls() })}

{title}

+ {renderCta} + {renderCloseButton()}
);