@hanzogui/toast 3.0.2 → 7.0.0

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.
Files changed (167) hide show
  1. package/package.json +42 -25
  2. package/src/Toast.tsx +5 -5
  3. package/src/ToastAnnounce.tsx +2 -2
  4. package/src/ToastComposable.tsx +1380 -0
  5. package/src/ToastImpl.tsx +19 -7
  6. package/src/ToastItemFrame.tsx +136 -0
  7. package/src/ToastPortal.tsx +2 -2
  8. package/src/ToastProvider.tsx +13 -6
  9. package/src/ToastState.ts +398 -0
  10. package/src/ToastViewport.tsx +11 -10
  11. package/src/Toaster.tsx +181 -0
  12. package/src/createNativeToast.native.tsx +4 -0
  13. package/src/createNativeToast.tsx +18 -24
  14. package/src/dispatchNativeToast.ts +43 -0
  15. package/src/useAnimatedDragGesture.native.ts +255 -0
  16. package/src/useAnimatedDragGesture.ts +319 -0
  17. package/src/useReducedMotion.ts +59 -0
  18. package/src/useToastAnimations.ts +377 -0
  19. package/src/v2.ts +31 -0
  20. package/types/Toast.d.ts +36 -36
  21. package/types/ToastAnnounce.d.ts +4 -4
  22. package/types/ToastComposable.d.ts +199 -0
  23. package/types/ToastImperative.d.ts +2 -2
  24. package/types/ToastImpl.d.ts +12 -12
  25. package/types/ToastItemFrame.d.ts +25 -0
  26. package/types/ToastProvider.d.ts +8 -8
  27. package/types/ToastState.d.ts +179 -0
  28. package/types/ToastViewport.d.ts +12 -12
  29. package/types/Toaster.d.ts +112 -0
  30. package/types/createNativeToast.d.ts +5 -0
  31. package/types/createNativeToast.native.d.ts +1 -0
  32. package/types/dispatchNativeToast.d.ts +12 -0
  33. package/types/useAnimatedDragGesture.d.ts +33 -0
  34. package/types/useAnimatedDragGesture.native.d.ts +33 -0
  35. package/types/useReducedMotion.d.ts +6 -0
  36. package/types/useToastAnimations.d.ts +50 -0
  37. package/types/v2.d.ts +10 -0
  38. package/v2/index.cjs +2 -0
  39. package/v2/index.js +2 -0
  40. package/v2/index.native.cjs +2 -0
  41. package/v2/index.native.js +2 -0
  42. package/LICENSE +0 -21
  43. package/dist/cjs/Toast.cjs +0 -170
  44. package/dist/cjs/Toast.native.js +0 -174
  45. package/dist/cjs/Toast.native.js.map +0 -1
  46. package/dist/cjs/ToastAnnounce.cjs +0 -97
  47. package/dist/cjs/ToastAnnounce.native.js +0 -105
  48. package/dist/cjs/ToastAnnounce.native.js.map +0 -1
  49. package/dist/cjs/ToastImperative.cjs +0 -100
  50. package/dist/cjs/ToastImperative.native.js +0 -122
  51. package/dist/cjs/ToastImperative.native.js.map +0 -1
  52. package/dist/cjs/ToastImpl.cjs +0 -292
  53. package/dist/cjs/ToastImpl.native.js +0 -326
  54. package/dist/cjs/ToastImpl.native.js.map +0 -1
  55. package/dist/cjs/ToastPortal.cjs +0 -44
  56. package/dist/cjs/ToastPortal.native.js +0 -47
  57. package/dist/cjs/ToastPortal.native.js.map +0 -1
  58. package/dist/cjs/ToastProvider.cjs +0 -146
  59. package/dist/cjs/ToastProvider.native.js +0 -159
  60. package/dist/cjs/ToastProvider.native.js.map +0 -1
  61. package/dist/cjs/ToastViewport.cjs +0 -278
  62. package/dist/cjs/ToastViewport.native.js +0 -315
  63. package/dist/cjs/ToastViewport.native.js.map +0 -1
  64. package/dist/cjs/constants.cjs +0 -28
  65. package/dist/cjs/constants.native.js +0 -31
  66. package/dist/cjs/constants.native.js.map +0 -1
  67. package/dist/cjs/createNativeToast.cjs +0 -51
  68. package/dist/cjs/createNativeToast.native.js +0 -48
  69. package/dist/cjs/createNativeToast.native.js.map +0 -1
  70. package/dist/cjs/index.cjs +0 -18
  71. package/dist/cjs/index.native.js +0 -21
  72. package/dist/cjs/index.native.js.map +0 -1
  73. package/dist/cjs/types.cjs +0 -16
  74. package/dist/cjs/types.native.js +0 -19
  75. package/dist/cjs/types.native.js.map +0 -1
  76. package/dist/esm/Toast.mjs +0 -131
  77. package/dist/esm/Toast.mjs.map +0 -1
  78. package/dist/esm/Toast.native.js +0 -132
  79. package/dist/esm/Toast.native.js.map +0 -1
  80. package/dist/esm/ToastAnnounce.mjs +0 -62
  81. package/dist/esm/ToastAnnounce.mjs.map +0 -1
  82. package/dist/esm/ToastAnnounce.native.js +0 -67
  83. package/dist/esm/ToastAnnounce.native.js.map +0 -1
  84. package/dist/esm/ToastImperative.mjs +0 -63
  85. package/dist/esm/ToastImperative.mjs.map +0 -1
  86. package/dist/esm/ToastImperative.native.js +0 -82
  87. package/dist/esm/ToastImperative.native.js.map +0 -1
  88. package/dist/esm/ToastImpl.mjs +0 -256
  89. package/dist/esm/ToastImpl.mjs.map +0 -1
  90. package/dist/esm/ToastImpl.native.js +0 -287
  91. package/dist/esm/ToastImpl.native.js.map +0 -1
  92. package/dist/esm/ToastPortal.mjs +0 -21
  93. package/dist/esm/ToastPortal.mjs.map +0 -1
  94. package/dist/esm/ToastPortal.native.js +0 -21
  95. package/dist/esm/ToastPortal.native.js.map +0 -1
  96. package/dist/esm/ToastProvider.mjs +0 -108
  97. package/dist/esm/ToastProvider.mjs.map +0 -1
  98. package/dist/esm/ToastProvider.native.js +0 -118
  99. package/dist/esm/ToastProvider.native.js.map +0 -1
  100. package/dist/esm/ToastViewport.mjs +0 -241
  101. package/dist/esm/ToastViewport.mjs.map +0 -1
  102. package/dist/esm/ToastViewport.native.js +0 -275
  103. package/dist/esm/ToastViewport.native.js.map +0 -1
  104. package/dist/esm/constants.mjs +0 -4
  105. package/dist/esm/constants.mjs.map +0 -1
  106. package/dist/esm/constants.native.js +0 -4
  107. package/dist/esm/constants.native.js.map +0 -1
  108. package/dist/esm/createNativeToast.mjs +0 -27
  109. package/dist/esm/createNativeToast.mjs.map +0 -1
  110. package/dist/esm/createNativeToast.native.js +0 -21
  111. package/dist/esm/createNativeToast.native.js.map +0 -1
  112. package/dist/esm/index.js +0 -2
  113. package/dist/esm/index.js.map +0 -1
  114. package/dist/esm/index.mjs +0 -2
  115. package/dist/esm/index.mjs.map +0 -1
  116. package/dist/esm/index.native.js +0 -2
  117. package/dist/esm/index.native.js.map +0 -1
  118. package/dist/esm/types.mjs +0 -2
  119. package/dist/esm/types.mjs.map +0 -1
  120. package/dist/esm/types.native.js +0 -2
  121. package/dist/esm/types.native.js.map +0 -1
  122. package/dist/jsx/Toast.mjs +0 -131
  123. package/dist/jsx/Toast.mjs.map +0 -1
  124. package/dist/jsx/Toast.native.js +0 -174
  125. package/dist/jsx/Toast.native.js.map +0 -1
  126. package/dist/jsx/ToastAnnounce.mjs +0 -62
  127. package/dist/jsx/ToastAnnounce.mjs.map +0 -1
  128. package/dist/jsx/ToastAnnounce.native.js +0 -105
  129. package/dist/jsx/ToastAnnounce.native.js.map +0 -1
  130. package/dist/jsx/ToastImperative.mjs +0 -63
  131. package/dist/jsx/ToastImperative.mjs.map +0 -1
  132. package/dist/jsx/ToastImperative.native.js +0 -122
  133. package/dist/jsx/ToastImperative.native.js.map +0 -1
  134. package/dist/jsx/ToastImpl.mjs +0 -256
  135. package/dist/jsx/ToastImpl.mjs.map +0 -1
  136. package/dist/jsx/ToastImpl.native.js +0 -326
  137. package/dist/jsx/ToastImpl.native.js.map +0 -1
  138. package/dist/jsx/ToastPortal.mjs +0 -21
  139. package/dist/jsx/ToastPortal.mjs.map +0 -1
  140. package/dist/jsx/ToastPortal.native.js +0 -47
  141. package/dist/jsx/ToastPortal.native.js.map +0 -1
  142. package/dist/jsx/ToastProvider.mjs +0 -108
  143. package/dist/jsx/ToastProvider.mjs.map +0 -1
  144. package/dist/jsx/ToastProvider.native.js +0 -159
  145. package/dist/jsx/ToastProvider.native.js.map +0 -1
  146. package/dist/jsx/ToastViewport.mjs +0 -241
  147. package/dist/jsx/ToastViewport.mjs.map +0 -1
  148. package/dist/jsx/ToastViewport.native.js +0 -315
  149. package/dist/jsx/ToastViewport.native.js.map +0 -1
  150. package/dist/jsx/constants.mjs +0 -4
  151. package/dist/jsx/constants.mjs.map +0 -1
  152. package/dist/jsx/constants.native.js +0 -31
  153. package/dist/jsx/constants.native.js.map +0 -1
  154. package/dist/jsx/createNativeToast.mjs +0 -27
  155. package/dist/jsx/createNativeToast.mjs.map +0 -1
  156. package/dist/jsx/createNativeToast.native.js +0 -48
  157. package/dist/jsx/createNativeToast.native.js.map +0 -1
  158. package/dist/jsx/index.js +0 -2
  159. package/dist/jsx/index.js.map +0 -1
  160. package/dist/jsx/index.mjs +0 -2
  161. package/dist/jsx/index.mjs.map +0 -1
  162. package/dist/jsx/index.native.js +0 -21
  163. package/dist/jsx/index.native.js.map +0 -1
  164. package/dist/jsx/types.mjs +0 -2
  165. package/dist/jsx/types.mjs.map +0 -1
  166. package/dist/jsx/types.native.js +0 -19
  167. package/dist/jsx/types.native.js.map +0 -1
@@ -0,0 +1,377 @@
1
+ /**
2
+ * Hook for cross-animation-driver toast drag animations.
3
+ *
4
+ * Animation strategy (all cross-driver):
5
+ * - AnimatePresence => enter/exit styles
6
+ * - transition prop => non-interactive styles (stacking, scale, opacity)
7
+ * - useAnimatedNumber/Style => interactive styles (drag gestures only)
8
+ *
9
+ * This hook handles ONLY the drag gesture animations.
10
+ * Uses the same pattern as Sheet for universal animation support.
11
+ *
12
+ * NOTE: For CSS driver, we use a ref-based approach with direct DOM manipulation
13
+ * because CSS driver's useAnimatedNumberStyle doesn't reactively update.
14
+ * For Motion/Reanimated drivers, we use the AnimatedView + motionValue pattern.
15
+ */
16
+
17
+ import { isWeb } from '@hanzogui/constants'
18
+ import { useConfiguration, useEvent, View as HanzoguiView } from '@hanzogui/core'
19
+ import * as React from 'react'
20
+ import type { Animated } from 'react-native'
21
+
22
+ export interface UseToastAnimationsOptions {
23
+ /**
24
+ * Called when exit animation completes
25
+ */
26
+ onExitComplete?: () => void
27
+ /**
28
+ * When true, animations complete instantly (accessibility)
29
+ */
30
+ reducedMotion?: boolean
31
+ /**
32
+ * Primary swipe axis — determines which animated value is tracked for style updates.
33
+ * 'horizontal' tracks translateX, 'vertical' tracks translateY.
34
+ */
35
+ swipeAxis?: 'horizontal' | 'vertical'
36
+ }
37
+
38
+ export interface ToastAnimationValues {
39
+ /** set drag offset directly (no animation, for gesture moves) */
40
+ setDragOffset: (x: number, y: number) => void
41
+ /** spring back to origin after cancelled drag */
42
+ springBack: (onComplete?: () => void) => void
43
+ /** animate out in a direction after successful swipe, with optional velocity for smooth continuation */
44
+ animateOut: (
45
+ direction: 'left' | 'right' | 'up' | 'down',
46
+ velocity?: number,
47
+ onComplete?: () => void
48
+ ) => void
49
+ /** stop any running animations */
50
+ stop: () => void
51
+ /** the animated style to spread on the AnimatedView (for motion/reanimated drivers) */
52
+ animatedStyle: any
53
+ /** the animated view component from the driver */
54
+ AnimatedView: typeof Animated.View
55
+ /** ref to attach to the drag wrapper element (for CSS driver direct DOM updates) */
56
+ dragRef: React.RefObject<HTMLDivElement | null>
57
+ }
58
+
59
+ // tuned for snappy, premium feel like Sonner
60
+ const SPRING_CONFIG = {
61
+ type: 'spring' as const,
62
+ damping: 30,
63
+ stiffness: 400,
64
+ mass: 0.5,
65
+ }
66
+
67
+ const EXIT_DISTANCE = 200
68
+
69
+ // simple spring animation for CSS driver
70
+ function animateSpring(
71
+ element: HTMLElement,
72
+ fromX: number,
73
+ fromY: number,
74
+ toX: number,
75
+ toY: number,
76
+ config: {
77
+ damping?: number
78
+ stiffness?: number
79
+ mass?: number
80
+ initialVelocityX?: number
81
+ initialVelocityY?: number
82
+ fadeOut?: boolean
83
+ },
84
+ onComplete?: () => void
85
+ ) {
86
+ const {
87
+ damping = 30,
88
+ stiffness = 400,
89
+ mass = 0.5,
90
+ initialVelocityX = 0,
91
+ initialVelocityY = 0,
92
+ fadeOut = false,
93
+ } = config
94
+
95
+ let x = fromX
96
+ let y = fromY
97
+ // use initial velocity from gesture for smooth continuation
98
+ let velocityX = initialVelocityX
99
+ let velocityY = initialVelocityY
100
+ let animationId: number | null = null
101
+ const targetX = toX
102
+ const targetY = toY
103
+
104
+ // for fade out, track progress based on distance traveled
105
+ const totalDistance = Math.sqrt((toX - fromX) ** 2 + (toY - fromY) ** 2) || 1
106
+
107
+ function step() {
108
+ // spring physics
109
+ const forceX = -stiffness * (x - targetX)
110
+ const forceY = -stiffness * (y - targetY)
111
+ const dampingForceX = -damping * velocityX
112
+ const dampingForceY = -damping * velocityY
113
+
114
+ const accelerationX = (forceX + dampingForceX) / mass
115
+ const accelerationY = (forceY + dampingForceY) / mass
116
+
117
+ velocityX += accelerationX * 0.016 // ~60fps
118
+ velocityY += accelerationY * 0.016
119
+ x += velocityX * 0.016
120
+ y += velocityY * 0.016
121
+
122
+ element.style.transform = `translate3d(${x}px, ${y}px, 0)`
123
+
124
+ // animate opacity based on progress toward target
125
+ if (fadeOut) {
126
+ const distanceTraveled = Math.sqrt((x - fromX) ** 2 + (y - fromY) ** 2)
127
+ const progress = Math.min(distanceTraveled / totalDistance, 1)
128
+ element.style.opacity = String(1 - progress)
129
+ }
130
+
131
+ // check if close enough to target and velocity is low
132
+ const distanceX = Math.abs(x - targetX)
133
+ const distanceY = Math.abs(y - targetY)
134
+ const speed = Math.sqrt(velocityX * velocityX + velocityY * velocityY)
135
+
136
+ if (distanceX < 0.5 && distanceY < 0.5 && speed < 0.5) {
137
+ element.style.transform = `translate3d(${targetX}px, ${targetY}px, 0)`
138
+ if (fadeOut) {
139
+ element.style.opacity = '0'
140
+ }
141
+ onComplete?.()
142
+ return
143
+ }
144
+
145
+ animationId = requestAnimationFrame(step)
146
+ }
147
+
148
+ animationId = requestAnimationFrame(step)
149
+
150
+ return () => {
151
+ if (animationId) {
152
+ cancelAnimationFrame(animationId)
153
+ }
154
+ }
155
+ }
156
+
157
+ export function useToastAnimations(
158
+ options: UseToastAnimationsOptions = {}
159
+ ): ToastAnimationValues {
160
+ const { onExitComplete, reducedMotion, swipeAxis = 'horizontal' } = options
161
+
162
+ const { animationDriver } = useConfiguration()
163
+
164
+ if (!animationDriver) {
165
+ throw new Error('Toast requires an animation driver to be set in HanzoguiProvider')
166
+ }
167
+
168
+ const { useAnimatedNumber, useAnimatedNumberStyle, useAnimatedNumbersStyle } =
169
+ animationDriver
170
+ const AnimatedView = (animationDriver.View ?? HanzoguiView) as typeof Animated.View
171
+
172
+ // ref for direct DOM manipulation (CSS driver fallback)
173
+ const dragRef = React.useRef<HTMLDivElement>(null)
174
+ const cancelAnimationRef = React.useRef<(() => void) | null>(null)
175
+ const currentOffsetRef = React.useRef({ x: 0, y: 0 })
176
+
177
+ // on web, use direct DOM for drag (CSS driver has no reactive style updates)
178
+ // on native, use the animation driver's AnimatedView + animatedStyle
179
+ const useDirectDom = isWeb
180
+
181
+ // animated values for drag translation
182
+ const translateX = useAnimatedNumber(0)
183
+ const translateY = useAnimatedNumber(0)
184
+
185
+ // multi-value: both axes reactive in one animated style (off-thread on Reanimated)
186
+ const animatedStyleMulti = useAnimatedNumbersStyle
187
+ ? useAnimatedNumbersStyle([translateX, translateY], (x: number, y: number) => {
188
+ 'worklet'
189
+ return { transform: [{ translateX: x }, { translateY: y }] }
190
+ })
191
+ : null
192
+
193
+ // single-value fallback for drivers without useAnimatedNumbersStyle
194
+ const animatedStyleFallback = useAnimatedNumberStyle(
195
+ swipeAxis === 'vertical' ? translateY : translateX,
196
+ (primary) => {
197
+ 'worklet'
198
+ const secondary =
199
+ swipeAxis === 'vertical' ? translateX.getValue() : translateY.getValue()
200
+ return swipeAxis === 'vertical'
201
+ ? { transform: [{ translateX: secondary }, { translateY: primary }] }
202
+ : { transform: [{ translateX: primary }, { translateY: secondary }] }
203
+ }
204
+ )
205
+
206
+ const animatedStyle = animatedStyleMulti ?? animatedStyleFallback
207
+
208
+ // set drag offset directly (no animation) - used during gesture
209
+ const setDragOffset = useEvent((x: number, y: number) => {
210
+ // cancel any running animation (e.g., spring back from previous gesture)
211
+ cancelAnimationRef.current?.()
212
+ cancelAnimationRef.current = null
213
+
214
+ currentOffsetRef.current = { x, y }
215
+
216
+ if (useDirectDom && dragRef.current) {
217
+ // direct DOM manipulation for CSS driver
218
+ dragRef.current.style.transform = `translate3d(${x}px, ${y}px, 0)`
219
+ dragRef.current.style.opacity = '1' // reset in case previous animation faded it
220
+ } else {
221
+ // use animation driver for motion/reanimated
222
+ translateX.setValue(x, { type: 'direct' })
223
+ translateY.setValue(y, { type: 'direct' })
224
+ }
225
+ })
226
+
227
+ // spring back to origin after cancelled drag
228
+ const springBack = useEvent((onComplete?: () => void) => {
229
+ // cancel any running animation
230
+ cancelAnimationRef.current?.()
231
+
232
+ if (reducedMotion) {
233
+ // instant for reduced motion
234
+ if (useDirectDom && dragRef.current) {
235
+ dragRef.current.style.transform = 'translate3d(0px, 0px, 0)'
236
+ } else {
237
+ translateX.setValue(0, { type: 'direct' })
238
+ translateY.setValue(0, { type: 'direct' })
239
+ }
240
+ currentOffsetRef.current = { x: 0, y: 0 }
241
+ onComplete?.()
242
+ return
243
+ }
244
+
245
+ if (useDirectDom && dragRef.current) {
246
+ // use JS spring animation for CSS driver
247
+ const { x, y } = currentOffsetRef.current
248
+ cancelAnimationRef.current = animateSpring(
249
+ dragRef.current,
250
+ x,
251
+ y,
252
+ 0,
253
+ 0,
254
+ SPRING_CONFIG,
255
+ () => {
256
+ currentOffsetRef.current = { x: 0, y: 0 }
257
+ onComplete?.()
258
+ }
259
+ )
260
+ } else {
261
+ // use animation driver for motion/reanimated
262
+ translateX.setValue(0, SPRING_CONFIG)
263
+ translateY.setValue(0, SPRING_CONFIG, onComplete)
264
+ }
265
+ })
266
+
267
+ // animate out in a direction after successful swipe
268
+ // velocity is in px/ms from gesture, used for smooth momentum continuation
269
+ const animateOut = useEvent(
270
+ (
271
+ direction: 'left' | 'right' | 'up' | 'down',
272
+ velocity?: number,
273
+ onComplete?: () => void
274
+ ) => {
275
+ // cancel any running animation
276
+ cancelAnimationRef.current?.()
277
+
278
+ const { x: curX, y: curY } = currentOffsetRef.current
279
+
280
+ // ensure exit target is always further than current drag position
281
+ // (user may have dragged past EXIT_DISTANCE already)
282
+ let exitX =
283
+ direction === 'left' ? -EXIT_DISTANCE : direction === 'right' ? EXIT_DISTANCE : 0
284
+ let exitY =
285
+ direction === 'up' ? -EXIT_DISTANCE : direction === 'down' ? EXIT_DISTANCE : 0
286
+
287
+ if (direction === 'left' && curX < exitX) exitX = curX - 50
288
+ else if (direction === 'right' && curX > exitX) exitX = curX + 50
289
+ if (direction === 'up' && curY < exitY) exitY = curY - 50
290
+ else if (direction === 'down' && curY > exitY) exitY = curY + 50
291
+
292
+ if (reducedMotion) {
293
+ // instant for reduced motion
294
+ if (useDirectDom && dragRef.current) {
295
+ dragRef.current.style.transform = `translate3d(${exitX}px, ${exitY}px, 0)`
296
+ } else {
297
+ translateX.setValue(exitX, { type: 'direct' })
298
+ translateY.setValue(exitY, { type: 'direct' })
299
+ }
300
+ onComplete?.()
301
+ onExitComplete?.()
302
+ return
303
+ }
304
+
305
+ // convert velocity from px/ms to px/frame (assuming 60fps = 16.67ms/frame)
306
+ // multiply by ~500 to get a reasonable initial velocity for the spring
307
+ const velocityScale = (velocity ?? 0) * 500
308
+ const initialVelocityX =
309
+ direction === 'left' ? -velocityScale : direction === 'right' ? velocityScale : 0
310
+ const initialVelocityY =
311
+ direction === 'up' ? -velocityScale : direction === 'down' ? velocityScale : 0
312
+
313
+ // exit animation config - tuned for smooth momentum continuation
314
+ const exitConfig = {
315
+ damping: 25,
316
+ stiffness: 350,
317
+ mass: 0.4,
318
+ initialVelocityX,
319
+ initialVelocityY,
320
+ fadeOut: true,
321
+ }
322
+
323
+ if (useDirectDom && dragRef.current) {
324
+ // use JS spring animation for CSS driver
325
+ const { x, y } = currentOffsetRef.current
326
+ cancelAnimationRef.current = animateSpring(
327
+ dragRef.current,
328
+ x,
329
+ y,
330
+ exitX,
331
+ exitY,
332
+ exitConfig,
333
+ () => {
334
+ onComplete?.()
335
+ onExitComplete?.()
336
+ }
337
+ )
338
+ } else {
339
+ // animation driver path (reanimated/RN)
340
+ const springConfig = {
341
+ type: 'spring' as const,
342
+ damping: 25,
343
+ stiffness: 350,
344
+ mass: 0.4,
345
+ }
346
+ translateX.setValue(exitX, springConfig)
347
+ translateY.setValue(exitY, springConfig, () => {
348
+ onComplete?.()
349
+ onExitComplete?.()
350
+ })
351
+ }
352
+ }
353
+ )
354
+
355
+ const stop = useEvent(() => {
356
+ cancelAnimationRef.current?.()
357
+ translateX.stop()
358
+ translateY.stop()
359
+ })
360
+
361
+ // cleanup on unmount
362
+ React.useEffect(() => {
363
+ return () => {
364
+ cancelAnimationRef.current?.()
365
+ }
366
+ }, [])
367
+
368
+ return {
369
+ setDragOffset,
370
+ springBack,
371
+ animateOut,
372
+ stop,
373
+ animatedStyle,
374
+ AnimatedView,
375
+ dragRef,
376
+ }
377
+ }
package/src/v2.ts ADDED
@@ -0,0 +1,31 @@
1
+ // Toast v2 - composable component API
2
+ export { Toast, useToasts, useToastItem } from './ToastComposable'
3
+ export type {
4
+ ToastRootProps,
5
+ ToastViewportProps,
6
+ ToastItemProps,
7
+ ToastItemRenderProps,
8
+ ToastListProps,
9
+ ToastPosition,
10
+ ToastIcons,
11
+ } from './ToastComposable'
12
+
13
+ // Toast v2 - imperative API
14
+ export { toast } from './ToastState'
15
+ export type {
16
+ ToastT,
17
+ ToastType,
18
+ ToastToDismiss,
19
+ ExternalToast,
20
+ PromiseT,
21
+ PromiseData,
22
+ ToastAction,
23
+ } from './ToastState'
24
+
25
+ // Toaster - all-in-one component (thin wrapper over composable API)
26
+ export { Toaster } from './Toaster'
27
+ export type { ToasterProps, ToasterPosition } from './Toaster'
28
+
29
+ export type { SwipeDirection } from './ToastProvider'
30
+ export type { BurntToastOptions, CreateNativeToastOptions, NativeToastRef } from './types'
31
+ export { requestNotificationPermission } from './createNativeToast'
package/types/Toast.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { GetProps, NativePlatform, NativeValue, GuiElement } from '@gui/core';
1
+ import type { GetProps, NativePlatform, NativeValue, HanzoguiElement } from '@hanzogui/core';
2
2
  import * as React from 'react';
3
3
  import type { CustomData } from './ToastImperative';
4
4
  import { useToast, useToastController, useToastState } from './ToastImperative';
@@ -7,15 +7,15 @@ import type { ScopedProps, ToastProviderProps } from './ToastProvider';
7
7
  import { ToastProvider } from './ToastProvider';
8
8
  import type { ToastViewportProps } from './ToastViewport';
9
9
  import { ToastViewport } from './ToastViewport';
10
- declare const ToastTitle: import("@gui/core").GuiComponent<import("@gui/core").TamaDefer, import("@gui/core").GuiTextElement, import("@gui/core").TextNonStyleProps, import("@gui/core").TextStylePropsBase, {
10
+ declare const ToastTitle: import("@hanzogui/core").HanzoguiComponent<import("@hanzogui/core").TamaDefer, import("@hanzogui/core").HanzoguiTextElement, import("@hanzogui/core").TextNonStyleProps, import("@hanzogui/core").TextStylePropsBase, {
11
11
  unstyled?: boolean | undefined;
12
- size?: import("@gui/core").FontSizeTokens | undefined;
13
- }, import("@gui/core").StaticConfigPublic>;
12
+ size?: import("@hanzogui/core").FontSizeTokens | undefined;
13
+ }, import("@hanzogui/core").StaticConfigPublic>;
14
14
  type ToastTitleProps = GetProps<typeof ToastTitle>;
15
- declare const ToastDescription: import("@gui/core").GuiComponent<import("@gui/core").TamaDefer, import("@gui/core").GuiTextElement, import("@gui/core").TextNonStyleProps, import("@gui/core").TextStylePropsBase, {
15
+ declare const ToastDescription: import("@hanzogui/core").HanzoguiComponent<import("@hanzogui/core").TamaDefer, import("@hanzogui/core").HanzoguiTextElement, import("@hanzogui/core").TextNonStyleProps, import("@hanzogui/core").TextStylePropsBase, {
16
16
  unstyled?: boolean | undefined;
17
- size?: import("@gui/core").FontSizeTokens | undefined;
18
- }, import("@gui/core").StaticConfigPublic>;
17
+ size?: import("@hanzogui/core").FontSizeTokens | undefined;
18
+ }, import("@hanzogui/core").StaticConfigPublic>;
19
19
  type ToastDescriptionProps = GetProps<typeof ToastDescription>;
20
20
  type ToastActionProps = ScopedProps<ToastCloseProps & {
21
21
  /**
@@ -26,58 +26,58 @@ type ToastActionProps = ScopedProps<ToastCloseProps & {
26
26
  */
27
27
  altText: string;
28
28
  }>;
29
- declare const ToastCloseFrame: import("@gui/core").GuiComponent<import("@gui/core").TamaDefer, GuiElement, import("@gui/core").RNGuiViewNonStyleProps, import("@gui/core").StackStyleBase, {
30
- elevation?: number | import("@gui/core").SizeTokens | undefined;
29
+ declare const ToastCloseFrame: import("@hanzogui/core").HanzoguiComponent<import("@hanzogui/core").TamaDefer, HanzoguiElement, import("@hanzogui/core").RNHanzoguiViewNonStyleProps, import("@hanzogui/core").StackStyleBase, {
30
+ elevation?: number | import("@hanzogui/core").SizeTokens | undefined;
31
31
  fullscreen?: boolean | undefined;
32
- }, import("@gui/core").StaticConfigPublic>;
32
+ }, import("@hanzogui/core").StaticConfigPublic>;
33
33
  type ToastCloseFrameProps = GetProps<typeof ToastCloseFrame>;
34
34
  type ToastCloseProps = ScopedProps<ToastCloseFrameProps & {}>;
35
- declare const Toast: React.ForwardRefExoticComponent<Omit<import("@gui/core").GetFinalProps<import("@gui/core").RNGuiViewNonStyleProps, import("@gui/core").StackStyleBase, {
35
+ declare const Toast: React.ForwardRefExoticComponent<Omit<import("@hanzogui/core").GetFinalProps<import("@hanzogui/core").RNHanzoguiViewNonStyleProps, import("@hanzogui/core").StackStyleBase, {
36
36
  unstyled?: boolean | undefined;
37
- elevation?: number | import("@gui/core").SizeTokens | undefined;
37
+ elevation?: number | import("@hanzogui/core").SizeTokens | undefined;
38
38
  fullscreen?: boolean | undefined;
39
- }>, keyof ToastExtraProps> & ToastExtraProps & React.RefAttributes<GuiElement>> & import("@gui/core").StaticComponentObject<Omit<import("@gui/core").GetFinalProps<import("@gui/core").RNGuiViewNonStyleProps, import("@gui/core").StackStyleBase, {
39
+ }>, keyof ToastExtraProps> & ToastExtraProps & React.RefAttributes<HanzoguiElement>> & import("@hanzogui/core").StaticComponentObject<Omit<import("@hanzogui/core").GetFinalProps<import("@hanzogui/core").RNHanzoguiViewNonStyleProps, import("@hanzogui/core").StackStyleBase, {
40
40
  unstyled?: boolean | undefined;
41
- elevation?: number | import("@gui/core").SizeTokens | undefined;
41
+ elevation?: number | import("@hanzogui/core").SizeTokens | undefined;
42
42
  fullscreen?: boolean | undefined;
43
- }>, keyof ToastExtraProps> & ToastExtraProps, GuiElement, import("@gui/core").RNGuiViewNonStyleProps & ToastExtraProps, import("@gui/core").StackStyleBase, {
43
+ }>, keyof ToastExtraProps> & ToastExtraProps, HanzoguiElement, import("@hanzogui/core").RNHanzoguiViewNonStyleProps & ToastExtraProps, import("@hanzogui/core").StackStyleBase, {
44
44
  unstyled?: boolean | undefined;
45
- elevation?: number | import("@gui/core").SizeTokens | undefined;
45
+ elevation?: number | import("@hanzogui/core").SizeTokens | undefined;
46
46
  fullscreen?: boolean | undefined;
47
- }, import("@gui/core").StaticConfigPublic> & Omit<import("@gui/core").StaticConfigPublic, "staticConfig" | "styleable"> & {
48
- __tama: [Omit<import("@gui/core").GetFinalProps<import("@gui/core").RNGuiViewNonStyleProps, import("@gui/core").StackStyleBase, {
47
+ }, import("@hanzogui/core").StaticConfigPublic> & Omit<import("@hanzogui/core").StaticConfigPublic, "staticConfig" | "styleable"> & {
48
+ __tama: [Omit<import("@hanzogui/core").GetFinalProps<import("@hanzogui/core").RNHanzoguiViewNonStyleProps, import("@hanzogui/core").StackStyleBase, {
49
49
  unstyled?: boolean | undefined;
50
- elevation?: number | import("@gui/core").SizeTokens | undefined;
50
+ elevation?: number | import("@hanzogui/core").SizeTokens | undefined;
51
51
  fullscreen?: boolean | undefined;
52
- }>, keyof ToastExtraProps> & ToastExtraProps, GuiElement, import("@gui/core").RNGuiViewNonStyleProps & ToastExtraProps, import("@gui/core").StackStyleBase, {
52
+ }>, keyof ToastExtraProps> & ToastExtraProps, HanzoguiElement, import("@hanzogui/core").RNHanzoguiViewNonStyleProps & ToastExtraProps, import("@hanzogui/core").StackStyleBase, {
53
53
  unstyled?: boolean | undefined;
54
- elevation?: number | import("@gui/core").SizeTokens | undefined;
54
+ elevation?: number | import("@hanzogui/core").SizeTokens | undefined;
55
55
  fullscreen?: boolean | undefined;
56
- }, import("@gui/core").StaticConfigPublic];
56
+ }, import("@hanzogui/core").StaticConfigPublic];
57
57
  } & {
58
- Title: import("@gui/core").GuiComponent<import("@gui/core").TamaDefer, import("@gui/core").GuiTextElement, import("@gui/core").TextNonStyleProps, import("@gui/core").TextStylePropsBase, {
58
+ Title: import("@hanzogui/core").HanzoguiComponent<import("@hanzogui/core").TamaDefer, import("@hanzogui/core").HanzoguiTextElement, import("@hanzogui/core").TextNonStyleProps, import("@hanzogui/core").TextStylePropsBase, {
59
59
  unstyled?: boolean | undefined;
60
- size?: import("@gui/core").FontSizeTokens | undefined;
61
- }, import("@gui/core").StaticConfigPublic>;
62
- Description: import("@gui/core").GuiComponent<import("@gui/core").TamaDefer, import("@gui/core").GuiTextElement, import("@gui/core").TextNonStyleProps, import("@gui/core").TextStylePropsBase, {
60
+ size?: import("@hanzogui/core").FontSizeTokens | undefined;
61
+ }, import("@hanzogui/core").StaticConfigPublic>;
62
+ Description: import("@hanzogui/core").HanzoguiComponent<import("@hanzogui/core").TamaDefer, import("@hanzogui/core").HanzoguiTextElement, import("@hanzogui/core").TextNonStyleProps, import("@hanzogui/core").TextStylePropsBase, {
63
63
  unstyled?: boolean | undefined;
64
- size?: import("@gui/core").FontSizeTokens | undefined;
65
- }, import("@gui/core").StaticConfigPublic>;
64
+ size?: import("@hanzogui/core").FontSizeTokens | undefined;
65
+ }, import("@hanzogui/core").StaticConfigPublic>;
66
66
  Action: React.ForwardRefExoticComponent<Omit<ToastActionProps, "scope"> & {
67
67
  scope?: import("./ToastProvider").ToastScopes;
68
- } & React.RefAttributes<GuiElement>>;
69
- Close: React.ForwardRefExoticComponent<Omit<Omit<import("@gui/core").RNGuiViewNonStyleProps, "elevation" | keyof import("@gui/core").StackStyleBase | "fullscreen"> & import("@gui/core").WithThemeValues<import("@gui/core").StackStyleBase> & {
70
- elevation?: number | import("@gui/core").SizeTokens | undefined;
68
+ } & React.RefAttributes<HanzoguiElement>>;
69
+ Close: React.ForwardRefExoticComponent<Omit<Omit<import("@hanzogui/core").RNHanzoguiViewNonStyleProps, "elevation" | keyof import("@hanzogui/core").StackStyleBase | "fullscreen"> & import("@hanzogui/core").WithThemeValues<import("@hanzogui/core").StackStyleBase> & {
70
+ elevation?: number | import("@hanzogui/core").SizeTokens | undefined;
71
71
  fullscreen?: boolean | undefined;
72
- } & import("@gui/core").WithShorthands<import("@gui/core").WithThemeValues<import("@gui/core").StackStyleBase>> & import("@gui/core").WithPseudoProps<import("@gui/core").WithThemeValues<import("@gui/core").StackStyleBase> & {
73
- elevation?: number | import("@gui/core").SizeTokens | undefined;
72
+ } & import("@hanzogui/core").WithShorthands<import("@hanzogui/core").WithThemeValues<import("@hanzogui/core").StackStyleBase>> & import("@hanzogui/core").WithPseudoProps<import("@hanzogui/core").WithThemeValues<import("@hanzogui/core").StackStyleBase> & {
73
+ elevation?: number | import("@hanzogui/core").SizeTokens | undefined;
74
74
  fullscreen?: boolean | undefined;
75
- } & import("@gui/core").WithShorthands<import("@gui/core").WithThemeValues<import("@gui/core").StackStyleBase>>> & import("@gui/core").WithMediaProps<import("@gui/core").WithThemeShorthandsAndPseudos<import("@gui/core").StackStyleBase, {
76
- elevation?: number | import("@gui/core").SizeTokens | undefined;
75
+ } & import("@hanzogui/core").WithShorthands<import("@hanzogui/core").WithThemeValues<import("@hanzogui/core").StackStyleBase>>> & import("@hanzogui/core").WithMediaProps<import("@hanzogui/core").WithThemeShorthandsAndPseudos<import("@hanzogui/core").StackStyleBase, {
76
+ elevation?: number | import("@hanzogui/core").SizeTokens | undefined;
77
77
  fullscreen?: boolean | undefined;
78
78
  }>>, "scope"> & {
79
79
  scope?: import("./ToastProvider").ToastScopes;
80
- } & React.RefAttributes<GuiElement>>;
80
+ } & React.RefAttributes<HanzoguiElement>>;
81
81
  };
82
82
  export { Toast, ToastProvider, ToastViewport, useToast, useToastController, useToastState, };
83
83
  export type { CustomData, ToastActionProps, ToastCloseProps, ToastDescriptionProps, NativePlatform as ToastNativePlatform, NativeValue as ToastNativeValue, ToastProps, ToastProviderProps, ToastTitleProps, ToastViewportProps, };
@@ -1,14 +1,14 @@
1
- import type { GetProps, GuiElement } from '@gui/core';
2
- import { VisuallyHidden } from '@gui/visually-hidden';
1
+ import type { GetProps, HanzoguiElement } from '@hanzogui/core';
2
+ import { VisuallyHidden } from '@hanzogui/visually-hidden';
3
3
  import * as React from 'react';
4
4
  import type { ScopedProps } from './ToastProvider';
5
- declare const ToastAnnounceExcludeFrame: import("@gui/core").GuiComponent<import("@gui/core").TamaDefer, GuiElement, import("@gui/core").RNGuiViewNonStyleProps, import("@gui/core").StackStyleBase, {}, import("@gui/core").StaticConfigPublic>;
5
+ declare const ToastAnnounceExcludeFrame: import("@hanzogui/core").HanzoguiComponent<import("@hanzogui/core").TamaDefer, HanzoguiElement, import("@hanzogui/core").RNHanzoguiViewNonStyleProps, import("@hanzogui/core").StackStyleBase, {}, import("@hanzogui/core").StaticConfigPublic>;
6
6
  type ToastAnnounceExcludeFrameProps = GetProps<typeof ToastAnnounceExcludeFrame>;
7
7
  type ToastAnnounceExcludeExtraProps = {
8
8
  altText?: string;
9
9
  };
10
10
  type ToastAnnounceExcludeProps = ToastAnnounceExcludeFrameProps & ToastAnnounceExcludeExtraProps;
11
- declare const ToastAnnounceExclude: React.ForwardRefExoticComponent<Omit<import("@gui/core").RNGuiViewNonStyleProps, keyof import("@gui/core").StackStyleBase> & import("@gui/core").WithThemeValues<import("@gui/core").StackStyleBase> & import("@gui/core").WithShorthands<import("@gui/core").WithThemeValues<import("@gui/core").StackStyleBase>> & import("@gui/core").WithPseudoProps<import("@gui/core").WithThemeValues<import("@gui/core").StackStyleBase> & import("@gui/core").WithShorthands<import("@gui/core").WithThemeValues<import("@gui/core").StackStyleBase>>> & import("@gui/core").WithMediaProps<import("@gui/core").WithThemeShorthandsAndPseudos<import("@gui/core").StackStyleBase, {}>> & ToastAnnounceExcludeExtraProps & React.RefAttributes<GuiElement>>;
11
+ declare const ToastAnnounceExclude: React.ForwardRefExoticComponent<Omit<import("@hanzogui/core").RNHanzoguiViewNonStyleProps, keyof import("@hanzogui/core").StackStyleBase> & import("@hanzogui/core").WithThemeValues<import("@hanzogui/core").StackStyleBase> & import("@hanzogui/core").WithShorthands<import("@hanzogui/core").WithThemeValues<import("@hanzogui/core").StackStyleBase>> & import("@hanzogui/core").WithPseudoProps<import("@hanzogui/core").WithThemeValues<import("@hanzogui/core").StackStyleBase> & import("@hanzogui/core").WithShorthands<import("@hanzogui/core").WithThemeValues<import("@hanzogui/core").StackStyleBase>>> & import("@hanzogui/core").WithMediaProps<import("@hanzogui/core").WithThemeShorthandsAndPseudos<import("@hanzogui/core").StackStyleBase, {}>> & ToastAnnounceExcludeExtraProps & React.RefAttributes<HanzoguiElement>>;
12
12
  interface ToastAnnounceProps extends Omit<GetProps<typeof VisuallyHidden>, 'children'>, ScopedProps<{
13
13
  children: string[];
14
14
  }> {