about summary refs log tree commit diff
path: root/src/components/Toast/index.web.tsx
diff options
context:
space:
mode:
authorEric Bailey <git@esb.lol>2025-08-26 11:20:04 -0500
committerGitHub <noreply@github.com>2025-08-26 11:20:04 -0500
commit8ec20026c042e1f26224ef2967dad6f0386e1eca (patch)
tree751add9e13a9c631724cc1c7ec120bdbc4f3a318 /src/components/Toast/index.web.tsx
parentacd7211b357f2bfc74bf0828994e12f0c41d39d5 (diff)
downloadvoidsky-8ec20026c042e1f26224ef2967dad6f0386e1eca.tar.zst
Yeah toast (#8878)
* Split out into macro component

* Add Action component

* Add fallback

* add button to view post after sending

* Dismiss toast when clicking action button

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
Diffstat (limited to 'src/components/Toast/index.web.tsx')
-rw-r--r--src/components/Toast/index.web.tsx42
1 files changed, 36 insertions, 6 deletions
diff --git a/src/components/Toast/index.web.tsx b/src/components/Toast/index.web.tsx
index 857ed7b39..c4db20dca 100644
--- a/src/components/Toast/index.web.tsx
+++ b/src/components/Toast/index.web.tsx
@@ -1,10 +1,19 @@
+import React from 'react'
+import {nanoid} from 'nanoid/non-secure'
 import {toast as sonner, Toaster} from 'sonner'
 
 import {atoms as a} from '#/alf'
 import {DURATION} from '#/components/Toast/const'
-import {Toast} from '#/components/Toast/Toast'
+import {
+  Default as DefaultToast,
+  ToastConfigProvider,
+} from '#/components/Toast/Toast'
 import {type BaseToastOptions} from '#/components/Toast/types'
 
+export {DURATION} from '#/components/Toast/const'
+export * from '#/components/Toast/Toast'
+export {type ToastType} from '#/components/Toast/types'
+
 /**
  * Toasts are rendered in a global outlet, which is placed at the top of the
  * component tree.
@@ -32,9 +41,30 @@ export function show(
   content: React.ReactNode,
   {type, ...options}: BaseToastOptions = {},
 ) {
-  sonner(<Toast content={content} type={type} />, {
-    unstyled: true, // required on web
-    ...options,
-    duration: options?.duration ?? DURATION,
-  })
+  const id = nanoid()
+
+  if (typeof content === 'string') {
+    sonner(
+      <ToastConfigProvider id={id}>
+        <DefaultToast content={content} type={type} />
+      </ToastConfigProvider>,
+      {
+        ...options,
+        unstyled: true, // required on web
+        id,
+        duration: options?.duration ?? DURATION,
+      },
+    )
+  } else if (React.isValidElement(content)) {
+    sonner(<ToastConfigProvider id={id}>{content}</ToastConfigProvider>, {
+      ...options,
+      unstyled: true, // required on web
+      id,
+      duration: options?.duration ?? DURATION,
+    })
+  } else {
+    throw new Error(
+      `Toast can be a string or a React element, got ${typeof content}`,
+    )
+  }
 }