about summary refs log tree commit diff
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
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>
-rw-r--r--.eslintrc.js1
-rw-r--r--src/components/Toast/Toast.tsx269
-rw-r--r--src/components/Toast/index.tsx57
-rw-r--r--src/components/Toast/index.web.tsx42
-rw-r--r--src/components/Toast/sonner/index.ts3
-rw-r--r--src/components/Toast/sonner/index.web.ts3
-rw-r--r--src/view/com/composer/Composer.tsx39
-rw-r--r--src/view/screens/Storybook/Toasts.tsx89
8 files changed, 414 insertions, 89 deletions
diff --git a/.eslintrc.js b/.eslintrc.js
index 59c1b4eb4..b9c89c3d5 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -34,6 +34,7 @@ module.exports = {
           'P',
           'Admonition',
           'Admonition.Admonition',
+          'Toast.Action',
           'AgeAssuranceAdmonition',
           'Span',
         ],
diff --git a/src/components/Toast/Toast.tsx b/src/components/Toast/Toast.tsx
index 4d782597d..53d5e5115 100644
--- a/src/components/Toast/Toast.tsx
+++ b/src/components/Toast/Toast.tsx
@@ -1,21 +1,32 @@
 import {createContext, useContext, useMemo} from 'react'
-import {View} from 'react-native'
+import {type GestureResponderEvent, View} from 'react-native'
 
 import {atoms as a, select, useAlf, useTheme} from '#/alf'
+import {
+  Button,
+  type ButtonProps,
+  type UninheritableButtonProps,
+} from '#/components/Button'
+import {CircleCheck_Stroke2_Corner0_Rounded as CircleCheck} from '#/components/icons/CircleCheck'
 import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
 import {CircleInfo_Stroke2_Corner0_Rounded as ErrorIcon} from '#/components/icons/CircleInfo'
+import {type Props as SVGIconProps} from '#/components/icons/common'
 import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons/Warning'
+import {dismiss} from '#/components/Toast/sonner'
 import {type ToastType} from '#/components/Toast/types'
-import {Text} from '#/components/Typography'
-import {CircleCheck_Stroke2_Corner0_Rounded as CircleCheck} from '../icons/CircleCheck'
+import {Text as BaseText} from '#/components/Typography'
 
-type ContextType = {
+type ToastConfigContextType = {
+  id: string
+}
+
+type ToastThemeContextType = {
   type: ToastType
 }
 
 export type ToastComponentProps = {
   type?: ToastType
-  content: React.ReactNode
+  content: string
 }
 
 export const ICONS = {
@@ -26,81 +37,239 @@ export const ICONS = {
   info: CircleInfo,
 }
 
-const Context = createContext<ContextType>({
+const ToastConfigContext = createContext<ToastConfigContextType>({
+  id: '',
+})
+ToastConfigContext.displayName = 'ToastConfigContext'
+
+export function ToastConfigProvider({
+  children,
+  id,
+}: {
+  children: React.ReactNode
+  id: string
+}) {
+  return (
+    <ToastConfigContext.Provider value={useMemo(() => ({id}), [id])}>
+      {children}
+    </ToastConfigContext.Provider>
+  )
+}
+
+const ToastThemeContext = createContext<ToastThemeContextType>({
   type: 'default',
 })
-Context.displayName = 'ToastContext'
+ToastThemeContext.displayName = 'ToastThemeContext'
 
-export function Toast({type = 'default', content}: ToastComponentProps) {
-  const {fonts} = useAlf()
+export function Default({type = 'default', content}: ToastComponentProps) {
+  return (
+    <Outer type={type}>
+      <Icon />
+      <Text>{content}</Text>
+    </Outer>
+  )
+}
+
+export function Outer({
+  children,
+  type = 'default',
+}: {
+  children: React.ReactNode
+  type?: ToastType
+}) {
   const t = useTheme()
   const styles = useToastStyles({type})
-  const Icon = ICONS[type]
-  /**
-   * Vibes-based number, adjusts `top` of `View` that wraps the text to
-   * compensate for different type sizes and keep the first line of text
-   * aligned with the icon. - esb
-   */
-  const fontScaleCompensation = useMemo(
-    () => parseInt(fonts.scale) * -1 * 0.65,
-    [fonts.scale],
-  )
 
   return (
-    <Context.Provider value={useMemo(() => ({type}), [type])}>
+    <ToastThemeContext.Provider value={useMemo(() => ({type}), [type])}>
       <View
         style={[
           a.flex_1,
-          a.py_lg,
-          a.pl_xl,
-          a.pr_2xl,
+          a.p_lg,
           a.rounded_md,
           a.border,
           a.flex_row,
           a.gap_sm,
           t.atoms.shadow_sm,
           {
+            paddingVertical: 14, // 16 seems too big
             backgroundColor: styles.backgroundColor,
             borderColor: styles.borderColor,
           },
         ]}>
-        <Icon size="md" fill={styles.iconColor} />
-
-        <View
-          style={[
-            a.flex_1,
-            {
-              top: fontScaleCompensation,
-            },
-          ]}>
-          {typeof content === 'string' ? (
-            <ToastText>{content}</ToastText>
-          ) : (
-            content
-          )}
-        </View>
+        {children}
       </View>
-    </Context.Provider>
+    </ToastThemeContext.Provider>
   )
 }
 
-export function ToastText({children}: {children: React.ReactNode}) {
-  const {type} = useContext(Context)
+export function Icon({icon}: {icon?: React.ComponentType<SVGIconProps>}) {
+  const {type} = useContext(ToastThemeContext)
+  const styles = useToastStyles({type})
+  const IconComponent = icon || ICONS[type]
+  return <IconComponent size="md" fill={styles.iconColor} />
+}
+
+export function Text({children}: {children: React.ReactNode}) {
+  const {type} = useContext(ToastThemeContext)
   const {textColor} = useToastStyles({type})
+  const {fontScaleCompensation} = useToastFontScaleCompensation()
   return (
-    <Text
-      selectable={false}
+    <View
       style={[
-        a.text_md,
-        a.font_medium,
-        a.leading_snug,
-        a.pointer_events_none,
+        a.flex_1,
+        a.pr_lg,
         {
-          color: textColor,
+          top: fontScaleCompensation,
         },
       ]}>
-      {children}
-    </Text>
+      <BaseText
+        selectable={false}
+        style={[
+          a.text_md,
+          a.font_medium,
+          a.leading_snug,
+          a.pointer_events_none,
+          {
+            color: textColor,
+          },
+        ]}>
+        {children}
+      </BaseText>
+    </View>
+  )
+}
+
+export function Action(
+  props: Omit<ButtonProps, UninheritableButtonProps | 'children'> & {
+    children: string
+  },
+) {
+  const t = useTheme()
+  const {fontScaleCompensation} = useToastFontScaleCompensation()
+  const {type} = useContext(ToastThemeContext)
+  const {id} = useContext(ToastConfigContext)
+  const styles = useMemo(() => {
+    const base = {
+      base: {
+        textColor: t.palette.contrast_600,
+        backgroundColor: t.atoms.bg_contrast_25.backgroundColor,
+      },
+      interacted: {
+        textColor: t.atoms.text.color,
+        backgroundColor: t.atoms.bg_contrast_50.backgroundColor,
+      },
+    }
+    return {
+      default: base,
+      success: {
+        base: {
+          textColor: select(t.name, {
+            light: t.palette.primary_800,
+            dim: t.palette.primary_900,
+            dark: t.palette.primary_900,
+          }),
+          backgroundColor: t.palette.primary_25,
+        },
+        interacted: {
+          textColor: select(t.name, {
+            light: t.palette.primary_900,
+            dim: t.palette.primary_975,
+            dark: t.palette.primary_975,
+          }),
+          backgroundColor: t.palette.primary_50,
+        },
+      },
+      error: {
+        base: {
+          textColor: select(t.name, {
+            light: t.palette.negative_700,
+            dim: t.palette.negative_900,
+            dark: t.palette.negative_900,
+          }),
+          backgroundColor: t.palette.negative_25,
+        },
+        interacted: {
+          textColor: select(t.name, {
+            light: t.palette.negative_900,
+            dim: t.palette.negative_975,
+            dark: t.palette.negative_975,
+          }),
+          backgroundColor: t.palette.negative_50,
+        },
+      },
+      warning: base,
+      info: base,
+    }[type]
+  }, [t, type])
+
+  const onPress = (e: GestureResponderEvent) => {
+    console.log('Toast Action pressed, dismissing toast', id)
+    dismiss(id)
+    props.onPress?.(e)
+  }
+
+  return (
+    <View style={{top: fontScaleCompensation}}>
+      <Button {...props} onPress={onPress}>
+        {s => {
+          const interacted = s.pressed || s.hovered || s.focused
+          return (
+            <>
+              <View
+                style={[
+                  a.absolute,
+                  a.curve_continuous,
+                  {
+                    // tiny button styles
+                    top: -5,
+                    bottom: -5,
+                    left: -9,
+                    right: -9,
+                    borderRadius: 6,
+                    backgroundColor: interacted
+                      ? styles.interacted.backgroundColor
+                      : styles.base.backgroundColor,
+                  },
+                ]}
+              />
+              <BaseText
+                style={[
+                  a.text_md,
+                  a.font_medium,
+                  a.leading_snug,
+                  {
+                    color: interacted
+                      ? styles.interacted.textColor
+                      : styles.base.textColor,
+                  },
+                ]}>
+                {props.children}
+              </BaseText>
+            </>
+          )
+        }}
+      </Button>
+    </View>
+  )
+}
+
+/**
+ * Vibes-based number, provides t `top` value to wrap the text to compensate
+ * for different type sizes and keep the first line of text aligned with the
+ * icon. - esb
+ */
+function useToastFontScaleCompensation() {
+  const {fonts} = useAlf()
+  const fontScaleCompensation = useMemo(
+    () => parseInt(fonts.scale) * -1 * 0.65,
+    [fonts.scale],
+  )
+  return useMemo(
+    () => ({
+      fontScaleCompensation,
+    }),
+    [fontScaleCompensation],
   )
 }
 
diff --git a/src/components/Toast/index.tsx b/src/components/Toast/index.tsx
index 286d414a1..16d62afcd 100644
--- a/src/components/Toast/index.tsx
+++ b/src/components/Toast/index.tsx
@@ -1,15 +1,21 @@
+import React from 'react'
 import {View} from 'react-native'
+import {nanoid} from 'nanoid/non-secure'
 import {toast as sonner, Toaster} from 'sonner-native'
 
 import {atoms as a} from '#/alf'
 import {DURATION} from '#/components/Toast/const'
 import {
-  Toast as BaseToast,
+  Default as DefaultToast,
+  Outer as BaseOuter,
   type ToastComponentProps,
+  ToastConfigProvider,
 } from '#/components/Toast/Toast'
 import {type BaseToastOptions} from '#/components/Toast/types'
 
 export {DURATION} from '#/components/Toast/const'
+export {Action, Icon, Text} 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
@@ -22,10 +28,24 @@ export function ToastOutlet() {
 /**
  * The toast UI component
  */
-export function Toast({type, content}: ToastComponentProps) {
+export function Default({type, content}: ToastComponentProps) {
   return (
     <View style={[a.px_xl, a.w_full]}>
-      <BaseToast content={content} type={type} />
+      <DefaultToast content={content} type={type} />
+    </View>
+  )
+}
+
+export function Outer({
+  children,
+  type = 'default',
+}: {
+  children: React.ReactNode
+  type?: ToastComponentProps['type']
+}) {
+  return (
+    <View style={[a.px_xl, a.w_full]}>
+      <BaseOuter type={type}>{children}</BaseOuter>
     </View>
   )
 }
@@ -42,8 +62,31 @@ export function show(
   content: React.ReactNode,
   {type, ...options}: BaseToastOptions = {},
 ) {
-  sonner.custom(<Toast content={content} type={type} />, {
-    ...options,
-    duration: options?.duration ?? DURATION,
-  })
+  const id = nanoid()
+
+  if (typeof content === 'string') {
+    sonner.custom(
+      <ToastConfigProvider id={id}>
+        <DefaultToast content={content} type={type} />
+      </ToastConfigProvider>,
+      {
+        ...options,
+        id,
+        duration: options?.duration ?? DURATION,
+      },
+    )
+  } else if (React.isValidElement(content)) {
+    sonner.custom(
+      <ToastConfigProvider id={id}>{content}</ToastConfigProvider>,
+      {
+        ...options,
+        id,
+        duration: options?.duration ?? DURATION,
+      },
+    )
+  } else {
+    throw new Error(
+      `Toast can be a string or a React element, got ${typeof content}`,
+    )
+  }
 }
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}`,
+    )
+  }
 }
diff --git a/src/components/Toast/sonner/index.ts b/src/components/Toast/sonner/index.ts
new file mode 100644
index 000000000..35f8552c7
--- /dev/null
+++ b/src/components/Toast/sonner/index.ts
@@ -0,0 +1,3 @@
+import {toast} from 'sonner-native'
+
+export const dismiss = toast.dismiss
diff --git a/src/components/Toast/sonner/index.web.ts b/src/components/Toast/sonner/index.web.ts
new file mode 100644
index 000000000..12c4741d6
--- /dev/null
+++ b/src/components/Toast/sonner/index.web.ts
@@ -0,0 +1,3 @@
+import {toast} from 'sonner'
+
+export const dismiss = toast.dismiss
diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx
index d0dbdfaba..7d4eb8ca7 100644
--- a/src/view/com/composer/Composer.tsx
+++ b/src/view/com/composer/Composer.tsx
@@ -46,12 +46,14 @@ import {
   AppBskyFeedDefs,
   type AppBskyFeedGetPostThread,
   AppBskyUnspeccedDefs,
+  AtUri,
   type BskyAgent,
   type RichText,
 } from '@atproto/api'
 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
 import {msg, plural, Trans} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
+import {useNavigation} from '@react-navigation/native'
 import {useQueryClient} from '@tanstack/react-query'
 
 import * as apilib from '#/lib/api/index'
@@ -70,6 +72,7 @@ import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
 import {usePalette} from '#/lib/hooks/usePalette'
 import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
 import {mimeToExt} from '#/lib/media/video/util'
+import {type NavigationProp} from '#/lib/routes/types'
 import {logEvent} from '#/lib/statsig/statsig'
 import {cleanError} from '#/lib/strings/errors'
 import {colors} from '#/lib/styles'
@@ -123,12 +126,13 @@ import {Text} from '#/view/com/util/text/Text'
 import {UserAvatar} from '#/view/com/util/UserAvatar'
 import {atoms as a, native, useTheme, web} from '#/alf'
 import {Button, ButtonIcon, ButtonText} from '#/components/Button'
+import {CircleCheck_Stroke2_Corner0_Rounded as CircleCheckIcon} from '#/components/icons/CircleCheck'
 import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
 import {EmojiArc_Stroke2_Corner0_Rounded as EmojiSmile} from '#/components/icons/Emoji'
 import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
 import {LazyQuoteEmbed} from '#/components/Post/Embed/LazyQuoteEmbed'
 import * as Prompt from '#/components/Prompt'
-import * as toast from '#/components/Toast'
+import * as Toast from '#/components/Toast'
 import {Text as NewText} from '#/components/Typography'
 import {BottomSheetPortalProvider} from '../../../../modules/bottom-sheet'
 import {
@@ -188,6 +192,7 @@ export const ComposePost = ({
   const {closeAllDialogs} = useDialogStateControlContext()
   const {closeAllModals} = useModalControls()
   const {data: preferences} = usePreferencesQuery()
+  const navigation = useNavigation<NavigationProp>()
 
   const [isKeyboardVisible] = useIsKeyboardVisible({iosUseWillEvents: true})
   const [isPublishing, setIsPublishing] = useState(false)
@@ -521,12 +526,27 @@ export const ComposePost = ({
       onPostSuccess?.(postSuccessData)
     }
     onClose()
-    toast.show(
-      thread.posts.length > 1
-        ? _(msg`Your posts have been published`)
-        : replyTo
-          ? _(msg`Your reply has been published`)
-          : _(msg`Your post has been published`),
+    Toast.show(
+      <Toast.Outer type="success">
+        <Toast.Icon icon={CircleCheckIcon} />
+        <Toast.Text>
+          {thread.posts.length > 1
+            ? _(msg`Your posts were sent`)
+            : replyTo
+              ? _(msg`Your reply was sent`)
+              : _(msg`Your post was sent`)}
+        </Toast.Text>
+        {postUri && (
+          <Toast.Action
+            label={_(msg`View post`)}
+            onPress={() => {
+              const {host: name, rkey} = new AtUri(postUri)
+              navigation.navigate('PostThread', {name, rkey})
+            }}>
+            View
+          </Toast.Action>
+        )}
+      </Toast.Outer>,
       {type: 'success'},
     )
   }, [
@@ -543,6 +563,7 @@ export const ComposePost = ({
     replyTo,
     setLangPrefs,
     queryClient,
+    navigation,
   ])
 
   // Preserves the referential identity passed to each post item.
@@ -826,7 +847,7 @@ let ComposerPost = React.memo(function ComposerPost({
         if (isNative) return // web only
         const [mimeType] = uri.slice('data:'.length).split(';')
         if (!SUPPORTED_MIME_TYPES.includes(mimeType as SupportedMimeTypes)) {
-          toast.show(_(msg`Unsupported video type: ${mimeType}`), {
+          Toast.show(_(msg`Unsupported video type: ${mimeType}`), {
             type: 'error',
           })
           return
@@ -1362,7 +1383,7 @@ function ComposerFooter({
       }
 
       errors.map(error => {
-        toast.show(error, {
+        Toast.show(error, {
           type: 'warning',
         })
       })
diff --git a/src/view/screens/Storybook/Toasts.tsx b/src/view/screens/Storybook/Toasts.tsx
index 98d5b05e3..319f88e21 100644
--- a/src/view/screens/Storybook/Toasts.tsx
+++ b/src/view/screens/Storybook/Toasts.tsx
@@ -2,74 +2,129 @@ import {Pressable, View} from 'react-native'
 
 import {show as deprecatedShow} from '#/view/com/util/Toast'
 import {atoms as a} from '#/alf'
-import * as toast from '#/components/Toast'
-import {Toast} from '#/components/Toast/Toast'
+import {Globe_Stroke2_Corner0_Rounded as GlobeIcon} from '#/components/icons/Globe'
+import * as Toast from '#/components/Toast'
+import {Default} from '#/components/Toast/Toast'
 import {H1} from '#/components/Typography'
 
+function ToastWithAction({type = 'default'}: {type?: Toast.ToastType}) {
+  return (
+    <Toast.Outer type={type}>
+      <Toast.Icon icon={GlobeIcon} />
+      <Toast.Text>This toast has an action button</Toast.Text>
+      <Toast.Action
+        label="Action"
+        onPress={() => console.log('Action clicked!')}>
+        Action
+      </Toast.Action>
+    </Toast.Outer>
+  )
+}
+
+function LongToastWithAction({type = 'default'}: {type?: Toast.ToastType}) {
+  return (
+    <Toast.Outer type={type}>
+      <Toast.Icon icon={GlobeIcon} />
+      <Toast.Text>
+        This is a longer message to test how the toast handles multiple lines of
+        text content.
+      </Toast.Text>
+      <Toast.Action
+        label="Action"
+        onPress={() => console.log('Action clicked!')}>
+        Action
+      </Toast.Action>
+    </Toast.Outer>
+  )
+}
+
 export function Toasts() {
   return (
     <View style={[a.gap_md]}>
       <H1>Toast Examples</H1>
 
       <View style={[a.gap_md]}>
+        <View style={[a.gap_md, {marginHorizontal: a.px_xl.paddingLeft * -1}]}>
+          <Pressable
+            accessibilityRole="button"
+            onPress={() => Toast.show(<ToastWithAction />)}>
+            <ToastWithAction />
+          </Pressable>
+          <Pressable
+            accessibilityRole="button"
+            onPress={() => Toast.show(<LongToastWithAction />)}>
+            <LongToastWithAction />
+          </Pressable>
+          <Pressable
+            accessibilityRole="button"
+            onPress={() => Toast.show(<ToastWithAction type="success" />)}>
+            <ToastWithAction type="success" />
+          </Pressable>
+          <Pressable
+            accessibilityRole="button"
+            onPress={() => Toast.show(<ToastWithAction type="error" />)}>
+            <ToastWithAction type="error" />
+          </Pressable>
+        </View>
+
         <Pressable
           accessibilityRole="button"
-          onPress={() => toast.show(`Hey I'm a toast!`)}>
-          <Toast content="Hey I'm a toast!" />
+          onPress={() => Toast.show(`Hey I'm a toast!`)}>
+          <Default content="Hey I'm a toast!" />
         </Pressable>
         <Pressable
           accessibilityRole="button"
           onPress={() =>
-            toast.show(`This toast will disappear after 6 seconds`, {
+            Toast.show(`This toast will disappear after 6 seconds`, {
               duration: 6e3,
             })
           }>
-          <Toast content="This toast will disappear after 6 seconds" />
+          <Default content="This toast will disappear after 6 seconds" />
         </Pressable>
         <Pressable
           accessibilityRole="button"
           onPress={() =>
-            toast.show(
+            Toast.show(
               `This is a longer message to test how the toast handles multiple lines of text content.`,
             )
           }>
-          <Toast content="This is a longer message to test how the toast handles multiple lines of text content." />
+          <Default content="This is a longer message to test how the toast handles multiple lines of text content." />
         </Pressable>
         <Pressable
           accessibilityRole="button"
           onPress={() =>
-            toast.show(`Success! Yayyyyyyy :)`, {
+            Toast.show(`Success! Yayyyyyyy :)`, {
               type: 'success',
             })
           }>
-          <Toast content="Success! Yayyyyyyy :)" type="success" />
+          <Default content="Success! Yayyyyyyy :)" type="success" />
         </Pressable>
         <Pressable
           accessibilityRole="button"
           onPress={() =>
-            toast.show(`I'm providing info!`, {
+            Toast.show(`I'm providing info!`, {
               type: 'info',
             })
           }>
-          <Toast content="I'm providing info!" type="info" />
+          <Default content="I'm providing info!" type="info" />
         </Pressable>
         <Pressable
           accessibilityRole="button"
           onPress={() =>
-            toast.show(`This is a warning toast`, {
+            Toast.show(`This is a warning toast`, {
               type: 'warning',
             })
           }>
-          <Toast content="This is a warning toast" type="warning" />
+          <Default content="This is a warning toast" type="warning" />
         </Pressable>
         <Pressable
           accessibilityRole="button"
           onPress={() =>
-            toast.show(`This is an error toast :(`, {
+            Toast.show(`This is an error toast :(`, {
               type: 'error',
             })
           }>
-          <Toast content="This is an error toast :(" type="error" />
+          <Default content="This is an error toast :(" type="error" />
         </Pressable>
 
         <Pressable
@@ -80,7 +135,7 @@ export function Toasts() {
               'exclamation-circle',
             )
           }>
-          <Toast
+          <Default
             content="This is a test of the deprecated API"
             type="warning"
           />