From d47c3ae3d6f25e7c1af83b0f6d3922f5ff93c434 Mon Sep 17 00:00:00 2001 From: andresdjasso Date: Mon, 8 Jun 2026 14:13:37 -0500 Subject: [PATCH 01/17] =?UTF-8?q?feat(emcn/toast):=20redesign=20toast=20?= =?UTF-8?q?=E2=80=94=20intent=20variants,=20Sonner-style=20stack,=20hover?= =?UTF-8?q?=20text=20reveal,=20dismiss-all?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Component (apps/sim/components/emcn/components/toast/toast.tsx): - Variants default/info/success/warning/error, each with a distinct outline icon (CircleAlert/TriangleAlert/CircleCheck/Info/Bell) rendered inline with the message in a neutral color — no badge; intent reads from icon + copy. - Stacking modeled on Sonner/Base-UI: a collapsed pile that fans open upward only when the cards are hovered. One fixed-duration expo-out tween drives all cards so rapid arrivals move in unison (no lagging card); cards arrive collapsed (expand is scoped to a wrapper around the cards, not the dismiss control). - Title vs subtext hierarchy: message is a medium, primary-color title; the optional description is lighter/smaller subtext. - Truncated text reveals its hidden lines on hover (RevealText): only the previously hidden lines blur in; the card height tracks the content so the action button stays pinned (no clipping). Larger bottom gradient fade hints at more text. - Concentric corner radius (16px = chip 8px + 8px padding); single-line cards use a tighter 12px so they don't read as pills. - Dismiss-all control: a small circular chip just outside the stack's bottom-left, shown at 2+ toasts. Linear auto-dismiss ring that restarts on each new arrival, pauses on hover, click to clear all; spring 'pop' entrance. - Bug fixes: route-scoped clearing (toasts no longer trail across navigation), dedup of the add/update double-fire, actionable toasts persist by default. Source/usage: - stores/terminal/console/store.ts: notifyBlockError now passes the block name as the title and the error as the description (title/subtext), plus the dedup window. - app/playground/page.tsx: Toast section added to the EMCN gallery. - New EMCN icons: circle-alert, circle-check, info, triangle-alert. Co-Authored-By: Claude Opus 4.8 --- apps/sim/app/playground/page.tsx | 1685 +++++++++-------- .../emcn/components/toast/toast.tsx | 674 +++++-- .../components/emcn/icons/circle-alert.tsx | 27 + .../components/emcn/icons/circle-check.tsx | 26 + apps/sim/components/emcn/icons/index.ts | 4 + apps/sim/components/emcn/icons/info.tsx | 27 + .../components/emcn/icons/triangle-alert.tsx | 27 + apps/sim/stores/terminal/console/store.ts | 23 +- 8 files changed, 1548 insertions(+), 945 deletions(-) create mode 100644 apps/sim/components/emcn/icons/circle-alert.tsx create mode 100644 apps/sim/components/emcn/icons/circle-check.tsx create mode 100644 apps/sim/components/emcn/icons/info.tsx create mode 100644 apps/sim/components/emcn/icons/triangle-alert.tsx diff --git a/apps/sim/app/playground/page.tsx b/apps/sim/app/playground/page.tsx index 1cc5ddf50b3..bd5a2ebb64f 100644 --- a/apps/sim/app/playground/page.tsx +++ b/apps/sim/app/playground/page.tsx @@ -78,9 +78,11 @@ import { type TagItem, Textarea, TimePicker, + ToastProvider, Tooltip, Trash, Trash2, + toast, Undo, Wrap, ZoomIn, @@ -164,809 +166,910 @@ export default function PlaygroundPage() { } return ( - -
-
- - - - - Go back - -
-
- - - - - {isDarkMode ? 'Light mode' : 'Dark mode'} - -
-
-
-

- EMCN Component Playground -

-

- All emcn UI components and their variants -

+ + +
+
+ + + + + Go back +
- - {/* Button */} -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - {/* ButtonGroup */} -
- - - cURL - Python - JavaScript - - - - - Option 1 - Option 2 - - - - - Option 1 - Option 2 - - - - - Option 1 - Option 2 - - - - - Only Option - - -
- - {/* Badge */} -
- - Default - - - Outline - - - Type - - - Green - - With Dot - - - - Red - - With Dot - - - - Blue - - With Dot - - - - Blue Secondary - - - Purple - - - Orange - - - Amber - - - Teal - - - Cyan - - - Gray - - - Gray Secondary - - - Small - Medium - Large - -
- - {/* Input */} -
- - - - - - -
- - {/* TagInput */} -
- -
- { - const isValid = value.includes('@') && value.includes('.') - setTagItems((prev) => [...prev, { value, isValid }]) - return isValid - }} - onRemove={(_, index) => { - setTagItems((prev) => prev.filter((_, i) => i !== index)) - }} - placeholder='Enter emails...' - placeholderWithTags='Add another' - /> -
-
- -
- true} - onRemove={() => {}} - placeholder='Add tags' - placeholderWithTags='Add another' - triggerKeys={['Enter', ',']} - /> -
-
- -
- false} - onRemove={() => {}} - placeholder='Disabled input' - disabled - /> -
-
-
- - {/* Textarea */} -
-