Bluesky app fork with some witchin' additions 馃挮
at readme-update 80 lines 1.9 kB view raw
1import React from 'react' 2import {nanoid} from 'nanoid/non-secure' 3import {toast as sonner, Toaster} from 'sonner' 4 5import {atoms as a} from '#/alf' 6import {DURATION} from '#/components/Toast/const' 7import { 8 Icon as ToastIcon, 9 Outer as ToastOuter, 10 Text as ToastText, 11 ToastConfigProvider, 12} from '#/components/Toast/Toast' 13import {type BaseToastOptions} from '#/components/Toast/types' 14 15export {DURATION} from '#/components/Toast/const' 16export * from '#/components/Toast/Toast' 17export {type ToastType} from '#/components/Toast/types' 18 19/** 20 * Toasts are rendered in a global outlet, which is placed at the top of the 21 * component tree. 22 */ 23export function ToastOutlet() { 24 return ( 25 <Toaster 26 position="bottom-left" 27 gap={a.gap_sm.gap} 28 offset={a.p_xl.padding} 29 mobileOffset={a.p_xl.padding} 30 /> 31 ) 32} 33 34/** 35 * Access the full Sonner API 36 */ 37export const api = sonner 38 39/** 40 * Our base toast API, using the `Toast` export of this file. 41 */ 42export function show( 43 content: React.ReactNode, 44 {type = 'default', ...options}: BaseToastOptions = {}, 45) { 46 const id = nanoid() 47 48 if (typeof content === 'string') { 49 sonner( 50 <ToastConfigProvider id={id} type={type}> 51 <ToastOuter> 52 <ToastIcon /> 53 <ToastText>{content}</ToastText> 54 </ToastOuter> 55 </ToastConfigProvider>, 56 { 57 ...options, 58 unstyled: true, // required on web 59 id, 60 duration: options?.duration ?? DURATION, 61 }, 62 ) 63 } else if (React.isValidElement(content)) { 64 sonner( 65 <ToastConfigProvider id={id} type={type}> 66 {content} 67 </ToastConfigProvider>, 68 { 69 ...options, 70 unstyled: true, // required on web 71 id, 72 duration: options?.duration ?? DURATION, 73 }, 74 ) 75 } else { 76 throw new Error( 77 `Toast can be a string or a React element, got ${typeof content}`, 78 ) 79 } 80}