about summary refs log tree commit diff
path: root/src/components/Toast/index.web.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/Toast/index.web.tsx')
-rw-r--r--src/components/Toast/index.web.tsx54
1 files changed, 47 insertions, 7 deletions
diff --git a/src/components/Toast/index.web.tsx b/src/components/Toast/index.web.tsx
index 857ed7b39..8b2028db9 100644
--- a/src/components/Toast/index.web.tsx
+++ b/src/components/Toast/index.web.tsx
@@ -1,10 +1,21 @@
+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 {
+  Icon as ToastIcon,
+  Outer as ToastOuter,
+  Text as ToastText,
+  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.
@@ -30,11 +41,40 @@ export const api = sonner
  */
 export function show(
   content: React.ReactNode,
-  {type, ...options}: BaseToastOptions = {},
+  {type = 'default', ...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} type={type}>
+        <ToastOuter>
+          <ToastIcon />
+          <ToastText>{content}</ToastText>
+        </ToastOuter>
+      </ToastConfigProvider>,
+      {
+        ...options,
+        unstyled: true, // required on web
+        id,
+        duration: options?.duration ?? DURATION,
+      },
+    )
+  } else if (React.isValidElement(content)) {
+    sonner(
+      <ToastConfigProvider id={id} type={type}>
+        {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}`,
+    )
+  }
 }