@tamagui/v2-toast 2.0.0-1769464493958
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Toast.cjs +170 -0
- package/dist/cjs/Toast.js +119 -0
- package/dist/cjs/Toast.js.map +6 -0
- package/dist/cjs/Toast.native.js +174 -0
- package/dist/cjs/Toast.native.js.map +1 -0
- package/dist/cjs/ToastAnnounce.cjs +97 -0
- package/dist/cjs/ToastAnnounce.js +72 -0
- package/dist/cjs/ToastAnnounce.js.map +6 -0
- package/dist/cjs/ToastAnnounce.native.js +105 -0
- package/dist/cjs/ToastAnnounce.native.js.map +1 -0
- package/dist/cjs/ToastImperative.cjs +100 -0
- package/dist/cjs/ToastImperative.js +71 -0
- package/dist/cjs/ToastImperative.js.map +6 -0
- package/dist/cjs/ToastImperative.native.js +122 -0
- package/dist/cjs/ToastImperative.native.js.map +1 -0
- package/dist/cjs/ToastImpl.cjs +292 -0
- package/dist/cjs/ToastImpl.js +227 -0
- package/dist/cjs/ToastImpl.js.map +6 -0
- package/dist/cjs/ToastImpl.native.js +327 -0
- package/dist/cjs/ToastImpl.native.js.map +1 -0
- package/dist/cjs/ToastItem.cjs +466 -0
- package/dist/cjs/ToastItem.js +356 -0
- package/dist/cjs/ToastItem.js.map +6 -0
- package/dist/cjs/ToastItem.native.js +547 -0
- package/dist/cjs/ToastItem.native.js.map +1 -0
- package/dist/cjs/ToastPortal.cjs +44 -0
- package/dist/cjs/ToastPortal.js +26 -0
- package/dist/cjs/ToastPortal.js.map +6 -0
- package/dist/cjs/ToastPortal.native.js +47 -0
- package/dist/cjs/ToastPortal.native.js.map +1 -0
- package/dist/cjs/ToastProvider.cjs +146 -0
- package/dist/cjs/ToastProvider.js +105 -0
- package/dist/cjs/ToastProvider.js.map +6 -0
- package/dist/cjs/ToastProvider.native.js +159 -0
- package/dist/cjs/ToastProvider.native.js.map +1 -0
- package/dist/cjs/ToastState.cjs +248 -0
- package/dist/cjs/ToastState.js +160 -0
- package/dist/cjs/ToastState.js.map +6 -0
- package/dist/cjs/ToastState.native.js +257 -0
- package/dist/cjs/ToastState.native.js.map +1 -0
- package/dist/cjs/ToastViewport.cjs +278 -0
- package/dist/cjs/ToastViewport.js +263 -0
- package/dist/cjs/ToastViewport.js.map +6 -0
- package/dist/cjs/ToastViewport.native.js +316 -0
- package/dist/cjs/ToastViewport.native.js.map +1 -0
- package/dist/cjs/Toaster.cjs +219 -0
- package/dist/cjs/Toaster.js +177 -0
- package/dist/cjs/Toaster.js.map +6 -0
- package/dist/cjs/Toaster.native.js +279 -0
- package/dist/cjs/Toaster.native.js.map +1 -0
- package/dist/cjs/constants.cjs +28 -0
- package/dist/cjs/constants.js +22 -0
- package/dist/cjs/constants.js.map +6 -0
- package/dist/cjs/constants.native.js +31 -0
- package/dist/cjs/constants.native.js.map +1 -0
- package/dist/cjs/createNativeToast.cjs +51 -0
- package/dist/cjs/createNativeToast.js +44 -0
- package/dist/cjs/createNativeToast.js.map +6 -0
- package/dist/cjs/createNativeToast.native.js +47 -0
- package/dist/cjs/createNativeToast.native.js.map +1 -0
- package/dist/cjs/index.cjs +28 -0
- package/dist/cjs/index.js +22 -0
- package/dist/cjs/index.js.map +6 -0
- package/dist/cjs/index.native.js +31 -0
- package/dist/cjs/index.native.js.map +1 -0
- package/dist/cjs/types.cjs +16 -0
- package/dist/cjs/types.js +14 -0
- package/dist/cjs/types.js.map +6 -0
- package/dist/cjs/types.native.js +19 -0
- package/dist/cjs/types.native.js.map +1 -0
- package/dist/cjs/useDragGesture.cjs +129 -0
- package/dist/cjs/useDragGesture.js +100 -0
- package/dist/cjs/useDragGesture.js.map +6 -0
- package/dist/cjs/useDragGesture.native.js +146 -0
- package/dist/cjs/useDragGesture.native.js.map +1 -0
- package/dist/esm/Toast.js +107 -0
- package/dist/esm/Toast.js.map +6 -0
- package/dist/esm/Toast.mjs +131 -0
- package/dist/esm/Toast.mjs.map +1 -0
- package/dist/esm/Toast.native.js +132 -0
- package/dist/esm/Toast.native.js.map +1 -0
- package/dist/esm/ToastAnnounce.js +55 -0
- package/dist/esm/ToastAnnounce.js.map +6 -0
- package/dist/esm/ToastAnnounce.mjs +62 -0
- package/dist/esm/ToastAnnounce.mjs.map +1 -0
- package/dist/esm/ToastAnnounce.native.js +67 -0
- package/dist/esm/ToastAnnounce.native.js.map +1 -0
- package/dist/esm/ToastImperative.js +50 -0
- package/dist/esm/ToastImperative.js.map +6 -0
- package/dist/esm/ToastImperative.mjs +63 -0
- package/dist/esm/ToastImperative.mjs.map +1 -0
- package/dist/esm/ToastImperative.native.js +82 -0
- package/dist/esm/ToastImperative.native.js.map +1 -0
- package/dist/esm/ToastImpl.js +225 -0
- package/dist/esm/ToastImpl.js.map +6 -0
- package/dist/esm/ToastImpl.mjs +256 -0
- package/dist/esm/ToastImpl.mjs.map +1 -0
- package/dist/esm/ToastImpl.native.js +288 -0
- package/dist/esm/ToastImpl.native.js.map +1 -0
- package/dist/esm/ToastItem.js +339 -0
- package/dist/esm/ToastItem.js.map +6 -0
- package/dist/esm/ToastItem.mjs +432 -0
- package/dist/esm/ToastItem.mjs.map +1 -0
- package/dist/esm/ToastItem.native.js +510 -0
- package/dist/esm/ToastItem.native.js.map +1 -0
- package/dist/esm/ToastPortal.js +13 -0
- package/dist/esm/ToastPortal.js.map +6 -0
- package/dist/esm/ToastPortal.mjs +21 -0
- package/dist/esm/ToastPortal.mjs.map +1 -0
- package/dist/esm/ToastPortal.native.js +21 -0
- package/dist/esm/ToastPortal.native.js.map +1 -0
- package/dist/esm/ToastProvider.js +87 -0
- package/dist/esm/ToastProvider.js.map +6 -0
- package/dist/esm/ToastProvider.mjs +108 -0
- package/dist/esm/ToastProvider.mjs.map +1 -0
- package/dist/esm/ToastProvider.native.js +118 -0
- package/dist/esm/ToastProvider.native.js.map +1 -0
- package/dist/esm/ToastState.js +144 -0
- package/dist/esm/ToastState.js.map +6 -0
- package/dist/esm/ToastState.mjs +224 -0
- package/dist/esm/ToastState.mjs.map +1 -0
- package/dist/esm/ToastState.native.js +230 -0
- package/dist/esm/ToastState.native.js.map +1 -0
- package/dist/esm/ToastViewport.js +250 -0
- package/dist/esm/ToastViewport.js.map +6 -0
- package/dist/esm/ToastViewport.mjs +241 -0
- package/dist/esm/ToastViewport.mjs.map +1 -0
- package/dist/esm/ToastViewport.native.js +276 -0
- package/dist/esm/ToastViewport.native.js.map +1 -0
- package/dist/esm/Toaster.js +160 -0
- package/dist/esm/Toaster.js.map +6 -0
- package/dist/esm/Toaster.mjs +185 -0
- package/dist/esm/Toaster.mjs.map +1 -0
- package/dist/esm/Toaster.native.js +242 -0
- package/dist/esm/Toaster.native.js.map +1 -0
- package/dist/esm/constants.js +6 -0
- package/dist/esm/constants.js.map +6 -0
- package/dist/esm/constants.mjs +4 -0
- package/dist/esm/constants.mjs.map +1 -0
- package/dist/esm/constants.native.js +4 -0
- package/dist/esm/constants.native.js.map +1 -0
- package/dist/esm/createNativeToast.js +28 -0
- package/dist/esm/createNativeToast.js.map +6 -0
- package/dist/esm/createNativeToast.mjs +27 -0
- package/dist/esm/createNativeToast.mjs.map +1 -0
- package/dist/esm/createNativeToast.native.js +20 -0
- package/dist/esm/createNativeToast.native.js.map +1 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +6 -0
- package/dist/esm/index.mjs +4 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/index.native.js +4 -0
- package/dist/esm/index.native.js.map +1 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/types.js.map +6 -0
- package/dist/esm/types.mjs +2 -0
- package/dist/esm/types.mjs.map +1 -0
- package/dist/esm/types.native.js +2 -0
- package/dist/esm/types.native.js.map +1 -0
- package/dist/esm/useDragGesture.js +76 -0
- package/dist/esm/useDragGesture.js.map +6 -0
- package/dist/esm/useDragGesture.mjs +95 -0
- package/dist/esm/useDragGesture.mjs.map +1 -0
- package/dist/esm/useDragGesture.native.js +109 -0
- package/dist/esm/useDragGesture.native.js.map +1 -0
- package/dist/jsx/Toast.js +107 -0
- package/dist/jsx/Toast.js.map +6 -0
- package/dist/jsx/Toast.mjs +131 -0
- package/dist/jsx/Toast.mjs.map +1 -0
- package/dist/jsx/Toast.native.js +174 -0
- package/dist/jsx/Toast.native.js.map +1 -0
- package/dist/jsx/ToastAnnounce.js +55 -0
- package/dist/jsx/ToastAnnounce.js.map +6 -0
- package/dist/jsx/ToastAnnounce.mjs +62 -0
- package/dist/jsx/ToastAnnounce.mjs.map +1 -0
- package/dist/jsx/ToastAnnounce.native.js +105 -0
- package/dist/jsx/ToastAnnounce.native.js.map +1 -0
- package/dist/jsx/ToastImperative.js +50 -0
- package/dist/jsx/ToastImperative.js.map +6 -0
- package/dist/jsx/ToastImperative.mjs +63 -0
- package/dist/jsx/ToastImperative.mjs.map +1 -0
- package/dist/jsx/ToastImperative.native.js +122 -0
- package/dist/jsx/ToastImperative.native.js.map +1 -0
- package/dist/jsx/ToastImpl.js +225 -0
- package/dist/jsx/ToastImpl.js.map +6 -0
- package/dist/jsx/ToastImpl.mjs +256 -0
- package/dist/jsx/ToastImpl.mjs.map +1 -0
- package/dist/jsx/ToastImpl.native.js +327 -0
- package/dist/jsx/ToastImpl.native.js.map +1 -0
- package/dist/jsx/ToastItem.js +339 -0
- package/dist/jsx/ToastItem.js.map +6 -0
- package/dist/jsx/ToastItem.mjs +432 -0
- package/dist/jsx/ToastItem.mjs.map +1 -0
- package/dist/jsx/ToastItem.native.js +547 -0
- package/dist/jsx/ToastItem.native.js.map +1 -0
- package/dist/jsx/ToastPortal.js +13 -0
- package/dist/jsx/ToastPortal.js.map +6 -0
- package/dist/jsx/ToastPortal.mjs +21 -0
- package/dist/jsx/ToastPortal.mjs.map +1 -0
- package/dist/jsx/ToastPortal.native.js +47 -0
- package/dist/jsx/ToastPortal.native.js.map +1 -0
- package/dist/jsx/ToastProvider.js +87 -0
- package/dist/jsx/ToastProvider.js.map +6 -0
- package/dist/jsx/ToastProvider.mjs +108 -0
- package/dist/jsx/ToastProvider.mjs.map +1 -0
- package/dist/jsx/ToastProvider.native.js +159 -0
- package/dist/jsx/ToastProvider.native.js.map +1 -0
- package/dist/jsx/ToastState.js +144 -0
- package/dist/jsx/ToastState.js.map +6 -0
- package/dist/jsx/ToastState.mjs +224 -0
- package/dist/jsx/ToastState.mjs.map +1 -0
- package/dist/jsx/ToastState.native.js +257 -0
- package/dist/jsx/ToastState.native.js.map +1 -0
- package/dist/jsx/ToastViewport.js +250 -0
- package/dist/jsx/ToastViewport.js.map +6 -0
- package/dist/jsx/ToastViewport.mjs +241 -0
- package/dist/jsx/ToastViewport.mjs.map +1 -0
- package/dist/jsx/ToastViewport.native.js +316 -0
- package/dist/jsx/ToastViewport.native.js.map +1 -0
- package/dist/jsx/Toaster.js +160 -0
- package/dist/jsx/Toaster.js.map +6 -0
- package/dist/jsx/Toaster.mjs +185 -0
- package/dist/jsx/Toaster.mjs.map +1 -0
- package/dist/jsx/Toaster.native.js +279 -0
- package/dist/jsx/Toaster.native.js.map +1 -0
- package/dist/jsx/constants.js +6 -0
- package/dist/jsx/constants.js.map +6 -0
- package/dist/jsx/constants.mjs +4 -0
- package/dist/jsx/constants.mjs.map +1 -0
- package/dist/jsx/constants.native.js +31 -0
- package/dist/jsx/constants.native.js.map +1 -0
- package/dist/jsx/createNativeToast.js +28 -0
- package/dist/jsx/createNativeToast.js.map +6 -0
- package/dist/jsx/createNativeToast.mjs +27 -0
- package/dist/jsx/createNativeToast.mjs.map +1 -0
- package/dist/jsx/createNativeToast.native.js +47 -0
- package/dist/jsx/createNativeToast.native.js.map +1 -0
- package/dist/jsx/index.js +7 -0
- package/dist/jsx/index.js.map +6 -0
- package/dist/jsx/index.mjs +4 -0
- package/dist/jsx/index.mjs.map +1 -0
- package/dist/jsx/index.native.js +31 -0
- package/dist/jsx/index.native.js.map +1 -0
- package/dist/jsx/types.js +1 -0
- package/dist/jsx/types.js.map +6 -0
- package/dist/jsx/types.mjs +2 -0
- package/dist/jsx/types.mjs.map +1 -0
- package/dist/jsx/types.native.js +19 -0
- package/dist/jsx/types.native.js.map +1 -0
- package/dist/jsx/useDragGesture.js +76 -0
- package/dist/jsx/useDragGesture.js.map +6 -0
- package/dist/jsx/useDragGesture.mjs +95 -0
- package/dist/jsx/useDragGesture.mjs.map +1 -0
- package/dist/jsx/useDragGesture.native.js +146 -0
- package/dist/jsx/useDragGesture.native.js.map +1 -0
- package/package.json +77 -0
- package/src/Toast.tsx +219 -0
- package/src/ToastAnnounce.tsx +102 -0
- package/src/ToastImperative.tsx +190 -0
- package/src/ToastImpl.tsx +503 -0
- package/src/ToastItem.tsx +694 -0
- package/src/ToastPortal.tsx +19 -0
- package/src/ToastProvider.tsx +197 -0
- package/src/ToastState.ts +397 -0
- package/src/ToastViewport.tsx +430 -0
- package/src/Toaster.tsx +445 -0
- package/src/constants.ts +2 -0
- package/src/createNativeToast.native.tsx +22 -0
- package/src/createNativeToast.tsx +48 -0
- package/src/index.ts +17 -0
- package/src/types.ts +71 -0
- package/src/useDragGesture.native.ts +199 -0
- package/src/useDragGesture.ts +218 -0
- package/types/Toast.d.ts +84 -0
- package/types/Toast.d.ts.map +1 -0
- package/types/ToastAnnounce.d.ts +18 -0
- package/types/ToastAnnounce.d.ts.map +1 -0
- package/types/ToastImperative.d.ts +95 -0
- package/types/ToastImperative.d.ts.map +1 -0
- package/types/ToastImpl.d.ts +109 -0
- package/types/ToastImpl.d.ts.map +1 -0
- package/types/ToastItem.d.ts +34 -0
- package/types/ToastItem.d.ts.map +1 -0
- package/types/ToastPortal.d.ts +8 -0
- package/types/ToastPortal.d.ts.map +1 -0
- package/types/ToastProvider.d.ts +92 -0
- package/types/ToastProvider.d.ts.map +1 -0
- package/types/ToastState.d.ts +177 -0
- package/types/ToastState.d.ts.map +1 -0
- package/types/ToastViewport.d.ts +75 -0
- package/types/ToastViewport.d.ts.map +1 -0
- package/types/Toaster.d.ts +120 -0
- package/types/Toaster.d.ts.map +1 -0
- package/types/constants.d.ts +3 -0
- package/types/constants.d.ts.map +1 -0
- package/types/createNativeToast.d.ts +4 -0
- package/types/createNativeToast.d.ts.map +1 -0
- package/types/createNativeToast.native.d.ts +4 -0
- package/types/createNativeToast.native.d.ts.map +1 -0
- package/types/index.d.ts +7 -0
- package/types/index.d.ts.map +1 -0
- package/types/types.d.ts +61 -0
- package/types/types.d.ts.map +1 -0
- package/types/useDragGesture.d.ts +32 -0
- package/types/useDragGesture.d.ts.map +1 -0
- package/types/useDragGesture.native.d.ts +26 -0
- package/types/useDragGesture.native.d.ts.map +1 -0
package/src/Toast.tsx
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { AnimatePresence } from '@tamagui/animate-presence'
|
|
2
|
+
import type { GetProps, NativePlatform, NativeValue, TamaguiElement } from '@tamagui/core'
|
|
3
|
+
import { styled, useEvent } from '@tamagui/core'
|
|
4
|
+
import { composeEventHandlers, withStaticProperties } from '@tamagui/helpers'
|
|
5
|
+
import { YStack } from '@tamagui/stacks'
|
|
6
|
+
import { SizableText } from '@tamagui/text'
|
|
7
|
+
import { useControllableState } from '@tamagui/use-controllable-state'
|
|
8
|
+
import * as React from 'react'
|
|
9
|
+
import { ToastAnnounceExclude } from './ToastAnnounce'
|
|
10
|
+
import type { CustomData } from './ToastImperative'
|
|
11
|
+
import { useToast, useToastController, useToastState } from './ToastImperative'
|
|
12
|
+
import type { ToastExtraProps, ToastProps } from './ToastImpl'
|
|
13
|
+
import { ToastImpl, ToastImplFrame, useToastInteractiveContext } from './ToastImpl'
|
|
14
|
+
import type { ScopedProps, ToastProviderProps } from './ToastProvider'
|
|
15
|
+
import { ToastProvider } from './ToastProvider'
|
|
16
|
+
import type { ToastViewportProps } from './ToastViewport'
|
|
17
|
+
import { ToastViewport } from './ToastViewport'
|
|
18
|
+
|
|
19
|
+
/* -------------------------------------------------------------------------------------------------
|
|
20
|
+
* ToastTitle
|
|
21
|
+
* -----------------------------------------------------------------------------------------------*/
|
|
22
|
+
|
|
23
|
+
const TITLE_NAME = 'ToastTitle'
|
|
24
|
+
|
|
25
|
+
const ToastTitle = styled(SizableText, {
|
|
26
|
+
name: TITLE_NAME,
|
|
27
|
+
|
|
28
|
+
variants: {
|
|
29
|
+
unstyled: {
|
|
30
|
+
false: {
|
|
31
|
+
color: '$color',
|
|
32
|
+
size: '$4',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
} as const,
|
|
36
|
+
|
|
37
|
+
defaultVariants: {
|
|
38
|
+
unstyled: process.env.TAMAGUI_HEADLESS === '1',
|
|
39
|
+
},
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
type ToastTitleProps = GetProps<typeof ToastTitle>
|
|
43
|
+
|
|
44
|
+
/* -------------------------------------------------------------------------------------------------
|
|
45
|
+
* ToastDescription
|
|
46
|
+
* -----------------------------------------------------------------------------------------------*/
|
|
47
|
+
|
|
48
|
+
const DESCRIPTION_NAME = 'ToastDescription'
|
|
49
|
+
|
|
50
|
+
const ToastDescription = styled(SizableText, {
|
|
51
|
+
name: DESCRIPTION_NAME,
|
|
52
|
+
|
|
53
|
+
variants: {
|
|
54
|
+
unstyled: {
|
|
55
|
+
false: {
|
|
56
|
+
color: '$color11',
|
|
57
|
+
size: '$1',
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
} as const,
|
|
61
|
+
|
|
62
|
+
defaultVariants: {
|
|
63
|
+
unstyled: process.env.TAMAGUI_HEADLESS === '1',
|
|
64
|
+
},
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
type ToastDescriptionProps = GetProps<typeof ToastDescription>
|
|
68
|
+
|
|
69
|
+
/* -------------------------------------------------------------------------------------------------
|
|
70
|
+
* ToastAction
|
|
71
|
+
* -----------------------------------------------------------------------------------------------*/
|
|
72
|
+
|
|
73
|
+
const ACTION_NAME = 'ToastAction'
|
|
74
|
+
|
|
75
|
+
type ToastActionProps = ScopedProps<
|
|
76
|
+
ToastCloseProps & {
|
|
77
|
+
/**
|
|
78
|
+
* A short description for an alternate way to carry out the action. For screen reader users
|
|
79
|
+
* who will not be able to navigate to the button easily/quickly.
|
|
80
|
+
* @example <ToastAction altText="Goto account settings to updgrade">Upgrade</ToastAction>
|
|
81
|
+
* @example <ToastAction altText="Undo (Alt+U)">Undo</ToastAction>
|
|
82
|
+
*/
|
|
83
|
+
altText: string
|
|
84
|
+
}
|
|
85
|
+
>
|
|
86
|
+
|
|
87
|
+
const ToastAction = React.forwardRef<TamaguiElement, ScopedProps<ToastActionProps>>(
|
|
88
|
+
function ToastAction(props, forwardedRef) {
|
|
89
|
+
const { altText, ...actionProps } = props
|
|
90
|
+
if (!altText) return null
|
|
91
|
+
return (
|
|
92
|
+
<ToastAnnounceExclude altText={altText} asChild>
|
|
93
|
+
<ToastClose {...actionProps} ref={forwardedRef} />
|
|
94
|
+
</ToastAnnounceExclude>
|
|
95
|
+
)
|
|
96
|
+
}
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
ToastAction.propTypes = {
|
|
100
|
+
altText(props) {
|
|
101
|
+
if (!props.altText) {
|
|
102
|
+
return new Error(`Missing prop \`altText\` expected on \`${ACTION_NAME}\``)
|
|
103
|
+
}
|
|
104
|
+
return null
|
|
105
|
+
},
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* -------------------------------------------------------------------------------------------------
|
|
109
|
+
* ToastClose
|
|
110
|
+
* -----------------------------------------------------------------------------------------------*/
|
|
111
|
+
|
|
112
|
+
const CLOSE_NAME = 'ToastClose'
|
|
113
|
+
|
|
114
|
+
const ToastCloseFrame = styled(YStack, {
|
|
115
|
+
name: CLOSE_NAME,
|
|
116
|
+
render: 'button',
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
type ToastCloseFrameProps = GetProps<typeof ToastCloseFrame>
|
|
120
|
+
type ToastCloseProps = ScopedProps<ToastCloseFrameProps & {}>
|
|
121
|
+
|
|
122
|
+
const ToastClose = React.forwardRef<TamaguiElement, ToastCloseProps>(
|
|
123
|
+
function ToastClose(props, forwardedRef) {
|
|
124
|
+
const { scope, ...closeProps } = props
|
|
125
|
+
const interactiveContext = useToastInteractiveContext(scope)
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
<ToastAnnounceExclude asChild>
|
|
129
|
+
<ToastCloseFrame
|
|
130
|
+
aria-label="Close"
|
|
131
|
+
{...closeProps}
|
|
132
|
+
ref={forwardedRef}
|
|
133
|
+
onPress={composeEventHandlers(props.onPress as any, interactiveContext.onClose)}
|
|
134
|
+
/>
|
|
135
|
+
</ToastAnnounceExclude>
|
|
136
|
+
)
|
|
137
|
+
}
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
/* -------------------------------------------------------------------------------------------------
|
|
141
|
+
* Toast
|
|
142
|
+
* -----------------------------------------------------------------------------------------------*/
|
|
143
|
+
|
|
144
|
+
const ToastComponent = ToastImplFrame.styleable<ToastExtraProps>(
|
|
145
|
+
function Toast(props, forwardedRef) {
|
|
146
|
+
const { forceMount, open: openProp, defaultOpen, onOpenChange, ...toastProps } = props
|
|
147
|
+
const [open, setOpen] = useControllableState({
|
|
148
|
+
prop: openProp,
|
|
149
|
+
defaultProp: defaultOpen ?? true,
|
|
150
|
+
onChange: onOpenChange,
|
|
151
|
+
strategy: 'most-recent-wins',
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
const currentToast = useToastState()
|
|
155
|
+
const { hide } = useToastController()
|
|
156
|
+
|
|
157
|
+
const id = React.useId()
|
|
158
|
+
const onPause = useEvent(props.onPause)
|
|
159
|
+
const onResume = useEvent(props.onResume)
|
|
160
|
+
const isHide = currentToast?.hide === true
|
|
161
|
+
const shouldShow = (forceMount || open) && !isHide
|
|
162
|
+
|
|
163
|
+
return (
|
|
164
|
+
<AnimatePresence key={id}>
|
|
165
|
+
{shouldShow ? (
|
|
166
|
+
<ToastImpl
|
|
167
|
+
id={id}
|
|
168
|
+
open={open}
|
|
169
|
+
{...toastProps}
|
|
170
|
+
ref={forwardedRef}
|
|
171
|
+
onClose={() => {
|
|
172
|
+
setOpen(false)
|
|
173
|
+
hide()
|
|
174
|
+
}}
|
|
175
|
+
onPause={onPause}
|
|
176
|
+
onResume={onResume}
|
|
177
|
+
onSwipeEnd={composeEventHandlers(props.onSwipeEnd, (event) => {
|
|
178
|
+
setOpen(false)
|
|
179
|
+
})}
|
|
180
|
+
/>
|
|
181
|
+
) : null}
|
|
182
|
+
</AnimatePresence>
|
|
183
|
+
)
|
|
184
|
+
}
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
const Toast = withStaticProperties(ToastComponent, {
|
|
188
|
+
Title: ToastTitle,
|
|
189
|
+
Description: ToastDescription,
|
|
190
|
+
Action: ToastAction,
|
|
191
|
+
Close: ToastClose,
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
/* ---------------------------------------------------------------------------------------------- */
|
|
195
|
+
|
|
196
|
+
export {
|
|
197
|
+
Toast,
|
|
198
|
+
ToastProvider,
|
|
199
|
+
ToastViewport,
|
|
200
|
+
//
|
|
201
|
+
// imperative
|
|
202
|
+
useToast,
|
|
203
|
+
useToastController,
|
|
204
|
+
useToastState,
|
|
205
|
+
}
|
|
206
|
+
export type {
|
|
207
|
+
// imperative
|
|
208
|
+
CustomData,
|
|
209
|
+
ToastActionProps,
|
|
210
|
+
ToastCloseProps,
|
|
211
|
+
ToastDescriptionProps,
|
|
212
|
+
NativePlatform as ToastNativePlatform,
|
|
213
|
+
// backwards
|
|
214
|
+
NativeValue as ToastNativeValue,
|
|
215
|
+
ToastProps,
|
|
216
|
+
ToastProviderProps,
|
|
217
|
+
ToastTitleProps,
|
|
218
|
+
ToastViewportProps,
|
|
219
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { useIsomorphicLayoutEffect } from '@tamagui/constants'
|
|
2
|
+
import type { GetProps, TamaguiElement } from '@tamagui/core'
|
|
3
|
+
import { View, Text, styled, useEvent } from '@tamagui/core'
|
|
4
|
+
import { Portal } from '@tamagui/portal'
|
|
5
|
+
import { startTransition } from '@tamagui/start-transition'
|
|
6
|
+
import { VisuallyHidden } from '@tamagui/visually-hidden'
|
|
7
|
+
import * as React from 'react'
|
|
8
|
+
|
|
9
|
+
import type { ScopedProps } from './ToastProvider'
|
|
10
|
+
import { useToastProviderContext } from './ToastProvider'
|
|
11
|
+
|
|
12
|
+
const ToastAnnounceExcludeFrame = styled(View, {
|
|
13
|
+
name: 'ToastAnnounceExclude',
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
type ToastAnnounceExcludeFrameProps = GetProps<typeof ToastAnnounceExcludeFrame>
|
|
17
|
+
|
|
18
|
+
type ToastAnnounceExcludeExtraProps = {
|
|
19
|
+
altText?: string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type ToastAnnounceExcludeProps = ToastAnnounceExcludeFrameProps &
|
|
23
|
+
ToastAnnounceExcludeExtraProps
|
|
24
|
+
|
|
25
|
+
const ToastAnnounceExclude = React.forwardRef<TamaguiElement, ToastAnnounceExcludeProps>(
|
|
26
|
+
(props, forwardedRef) => {
|
|
27
|
+
const { altText, ...announceExcludeProps } = props
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<ToastAnnounceExcludeFrame
|
|
31
|
+
data-toast-announce-exclude=""
|
|
32
|
+
data-toast-announce-alt={altText || undefined}
|
|
33
|
+
{...announceExcludeProps}
|
|
34
|
+
ref={forwardedRef}
|
|
35
|
+
/>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
/* -----------------------------------------------------------------------------------------------*/
|
|
41
|
+
|
|
42
|
+
interface ToastAnnounceProps
|
|
43
|
+
extends Omit<GetProps<typeof VisuallyHidden>, 'children'>,
|
|
44
|
+
ScopedProps<{ children: string[] }> {}
|
|
45
|
+
|
|
46
|
+
const ToastAnnounce: React.FC<ToastAnnounceProps> = (
|
|
47
|
+
props: ScopedProps<ToastAnnounceProps>
|
|
48
|
+
) => {
|
|
49
|
+
const { scope, children, ...announceProps } = props
|
|
50
|
+
const context = useToastProviderContext(scope)
|
|
51
|
+
const [renderAnnounceText, setRenderAnnounceText] = React.useState(false)
|
|
52
|
+
const [isAnnounced, setIsAnnounced] = React.useState(false)
|
|
53
|
+
|
|
54
|
+
// render text content in the next frame to ensure toast is announced in NVDA
|
|
55
|
+
useNextFrame(() => {
|
|
56
|
+
startTransition(() => {
|
|
57
|
+
setRenderAnnounceText(true)
|
|
58
|
+
})
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
// cleanup after announcing
|
|
62
|
+
React.useEffect(() => {
|
|
63
|
+
const timer = setTimeout(() => setIsAnnounced(true), 1000)
|
|
64
|
+
return () => clearTimeout(timer)
|
|
65
|
+
}, [])
|
|
66
|
+
|
|
67
|
+
return isAnnounced ? null : (
|
|
68
|
+
<Portal>
|
|
69
|
+
<VisuallyHidden {...announceProps}>
|
|
70
|
+
{renderAnnounceText && (
|
|
71
|
+
<Text>
|
|
72
|
+
{context.label} {children}
|
|
73
|
+
</Text>
|
|
74
|
+
)}
|
|
75
|
+
</VisuallyHidden>
|
|
76
|
+
</Portal>
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* -----------------------------------------------------------------------------------------------*/
|
|
81
|
+
|
|
82
|
+
function useNextFrame(callback = () => {}) {
|
|
83
|
+
const fn = useEvent(callback)
|
|
84
|
+
useIsomorphicLayoutEffect(() => {
|
|
85
|
+
let raf1 = 0
|
|
86
|
+
let raf2 = 0
|
|
87
|
+
raf1 = requestAnimationFrame(() => {
|
|
88
|
+
raf2 = requestAnimationFrame(fn)
|
|
89
|
+
})
|
|
90
|
+
return () => {
|
|
91
|
+
cancelAnimationFrame(raf1)
|
|
92
|
+
cancelAnimationFrame(raf2)
|
|
93
|
+
}
|
|
94
|
+
}, [fn])
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export {
|
|
98
|
+
ToastAnnounce,
|
|
99
|
+
ToastAnnounceExclude,
|
|
100
|
+
type ToastAnnounceExcludeProps,
|
|
101
|
+
type ToastAnnounceProps,
|
|
102
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import type { NativePlatform, NativeValue } from '@tamagui/core'
|
|
2
|
+
import { isAndroid, isIos, isWeb } from '@tamagui/core'
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import { createNativeToast } from './createNativeToast'
|
|
5
|
+
import type { CreateNativeToastOptions, NativeToastRef } from './types'
|
|
6
|
+
|
|
7
|
+
export interface ToastImperativeOptions
|
|
8
|
+
extends Omit<CreateNativeToastOptions, 'message'> {
|
|
9
|
+
/**
|
|
10
|
+
* Will show a native toast if is true or is set to the current platform. On iOS, it wraps `SPIndicator` and `SPAlert`. On Android, it wraps `ToastAndroid`. On web, it wraps Notification API. Mobile's native features are handled by `burnt`.
|
|
11
|
+
*/
|
|
12
|
+
native?: NativeValue
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Override this in your application to get custom toast fields.
|
|
17
|
+
*
|
|
18
|
+
* e.g.
|
|
19
|
+
* ```ts
|
|
20
|
+
* declare module '@tamagui/toast' {
|
|
21
|
+
* interface CustomData {
|
|
22
|
+
* preset: 'error' | 'success'
|
|
23
|
+
* isUrgent: true
|
|
24
|
+
* }
|
|
25
|
+
* }
|
|
26
|
+
*```
|
|
27
|
+
* You will get auto-completion:
|
|
28
|
+
* ```ts
|
|
29
|
+
* toast.show("Message", { preset: 'error', isUrgent: true })
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export interface CustomData {
|
|
33
|
+
[key: string]: any
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
type ShowOptions = CreateNativeToastOptions &
|
|
37
|
+
CustomData & {
|
|
38
|
+
/**
|
|
39
|
+
* Used when need custom data
|
|
40
|
+
*/
|
|
41
|
+
customData?: CustomData
|
|
42
|
+
/**
|
|
43
|
+
* Overrides the native option on `ToastImperativeProvider`
|
|
44
|
+
*/
|
|
45
|
+
native?: NativeValue
|
|
46
|
+
/**
|
|
47
|
+
* Which viewport to send this toast to. This is only intended to be used with custom toasts and you should wire it up when creating the toast.
|
|
48
|
+
*/
|
|
49
|
+
viewportName?: string | 'default'
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
type ToastData = { title: string; id: string } & ShowOptions & {
|
|
53
|
+
isHandledNatively: boolean
|
|
54
|
+
} & CustomData
|
|
55
|
+
|
|
56
|
+
interface ToastContextI {
|
|
57
|
+
nativeToast: NativeToastRef | null
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Call it to show a new toast. If you're using native toasts, you can pass native options using \`burntOptions\` or \`notificationOptions\` depending on the native platform (mobile/web).
|
|
61
|
+
*/
|
|
62
|
+
show: (title: string, options?: ShowOptions) => boolean
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Call it to hide the currently displayed toast.
|
|
66
|
+
*
|
|
67
|
+
* _NOTE_: does not work on Android native toasts
|
|
68
|
+
*
|
|
69
|
+
* _NOTE_: hides the last toast on web notification toasts
|
|
70
|
+
*/
|
|
71
|
+
hide: () => void
|
|
72
|
+
|
|
73
|
+
options?: ToastImperativeOptions
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const ToastContext = React.createContext<ToastContextI>({} as any)
|
|
77
|
+
const ToastCurrentContext = React.createContext<ToastData | null>(null)
|
|
78
|
+
|
|
79
|
+
export const useToastController = () => {
|
|
80
|
+
return React.useContext(ToastContext)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export const useToastState = () => {
|
|
84
|
+
return React.useContext(ToastCurrentContext)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** @deprecated use `useToastController` and `useToastState` instead to avoid performance pitfalls */
|
|
88
|
+
export const useToast = () => {
|
|
89
|
+
return {
|
|
90
|
+
...useToastController(),
|
|
91
|
+
currentToast: useToastState(),
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
interface ToastImperativeProviderProps {
|
|
96
|
+
children: React.ReactNode
|
|
97
|
+
/**
|
|
98
|
+
* Used to provide defaults to imperative API. Options can be overwritten when calling `show()`.
|
|
99
|
+
*/
|
|
100
|
+
options: ToastImperativeOptions
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export const ToastImperativeProvider = ({
|
|
104
|
+
children,
|
|
105
|
+
options,
|
|
106
|
+
}: ToastImperativeProviderProps) => {
|
|
107
|
+
const counterRef = React.useRef(0)
|
|
108
|
+
|
|
109
|
+
const [toast, setToast] = React.useState<ToastData | null>(null)
|
|
110
|
+
|
|
111
|
+
const [lastNativeToastRef, setLastNativeToastRef] =
|
|
112
|
+
React.useState<ToastContextI['nativeToast']>(null)
|
|
113
|
+
|
|
114
|
+
const show = React.useCallback<ToastContextI['show']>(
|
|
115
|
+
(title, showOptions) => {
|
|
116
|
+
const native = showOptions?.native ?? options.native
|
|
117
|
+
const isWebNative = Array.isArray(native)
|
|
118
|
+
? native.includes('web')
|
|
119
|
+
: native === 'web'
|
|
120
|
+
const isMobileNative = Array.isArray(native)
|
|
121
|
+
? native.includes('mobile')
|
|
122
|
+
: native === 'mobile'
|
|
123
|
+
const isAndroidNative =
|
|
124
|
+
isMobileNative ||
|
|
125
|
+
(Array.isArray(native) ? native.includes('android') : native === 'android')
|
|
126
|
+
const isIosNative =
|
|
127
|
+
isMobileNative ||
|
|
128
|
+
(Array.isArray(native) ? native.includes('ios') : native === 'ios')
|
|
129
|
+
|
|
130
|
+
const isHandledNatively =
|
|
131
|
+
native === true ||
|
|
132
|
+
(isWeb && isWebNative) ||
|
|
133
|
+
(!isWeb && isMobileNative) ||
|
|
134
|
+
(isAndroid && isAndroidNative) ||
|
|
135
|
+
(isIos && isIosNative)
|
|
136
|
+
|
|
137
|
+
if (isHandledNatively) {
|
|
138
|
+
const nativeToastResult = createNativeToast(title, showOptions ?? {})
|
|
139
|
+
if (typeof nativeToastResult === 'object' && nativeToastResult.nativeToastRef) {
|
|
140
|
+
setLastNativeToastRef(nativeToastResult.nativeToastRef)
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
counterRef.current++
|
|
144
|
+
setToast({
|
|
145
|
+
...showOptions?.customData,
|
|
146
|
+
...showOptions,
|
|
147
|
+
viewportName: showOptions?.viewportName ?? 'default',
|
|
148
|
+
title,
|
|
149
|
+
id: counterRef.current.toString(),
|
|
150
|
+
isHandledNatively,
|
|
151
|
+
})
|
|
152
|
+
return true
|
|
153
|
+
},
|
|
154
|
+
[setToast, JSON.stringify(options.native || null)]
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
const hide = React.useCallback(() => {
|
|
158
|
+
lastNativeToastRef?.close()
|
|
159
|
+
setToast((prev) => {
|
|
160
|
+
if (!prev) return null
|
|
161
|
+
return {
|
|
162
|
+
...prev,
|
|
163
|
+
hide: true,
|
|
164
|
+
}
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
setTimeout(() => {
|
|
168
|
+
setToast(null)
|
|
169
|
+
}, 100)
|
|
170
|
+
}, [setToast, lastNativeToastRef])
|
|
171
|
+
|
|
172
|
+
const contextValue = React.useMemo(() => {
|
|
173
|
+
return {
|
|
174
|
+
show,
|
|
175
|
+
hide,
|
|
176
|
+
nativeToast: lastNativeToastRef,
|
|
177
|
+
options,
|
|
178
|
+
}
|
|
179
|
+
}, [show, hide, lastNativeToastRef, JSON.stringify(options || null)])
|
|
180
|
+
|
|
181
|
+
return (
|
|
182
|
+
<ToastContext.Provider value={contextValue}>
|
|
183
|
+
<ToastCurrentContext.Provider value={toast}>
|
|
184
|
+
{children}
|
|
185
|
+
</ToastCurrentContext.Provider>
|
|
186
|
+
</ToastContext.Provider>
|
|
187
|
+
)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export type { NativePlatform, NativeValue, ToastImperativeProviderProps }
|