Toast
FeedbackWeb + NativeNativeMITuseOtfToast + toast() — success / error / info / warning variants.
bun add @otfdashkit/ui-native
Code
@otfdashkit/ui-nativeimport { OtfButton, SizableText, XStack, YStack, toast, useOtfToast } from '@otfdashkit/ui-native'
import { Section, ShowcaseFrame } from '../../components/ShowcaseFrame'
export default function ToastShowcase() {
const { show } = useOtfToast()
return (
<ShowcaseFrame
title="Toast"
description="Transient banner — call toast() from anywhere, or the useOtfToast() hook inside React. Wrap your tree in OtfToastProvider once."
docPath="packages/ui-native/src/interface/OtfToast.tsx"
>
{/* Use explicit variant/color props — theme="green/red/yellow" on OtfButton
doesn't work because our variant system uses explicit backgroundColor
overrides that win over Tamagui's theme tinting. */}
<Section title="Variants" hint="Auto-dismiss after 3s">
<XStack gap="$2" flexWrap="wrap">
<OtfButton
variant="default"
onPress={() => toast('Heads up.')}
>
Default
</OtfButton>
<OtfButton
variant="primary"
backgroundColor="#16a34a"
pressStyle={{ backgroundColor: '#15803d', scale: 0.97 }}
onPress={() => toast('Profile saved.', 'success')}
>
Success
</OtfButton>
<OtfButton
variant="destructive"
onPress={() => toast('Could not save profile.', 'error')}
>
Error
</OtfButton>
<OtfButton
variant="primary"
backgroundColor="#d97706"
pressStyle={{ backgroundColor: '#b45309', scale: 0.97 }}
onPress={() => toast('Connection unstable.', 'warning')}
>
Warning
</OtfButton>
</XStack>
</Section>
<Section title="With message body">
<XStack gap="$2" flexWrap="wrap">
<OtfButton
variant="primary"
backgroundColor="#16a34a"
pressStyle={{ backgroundColor: '#15803d', scale: 0.97 }}
onPress={() =>
toast('Workout logged', {
variant: 'success',
message: '5.2km run · 28:14 · saved to your timeline.',
})
}
>
Success + body
</OtfButton>
<OtfButton
variant="destructive"
onPress={() =>
toast('Sync failed', {
variant: 'error',
message: 'We could not reach the server. Retrying in 30 seconds.',
})
}
>
Error + body
</OtfButton>
</XStack>
</Section>
<Section title="Custom duration">
<XStack gap="$2" flexWrap="wrap">
<OtfButton
variant="outlined"
onPress={() => toast('Quick toast', { duration: 1000 })}
>
1s
</OtfButton>
<OtfButton
variant="outlined"
onPress={() => toast('Sticky toast', { duration: 8000 })}
>
8s
</OtfButton>
</XStack>
</Section>
<Section title="useOtfToast() hook" hint="Same API, scoped to React tree">
<YStack gap="$2">
<SizableText size="$2" color="$color11">
Inside components, prefer the hook — it doesn't depend on the
module-level singleton.
</SizableText>
<XStack gap="$2" flexWrap="wrap">
<OtfButton variant="default" onPress={() => show('Hook fired')}>show()</OtfButton>
<OtfButton
variant="primary"
backgroundColor="#16a34a"
pressStyle={{ backgroundColor: '#15803d', scale: 0.97 }}
onPress={() =>
show('Hook fired with body', {
variant: 'success',
message: 'This came through useOtfToast().',
})
}
>
show() + body
</OtfButton>
</XStack>
</YStack>
</Section>
</ShowcaseFrame>
)
}
Free with the SDK. This component ships in @otfdashkit/ui-native under the MIT license.