From c6c0606cf81ca0407d57a805a4a34b09c67e8c14 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia Date: Tue, 9 Dec 2025 19:51:53 +0530 Subject: [PATCH] refactor: toast design token updated --- .../create-issue-toast-action-items.tsx | 2 +- packages/propel/src/toast/toast.stories.tsx | 369 ++++++++++++++++-- packages/propel/src/toast/toast.tsx | 163 +++++--- 3 files changed, 443 insertions(+), 91 deletions(-) diff --git a/apps/web/core/components/issues/create-issue-toast-action-items.tsx b/apps/web/core/components/issues/create-issue-toast-action-items.tsx index 4b2924b9abb..550bc2ec4f4 100644 --- a/apps/web/core/components/issues/create-issue-toast-action-items.tsx +++ b/apps/web/core/components/issues/create-issue-toast-action-items.tsx @@ -55,7 +55,7 @@ export const CreateIssueToastActionItems = observer(function CreateIssueToastAct }; return ( -
+
Show Success Toast @@ -67,7 +67,7 @@ export const Error: Story = { message: "Something went wrong. Please try again.", }) } - className="rounded-sm bg-red-500 px-4 py-2 text-on-color hover:bg-red-600" + className="rounded-sm bg-danger-primary px-4 py-2 text-13 text-on-color hover:bg-danger-primary/90" > Show Error Toast @@ -89,7 +89,7 @@ export const Warning: Story = { message: "This action cannot be undone.", }) } - className="rounded-sm bg-yellow-500 px-4 py-2 text-on-color hover:bg-yellow-600" + className="rounded-sm bg-warning-primary px-4 py-2 text-13 text-on-color hover:bg-warning-primary/90" > Show Warning Toast @@ -111,7 +111,7 @@ export const Info: Story = { message: "Here's some helpful information for you.", }) } - className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600" + className="rounded-sm bg-accent-primary px-4 py-2 text-13 text-on-color hover:bg-accent-primary/90" > Show Info Toast @@ -132,7 +132,7 @@ export const Loading: Story = { title: "Loading...", }) } - className="rounded-sm bg-gray-500 px-4 py-2 text-on-color hover:bg-gray-600" + className="rounded-sm bg-layer-2 border border-subtle px-4 py-2 text-13 text-primary hover:bg-layer-1" > Show Loading Toast @@ -153,23 +153,14 @@ export const WithActionItems: Story = { title: "File uploaded", message: "Your file has been uploaded successfully.", actionItems: ( -
- - {`View work item`} - - -
+ <> + + + ), }) } - className="rounded-sm bg-green-500 px-4 py-2 text-on-color hover:bg-green-600" + className="rounded-sm bg-success-primary px-4 py-2 text-13 text-on-color hover:bg-success-primary/90" > Show Toast with Action @@ -198,7 +189,10 @@ export const UpdateToast: Story = { return ( <> - @@ -233,7 +227,7 @@ export const PromiseToast: Story = { @@ -256,7 +250,7 @@ export const AllTypes: Story = { message: "Operation successful", }) } - className="rounded-sm bg-green-500 px-3 py-2 text-13 text-on-color hover:bg-green-600" + className="rounded-sm bg-success-primary px-3 py-2 text-13 text-on-color hover:bg-success-primary/90" > Success @@ -268,7 +262,7 @@ export const AllTypes: Story = { message: "Operation failed", }) } - className="rounded-sm bg-red-500 px-3 py-2 text-13 text-on-color hover:bg-red-600" + className="rounded-sm bg-danger-primary px-3 py-2 text-13 text-on-color hover:bg-danger-primary/90" > Error @@ -280,7 +274,7 @@ export const AllTypes: Story = { message: "Please be careful", }) } - className="rounded-sm bg-yellow-500 px-3 py-2 text-13 text-on-color hover:bg-yellow-600" + className="rounded-sm bg-warning-primary px-3 py-2 text-13 text-on-color hover:bg-warning-primary/90" > Warning @@ -292,7 +286,7 @@ export const AllTypes: Story = { message: "Here's some info", }) } - className="rounded-sm bg-blue-500 px-3 py-2 text-13 text-on-color hover:bg-blue-600" + className="rounded-sm bg-accent-primary px-3 py-2 text-13 text-on-color hover:bg-accent-primary/90" > Info @@ -303,7 +297,7 @@ export const AllTypes: Story = { title: "Loading", }) } - className="rounded-sm bg-gray-500 px-3 py-2 text-13 text-on-color hover:bg-gray-600" + className="rounded-sm bg-layer-2 border border-subtle px-3 py-2 text-13 text-primary hover:bg-layer-1" > Loading @@ -340,7 +334,7 @@ export const MultipleToasts: Story = { }); }, 1000); }} - className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600" + className="rounded-sm bg-accent-primary px-4 py-2 text-13 text-on-color hover:bg-accent-primary/90" > Show Multiple Toasts @@ -361,7 +355,7 @@ export const TitleOnly: Story = { title: "Saved!", }) } - className="rounded-sm bg-green-500 px-4 py-2 text-on-color hover:bg-green-600" + className="rounded-sm bg-success-primary px-4 py-2 text-13 text-on-color hover:bg-success-primary/90" > Show Title Only @@ -384,7 +378,7 @@ export const LongMessage: Story = { "This is a longer message that provides more detailed information about what happened and what the user should do next.", }) } - className="rounded-sm bg-blue-500 px-4 py-2 text-on-color hover:bg-blue-600" + className="rounded-sm bg-accent-primary px-4 py-2 text-13 text-on-color hover:bg-accent-primary/90" > Show Long Message @@ -392,3 +386,318 @@ export const LongMessage: Story = { ); }, }; + +// ========== Static Variants ========== + +export const StaticVariants: Story = { + render() { + return ( +
+
+

All toast variants (static):

+
+
+ + + + + +
+
+ ); + }, +}; + +export const StaticSuccess: Story = { + render() { + return ( + + ); + }, +}; + +export const StaticError: Story = { + render() { + return ; + }, +}; + +export const StaticWarning: Story = { + render() { + return ( + + ); + }, +}; + +export const StaticInfo: Story = { + render() { + return ( + + ); + }, +}; + +export const StaticLoading: Story = { + render() { + return ; + }, +}; + +export const StaticWithActions: Story = { + render() { + return ( + + + + + } + /> + ); + }, +}; + +export const StaticDarkMode: Story = { + render() { + return ( +
+

Toast variants in dark mode:

+ + + + + +
+ ); + }, +}; + +// ========== Design Tokens Documentation ========== + +export const DesignTokens: Story = { + render() { + return ( +
+
+

Toast Design Tokens

+

+ The toast component uses semantic design tokens from the Plane design system. +

+
+ +
+

Token Mapping by Variant

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
VariantTitle TextIcon BGToast BGBorder
Success + text-primary + + bg-success-primary + + bg-surface-1 + + border-subtle +
Error + text-primary + + bg-danger-primary + + bg-surface-1 + + border-subtle +
Warning + text-primary + + bg-warning-primary + + bg-surface-1 + + border-subtle +
Info + text-primary + + bg-accent-primary + + bg-surface-1 + + border-subtle +
Loading + text-primary + + bg-layer-2 + + bg-surface-1 + + border-subtle +
+
+
+ +
+
+

Typography

+
    +
  • + Title:{" "} + text-14 font-semibold +
  • +
  • + Message:{" "} + text-13 +
  • +
  • + Message Color:{" "} + text-secondary +
  • +
  • + Action Button:{" "} + text-13 font-medium +
  • +
+
+ +
+

Dimensions & Styling

+
    +
  • + Width: 350px +
  • +
  • + Padding: 16px (p-4) +
  • +
  • + Border Radius: 8px (rounded-lg) +
  • +
  • + Shadow:{" "} + shadow-raised-200 +
  • +
  • + Border Width: 1px +
  • +
+
+
+ +
+

Icon Specifications

+
    +
  • + Icon Size: 20x20px +
  • +
  • + Icon Stroke Width: 2px +
  • +
  • + Icon Container: 40x40px circular (w-10 h-10 + rounded-full) +
  • +
  • + Icon Color:{" "} + text-on-color +
  • +
  • + Icon Background:{" "} + + bg-{"{"}variant{"}"}-primary + +
  • +
  • + Close Icon Size: 16x16px +
  • +
  • + Close Icon Color:{" "} + + text-icon-secondary hover:text-icon-tertiary + +
  • +
+
+ +
+

Visual Examples

+

See how the tokens are applied across all toast variants:

+
+ + + + + +
+
+
+ ); + }, +}; diff --git a/packages/propel/src/toast/toast.tsx b/packages/propel/src/toast/toast.tsx index 74b7b96e7f9..fac617a7af4 100644 --- a/packages/propel/src/toast/toast.tsx +++ b/packages/propel/src/toast/toast.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import { Toast as BaseToast } from "@base-ui-components/react/toast"; -import { AlertTriangle, CheckCircle2, XCircle } from "lucide-react"; -import { CloseIcon } from "../icons"; +import { AlertTriangle, CheckIcon, InfoIcon, XIcon } from "lucide-react"; +import { CloseIcon } from "../icons/actions/close-icon"; // spinner import { CircularBarSpinner } from "../spinners/circular-bar-spinner"; import { cn } from "../utils/classname"; @@ -63,40 +63,40 @@ export function Toast(props: ToastProps) { const TOAST_DATA = { [TOAST_TYPE.SUCCESS]: { - icon: , - textColorClassName: "text-toast-text-success", - backgroundColorClassName: "bg-toast-background-success", - borderColorClassName: "border-toast-border-success", + icon: , + iconBgClassName: "bg-success-primary", + backgroundColorClassName: "!bg-surface-1", + borderColorClassName: "border-subtle", }, [TOAST_TYPE.ERROR]: { - icon: , - textColorClassName: "text-toast-text-error", - backgroundColorClassName: "bg-toast-background-error", - borderColorClassName: "border-toast-border-error", + icon: , + iconBgClassName: "bg-danger-primary", + backgroundColorClassName: "bg-surface-1", + borderColorClassName: "border-subtle", }, [TOAST_TYPE.WARNING]: { - icon: , - textColorClassName: "text-toast-text-warning", - backgroundColorClassName: "bg-toast-background-warning", - borderColorClassName: "border-toast-border-warning", + icon: , + iconBgClassName: "bg-warning-primary", + backgroundColorClassName: "bg-surface-1", + borderColorClassName: "border-subtle", }, [TOAST_TYPE.INFO]: { - icon: <>, - textColorClassName: "text-toast-text-info", - backgroundColorClassName: "bg-toast-background-info", - borderColorClassName: "border-toast-border-info", + icon: , + iconBgClassName: "bg-accent-primary", + backgroundColorClassName: "bg-surface-1", + borderColorClassName: "border-subtle", }, [TOAST_TYPE.LOADING]: { - icon: , - textColorClassName: "text-toast-text-loading", - backgroundColorClassName: "bg-toast-background-loading", - borderColorClassName: "border-toast-border-loading", + icon: , + iconBgClassName: "bg-layer-2", + backgroundColorClassName: "bg-surface-1", + borderColorClassName: "border-subtle", }, [TOAST_TYPE.LOADING_TOAST]: { - icon: , - textColorClassName: "text-toast-text-loading", - backgroundColorClassName: "bg-toast-background-loading", - borderColorClassName: "border-toast-border-loading", + icon: , + iconBgClassName: "bg-layer-2", + backgroundColorClassName: "bg-surface-1", + borderColorClassName: "border-subtle", }, }; @@ -116,7 +116,7 @@ function ToastRender({ id, toast }: { id: React.Key; toast: BaseToast.Root.Toast key={id} className={cn( // Base layout and positioning - "flex group items-center rounded-lg border shadow-sm p-2 w-[350px]", + "flex group items-center rounded-lg border shadow-raised-200 w-[350px]", "absolute right-3 bottom-3 z-[calc(1000-var(--toast-index))]", "select-none transition-[opacity,transform] duration-500 ease-[cubic-bezier(0.22,1,0.36,1)]", @@ -157,45 +157,88 @@ function ToastRender({ id, toast }: { id: React.Key; toast: BaseToast.Root.Toast e.preventDefault(); }} > - {toastData.type === TOAST_TYPE.LOADING ? ( -
- {data.icon &&
{data.icon}
} -
-
- {toastData.title ?? "Loading..."} -
- + + +
+
+ {data.icon && ( +
- - -
+ {data.icon} +
+ )}
- ) : ( - <> - - - -
-
- {data.icon &&
{data.icon}
} -
- - {toastData.title} - - {toastData.message && ( - - {toastData.message} - +
+ + {toastData.type === TOAST_TYPE.LOADING ? (toastData.title ?? "Loading...") : toastData.title} + + {toastData.type !== TOAST_TYPE.LOADING && toastData.message && ( + + {toastData.message} + + )} + {toastData.type !== TOAST_TYPE.LOADING && toastData.actionItems && ( +
{toastData.actionItems}
+ )} +
+
+ + ); +} + +// Static toast component for Storybook and documentation +export type ToastStaticProps = { + type: TOAST_TYPE; + title: string; + message?: string; + actionItems?: React.ReactNode; + theme?: "light" | "dark"; +}; + +export function ToastStatic({ type, title, message, actionItems, theme = "light" }: ToastStaticProps) { + const data = TOAST_DATA[type]; + + return ( +
+
+
+ +
+
+
+ {data.icon && ( +
+ {data.icon}
+ )} +
+
+
+ {type === TOAST_TYPE.LOADING ? (title ?? "Loading...") : title}
- {toastData.actionItems &&
{toastData.actionItems}
} + {type !== TOAST_TYPE.LOADING && message && ( +
{message}
+ )} + {type !== TOAST_TYPE.LOADING && actionItems &&
{actionItems}
}
- - )} - +
+
+
); }