@metamask/design-system-react-native 0.38.1 → 0.39.1

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/CHANGELOG.md CHANGED
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.39.1]
11
+
12
+ ### Fixed
13
+
14
+ - Fixed `Toast` swipe-to-dismiss so a pan that fails after activation (for example when horizontal movement exceeds the fail offset) springs back to its visible position and resumes auto-dismiss instead of staying mid-offset ([#1427](https://github.com/MetaMask/metamask-design-system/pull/1427))
15
+
16
+ ## [0.39.0]
17
+
18
+ ### Added
19
+
20
+ - Added swipe-to-dismiss gesture support to Toast component with configurable distance and velocity thresholds ([#1415](https://github.com/MetaMask/metamask-design-system/pull/1415))
21
+
22
+ ### Fixed
23
+
24
+ - Fixed Checkbox selected state to use monochromatic icon colors instead of primary blue ([#1426](https://github.com/MetaMask/metamask-design-system/pull/1426))
25
+
10
26
  ## [0.38.1]
11
27
 
12
28
  ### Changed
@@ -649,7 +665,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
649
665
  - Full TypeScript support with type definitions and enums
650
666
  - React Native integration with TWRNC preset support
651
667
 
652
- [Unreleased]: https://github.com/MetaMask/metamask-design-system/compare/@metamask/design-system-react-native@0.38.1...HEAD
668
+ [Unreleased]: https://github.com/MetaMask/metamask-design-system/compare/@metamask/design-system-react-native@0.39.1...HEAD
669
+ [0.39.1]: https://github.com/MetaMask/metamask-design-system/compare/@metamask/design-system-react-native@0.39.0...@metamask/design-system-react-native@0.39.1
670
+ [0.39.0]: https://github.com/MetaMask/metamask-design-system/compare/@metamask/design-system-react-native@0.38.1...@metamask/design-system-react-native@0.39.0
653
671
  [0.38.1]: https://github.com/MetaMask/metamask-design-system/compare/@metamask/design-system-react-native@0.38.0...@metamask/design-system-react-native@0.38.1
654
672
  [0.38.0]: https://github.com/MetaMask/metamask-design-system/compare/@metamask/design-system-react-native@0.37.0...@metamask/design-system-react-native@0.38.0
655
673
  [0.37.0]: https://github.com/MetaMask/metamask-design-system/compare/@metamask/design-system-react-native@0.36.0...@metamask/design-system-react-native@0.37.0
@@ -72,20 +72,20 @@ exports.Checkbox = (0, react_1.forwardRef)(({ isSelected, isDisabled = false, is
72
72
  const tw = (0, design_system_twrnc_preset_1.useTailwind)();
73
73
  const twContainerClassNames = tw.style('flex-row items-center', isDisabled ? 'opacity-50' : 'opacity-100', twClassName);
74
74
  const getCheckboxContainerStyle = (0, react_1.useCallback)((pressed) => {
75
- const baseBg = isSelected ? 'bg-primary-default' : 'bg-default';
75
+ const baseBg = isSelected ? 'bg-icon-default' : 'bg-default';
76
76
  let baseBorder = 'border-default';
77
77
  if (isSelected) {
78
- baseBorder = 'border-primary-default';
78
+ baseBorder = 'border-icon-default';
79
79
  }
80
80
  else if (isInvalid) {
81
81
  baseBorder = 'border-error-default';
82
82
  }
83
83
  const pressedBg = isSelected
84
- ? 'bg-primary-default-pressed'
84
+ ? 'bg-icon-default-pressed'
85
85
  : 'bg-default-pressed';
86
86
  let pressedBorder = 'border-default';
87
87
  if (isSelected) {
88
- pressedBorder = 'border-primary-default-pressed';
88
+ pressedBorder = 'border-icon-default-pressed';
89
89
  }
90
90
  else if (isInvalid) {
91
91
  pressedBorder = 'border-error-default';
@@ -108,7 +108,7 @@ exports.Checkbox = (0, react_1.forwardRef)(({ isSelected, isDisabled = false, is
108
108
  ]}>
109
109
  {/* Always render icon, opacity driven by iconAnim */}
110
110
  <react_native_1.Animated.View style={{ opacity: iconAnim }}>
111
- <Icon_1.Icon name={Icon_1.IconName.Check} color={Icon_1.IconColor.PrimaryInverse} size={Icon_1.IconSize.Sm} {...checkedIconProps}/>
111
+ <Icon_1.Icon name={Icon_1.IconName.Check} color={Icon_1.IconColor.IconInverse} size={Icon_1.IconSize.Sm} {...checkedIconProps}/>
112
112
  </react_native_1.Animated.View>
113
113
  </AnimatedView>
114
114
  {label ? (<TextOrChildren_1.TextOrChildren textProps={{ ...labelProps, twClassName: 'ml-3' }}>
@@ -1 +1 @@
1
- {"version":3,"file":"Checkbox.cjs","sourceRoot":"","sources":["../../../src/components/Checkbox/Checkbox.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useTailwind } from '@metamask/design-system-twrnc-preset';\nimport React, {\n forwardRef,\n useRef,\n useImperativeHandle,\n useCallback,\n useEffect,\n} from 'react';\nimport type { PressableStateCallbackType } from 'react-native';\nimport { Pressable, Animated, Easing } from 'react-native';\n\nimport { Icon, IconName, IconColor, IconSize } from '../Icon';\nimport { TextOrChildren } from '../temp-components/TextOrChildren';\n\nimport type { CheckboxProps } from './Checkbox.types';\n\nconst AnimatedView = Animated.View;\n\nexport const Checkbox = forwardRef<{ toggle: () => void }, CheckboxProps>(\n (\n {\n isSelected,\n isDisabled = false,\n isInvalid = false,\n label = '',\n labelProps,\n onChange,\n checkboxContainerProps,\n checkedIconProps,\n twClassName,\n style,\n ...props\n },\n ref,\n ) => {\n // Animation values\n const scaleAnim = useRef(new Animated.Value(1)).current;\n const iconAnim = useRef(new Animated.Value(isSelected ? 1 : 0)).current;\n\n // Sync icon opacity whenever selection changes\n useEffect(() => {\n Animated.timing(iconAnim, {\n toValue: isSelected ? 1 : 0,\n duration: 300,\n easing: Easing.ease,\n useNativeDriver: true,\n }).start();\n }, [isSelected, iconAnim]);\n\n // Bounce effect when toggling\n const animateScale = useCallback(() => {\n Animated.sequence([\n Animated.timing(scaleAnim, {\n toValue: 1.15,\n duration: 100,\n easing: Easing.ease,\n useNativeDriver: true,\n }),\n Animated.timing(scaleAnim, {\n toValue: 1,\n duration: 100,\n easing: Easing.ease,\n useNativeDriver: true,\n }),\n ]).start();\n }, [scaleAnim]);\n\n // Press handler: notify parent, then bounce\n const handlePress = () => {\n if (isDisabled) {\n return;\n }\n onChange?.(!isSelected);\n animateScale();\n };\n\n useImperativeHandle(ref, () => ({ toggle: handlePress }), [handlePress]);\n\n const tw = useTailwind();\n const twContainerClassNames = tw.style(\n 'flex-row items-center',\n isDisabled ? 'opacity-50' : 'opacity-100',\n twClassName,\n );\n\n const getCheckboxContainerStyle = useCallback(\n (pressed: boolean): string => {\n const baseBg = isSelected ? 'bg-primary-default' : 'bg-default';\n let baseBorder = 'border-default';\n if (isSelected) {\n baseBorder = 'border-primary-default';\n } else if (isInvalid) {\n baseBorder = 'border-error-default';\n }\n const pressedBg = isSelected\n ? 'bg-primary-default-pressed'\n : 'bg-default-pressed';\n let pressedBorder = 'border-default';\n if (isSelected) {\n pressedBorder = 'border-primary-default-pressed';\n } else if (isInvalid) {\n pressedBorder = 'border-error-default';\n }\n return pressed\n ? `${pressedBg} ${pressedBorder}`\n : `${baseBg} ${baseBorder}`;\n },\n [isSelected, isInvalid],\n );\n\n return (\n <Pressable\n onPress={handlePress}\n accessible\n accessibilityRole=\"checkbox\"\n accessibilityState={{\n checked: isSelected,\n disabled: isDisabled,\n }}\n accessibilityLabel={typeof label === 'string' ? label : undefined}\n disabled={isDisabled}\n {...props}\n style={(state: PressableStateCallbackType) => [\n twContainerClassNames,\n typeof style === 'function' ? style(state) : style,\n ]}\n >\n {({ pressed }) => (\n <>\n <AnimatedView\n {...checkboxContainerProps}\n style={[\n tw`${getCheckboxContainerStyle(pressed)} flex size-[22px] items-center justify-center rounded border-2`,\n { transform: [{ scale: scaleAnim }] },\n ]}\n >\n {/* Always render icon, opacity driven by iconAnim */}\n <Animated.View style={{ opacity: iconAnim }}>\n <Icon\n name={IconName.Check}\n color={IconColor.PrimaryInverse}\n size={IconSize.Sm}\n {...checkedIconProps}\n />\n </Animated.View>\n </AnimatedView>\n {label ? (\n <TextOrChildren\n textProps={{ ...labelProps, twClassName: 'ml-3' }}\n >\n {label}\n </TextOrChildren>\n ) : null}\n </>\n )}\n </Pressable>\n );\n },\n);\n"]}
1
+ {"version":3,"file":"Checkbox.cjs","sourceRoot":"","sources":["../../../src/components/Checkbox/Checkbox.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useTailwind } from '@metamask/design-system-twrnc-preset';\nimport React, {\n forwardRef,\n useRef,\n useImperativeHandle,\n useCallback,\n useEffect,\n} from 'react';\nimport type { PressableStateCallbackType } from 'react-native';\nimport { Pressable, Animated, Easing } from 'react-native';\n\nimport { Icon, IconName, IconColor, IconSize } from '../Icon';\nimport { TextOrChildren } from '../temp-components/TextOrChildren';\n\nimport type { CheckboxProps } from './Checkbox.types';\n\nconst AnimatedView = Animated.View;\n\nexport const Checkbox = forwardRef<{ toggle: () => void }, CheckboxProps>(\n (\n {\n isSelected,\n isDisabled = false,\n isInvalid = false,\n label = '',\n labelProps,\n onChange,\n checkboxContainerProps,\n checkedIconProps,\n twClassName,\n style,\n ...props\n },\n ref,\n ) => {\n // Animation values\n const scaleAnim = useRef(new Animated.Value(1)).current;\n const iconAnim = useRef(new Animated.Value(isSelected ? 1 : 0)).current;\n\n // Sync icon opacity whenever selection changes\n useEffect(() => {\n Animated.timing(iconAnim, {\n toValue: isSelected ? 1 : 0,\n duration: 300,\n easing: Easing.ease,\n useNativeDriver: true,\n }).start();\n }, [isSelected, iconAnim]);\n\n // Bounce effect when toggling\n const animateScale = useCallback(() => {\n Animated.sequence([\n Animated.timing(scaleAnim, {\n toValue: 1.15,\n duration: 100,\n easing: Easing.ease,\n useNativeDriver: true,\n }),\n Animated.timing(scaleAnim, {\n toValue: 1,\n duration: 100,\n easing: Easing.ease,\n useNativeDriver: true,\n }),\n ]).start();\n }, [scaleAnim]);\n\n // Press handler: notify parent, then bounce\n const handlePress = () => {\n if (isDisabled) {\n return;\n }\n onChange?.(!isSelected);\n animateScale();\n };\n\n useImperativeHandle(ref, () => ({ toggle: handlePress }), [handlePress]);\n\n const tw = useTailwind();\n const twContainerClassNames = tw.style(\n 'flex-row items-center',\n isDisabled ? 'opacity-50' : 'opacity-100',\n twClassName,\n );\n\n const getCheckboxContainerStyle = useCallback(\n (pressed: boolean): string => {\n const baseBg = isSelected ? 'bg-icon-default' : 'bg-default';\n let baseBorder = 'border-default';\n if (isSelected) {\n baseBorder = 'border-icon-default';\n } else if (isInvalid) {\n baseBorder = 'border-error-default';\n }\n const pressedBg = isSelected\n ? 'bg-icon-default-pressed'\n : 'bg-default-pressed';\n let pressedBorder = 'border-default';\n if (isSelected) {\n pressedBorder = 'border-icon-default-pressed';\n } else if (isInvalid) {\n pressedBorder = 'border-error-default';\n }\n return pressed\n ? `${pressedBg} ${pressedBorder}`\n : `${baseBg} ${baseBorder}`;\n },\n [isSelected, isInvalid],\n );\n\n return (\n <Pressable\n onPress={handlePress}\n accessible\n accessibilityRole=\"checkbox\"\n accessibilityState={{\n checked: isSelected,\n disabled: isDisabled,\n }}\n accessibilityLabel={typeof label === 'string' ? label : undefined}\n disabled={isDisabled}\n {...props}\n style={(state: PressableStateCallbackType) => [\n twContainerClassNames,\n typeof style === 'function' ? style(state) : style,\n ]}\n >\n {({ pressed }) => (\n <>\n <AnimatedView\n {...checkboxContainerProps}\n style={[\n tw`${getCheckboxContainerStyle(pressed)} flex size-[22px] items-center justify-center rounded border-2`,\n { transform: [{ scale: scaleAnim }] },\n ]}\n >\n {/* Always render icon, opacity driven by iconAnim */}\n <Animated.View style={{ opacity: iconAnim }}>\n <Icon\n name={IconName.Check}\n color={IconColor.IconInverse}\n size={IconSize.Sm}\n {...checkedIconProps}\n />\n </Animated.View>\n </AnimatedView>\n {label ? (\n <TextOrChildren\n textProps={{ ...labelProps, twClassName: 'ml-3' }}\n >\n {label}\n </TextOrChildren>\n ) : null}\n </>\n )}\n </Pressable>\n );\n },\n);\n"]}
@@ -53,20 +53,20 @@ export const Checkbox = forwardRef(({ isSelected, isDisabled = false, isInvalid
53
53
  const tw = useTailwind();
54
54
  const twContainerClassNames = tw.style('flex-row items-center', isDisabled ? 'opacity-50' : 'opacity-100', twClassName);
55
55
  const getCheckboxContainerStyle = useCallback((pressed) => {
56
- const baseBg = isSelected ? 'bg-primary-default' : 'bg-default';
56
+ const baseBg = isSelected ? 'bg-icon-default' : 'bg-default';
57
57
  let baseBorder = 'border-default';
58
58
  if (isSelected) {
59
- baseBorder = 'border-primary-default';
59
+ baseBorder = 'border-icon-default';
60
60
  }
61
61
  else if (isInvalid) {
62
62
  baseBorder = 'border-error-default';
63
63
  }
64
64
  const pressedBg = isSelected
65
- ? 'bg-primary-default-pressed'
65
+ ? 'bg-icon-default-pressed'
66
66
  : 'bg-default-pressed';
67
67
  let pressedBorder = 'border-default';
68
68
  if (isSelected) {
69
- pressedBorder = 'border-primary-default-pressed';
69
+ pressedBorder = 'border-icon-default-pressed';
70
70
  }
71
71
  else if (isInvalid) {
72
72
  pressedBorder = 'border-error-default';
@@ -89,7 +89,7 @@ export const Checkbox = forwardRef(({ isSelected, isDisabled = false, isInvalid
89
89
  ]}>
90
90
  {/* Always render icon, opacity driven by iconAnim */}
91
91
  <Animated.View style={{ opacity: iconAnim }}>
92
- <Icon name={IconName.Check} color={IconColor.PrimaryInverse} size={IconSize.Sm} {...checkedIconProps}/>
92
+ <Icon name={IconName.Check} color={IconColor.IconInverse} size={IconSize.Sm} {...checkedIconProps}/>
93
93
  </Animated.View>
94
94
  </AnimatedView>
95
95
  {label ? (<TextOrChildren textProps={{ ...labelProps, twClassName: 'ml-3' }}>
@@ -1 +1 @@
1
- {"version":3,"file":"Checkbox.mjs","sourceRoot":"","sources":["../../../src/components/Checkbox/Checkbox.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useTailwind } from '@metamask/design-system-twrnc-preset';\nimport React, {\n forwardRef,\n useRef,\n useImperativeHandle,\n useCallback,\n useEffect,\n} from 'react';\nimport type { PressableStateCallbackType } from 'react-native';\nimport { Pressable, Animated, Easing } from 'react-native';\n\nimport { Icon, IconName, IconColor, IconSize } from '../Icon';\nimport { TextOrChildren } from '../temp-components/TextOrChildren';\n\nimport type { CheckboxProps } from './Checkbox.types';\n\nconst AnimatedView = Animated.View;\n\nexport const Checkbox = forwardRef<{ toggle: () => void }, CheckboxProps>(\n (\n {\n isSelected,\n isDisabled = false,\n isInvalid = false,\n label = '',\n labelProps,\n onChange,\n checkboxContainerProps,\n checkedIconProps,\n twClassName,\n style,\n ...props\n },\n ref,\n ) => {\n // Animation values\n const scaleAnim = useRef(new Animated.Value(1)).current;\n const iconAnim = useRef(new Animated.Value(isSelected ? 1 : 0)).current;\n\n // Sync icon opacity whenever selection changes\n useEffect(() => {\n Animated.timing(iconAnim, {\n toValue: isSelected ? 1 : 0,\n duration: 300,\n easing: Easing.ease,\n useNativeDriver: true,\n }).start();\n }, [isSelected, iconAnim]);\n\n // Bounce effect when toggling\n const animateScale = useCallback(() => {\n Animated.sequence([\n Animated.timing(scaleAnim, {\n toValue: 1.15,\n duration: 100,\n easing: Easing.ease,\n useNativeDriver: true,\n }),\n Animated.timing(scaleAnim, {\n toValue: 1,\n duration: 100,\n easing: Easing.ease,\n useNativeDriver: true,\n }),\n ]).start();\n }, [scaleAnim]);\n\n // Press handler: notify parent, then bounce\n const handlePress = () => {\n if (isDisabled) {\n return;\n }\n onChange?.(!isSelected);\n animateScale();\n };\n\n useImperativeHandle(ref, () => ({ toggle: handlePress }), [handlePress]);\n\n const tw = useTailwind();\n const twContainerClassNames = tw.style(\n 'flex-row items-center',\n isDisabled ? 'opacity-50' : 'opacity-100',\n twClassName,\n );\n\n const getCheckboxContainerStyle = useCallback(\n (pressed: boolean): string => {\n const baseBg = isSelected ? 'bg-primary-default' : 'bg-default';\n let baseBorder = 'border-default';\n if (isSelected) {\n baseBorder = 'border-primary-default';\n } else if (isInvalid) {\n baseBorder = 'border-error-default';\n }\n const pressedBg = isSelected\n ? 'bg-primary-default-pressed'\n : 'bg-default-pressed';\n let pressedBorder = 'border-default';\n if (isSelected) {\n pressedBorder = 'border-primary-default-pressed';\n } else if (isInvalid) {\n pressedBorder = 'border-error-default';\n }\n return pressed\n ? `${pressedBg} ${pressedBorder}`\n : `${baseBg} ${baseBorder}`;\n },\n [isSelected, isInvalid],\n );\n\n return (\n <Pressable\n onPress={handlePress}\n accessible\n accessibilityRole=\"checkbox\"\n accessibilityState={{\n checked: isSelected,\n disabled: isDisabled,\n }}\n accessibilityLabel={typeof label === 'string' ? label : undefined}\n disabled={isDisabled}\n {...props}\n style={(state: PressableStateCallbackType) => [\n twContainerClassNames,\n typeof style === 'function' ? style(state) : style,\n ]}\n >\n {({ pressed }) => (\n <>\n <AnimatedView\n {...checkboxContainerProps}\n style={[\n tw`${getCheckboxContainerStyle(pressed)} flex size-[22px] items-center justify-center rounded border-2`,\n { transform: [{ scale: scaleAnim }] },\n ]}\n >\n {/* Always render icon, opacity driven by iconAnim */}\n <Animated.View style={{ opacity: iconAnim }}>\n <Icon\n name={IconName.Check}\n color={IconColor.PrimaryInverse}\n size={IconSize.Sm}\n {...checkedIconProps}\n />\n </Animated.View>\n </AnimatedView>\n {label ? (\n <TextOrChildren\n textProps={{ ...labelProps, twClassName: 'ml-3' }}\n >\n {label}\n </TextOrChildren>\n ) : null}\n </>\n )}\n </Pressable>\n );\n },\n);\n"]}
1
+ {"version":3,"file":"Checkbox.mjs","sourceRoot":"","sources":["../../../src/components/Checkbox/Checkbox.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useTailwind } from '@metamask/design-system-twrnc-preset';\nimport React, {\n forwardRef,\n useRef,\n useImperativeHandle,\n useCallback,\n useEffect,\n} from 'react';\nimport type { PressableStateCallbackType } from 'react-native';\nimport { Pressable, Animated, Easing } from 'react-native';\n\nimport { Icon, IconName, IconColor, IconSize } from '../Icon';\nimport { TextOrChildren } from '../temp-components/TextOrChildren';\n\nimport type { CheckboxProps } from './Checkbox.types';\n\nconst AnimatedView = Animated.View;\n\nexport const Checkbox = forwardRef<{ toggle: () => void }, CheckboxProps>(\n (\n {\n isSelected,\n isDisabled = false,\n isInvalid = false,\n label = '',\n labelProps,\n onChange,\n checkboxContainerProps,\n checkedIconProps,\n twClassName,\n style,\n ...props\n },\n ref,\n ) => {\n // Animation values\n const scaleAnim = useRef(new Animated.Value(1)).current;\n const iconAnim = useRef(new Animated.Value(isSelected ? 1 : 0)).current;\n\n // Sync icon opacity whenever selection changes\n useEffect(() => {\n Animated.timing(iconAnim, {\n toValue: isSelected ? 1 : 0,\n duration: 300,\n easing: Easing.ease,\n useNativeDriver: true,\n }).start();\n }, [isSelected, iconAnim]);\n\n // Bounce effect when toggling\n const animateScale = useCallback(() => {\n Animated.sequence([\n Animated.timing(scaleAnim, {\n toValue: 1.15,\n duration: 100,\n easing: Easing.ease,\n useNativeDriver: true,\n }),\n Animated.timing(scaleAnim, {\n toValue: 1,\n duration: 100,\n easing: Easing.ease,\n useNativeDriver: true,\n }),\n ]).start();\n }, [scaleAnim]);\n\n // Press handler: notify parent, then bounce\n const handlePress = () => {\n if (isDisabled) {\n return;\n }\n onChange?.(!isSelected);\n animateScale();\n };\n\n useImperativeHandle(ref, () => ({ toggle: handlePress }), [handlePress]);\n\n const tw = useTailwind();\n const twContainerClassNames = tw.style(\n 'flex-row items-center',\n isDisabled ? 'opacity-50' : 'opacity-100',\n twClassName,\n );\n\n const getCheckboxContainerStyle = useCallback(\n (pressed: boolean): string => {\n const baseBg = isSelected ? 'bg-icon-default' : 'bg-default';\n let baseBorder = 'border-default';\n if (isSelected) {\n baseBorder = 'border-icon-default';\n } else if (isInvalid) {\n baseBorder = 'border-error-default';\n }\n const pressedBg = isSelected\n ? 'bg-icon-default-pressed'\n : 'bg-default-pressed';\n let pressedBorder = 'border-default';\n if (isSelected) {\n pressedBorder = 'border-icon-default-pressed';\n } else if (isInvalid) {\n pressedBorder = 'border-error-default';\n }\n return pressed\n ? `${pressedBg} ${pressedBorder}`\n : `${baseBg} ${baseBorder}`;\n },\n [isSelected, isInvalid],\n );\n\n return (\n <Pressable\n onPress={handlePress}\n accessible\n accessibilityRole=\"checkbox\"\n accessibilityState={{\n checked: isSelected,\n disabled: isDisabled,\n }}\n accessibilityLabel={typeof label === 'string' ? label : undefined}\n disabled={isDisabled}\n {...props}\n style={(state: PressableStateCallbackType) => [\n twContainerClassNames,\n typeof style === 'function' ? style(state) : style,\n ]}\n >\n {({ pressed }) => (\n <>\n <AnimatedView\n {...checkboxContainerProps}\n style={[\n tw`${getCheckboxContainerStyle(pressed)} flex size-[22px] items-center justify-center rounded border-2`,\n { transform: [{ scale: scaleAnim }] },\n ]}\n >\n {/* Always render icon, opacity driven by iconAnim */}\n <Animated.View style={{ opacity: iconAnim }}>\n <Icon\n name={IconName.Check}\n color={IconColor.IconInverse}\n size={IconSize.Sm}\n {...checkedIconProps}\n />\n </Animated.View>\n </AnimatedView>\n {label ? (\n <TextOrChildren\n textProps={{ ...labelProps, twClassName: 'ml-3' }}\n >\n {label}\n </TextOrChildren>\n ) : null}\n </>\n )}\n </Pressable>\n );\n },\n);\n"]}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TOAST_SEVERITY_ICON_MAP = exports.TOAST_SPRING_CONFIG = exports.TOAST_TOP_PADDING = exports.TOAST_VISIBILITY_DURATION = exports.TOAST_ANIMATION_DURATION = void 0;
3
+ exports.TOAST_SEVERITY_ICON_MAP = exports.TOAST_SWIPE_FAIL_OFFSET_X = exports.TOAST_SWIPE_ACTIVE_OFFSET_Y = exports.TOAST_DISMISS_VELOCITY_THRESHOLD = exports.TOAST_DISMISS_MIN_DISTANCE = exports.TOAST_DISMISS_DISTANCE_THRESHOLD = exports.TOAST_SPRING_CONFIG = exports.TOAST_TOP_PADDING = exports.TOAST_VISIBILITY_DURATION = exports.TOAST_ANIMATION_DURATION = void 0;
4
4
  // External dependencies.
5
5
  const design_system_shared_1 = require("@metamask/design-system-shared");
6
6
  const Toast_types_1 = require("./Toast.types.cjs");
@@ -16,6 +16,29 @@ exports.TOAST_SPRING_CONFIG = {
16
16
  dampingRatio: 0.85,
17
17
  duration: 500,
18
18
  };
19
+ /**
20
+ * Fraction of toast height that must be dragged upward to dismiss.
21
+ */
22
+ exports.TOAST_DISMISS_DISTANCE_THRESHOLD = 0.35;
23
+ /**
24
+ * Minimum upward drag distance (px) required to dismiss, used as a floor
25
+ * when the height-based threshold would otherwise be too small.
26
+ */
27
+ exports.TOAST_DISMISS_MIN_DISTANCE = 24;
28
+ /**
29
+ * Upward velocity (px/s) required to dismiss via a quick swipe.
30
+ */
31
+ exports.TOAST_DISMISS_VELOCITY_THRESHOLD = 800;
32
+ /**
33
+ * Minimum upward translation before the pan gesture activates,
34
+ * so taps and button presses still work.
35
+ */
36
+ exports.TOAST_SWIPE_ACTIVE_OFFSET_Y = -8;
37
+ /**
38
+ * Horizontal movement that fails the pan gesture before it activates,
39
+ * so horizontal scrolls elsewhere are not captured.
40
+ */
41
+ exports.TOAST_SWIPE_FAIL_OFFSET_X = 20;
19
42
  exports.TOAST_SEVERITY_ICON_MAP = {
20
43
  [Toast_types_1.ToastSeverity.Success]: design_system_shared_1.IconAlertSeverity.Success,
21
44
  [Toast_types_1.ToastSeverity.Warning]: design_system_shared_1.IconAlertSeverity.Warning,
@@ -1 +1 @@
1
- {"version":3,"file":"Toast.constants.cjs","sourceRoot":"","sources":["../../../src/components/Toast/Toast.constants.ts"],"names":[],"mappings":";;;AAAA,yBAAyB;AACzB,yEAAmE;AAGnE,mDAA8C;AAE9C,uEAGwC;AAFtC,gIAAA,wBAAwB,OAAA;AACxB,iIAAA,yBAAyB,OAAA;AAGd,QAAA,iBAAiB,GAAG,CAAC,CAAC;AAEnC;;;GAGG;AACU,QAAA,mBAAmB,GAAqB;IACnD,YAAY,EAAE,IAAI;IAClB,QAAQ,EAAE,GAAG;CACd,CAAC;AAEW,QAAA,uBAAuB,GAAG;IACrC,CAAC,2BAAa,CAAC,OAAO,CAAC,EAAE,wCAAiB,CAAC,OAAO;IAClD,CAAC,2BAAa,CAAC,OAAO,CAAC,EAAE,wCAAiB,CAAC,OAAO;IAClD,CAAC,2BAAa,CAAC,MAAM,CAAC,EAAE,wCAAiB,CAAC,MAAM;CACxC,CAAC","sourcesContent":["// External dependencies.\nimport { IconAlertSeverity } from '@metamask/design-system-shared';\nimport type { WithSpringConfig } from 'react-native-reanimated';\n\nimport { ToastSeverity } from './Toast.types';\n\nexport {\n TOAST_ANIMATION_DURATION,\n TOAST_VISIBILITY_DURATION,\n} from '@metamask/design-system-shared';\n\nexport const TOAST_TOP_PADDING = 8;\n\n/**\n * Spring tuned to approximate iOS system banner motion (inspired by UIKit\n * spring with dampingRatio ~0.7-0.85 / SwiftUI .snappy).\n */\nexport const TOAST_SPRING_CONFIG: WithSpringConfig = {\n dampingRatio: 0.85,\n duration: 500,\n};\n\nexport const TOAST_SEVERITY_ICON_MAP = {\n [ToastSeverity.Success]: IconAlertSeverity.Success,\n [ToastSeverity.Warning]: IconAlertSeverity.Warning,\n [ToastSeverity.Danger]: IconAlertSeverity.Danger,\n} as const;\n"]}
1
+ {"version":3,"file":"Toast.constants.cjs","sourceRoot":"","sources":["../../../src/components/Toast/Toast.constants.ts"],"names":[],"mappings":";;;AAAA,yBAAyB;AACzB,yEAAmE;AAGnE,mDAA8C;AAE9C,uEAGwC;AAFtC,gIAAA,wBAAwB,OAAA;AACxB,iIAAA,yBAAyB,OAAA;AAGd,QAAA,iBAAiB,GAAG,CAAC,CAAC;AAEnC;;;GAGG;AACU,QAAA,mBAAmB,GAAqB;IACnD,YAAY,EAAE,IAAI;IAClB,QAAQ,EAAE,GAAG;CACd,CAAC;AAEF;;GAEG;AACU,QAAA,gCAAgC,GAAG,IAAI,CAAC;AAErD;;;GAGG;AACU,QAAA,0BAA0B,GAAG,EAAE,CAAC;AAE7C;;GAEG;AACU,QAAA,gCAAgC,GAAG,GAAG,CAAC;AAEpD;;;GAGG;AACU,QAAA,2BAA2B,GAAG,CAAC,CAAC,CAAC;AAE9C;;;GAGG;AACU,QAAA,yBAAyB,GAAG,EAAE,CAAC;AAE/B,QAAA,uBAAuB,GAAG;IACrC,CAAC,2BAAa,CAAC,OAAO,CAAC,EAAE,wCAAiB,CAAC,OAAO;IAClD,CAAC,2BAAa,CAAC,OAAO,CAAC,EAAE,wCAAiB,CAAC,OAAO;IAClD,CAAC,2BAAa,CAAC,MAAM,CAAC,EAAE,wCAAiB,CAAC,MAAM;CACxC,CAAC","sourcesContent":["// External dependencies.\nimport { IconAlertSeverity } from '@metamask/design-system-shared';\nimport type { WithSpringConfig } from 'react-native-reanimated';\n\nimport { ToastSeverity } from './Toast.types';\n\nexport {\n TOAST_ANIMATION_DURATION,\n TOAST_VISIBILITY_DURATION,\n} from '@metamask/design-system-shared';\n\nexport const TOAST_TOP_PADDING = 8;\n\n/**\n * Spring tuned to approximate iOS system banner motion (inspired by UIKit\n * spring with dampingRatio ~0.7-0.85 / SwiftUI .snappy).\n */\nexport const TOAST_SPRING_CONFIG: WithSpringConfig = {\n dampingRatio: 0.85,\n duration: 500,\n};\n\n/**\n * Fraction of toast height that must be dragged upward to dismiss.\n */\nexport const TOAST_DISMISS_DISTANCE_THRESHOLD = 0.35;\n\n/**\n * Minimum upward drag distance (px) required to dismiss, used as a floor\n * when the height-based threshold would otherwise be too small.\n */\nexport const TOAST_DISMISS_MIN_DISTANCE = 24;\n\n/**\n * Upward velocity (px/s) required to dismiss via a quick swipe.\n */\nexport const TOAST_DISMISS_VELOCITY_THRESHOLD = 800;\n\n/**\n * Minimum upward translation before the pan gesture activates,\n * so taps and button presses still work.\n */\nexport const TOAST_SWIPE_ACTIVE_OFFSET_Y = -8;\n\n/**\n * Horizontal movement that fails the pan gesture before it activates,\n * so horizontal scrolls elsewhere are not captured.\n */\nexport const TOAST_SWIPE_FAIL_OFFSET_X = 20;\n\nexport const TOAST_SEVERITY_ICON_MAP = {\n [ToastSeverity.Success]: IconAlertSeverity.Success,\n [ToastSeverity.Warning]: IconAlertSeverity.Warning,\n [ToastSeverity.Danger]: IconAlertSeverity.Danger,\n} as const;\n"]}
@@ -6,6 +6,29 @@ export declare const TOAST_TOP_PADDING = 8;
6
6
  * spring with dampingRatio ~0.7-0.85 / SwiftUI .snappy).
7
7
  */
8
8
  export declare const TOAST_SPRING_CONFIG: WithSpringConfig;
9
+ /**
10
+ * Fraction of toast height that must be dragged upward to dismiss.
11
+ */
12
+ export declare const TOAST_DISMISS_DISTANCE_THRESHOLD = 0.35;
13
+ /**
14
+ * Minimum upward drag distance (px) required to dismiss, used as a floor
15
+ * when the height-based threshold would otherwise be too small.
16
+ */
17
+ export declare const TOAST_DISMISS_MIN_DISTANCE = 24;
18
+ /**
19
+ * Upward velocity (px/s) required to dismiss via a quick swipe.
20
+ */
21
+ export declare const TOAST_DISMISS_VELOCITY_THRESHOLD = 800;
22
+ /**
23
+ * Minimum upward translation before the pan gesture activates,
24
+ * so taps and button presses still work.
25
+ */
26
+ export declare const TOAST_SWIPE_ACTIVE_OFFSET_Y = -8;
27
+ /**
28
+ * Horizontal movement that fails the pan gesture before it activates,
29
+ * so horizontal scrolls elsewhere are not captured.
30
+ */
31
+ export declare const TOAST_SWIPE_FAIL_OFFSET_X = 20;
9
32
  export declare const TOAST_SEVERITY_ICON_MAP: {
10
33
  readonly success: "success";
11
34
  readonly warning: "warning";
@@ -1 +1 @@
1
- {"version":3,"file":"Toast.constants.d.cts","sourceRoot":"","sources":["../../../src/components/Toast/Toast.constants.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gCAAgC;AAIhE,OAAO,EACL,wBAAwB,EACxB,yBAAyB,GAC1B,uCAAuC;AAExC,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,gBAGjC,CAAC;AAEF,eAAO,MAAM,uBAAuB;;;;CAI1B,CAAC"}
1
+ {"version":3,"file":"Toast.constants.d.cts","sourceRoot":"","sources":["../../../src/components/Toast/Toast.constants.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gCAAgC;AAIhE,OAAO,EACL,wBAAwB,EACxB,yBAAyB,GAC1B,uCAAuC;AAExC,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,gBAGjC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gCAAgC,OAAO,CAAC;AAErD;;;GAGG;AACH,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C;;GAEG;AACH,eAAO,MAAM,gCAAgC,MAAM,CAAC;AAEpD;;;GAGG;AACH,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C;;;GAGG;AACH,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAE5C,eAAO,MAAM,uBAAuB;;;;CAI1B,CAAC"}
@@ -6,6 +6,29 @@ export declare const TOAST_TOP_PADDING = 8;
6
6
  * spring with dampingRatio ~0.7-0.85 / SwiftUI .snappy).
7
7
  */
8
8
  export declare const TOAST_SPRING_CONFIG: WithSpringConfig;
9
+ /**
10
+ * Fraction of toast height that must be dragged upward to dismiss.
11
+ */
12
+ export declare const TOAST_DISMISS_DISTANCE_THRESHOLD = 0.35;
13
+ /**
14
+ * Minimum upward drag distance (px) required to dismiss, used as a floor
15
+ * when the height-based threshold would otherwise be too small.
16
+ */
17
+ export declare const TOAST_DISMISS_MIN_DISTANCE = 24;
18
+ /**
19
+ * Upward velocity (px/s) required to dismiss via a quick swipe.
20
+ */
21
+ export declare const TOAST_DISMISS_VELOCITY_THRESHOLD = 800;
22
+ /**
23
+ * Minimum upward translation before the pan gesture activates,
24
+ * so taps and button presses still work.
25
+ */
26
+ export declare const TOAST_SWIPE_ACTIVE_OFFSET_Y = -8;
27
+ /**
28
+ * Horizontal movement that fails the pan gesture before it activates,
29
+ * so horizontal scrolls elsewhere are not captured.
30
+ */
31
+ export declare const TOAST_SWIPE_FAIL_OFFSET_X = 20;
9
32
  export declare const TOAST_SEVERITY_ICON_MAP: {
10
33
  readonly success: "success";
11
34
  readonly warning: "warning";
@@ -1 +1 @@
1
- {"version":3,"file":"Toast.constants.d.mts","sourceRoot":"","sources":["../../../src/components/Toast/Toast.constants.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gCAAgC;AAIhE,OAAO,EACL,wBAAwB,EACxB,yBAAyB,GAC1B,uCAAuC;AAExC,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,gBAGjC,CAAC;AAEF,eAAO,MAAM,uBAAuB;;;;CAI1B,CAAC"}
1
+ {"version":3,"file":"Toast.constants.d.mts","sourceRoot":"","sources":["../../../src/components/Toast/Toast.constants.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gCAAgC;AAIhE,OAAO,EACL,wBAAwB,EACxB,yBAAyB,GAC1B,uCAAuC;AAExC,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,gBAGjC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gCAAgC,OAAO,CAAC;AAErD;;;GAGG;AACH,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C;;GAEG;AACH,eAAO,MAAM,gCAAgC,MAAM,CAAC;AAEpD;;;GAGG;AACH,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C;;;GAGG;AACH,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAE5C,eAAO,MAAM,uBAAuB;;;;CAI1B,CAAC"}
@@ -11,6 +11,29 @@ export const TOAST_SPRING_CONFIG = {
11
11
  dampingRatio: 0.85,
12
12
  duration: 500,
13
13
  };
14
+ /**
15
+ * Fraction of toast height that must be dragged upward to dismiss.
16
+ */
17
+ export const TOAST_DISMISS_DISTANCE_THRESHOLD = 0.35;
18
+ /**
19
+ * Minimum upward drag distance (px) required to dismiss, used as a floor
20
+ * when the height-based threshold would otherwise be too small.
21
+ */
22
+ export const TOAST_DISMISS_MIN_DISTANCE = 24;
23
+ /**
24
+ * Upward velocity (px/s) required to dismiss via a quick swipe.
25
+ */
26
+ export const TOAST_DISMISS_VELOCITY_THRESHOLD = 800;
27
+ /**
28
+ * Minimum upward translation before the pan gesture activates,
29
+ * so taps and button presses still work.
30
+ */
31
+ export const TOAST_SWIPE_ACTIVE_OFFSET_Y = -8;
32
+ /**
33
+ * Horizontal movement that fails the pan gesture before it activates,
34
+ * so horizontal scrolls elsewhere are not captured.
35
+ */
36
+ export const TOAST_SWIPE_FAIL_OFFSET_X = 20;
14
37
  export const TOAST_SEVERITY_ICON_MAP = {
15
38
  [ToastSeverity.Success]: IconAlertSeverity.Success,
16
39
  [ToastSeverity.Warning]: IconAlertSeverity.Warning,
@@ -1 +1 @@
1
- {"version":3,"file":"Toast.constants.mjs","sourceRoot":"","sources":["../../../src/components/Toast/Toast.constants.ts"],"names":[],"mappings":"AAAA,yBAAyB;AACzB,OAAO,EAAE,iBAAiB,EAAE,uCAAuC;AAGnE,OAAO,EAAE,aAAa,EAAE,0BAAsB;AAE9C,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EAC1B,uCAAuC;AAExC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAEnC;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAqB;IACnD,YAAY,EAAE,IAAI;IAClB,QAAQ,EAAE,GAAG;CACd,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC,OAAO;IAClD,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC,OAAO;IAClD,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC,MAAM;CACxC,CAAC","sourcesContent":["// External dependencies.\nimport { IconAlertSeverity } from '@metamask/design-system-shared';\nimport type { WithSpringConfig } from 'react-native-reanimated';\n\nimport { ToastSeverity } from './Toast.types';\n\nexport {\n TOAST_ANIMATION_DURATION,\n TOAST_VISIBILITY_DURATION,\n} from '@metamask/design-system-shared';\n\nexport const TOAST_TOP_PADDING = 8;\n\n/**\n * Spring tuned to approximate iOS system banner motion (inspired by UIKit\n * spring with dampingRatio ~0.7-0.85 / SwiftUI .snappy).\n */\nexport const TOAST_SPRING_CONFIG: WithSpringConfig = {\n dampingRatio: 0.85,\n duration: 500,\n};\n\nexport const TOAST_SEVERITY_ICON_MAP = {\n [ToastSeverity.Success]: IconAlertSeverity.Success,\n [ToastSeverity.Warning]: IconAlertSeverity.Warning,\n [ToastSeverity.Danger]: IconAlertSeverity.Danger,\n} as const;\n"]}
1
+ {"version":3,"file":"Toast.constants.mjs","sourceRoot":"","sources":["../../../src/components/Toast/Toast.constants.ts"],"names":[],"mappings":"AAAA,yBAAyB;AACzB,OAAO,EAAE,iBAAiB,EAAE,uCAAuC;AAGnE,OAAO,EAAE,aAAa,EAAE,0BAAsB;AAE9C,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EAC1B,uCAAuC;AAExC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAEnC;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAqB;IACnD,YAAY,EAAE,IAAI;IAClB,QAAQ,EAAE,GAAG;CACd,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,IAAI,CAAC;AAErD;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,CAAC;AAE7C;;GAEG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,GAAG,CAAC;AAEpD;;;GAGG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,CAAC;AAE9C;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,CAAC;AAE5C,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC,OAAO;IAClD,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC,OAAO;IAClD,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC,MAAM;CACxC,CAAC","sourcesContent":["// External dependencies.\nimport { IconAlertSeverity } from '@metamask/design-system-shared';\nimport type { WithSpringConfig } from 'react-native-reanimated';\n\nimport { ToastSeverity } from './Toast.types';\n\nexport {\n TOAST_ANIMATION_DURATION,\n TOAST_VISIBILITY_DURATION,\n} from '@metamask/design-system-shared';\n\nexport const TOAST_TOP_PADDING = 8;\n\n/**\n * Spring tuned to approximate iOS system banner motion (inspired by UIKit\n * spring with dampingRatio ~0.7-0.85 / SwiftUI .snappy).\n */\nexport const TOAST_SPRING_CONFIG: WithSpringConfig = {\n dampingRatio: 0.85,\n duration: 500,\n};\n\n/**\n * Fraction of toast height that must be dragged upward to dismiss.\n */\nexport const TOAST_DISMISS_DISTANCE_THRESHOLD = 0.35;\n\n/**\n * Minimum upward drag distance (px) required to dismiss, used as a floor\n * when the height-based threshold would otherwise be too small.\n */\nexport const TOAST_DISMISS_MIN_DISTANCE = 24;\n\n/**\n * Upward velocity (px/s) required to dismiss via a quick swipe.\n */\nexport const TOAST_DISMISS_VELOCITY_THRESHOLD = 800;\n\n/**\n * Minimum upward translation before the pan gesture activates,\n * so taps and button presses still work.\n */\nexport const TOAST_SWIPE_ACTIVE_OFFSET_Y = -8;\n\n/**\n * Horizontal movement that fails the pan gesture before it activates,\n * so horizontal scrolls elsewhere are not captured.\n */\nexport const TOAST_SWIPE_FAIL_OFFSET_X = 20;\n\nexport const TOAST_SEVERITY_ICON_MAP = {\n [ToastSeverity.Success]: IconAlertSeverity.Success,\n [ToastSeverity.Warning]: IconAlertSeverity.Warning,\n [ToastSeverity.Danger]: IconAlertSeverity.Danger,\n} as const;\n"]}
@@ -28,6 +28,7 @@ exports.toast = exports.Toaster = void 0;
28
28
  const design_system_twrnc_preset_1 = require("@metamask/design-system-twrnc-preset");
29
29
  const react_1 = __importStar(require("react"));
30
30
  const react_native_1 = require("react-native");
31
+ const react_native_gesture_handler_1 = require("react-native-gesture-handler");
31
32
  const react_native_reanimated_1 = __importStar(require("react-native-reanimated"));
32
33
  const react_native_safe_area_context_1 = require("react-native-safe-area-context");
33
34
  const react_native_worklets_1 = require("react-native-worklets");
@@ -49,10 +50,26 @@ const ToasterComponent = (0, react_1.forwardRef)(({ twClassName, ...props }, ref
49
50
  const tw = (0, design_system_twrnc_preset_1.useTailwind)();
50
51
  const [toastOptions, setToastOptions] = (0, react_1.useState)(undefined);
51
52
  const replacementTimerRef = (0, react_1.useRef)(null);
53
+ const autoDismissTimeoutRef = (0, react_1.useRef)(null);
54
+ const animationStartedRef = (0, react_1.useRef)(false);
55
+ const visibleAtRef = (0, react_1.useRef)(null);
56
+ const hasNoTimeoutRef = (0, react_1.useRef)(false);
57
+ // Invalidates queued spring-back resumes after replace/dismiss. A completed
58
+ // spring cannot be cancelled, so scheduleOnRN(resume) can still run later.
59
+ const toastGenerationRef = (0, react_1.useRef)(0);
52
60
  const { top: topInset } = (0, react_native_safe_area_context_1.useSafeAreaInsets)();
53
61
  const toastHeight = (0, react_native_reanimated_1.useSharedValue)(screenHeight);
62
+ const hiddenTranslateY = (0, react_native_reanimated_1.useSharedValue)(-screenHeight);
63
+ const visibleTranslateY = (0, react_native_reanimated_1.useSharedValue)(0);
64
+ const gestureStartY = (0, react_native_reanimated_1.useSharedValue)(0);
54
65
  const translateYProgress = (0, react_native_reanimated_1.useSharedValue)(-screenHeight);
66
+ const isDismissing = (0, react_native_reanimated_1.useSharedValue)(false);
67
+ // True after onStart until onEnd/onFinalize recovers. Used so a failed pan
68
+ // (e.g. failOffsetX after activation) still springs back and resumes dismiss.
69
+ const isSwipeActive = (0, react_native_reanimated_1.useSharedValue)(false);
70
+ const toastGeneration = (0, react_native_reanimated_1.useSharedValue)(0);
55
71
  const topOffset = toastOptions?.topOffset ?? 0;
72
+ hasNoTimeoutRef.current = Boolean(toastOptions?.hasNoTimeout);
56
73
  const animatedStyle = (0, react_native_reanimated_1.useAnimatedStyle)(() => ({
57
74
  transform: [{ translateY: translateYProgress.value + topOffset }],
58
75
  }));
@@ -61,16 +78,80 @@ const ToasterComponent = (0, react_1.forwardRef)(({ twClassName, ...props }, ref
61
78
  animatedStyle,
62
79
  ], [tw, animatedStyle]);
63
80
  const innerRef = (0, react_1.useRef)(null);
64
- const resetState = () => setToastOptions(undefined);
81
+ const clearScheduledAutoDismiss = () => {
82
+ if (autoDismissTimeoutRef.current !== null) {
83
+ clearTimeout(autoDismissTimeoutRef.current);
84
+ autoDismissTimeoutRef.current = null;
85
+ }
86
+ };
87
+ const bumpToastGeneration = () => {
88
+ toastGenerationRef.current += 1;
89
+ toastGeneration.value = toastGenerationRef.current;
90
+ };
91
+ const resetState = () => {
92
+ animationStartedRef.current = false;
93
+ visibleAtRef.current = null;
94
+ isDismissing.value = false;
95
+ isSwipeActive.value = false;
96
+ clearScheduledAutoDismiss();
97
+ setToastOptions(undefined);
98
+ };
99
+ const startDismissAnimation = () => {
100
+ bumpToastGeneration();
101
+ clearScheduledAutoDismiss();
102
+ isDismissing.value = true;
103
+ visibleAtRef.current = null;
104
+ translateYProgress.value = (0, react_native_reanimated_1.withSpring)(hiddenTranslateY.value, Toast_constants_1.TOAST_SPRING_CONFIG, (finished) => {
105
+ if (finished) {
106
+ (0, react_native_worklets_1.scheduleOnRN)(resetState);
107
+ }
108
+ });
109
+ };
110
+ const scheduleAutoDismiss = (delayMs) => {
111
+ clearScheduledAutoDismiss();
112
+ autoDismissTimeoutRef.current = setTimeout(() => {
113
+ autoDismissTimeoutRef.current = null;
114
+ startDismissAnimation();
115
+ }, delayMs);
116
+ };
117
+ const beginAutoDismiss = () => {
118
+ visibleAtRef.current = Date.now();
119
+ scheduleAutoDismiss(Toast_constants_1.TOAST_VISIBILITY_DURATION);
120
+ };
121
+ const resumeAutoDismissAfterSwipe = () => {
122
+ if (hasNoTimeoutRef.current || isDismissing.value) {
123
+ return;
124
+ }
125
+ // Entrance was interrupted before auto-dismiss started — start a full timer.
126
+ if (visibleAtRef.current === null) {
127
+ beginAutoDismiss();
128
+ return;
129
+ }
130
+ const elapsed = Date.now() - visibleAtRef.current;
131
+ if (elapsed >= Toast_constants_1.TOAST_VISIBILITY_DURATION) {
132
+ startDismissAnimation();
133
+ return;
134
+ }
135
+ scheduleAutoDismiss(Toast_constants_1.TOAST_VISIBILITY_DURATION - elapsed);
136
+ };
65
137
  const showToast = (options) => {
138
+ bumpToastGeneration();
66
139
  let timeoutDuration = 0;
67
140
  const normalizedOptions = {
68
141
  hasNoTimeout: false,
69
142
  ...options,
70
143
  };
71
144
  if (toastOptions) {
145
+ // Always clear any pending auto-dismiss from the previous toast, including
146
+ // when the replacement is persistent (hasNoTimeout). Otherwise the old
147
+ // timer can fire and dismiss the new toast.
148
+ clearScheduledAutoDismiss();
72
149
  (0, react_native_reanimated_1.cancelAnimation)(translateYProgress);
73
150
  timeoutDuration = 100;
151
+ animationStartedRef.current = false;
152
+ visibleAtRef.current = null;
153
+ isDismissing.value = false;
154
+ isSwipeActive.value = false;
74
155
  setToastOptions(undefined);
75
156
  }
76
157
  if (replacementTimerRef.current !== null) {
@@ -86,10 +167,109 @@ const ToasterComponent = (0, react_1.forwardRef)(({ twClassName, ...props }, ref
86
167
  clearTimeout(replacementTimerRef.current);
87
168
  replacementTimerRef.current = null;
88
169
  }
89
- translateYProgress.value = (0, react_native_reanimated_1.withSpring)(getHiddenTranslateY(toastHeight.value, topOffset), Toast_constants_1.TOAST_SPRING_CONFIG, () => {
90
- (0, react_native_worklets_1.scheduleOnRN)(resetState);
91
- });
170
+ startDismissAnimation();
92
171
  };
172
+ const closeToastRef = (0, react_1.useRef)(closeToast);
173
+ const resumeAutoDismissAfterSwipeRef = (0, react_1.useRef)(resumeAutoDismissAfterSwipe);
174
+ const clearScheduledAutoDismissRef = (0, react_1.useRef)(clearScheduledAutoDismiss);
175
+ closeToastRef.current = closeToast;
176
+ resumeAutoDismissAfterSwipeRef.current = resumeAutoDismissAfterSwipe;
177
+ clearScheduledAutoDismissRef.current = clearScheduledAutoDismiss;
178
+ const dismissToastFromSwipe = () => {
179
+ closeToastRef.current();
180
+ };
181
+ const resumeAutoDismissFromSwipe = (generation) => {
182
+ // Ignore resumes from a toast that was replaced or dismissed after the
183
+ // spring-back started (completed springs cannot be cancelled).
184
+ if (generation !== toastGenerationRef.current) {
185
+ return;
186
+ }
187
+ resumeAutoDismissAfterSwipeRef.current();
188
+ };
189
+ const clearScheduledAutoDismissFromSwipe = () => {
190
+ clearScheduledAutoDismissRef.current();
191
+ };
192
+ const swipeGesture = (0, react_1.useMemo)(() => {
193
+ // These gesture callbacks need explicit 'worklet' directives because this
194
+ // package ships a pre-built dist compiled by ts-bridge (tsc), which emits the
195
+ // gesture chain as a namespaced call (react_native_gesture_handler_1.Gesture).
196
+ // The consumer's Reanimated/Worklets Babel plugin does run over dist, but its
197
+ // gesture auto-detection doesn't recognize that compiled namespaced form.
198
+ const springBackAfterSwipe = () => {
199
+ 'worklet';
200
+ const generationAtSpringStart = toastGeneration.value;
201
+ translateYProgress.value = (0, react_native_reanimated_1.withSpring)(visibleTranslateY.value, Toast_constants_1.TOAST_SPRING_CONFIG, (finished) => {
202
+ // A new pan cancels this spring via cancelAnimation; only resume
203
+ // auto-dismiss when the spring-back completed naturally.
204
+ if (finished) {
205
+ (0, react_native_worklets_1.scheduleOnRN)(resumeAutoDismissFromSwipe, generationAtSpringStart);
206
+ }
207
+ });
208
+ };
209
+ return react_native_gesture_handler_1.Gesture.Pan()
210
+ .activeOffsetY(Toast_constants_1.TOAST_SWIPE_ACTIVE_OFFSET_Y)
211
+ .failOffsetX([-Toast_constants_1.TOAST_SWIPE_FAIL_OFFSET_X, Toast_constants_1.TOAST_SWIPE_FAIL_OFFSET_X])
212
+ .onStart(() => {
213
+ 'worklet';
214
+ // Don't interrupt an in-progress dismiss animation.
215
+ if (isDismissing.value) {
216
+ return;
217
+ }
218
+ isSwipeActive.value = true;
219
+ (0, react_native_worklets_1.scheduleOnRN)(clearScheduledAutoDismissFromSwipe);
220
+ (0, react_native_reanimated_1.cancelAnimation)(translateYProgress);
221
+ gestureStartY.value = translateYProgress.value;
222
+ })
223
+ .onUpdate((event) => {
224
+ 'worklet';
225
+ if (isDismissing.value || !isSwipeActive.value) {
226
+ return;
227
+ }
228
+ const nextTranslateY = gestureStartY.value + event.translationY;
229
+ // Toast sits at the top; only allow dragging upward (more negative).
230
+ translateYProgress.value = Math.min(nextTranslateY, visibleTranslateY.value);
231
+ })
232
+ .onEnd((event) => {
233
+ 'worklet';
234
+ if (!isSwipeActive.value) {
235
+ return;
236
+ }
237
+ isSwipeActive.value = false;
238
+ if (isDismissing.value) {
239
+ return;
240
+ }
241
+ const { translationY, velocityY } = event;
242
+ const dismissDistance = Math.max(toastHeight.value * Toast_constants_1.TOAST_DISMISS_DISTANCE_THRESHOLD, Toast_constants_1.TOAST_DISMISS_MIN_DISTANCE);
243
+ const hasReachedDismissOffset = translationY <= -dismissDistance;
244
+ const hasReachedSwipeThreshold = Math.abs(velocityY) > Toast_constants_1.TOAST_DISMISS_VELOCITY_THRESHOLD;
245
+ const isQuickDismissing = velocityY < 0;
246
+ const shouldDismiss = hasReachedDismissOffset ||
247
+ (hasReachedSwipeThreshold && isQuickDismissing);
248
+ if (shouldDismiss) {
249
+ (0, react_native_worklets_1.scheduleOnRN)(dismissToastFromSwipe);
250
+ return;
251
+ }
252
+ springBackAfterSwipe();
253
+ })
254
+ .onFinalize(() => {
255
+ 'worklet';
256
+ // onEnd is skipped when the pan fails/cancels after activation
257
+ // (e.g. horizontal travel past failOffsetX). Recover position and
258
+ // auto-dismiss so the toast is not left stuck mid-offset.
259
+ if (!isSwipeActive.value) {
260
+ return;
261
+ }
262
+ // Clear before the dismiss check — same order as onEnd — so a pan
263
+ // cancelled mid-dismiss cannot leave isSwipeActive stuck true for a
264
+ // later toast (resetState alone is not enough if finalize races it).
265
+ isSwipeActive.value = false;
266
+ if (isDismissing.value) {
267
+ return;
268
+ }
269
+ springBackAfterSwipe();
270
+ });
271
+ // Shared values and swipe JS wrappers are stable for the component lifetime.
272
+ }, []);
93
273
  innerRef.current = {
94
274
  closeToast,
95
275
  showToast,
@@ -114,30 +294,38 @@ const ToasterComponent = (0, react_1.forwardRef)(({ twClassName, ...props }, ref
114
294
  .join(' ');
115
295
  const onAnimatedViewLayout = (e) => {
116
296
  const { height } = e.nativeEvent.layout;
117
- const hiddenTranslateY = getHiddenTranslateY(height, topOffset);
118
- const visibleTranslateY = topInset + Toast_constants_1.TOAST_TOP_PADDING;
297
+ const nextHiddenTranslateY = getHiddenTranslateY(height, topOffset);
298
+ const nextVisibleTranslateY = topInset + Toast_constants_1.TOAST_TOP_PADDING;
299
+ hiddenTranslateY.value = nextHiddenTranslateY;
300
+ visibleTranslateY.value = nextVisibleTranslateY;
119
301
  toastHeight.value = height;
120
- translateYProgress.value = hiddenTranslateY;
302
+ if (animationStartedRef.current) {
303
+ return;
304
+ }
305
+ animationStartedRef.current = true;
306
+ translateYProgress.value = nextHiddenTranslateY;
121
307
  if (toastOptions.hasNoTimeout) {
122
- translateYProgress.value = (0, react_native_reanimated_1.withSpring)(visibleTranslateY, Toast_constants_1.TOAST_SPRING_CONFIG);
308
+ translateYProgress.value = (0, react_native_reanimated_1.withSpring)(nextVisibleTranslateY, Toast_constants_1.TOAST_SPRING_CONFIG);
123
309
  }
124
310
  else {
125
- translateYProgress.value = (0, react_native_reanimated_1.withSpring)(visibleTranslateY, Toast_constants_1.TOAST_SPRING_CONFIG, () => {
126
- translateYProgress.value = (0, react_native_reanimated_1.withDelay)(Toast_constants_1.TOAST_VISIBILITY_DURATION, (0, react_native_reanimated_1.withSpring)(hiddenTranslateY, Toast_constants_1.TOAST_SPRING_CONFIG, () => {
127
- (0, react_native_worklets_1.scheduleOnRN)(resetState);
128
- }));
311
+ translateYProgress.value = (0, react_native_reanimated_1.withSpring)(nextVisibleTranslateY, Toast_constants_1.TOAST_SPRING_CONFIG, (finished) => {
312
+ if (finished) {
313
+ (0, react_native_worklets_1.scheduleOnRN)(beginAutoDismiss);
314
+ }
129
315
  });
130
316
  }
131
317
  };
132
- return (<react_native_reanimated_1.default.View onLayout={onAnimatedViewLayout} style={baseStyle} {...props}>
133
- {actionButtonLabel && actionButtonOnPress ? (<Toast_1.Toast {...toastProps} actionButtonLabel={actionButtonLabel} actionButtonOnPress={actionButtonOnPress} onClose={() => {
318
+ return (<react_native_gesture_handler_1.GestureDetector gesture={swipeGesture}>
319
+ <react_native_reanimated_1.default.View onLayout={onAnimatedViewLayout} style={baseStyle} {...props}>
320
+ {actionButtonLabel && actionButtonOnPress ? (<Toast_1.Toast {...toastProps} actionButtonLabel={actionButtonLabel} actionButtonOnPress={actionButtonOnPress} onClose={() => {
134
321
  closeToast();
135
322
  toastOnClose?.();
136
323
  }} twClassName={toastTwClassNames}/>) : (<Toast_1.Toast {...restToastProps} onClose={() => {
137
324
  closeToast();
138
325
  toastOnClose?.();
139
326
  }} twClassName={toastTwClassNames}/>)}
140
- </react_native_reanimated_1.default.View>);
327
+ </react_native_reanimated_1.default.View>
328
+ </react_native_gesture_handler_1.GestureDetector>);
141
329
  });
142
330
  ToasterComponent.displayName = 'Toaster';
143
331
  exports.Toaster = ToasterComponent;
@@ -1 +1 @@
1
- {"version":3,"file":"Toaster.cjs","sourceRoot":"","sources":["../../../src/components/Toast/Toaster.tsx"],"names":[],"mappings":"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","sourcesContent":["// Third party dependencies.\nimport { useTailwind } from '@metamask/design-system-twrnc-preset';\nimport React, {\n forwardRef,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport type { RefObject } from 'react';\nimport { Dimensions } from 'react-native';\nimport type { LayoutChangeEvent, StyleProp, ViewStyle } from 'react-native';\nimport Animated, {\n cancelAnimation,\n useAnimatedStyle,\n useSharedValue,\n withDelay,\n withSpring,\n} from 'react-native-reanimated';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport { scheduleOnRN } from 'react-native-worklets';\n\n// Internal dependencies.\nimport { Toast } from './Toast';\nimport {\n TOAST_SPRING_CONFIG,\n TOAST_TOP_PADDING,\n TOAST_VISIBILITY_DURATION,\n} from './Toast.constants';\nimport type {\n ToastOptions,\n ToastProps,\n ToasterProps,\n ToasterRef,\n} from './Toast.types';\n\nconst screenHeight = Dimensions.get('window').height;\n\nlet registeredRef: RefObject<ToasterRef | null> | null = null;\n\nconst assertRegisteredRef = (method: 'dismiss' | 'toast'): ToasterRef => {\n if (!registeredRef?.current) {\n const invocation = method === 'toast' ? 'toast()' : `toast.${method}()`;\n throw new Error(\n `${invocation} called before <Toaster /> mounted. Render <Toaster /> once at the root of your app.`,\n );\n }\n return registeredRef.current;\n};\n\nconst getToastProps = ({\n hasNoTimeout: _hasNoTimeout,\n onClose: _onClose,\n topOffset: _topOffset,\n twClassName: _twClassName,\n ...toastProps\n}: ToastOptions): Omit<ToastProps, 'twClassName'> => toastProps;\n\nconst getHiddenTranslateY = (height: number, offset: number) =>\n -(height + offset);\n\nconst ToasterComponent = forwardRef<ToasterRef, ToasterProps>(\n ({ twClassName, ...props }, ref) => {\n const tw = useTailwind();\n const [toastOptions, setToastOptions] = useState<ToastOptions | undefined>(\n undefined,\n );\n const replacementTimerRef = useRef<ReturnType<typeof setTimeout> | null>(\n null,\n );\n const { top: topInset } = useSafeAreaInsets();\n const toastHeight = useSharedValue(screenHeight);\n const translateYProgress = useSharedValue(-screenHeight);\n const topOffset = toastOptions?.topOffset ?? 0;\n const animatedStyle = useAnimatedStyle(() => ({\n transform: [{ translateY: translateYProgress.value + topOffset }],\n }));\n const baseStyle = useMemo(\n () =>\n [\n tw.style('absolute left-4 right-4 top-0'),\n animatedStyle,\n ] as StyleProp<ViewStyle>,\n [tw, animatedStyle],\n );\n const innerRef = useRef<ToasterRef | null>(null);\n\n const resetState = () => setToastOptions(undefined);\n\n const showToast = (options: ToastOptions) => {\n let timeoutDuration = 0;\n const normalizedOptions = {\n hasNoTimeout: false,\n ...options,\n };\n if (toastOptions) {\n cancelAnimation(translateYProgress);\n timeoutDuration = 100;\n setToastOptions(undefined);\n }\n if (replacementTimerRef.current !== null) {\n clearTimeout(replacementTimerRef.current);\n }\n replacementTimerRef.current = setTimeout(() => {\n replacementTimerRef.current = null;\n setToastOptions(normalizedOptions);\n }, timeoutDuration);\n };\n\n const closeToast = () => {\n if (replacementTimerRef.current !== null) {\n clearTimeout(replacementTimerRef.current);\n replacementTimerRef.current = null;\n }\n translateYProgress.value = withSpring(\n getHiddenTranslateY(toastHeight.value, topOffset),\n TOAST_SPRING_CONFIG,\n () => {\n scheduleOnRN(resetState);\n },\n );\n };\n\n innerRef.current = {\n closeToast,\n showToast,\n };\n\n useImperativeHandle(ref, () => innerRef.current as ToasterRef);\n\n useLayoutEffect(() => {\n registeredRef = innerRef;\n return () => {\n if (registeredRef === innerRef) {\n registeredRef = null;\n }\n };\n }, []);\n\n if (!toastOptions) {\n return null;\n }\n\n const { onClose: toastOnClose, twClassName: toastTwClassName } =\n toastOptions;\n const toastProps = getToastProps(toastOptions);\n const { actionButtonLabel, actionButtonOnPress, ...restToastProps } =\n toastProps;\n const toastTwClassNames = [twClassName, toastTwClassName]\n .filter(Boolean)\n .join(' ');\n\n const onAnimatedViewLayout = (e: LayoutChangeEvent) => {\n const { height } = e.nativeEvent.layout;\n const hiddenTranslateY = getHiddenTranslateY(height, topOffset);\n const visibleTranslateY = topInset + TOAST_TOP_PADDING;\n\n toastHeight.value = height;\n translateYProgress.value = hiddenTranslateY;\n\n if (toastOptions.hasNoTimeout) {\n translateYProgress.value = withSpring(\n visibleTranslateY,\n TOAST_SPRING_CONFIG,\n );\n } else {\n translateYProgress.value = withSpring(\n visibleTranslateY,\n TOAST_SPRING_CONFIG,\n () => {\n translateYProgress.value = withDelay(\n TOAST_VISIBILITY_DURATION,\n withSpring(hiddenTranslateY, TOAST_SPRING_CONFIG, () => {\n scheduleOnRN(resetState);\n }),\n );\n },\n );\n }\n };\n\n return (\n <Animated.View\n onLayout={onAnimatedViewLayout}\n style={baseStyle}\n {...props}\n >\n {actionButtonLabel && actionButtonOnPress ? (\n <Toast\n {...toastProps}\n actionButtonLabel={actionButtonLabel}\n actionButtonOnPress={actionButtonOnPress}\n onClose={() => {\n closeToast();\n toastOnClose?.();\n }}\n twClassName={toastTwClassNames}\n />\n ) : (\n <Toast\n {...restToastProps}\n onClose={() => {\n closeToast();\n toastOnClose?.();\n }}\n twClassName={toastTwClassNames}\n />\n )}\n </Animated.View>\n );\n },\n);\n\nToasterComponent.displayName = 'Toaster';\n\ntype ToastFunction = ((options: ToastOptions) => void) & {\n dismiss: () => void;\n};\n\nexport const Toaster = ToasterComponent;\n\nexport const toast = ((options: ToastOptions) => {\n assertRegisteredRef('toast').showToast(options);\n}) as ToastFunction;\n\ntoast.dismiss = () => {\n assertRegisteredRef('dismiss').closeToast();\n};\n"]}
1
+ {"version":3,"file":"Toaster.cjs","sourceRoot":"","sources":["../../../src/components/Toast/Toaster.tsx"],"names":[],"mappings":"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","sourcesContent":["// Third party dependencies.\nimport { useTailwind } from '@metamask/design-system-twrnc-preset';\nimport React, {\n forwardRef,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport type { RefObject } from 'react';\nimport { Dimensions } from 'react-native';\nimport type { LayoutChangeEvent, StyleProp, ViewStyle } from 'react-native';\nimport { Gesture, GestureDetector } from 'react-native-gesture-handler';\nimport Animated, {\n cancelAnimation,\n useAnimatedStyle,\n useSharedValue,\n withSpring,\n} from 'react-native-reanimated';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport { scheduleOnRN } from 'react-native-worklets';\n\n// Internal dependencies.\nimport { Toast } from './Toast';\nimport {\n TOAST_DISMISS_DISTANCE_THRESHOLD,\n TOAST_DISMISS_MIN_DISTANCE,\n TOAST_DISMISS_VELOCITY_THRESHOLD,\n TOAST_SPRING_CONFIG,\n TOAST_SWIPE_ACTIVE_OFFSET_Y,\n TOAST_SWIPE_FAIL_OFFSET_X,\n TOAST_TOP_PADDING,\n TOAST_VISIBILITY_DURATION,\n} from './Toast.constants';\nimport type {\n ToastOptions,\n ToastProps,\n ToasterProps,\n ToasterRef,\n} from './Toast.types';\n\nconst screenHeight = Dimensions.get('window').height;\n\nlet registeredRef: RefObject<ToasterRef | null> | null = null;\n\nconst assertRegisteredRef = (method: 'dismiss' | 'toast'): ToasterRef => {\n if (!registeredRef?.current) {\n const invocation = method === 'toast' ? 'toast()' : `toast.${method}()`;\n throw new Error(\n `${invocation} called before <Toaster /> mounted. Render <Toaster /> once at the root of your app.`,\n );\n }\n return registeredRef.current;\n};\n\nconst getToastProps = ({\n hasNoTimeout: _hasNoTimeout,\n onClose: _onClose,\n topOffset: _topOffset,\n twClassName: _twClassName,\n ...toastProps\n}: ToastOptions): Omit<ToastProps, 'twClassName'> => toastProps;\n\nconst getHiddenTranslateY = (height: number, offset: number) =>\n -(height + offset);\n\nconst ToasterComponent = forwardRef<ToasterRef, ToasterProps>(\n ({ twClassName, ...props }, ref) => {\n const tw = useTailwind();\n const [toastOptions, setToastOptions] = useState<ToastOptions | undefined>(\n undefined,\n );\n const replacementTimerRef = useRef<ReturnType<typeof setTimeout> | null>(\n null,\n );\n const autoDismissTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(\n null,\n );\n const animationStartedRef = useRef(false);\n const visibleAtRef = useRef<number | null>(null);\n const hasNoTimeoutRef = useRef(false);\n // Invalidates queued spring-back resumes after replace/dismiss. A completed\n // spring cannot be cancelled, so scheduleOnRN(resume) can still run later.\n const toastGenerationRef = useRef(0);\n const { top: topInset } = useSafeAreaInsets();\n const toastHeight = useSharedValue(screenHeight);\n const hiddenTranslateY = useSharedValue(-screenHeight);\n const visibleTranslateY = useSharedValue(0);\n const gestureStartY = useSharedValue(0);\n const translateYProgress = useSharedValue(-screenHeight);\n const isDismissing = useSharedValue(false);\n // True after onStart until onEnd/onFinalize recovers. Used so a failed pan\n // (e.g. failOffsetX after activation) still springs back and resumes dismiss.\n const isSwipeActive = useSharedValue(false);\n const toastGeneration = useSharedValue(0);\n const topOffset = toastOptions?.topOffset ?? 0;\n hasNoTimeoutRef.current = Boolean(toastOptions?.hasNoTimeout);\n const animatedStyle = useAnimatedStyle(() => ({\n transform: [{ translateY: translateYProgress.value + topOffset }],\n }));\n const baseStyle = useMemo(\n () =>\n [\n tw.style('absolute left-4 right-4 top-0'),\n animatedStyle,\n ] as StyleProp<ViewStyle>,\n [tw, animatedStyle],\n );\n const innerRef = useRef<ToasterRef | null>(null);\n\n const clearScheduledAutoDismiss = () => {\n if (autoDismissTimeoutRef.current !== null) {\n clearTimeout(autoDismissTimeoutRef.current);\n autoDismissTimeoutRef.current = null;\n }\n };\n\n const bumpToastGeneration = () => {\n toastGenerationRef.current += 1;\n toastGeneration.value = toastGenerationRef.current;\n };\n\n const resetState = () => {\n animationStartedRef.current = false;\n visibleAtRef.current = null;\n isDismissing.value = false;\n isSwipeActive.value = false;\n clearScheduledAutoDismiss();\n setToastOptions(undefined);\n };\n\n const startDismissAnimation = () => {\n bumpToastGeneration();\n clearScheduledAutoDismiss();\n isDismissing.value = true;\n visibleAtRef.current = null;\n translateYProgress.value = withSpring(\n hiddenTranslateY.value,\n TOAST_SPRING_CONFIG,\n (finished) => {\n if (finished) {\n scheduleOnRN(resetState);\n }\n },\n );\n };\n\n const scheduleAutoDismiss = (delayMs: number) => {\n clearScheduledAutoDismiss();\n autoDismissTimeoutRef.current = setTimeout(() => {\n autoDismissTimeoutRef.current = null;\n startDismissAnimation();\n }, delayMs);\n };\n\n const beginAutoDismiss = () => {\n visibleAtRef.current = Date.now();\n scheduleAutoDismiss(TOAST_VISIBILITY_DURATION);\n };\n\n const resumeAutoDismissAfterSwipe = () => {\n if (hasNoTimeoutRef.current || isDismissing.value) {\n return;\n }\n\n // Entrance was interrupted before auto-dismiss started — start a full timer.\n if (visibleAtRef.current === null) {\n beginAutoDismiss();\n return;\n }\n\n const elapsed = Date.now() - visibleAtRef.current;\n if (elapsed >= TOAST_VISIBILITY_DURATION) {\n startDismissAnimation();\n return;\n }\n\n scheduleAutoDismiss(TOAST_VISIBILITY_DURATION - elapsed);\n };\n\n const showToast = (options: ToastOptions) => {\n bumpToastGeneration();\n let timeoutDuration = 0;\n const normalizedOptions = {\n hasNoTimeout: false,\n ...options,\n };\n if (toastOptions) {\n // Always clear any pending auto-dismiss from the previous toast, including\n // when the replacement is persistent (hasNoTimeout). Otherwise the old\n // timer can fire and dismiss the new toast.\n clearScheduledAutoDismiss();\n cancelAnimation(translateYProgress);\n timeoutDuration = 100;\n animationStartedRef.current = false;\n visibleAtRef.current = null;\n isDismissing.value = false;\n isSwipeActive.value = false;\n setToastOptions(undefined);\n }\n if (replacementTimerRef.current !== null) {\n clearTimeout(replacementTimerRef.current);\n }\n replacementTimerRef.current = setTimeout(() => {\n replacementTimerRef.current = null;\n setToastOptions(normalizedOptions);\n }, timeoutDuration);\n };\n\n const closeToast = () => {\n if (replacementTimerRef.current !== null) {\n clearTimeout(replacementTimerRef.current);\n replacementTimerRef.current = null;\n }\n startDismissAnimation();\n };\n\n const closeToastRef = useRef(closeToast);\n const resumeAutoDismissAfterSwipeRef = useRef(resumeAutoDismissAfterSwipe);\n const clearScheduledAutoDismissRef = useRef(clearScheduledAutoDismiss);\n closeToastRef.current = closeToast;\n resumeAutoDismissAfterSwipeRef.current = resumeAutoDismissAfterSwipe;\n clearScheduledAutoDismissRef.current = clearScheduledAutoDismiss;\n\n const dismissToastFromSwipe = () => {\n closeToastRef.current();\n };\n\n const resumeAutoDismissFromSwipe = (generation: number) => {\n // Ignore resumes from a toast that was replaced or dismissed after the\n // spring-back started (completed springs cannot be cancelled).\n if (generation !== toastGenerationRef.current) {\n return;\n }\n resumeAutoDismissAfterSwipeRef.current();\n };\n\n const clearScheduledAutoDismissFromSwipe = () => {\n clearScheduledAutoDismissRef.current();\n };\n\n const swipeGesture = useMemo(() => {\n // These gesture callbacks need explicit 'worklet' directives because this\n // package ships a pre-built dist compiled by ts-bridge (tsc), which emits the\n // gesture chain as a namespaced call (react_native_gesture_handler_1.Gesture).\n // The consumer's Reanimated/Worklets Babel plugin does run over dist, but its\n // gesture auto-detection doesn't recognize that compiled namespaced form.\n const springBackAfterSwipe = () => {\n 'worklet';\n\n const generationAtSpringStart = toastGeneration.value;\n translateYProgress.value = withSpring(\n visibleTranslateY.value,\n TOAST_SPRING_CONFIG,\n (finished) => {\n // A new pan cancels this spring via cancelAnimation; only resume\n // auto-dismiss when the spring-back completed naturally.\n if (finished) {\n scheduleOnRN(resumeAutoDismissFromSwipe, generationAtSpringStart);\n }\n },\n );\n };\n\n return Gesture.Pan()\n .activeOffsetY(TOAST_SWIPE_ACTIVE_OFFSET_Y)\n .failOffsetX([-TOAST_SWIPE_FAIL_OFFSET_X, TOAST_SWIPE_FAIL_OFFSET_X])\n .onStart(() => {\n 'worklet';\n\n // Don't interrupt an in-progress dismiss animation.\n if (isDismissing.value) {\n return;\n }\n isSwipeActive.value = true;\n scheduleOnRN(clearScheduledAutoDismissFromSwipe);\n cancelAnimation(translateYProgress);\n gestureStartY.value = translateYProgress.value;\n })\n .onUpdate((event) => {\n 'worklet';\n\n if (isDismissing.value || !isSwipeActive.value) {\n return;\n }\n const nextTranslateY = gestureStartY.value + event.translationY;\n // Toast sits at the top; only allow dragging upward (more negative).\n translateYProgress.value = Math.min(\n nextTranslateY,\n visibleTranslateY.value,\n );\n })\n .onEnd((event) => {\n 'worklet';\n\n if (!isSwipeActive.value) {\n return;\n }\n isSwipeActive.value = false;\n\n if (isDismissing.value) {\n return;\n }\n const { translationY, velocityY } = event;\n const dismissDistance = Math.max(\n toastHeight.value * TOAST_DISMISS_DISTANCE_THRESHOLD,\n TOAST_DISMISS_MIN_DISTANCE,\n );\n const hasReachedDismissOffset = translationY <= -dismissDistance;\n const hasReachedSwipeThreshold =\n Math.abs(velocityY) > TOAST_DISMISS_VELOCITY_THRESHOLD;\n const isQuickDismissing = velocityY < 0;\n\n const shouldDismiss =\n hasReachedDismissOffset ||\n (hasReachedSwipeThreshold && isQuickDismissing);\n\n if (shouldDismiss) {\n scheduleOnRN(dismissToastFromSwipe);\n return;\n }\n\n springBackAfterSwipe();\n })\n .onFinalize(() => {\n 'worklet';\n\n // onEnd is skipped when the pan fails/cancels after activation\n // (e.g. horizontal travel past failOffsetX). Recover position and\n // auto-dismiss so the toast is not left stuck mid-offset.\n if (!isSwipeActive.value) {\n return;\n }\n // Clear before the dismiss check — same order as onEnd — so a pan\n // cancelled mid-dismiss cannot leave isSwipeActive stuck true for a\n // later toast (resetState alone is not enough if finalize races it).\n isSwipeActive.value = false;\n\n if (isDismissing.value) {\n return;\n }\n springBackAfterSwipe();\n });\n // Shared values and swipe JS wrappers are stable for the component lifetime.\n }, []);\n\n innerRef.current = {\n closeToast,\n showToast,\n };\n\n useImperativeHandle(ref, () => innerRef.current as ToasterRef);\n\n useLayoutEffect(() => {\n registeredRef = innerRef;\n return () => {\n if (registeredRef === innerRef) {\n registeredRef = null;\n }\n };\n }, []);\n\n if (!toastOptions) {\n return null;\n }\n\n const { onClose: toastOnClose, twClassName: toastTwClassName } =\n toastOptions;\n const toastProps = getToastProps(toastOptions);\n const { actionButtonLabel, actionButtonOnPress, ...restToastProps } =\n toastProps;\n const toastTwClassNames = [twClassName, toastTwClassName]\n .filter(Boolean)\n .join(' ');\n\n const onAnimatedViewLayout = (e: LayoutChangeEvent) => {\n const { height } = e.nativeEvent.layout;\n const nextHiddenTranslateY = getHiddenTranslateY(height, topOffset);\n const nextVisibleTranslateY = topInset + TOAST_TOP_PADDING;\n\n hiddenTranslateY.value = nextHiddenTranslateY;\n visibleTranslateY.value = nextVisibleTranslateY;\n toastHeight.value = height;\n\n if (animationStartedRef.current) {\n return;\n }\n\n animationStartedRef.current = true;\n translateYProgress.value = nextHiddenTranslateY;\n\n if (toastOptions.hasNoTimeout) {\n translateYProgress.value = withSpring(\n nextVisibleTranslateY,\n TOAST_SPRING_CONFIG,\n );\n } else {\n translateYProgress.value = withSpring(\n nextVisibleTranslateY,\n TOAST_SPRING_CONFIG,\n (finished) => {\n if (finished) {\n scheduleOnRN(beginAutoDismiss);\n }\n },\n );\n }\n };\n\n return (\n <GestureDetector gesture={swipeGesture}>\n <Animated.View\n onLayout={onAnimatedViewLayout}\n style={baseStyle}\n {...props}\n >\n {actionButtonLabel && actionButtonOnPress ? (\n <Toast\n {...toastProps}\n actionButtonLabel={actionButtonLabel}\n actionButtonOnPress={actionButtonOnPress}\n onClose={() => {\n closeToast();\n toastOnClose?.();\n }}\n twClassName={toastTwClassNames}\n />\n ) : (\n <Toast\n {...restToastProps}\n onClose={() => {\n closeToast();\n toastOnClose?.();\n }}\n twClassName={toastTwClassNames}\n />\n )}\n </Animated.View>\n </GestureDetector>\n );\n },\n);\n\nToasterComponent.displayName = 'Toaster';\n\ntype ToastFunction = ((options: ToastOptions) => void) & {\n dismiss: () => void;\n};\n\nexport const Toaster = ToasterComponent;\n\nexport const toast = ((options: ToastOptions) => {\n assertRegisteredRef('toast').showToast(options);\n}) as ToastFunction;\n\ntoast.dismiss = () => {\n assertRegisteredRef('dismiss').closeToast();\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"Toaster.d.cts","sourceRoot":"","sources":["../../../src/components/Toast/Toaster.tsx"],"names":[],"mappings":"AAEA,OAAO,KAON,cAAc;AAqBf,OAAO,KAAK,EACV,YAAY,EAGZ,UAAU,EACX,0BAAsB;AAqLvB,KAAK,aAAa,GAAG,CAAC,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC,GAAG;IACvD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,OAAO;;sFAAmB,CAAC;AAExC,eAAO,MAAM,KAAK,eAEC,CAAC"}
1
+ {"version":3,"file":"Toaster.d.cts","sourceRoot":"","sources":["../../../src/components/Toast/Toaster.tsx"],"names":[],"mappings":"AAEA,OAAO,KAON,cAAc;AA0Bf,OAAO,KAAK,EACV,YAAY,EAGZ,UAAU,EACX,0BAAsB;AAsZvB,KAAK,aAAa,GAAG,CAAC,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC,GAAG;IACvD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,OAAO;;sFAAmB,CAAC;AAExC,eAAO,MAAM,KAAK,eAEC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Toaster.d.mts","sourceRoot":"","sources":["../../../src/components/Toast/Toaster.tsx"],"names":[],"mappings":"AAEA,OAAO,KAON,cAAc;AAqBf,OAAO,KAAK,EACV,YAAY,EAGZ,UAAU,EACX,0BAAsB;AAqLvB,KAAK,aAAa,GAAG,CAAC,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC,GAAG;IACvD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,OAAO;;sFAAmB,CAAC;AAExC,eAAO,MAAM,KAAK,eAEC,CAAC"}
1
+ {"version":3,"file":"Toaster.d.mts","sourceRoot":"","sources":["../../../src/components/Toast/Toaster.tsx"],"names":[],"mappings":"AAEA,OAAO,KAON,cAAc;AA0Bf,OAAO,KAAK,EACV,YAAY,EAGZ,UAAU,EACX,0BAAsB;AAsZvB,KAAK,aAAa,GAAG,CAAC,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC,GAAG;IACvD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,OAAO;;sFAAmB,CAAC;AAExC,eAAO,MAAM,KAAK,eAEC,CAAC"}
@@ -9,12 +9,13 @@ import { useTailwind } from "@metamask/design-system-twrnc-preset";
9
9
  import $React, { forwardRef, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
10
10
  const React = $importDefault($React);
11
11
  import { Dimensions } from "react-native";
12
- import Animated, { cancelAnimation, useAnimatedStyle, useSharedValue, withDelay, withSpring } from "react-native-reanimated";
12
+ import { Gesture, GestureDetector } from "react-native-gesture-handler";
13
+ import Animated, { cancelAnimation, useAnimatedStyle, useSharedValue, withSpring } from "react-native-reanimated";
13
14
  import { useSafeAreaInsets } from "react-native-safe-area-context";
14
15
  import { scheduleOnRN } from "react-native-worklets";
15
16
  // Internal dependencies.
16
17
  import { Toast } from "./Toast.mjs";
17
- import { TOAST_SPRING_CONFIG, TOAST_TOP_PADDING, TOAST_VISIBILITY_DURATION } from "./Toast.constants.mjs";
18
+ import { TOAST_DISMISS_DISTANCE_THRESHOLD, TOAST_DISMISS_MIN_DISTANCE, TOAST_DISMISS_VELOCITY_THRESHOLD, TOAST_SPRING_CONFIG, TOAST_SWIPE_ACTIVE_OFFSET_Y, TOAST_SWIPE_FAIL_OFFSET_X, TOAST_TOP_PADDING, TOAST_VISIBILITY_DURATION } from "./Toast.constants.mjs";
18
19
  const screenHeight = Dimensions.get('window').height;
19
20
  let registeredRef = null;
20
21
  const assertRegisteredRef = (method) => {
@@ -30,10 +31,26 @@ const ToasterComponent = forwardRef(({ twClassName, ...props }, ref) => {
30
31
  const tw = useTailwind();
31
32
  const [toastOptions, setToastOptions] = useState(undefined);
32
33
  const replacementTimerRef = useRef(null);
34
+ const autoDismissTimeoutRef = useRef(null);
35
+ const animationStartedRef = useRef(false);
36
+ const visibleAtRef = useRef(null);
37
+ const hasNoTimeoutRef = useRef(false);
38
+ // Invalidates queued spring-back resumes after replace/dismiss. A completed
39
+ // spring cannot be cancelled, so scheduleOnRN(resume) can still run later.
40
+ const toastGenerationRef = useRef(0);
33
41
  const { top: topInset } = useSafeAreaInsets();
34
42
  const toastHeight = useSharedValue(screenHeight);
43
+ const hiddenTranslateY = useSharedValue(-screenHeight);
44
+ const visibleTranslateY = useSharedValue(0);
45
+ const gestureStartY = useSharedValue(0);
35
46
  const translateYProgress = useSharedValue(-screenHeight);
47
+ const isDismissing = useSharedValue(false);
48
+ // True after onStart until onEnd/onFinalize recovers. Used so a failed pan
49
+ // (e.g. failOffsetX after activation) still springs back and resumes dismiss.
50
+ const isSwipeActive = useSharedValue(false);
51
+ const toastGeneration = useSharedValue(0);
36
52
  const topOffset = toastOptions?.topOffset ?? 0;
53
+ hasNoTimeoutRef.current = Boolean(toastOptions?.hasNoTimeout);
37
54
  const animatedStyle = useAnimatedStyle(() => ({
38
55
  transform: [{ translateY: translateYProgress.value + topOffset }],
39
56
  }));
@@ -42,16 +59,80 @@ const ToasterComponent = forwardRef(({ twClassName, ...props }, ref) => {
42
59
  animatedStyle,
43
60
  ], [tw, animatedStyle]);
44
61
  const innerRef = useRef(null);
45
- const resetState = () => setToastOptions(undefined);
62
+ const clearScheduledAutoDismiss = () => {
63
+ if (autoDismissTimeoutRef.current !== null) {
64
+ clearTimeout(autoDismissTimeoutRef.current);
65
+ autoDismissTimeoutRef.current = null;
66
+ }
67
+ };
68
+ const bumpToastGeneration = () => {
69
+ toastGenerationRef.current += 1;
70
+ toastGeneration.value = toastGenerationRef.current;
71
+ };
72
+ const resetState = () => {
73
+ animationStartedRef.current = false;
74
+ visibleAtRef.current = null;
75
+ isDismissing.value = false;
76
+ isSwipeActive.value = false;
77
+ clearScheduledAutoDismiss();
78
+ setToastOptions(undefined);
79
+ };
80
+ const startDismissAnimation = () => {
81
+ bumpToastGeneration();
82
+ clearScheduledAutoDismiss();
83
+ isDismissing.value = true;
84
+ visibleAtRef.current = null;
85
+ translateYProgress.value = withSpring(hiddenTranslateY.value, TOAST_SPRING_CONFIG, (finished) => {
86
+ if (finished) {
87
+ scheduleOnRN(resetState);
88
+ }
89
+ });
90
+ };
91
+ const scheduleAutoDismiss = (delayMs) => {
92
+ clearScheduledAutoDismiss();
93
+ autoDismissTimeoutRef.current = setTimeout(() => {
94
+ autoDismissTimeoutRef.current = null;
95
+ startDismissAnimation();
96
+ }, delayMs);
97
+ };
98
+ const beginAutoDismiss = () => {
99
+ visibleAtRef.current = Date.now();
100
+ scheduleAutoDismiss(TOAST_VISIBILITY_DURATION);
101
+ };
102
+ const resumeAutoDismissAfterSwipe = () => {
103
+ if (hasNoTimeoutRef.current || isDismissing.value) {
104
+ return;
105
+ }
106
+ // Entrance was interrupted before auto-dismiss started — start a full timer.
107
+ if (visibleAtRef.current === null) {
108
+ beginAutoDismiss();
109
+ return;
110
+ }
111
+ const elapsed = Date.now() - visibleAtRef.current;
112
+ if (elapsed >= TOAST_VISIBILITY_DURATION) {
113
+ startDismissAnimation();
114
+ return;
115
+ }
116
+ scheduleAutoDismiss(TOAST_VISIBILITY_DURATION - elapsed);
117
+ };
46
118
  const showToast = (options) => {
119
+ bumpToastGeneration();
47
120
  let timeoutDuration = 0;
48
121
  const normalizedOptions = {
49
122
  hasNoTimeout: false,
50
123
  ...options,
51
124
  };
52
125
  if (toastOptions) {
126
+ // Always clear any pending auto-dismiss from the previous toast, including
127
+ // when the replacement is persistent (hasNoTimeout). Otherwise the old
128
+ // timer can fire and dismiss the new toast.
129
+ clearScheduledAutoDismiss();
53
130
  cancelAnimation(translateYProgress);
54
131
  timeoutDuration = 100;
132
+ animationStartedRef.current = false;
133
+ visibleAtRef.current = null;
134
+ isDismissing.value = false;
135
+ isSwipeActive.value = false;
55
136
  setToastOptions(undefined);
56
137
  }
57
138
  if (replacementTimerRef.current !== null) {
@@ -67,10 +148,109 @@ const ToasterComponent = forwardRef(({ twClassName, ...props }, ref) => {
67
148
  clearTimeout(replacementTimerRef.current);
68
149
  replacementTimerRef.current = null;
69
150
  }
70
- translateYProgress.value = withSpring(getHiddenTranslateY(toastHeight.value, topOffset), TOAST_SPRING_CONFIG, () => {
71
- scheduleOnRN(resetState);
72
- });
151
+ startDismissAnimation();
73
152
  };
153
+ const closeToastRef = useRef(closeToast);
154
+ const resumeAutoDismissAfterSwipeRef = useRef(resumeAutoDismissAfterSwipe);
155
+ const clearScheduledAutoDismissRef = useRef(clearScheduledAutoDismiss);
156
+ closeToastRef.current = closeToast;
157
+ resumeAutoDismissAfterSwipeRef.current = resumeAutoDismissAfterSwipe;
158
+ clearScheduledAutoDismissRef.current = clearScheduledAutoDismiss;
159
+ const dismissToastFromSwipe = () => {
160
+ closeToastRef.current();
161
+ };
162
+ const resumeAutoDismissFromSwipe = (generation) => {
163
+ // Ignore resumes from a toast that was replaced or dismissed after the
164
+ // spring-back started (completed springs cannot be cancelled).
165
+ if (generation !== toastGenerationRef.current) {
166
+ return;
167
+ }
168
+ resumeAutoDismissAfterSwipeRef.current();
169
+ };
170
+ const clearScheduledAutoDismissFromSwipe = () => {
171
+ clearScheduledAutoDismissRef.current();
172
+ };
173
+ const swipeGesture = useMemo(() => {
174
+ // These gesture callbacks need explicit 'worklet' directives because this
175
+ // package ships a pre-built dist compiled by ts-bridge (tsc), which emits the
176
+ // gesture chain as a namespaced call (react_native_gesture_handler_1.Gesture).
177
+ // The consumer's Reanimated/Worklets Babel plugin does run over dist, but its
178
+ // gesture auto-detection doesn't recognize that compiled namespaced form.
179
+ const springBackAfterSwipe = () => {
180
+ 'worklet';
181
+ const generationAtSpringStart = toastGeneration.value;
182
+ translateYProgress.value = withSpring(visibleTranslateY.value, TOAST_SPRING_CONFIG, (finished) => {
183
+ // A new pan cancels this spring via cancelAnimation; only resume
184
+ // auto-dismiss when the spring-back completed naturally.
185
+ if (finished) {
186
+ scheduleOnRN(resumeAutoDismissFromSwipe, generationAtSpringStart);
187
+ }
188
+ });
189
+ };
190
+ return Gesture.Pan()
191
+ .activeOffsetY(TOAST_SWIPE_ACTIVE_OFFSET_Y)
192
+ .failOffsetX([-TOAST_SWIPE_FAIL_OFFSET_X, TOAST_SWIPE_FAIL_OFFSET_X])
193
+ .onStart(() => {
194
+ 'worklet';
195
+ // Don't interrupt an in-progress dismiss animation.
196
+ if (isDismissing.value) {
197
+ return;
198
+ }
199
+ isSwipeActive.value = true;
200
+ scheduleOnRN(clearScheduledAutoDismissFromSwipe);
201
+ cancelAnimation(translateYProgress);
202
+ gestureStartY.value = translateYProgress.value;
203
+ })
204
+ .onUpdate((event) => {
205
+ 'worklet';
206
+ if (isDismissing.value || !isSwipeActive.value) {
207
+ return;
208
+ }
209
+ const nextTranslateY = gestureStartY.value + event.translationY;
210
+ // Toast sits at the top; only allow dragging upward (more negative).
211
+ translateYProgress.value = Math.min(nextTranslateY, visibleTranslateY.value);
212
+ })
213
+ .onEnd((event) => {
214
+ 'worklet';
215
+ if (!isSwipeActive.value) {
216
+ return;
217
+ }
218
+ isSwipeActive.value = false;
219
+ if (isDismissing.value) {
220
+ return;
221
+ }
222
+ const { translationY, velocityY } = event;
223
+ const dismissDistance = Math.max(toastHeight.value * TOAST_DISMISS_DISTANCE_THRESHOLD, TOAST_DISMISS_MIN_DISTANCE);
224
+ const hasReachedDismissOffset = translationY <= -dismissDistance;
225
+ const hasReachedSwipeThreshold = Math.abs(velocityY) > TOAST_DISMISS_VELOCITY_THRESHOLD;
226
+ const isQuickDismissing = velocityY < 0;
227
+ const shouldDismiss = hasReachedDismissOffset ||
228
+ (hasReachedSwipeThreshold && isQuickDismissing);
229
+ if (shouldDismiss) {
230
+ scheduleOnRN(dismissToastFromSwipe);
231
+ return;
232
+ }
233
+ springBackAfterSwipe();
234
+ })
235
+ .onFinalize(() => {
236
+ 'worklet';
237
+ // onEnd is skipped when the pan fails/cancels after activation
238
+ // (e.g. horizontal travel past failOffsetX). Recover position and
239
+ // auto-dismiss so the toast is not left stuck mid-offset.
240
+ if (!isSwipeActive.value) {
241
+ return;
242
+ }
243
+ // Clear before the dismiss check — same order as onEnd — so a pan
244
+ // cancelled mid-dismiss cannot leave isSwipeActive stuck true for a
245
+ // later toast (resetState alone is not enough if finalize races it).
246
+ isSwipeActive.value = false;
247
+ if (isDismissing.value) {
248
+ return;
249
+ }
250
+ springBackAfterSwipe();
251
+ });
252
+ // Shared values and swipe JS wrappers are stable for the component lifetime.
253
+ }, []);
74
254
  innerRef.current = {
75
255
  closeToast,
76
256
  showToast,
@@ -95,30 +275,38 @@ const ToasterComponent = forwardRef(({ twClassName, ...props }, ref) => {
95
275
  .join(' ');
96
276
  const onAnimatedViewLayout = (e) => {
97
277
  const { height } = e.nativeEvent.layout;
98
- const hiddenTranslateY = getHiddenTranslateY(height, topOffset);
99
- const visibleTranslateY = topInset + TOAST_TOP_PADDING;
278
+ const nextHiddenTranslateY = getHiddenTranslateY(height, topOffset);
279
+ const nextVisibleTranslateY = topInset + TOAST_TOP_PADDING;
280
+ hiddenTranslateY.value = nextHiddenTranslateY;
281
+ visibleTranslateY.value = nextVisibleTranslateY;
100
282
  toastHeight.value = height;
101
- translateYProgress.value = hiddenTranslateY;
283
+ if (animationStartedRef.current) {
284
+ return;
285
+ }
286
+ animationStartedRef.current = true;
287
+ translateYProgress.value = nextHiddenTranslateY;
102
288
  if (toastOptions.hasNoTimeout) {
103
- translateYProgress.value = withSpring(visibleTranslateY, TOAST_SPRING_CONFIG);
289
+ translateYProgress.value = withSpring(nextVisibleTranslateY, TOAST_SPRING_CONFIG);
104
290
  }
105
291
  else {
106
- translateYProgress.value = withSpring(visibleTranslateY, TOAST_SPRING_CONFIG, () => {
107
- translateYProgress.value = withDelay(TOAST_VISIBILITY_DURATION, withSpring(hiddenTranslateY, TOAST_SPRING_CONFIG, () => {
108
- scheduleOnRN(resetState);
109
- }));
292
+ translateYProgress.value = withSpring(nextVisibleTranslateY, TOAST_SPRING_CONFIG, (finished) => {
293
+ if (finished) {
294
+ scheduleOnRN(beginAutoDismiss);
295
+ }
110
296
  });
111
297
  }
112
298
  };
113
- return (<Animated.View onLayout={onAnimatedViewLayout} style={baseStyle} {...props}>
114
- {actionButtonLabel && actionButtonOnPress ? (<Toast {...toastProps} actionButtonLabel={actionButtonLabel} actionButtonOnPress={actionButtonOnPress} onClose={() => {
299
+ return (<GestureDetector gesture={swipeGesture}>
300
+ <Animated.View onLayout={onAnimatedViewLayout} style={baseStyle} {...props}>
301
+ {actionButtonLabel && actionButtonOnPress ? (<Toast {...toastProps} actionButtonLabel={actionButtonLabel} actionButtonOnPress={actionButtonOnPress} onClose={() => {
115
302
  closeToast();
116
303
  toastOnClose?.();
117
304
  }} twClassName={toastTwClassNames}/>) : (<Toast {...restToastProps} onClose={() => {
118
305
  closeToast();
119
306
  toastOnClose?.();
120
307
  }} twClassName={toastTwClassNames}/>)}
121
- </Animated.View>);
308
+ </Animated.View>
309
+ </GestureDetector>);
122
310
  });
123
311
  ToasterComponent.displayName = 'Toaster';
124
312
  export const Toaster = ToasterComponent;
@@ -1 +1 @@
1
- {"version":3,"file":"Toaster.mjs","sourceRoot":"","sources":["../../../src/components/Toast/Toaster.tsx"],"names":[],"mappings":"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","sourcesContent":["// Third party dependencies.\nimport { useTailwind } from '@metamask/design-system-twrnc-preset';\nimport React, {\n forwardRef,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport type { RefObject } from 'react';\nimport { Dimensions } from 'react-native';\nimport type { LayoutChangeEvent, StyleProp, ViewStyle } from 'react-native';\nimport Animated, {\n cancelAnimation,\n useAnimatedStyle,\n useSharedValue,\n withDelay,\n withSpring,\n} from 'react-native-reanimated';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport { scheduleOnRN } from 'react-native-worklets';\n\n// Internal dependencies.\nimport { Toast } from './Toast';\nimport {\n TOAST_SPRING_CONFIG,\n TOAST_TOP_PADDING,\n TOAST_VISIBILITY_DURATION,\n} from './Toast.constants';\nimport type {\n ToastOptions,\n ToastProps,\n ToasterProps,\n ToasterRef,\n} from './Toast.types';\n\nconst screenHeight = Dimensions.get('window').height;\n\nlet registeredRef: RefObject<ToasterRef | null> | null = null;\n\nconst assertRegisteredRef = (method: 'dismiss' | 'toast'): ToasterRef => {\n if (!registeredRef?.current) {\n const invocation = method === 'toast' ? 'toast()' : `toast.${method}()`;\n throw new Error(\n `${invocation} called before <Toaster /> mounted. Render <Toaster /> once at the root of your app.`,\n );\n }\n return registeredRef.current;\n};\n\nconst getToastProps = ({\n hasNoTimeout: _hasNoTimeout,\n onClose: _onClose,\n topOffset: _topOffset,\n twClassName: _twClassName,\n ...toastProps\n}: ToastOptions): Omit<ToastProps, 'twClassName'> => toastProps;\n\nconst getHiddenTranslateY = (height: number, offset: number) =>\n -(height + offset);\n\nconst ToasterComponent = forwardRef<ToasterRef, ToasterProps>(\n ({ twClassName, ...props }, ref) => {\n const tw = useTailwind();\n const [toastOptions, setToastOptions] = useState<ToastOptions | undefined>(\n undefined,\n );\n const replacementTimerRef = useRef<ReturnType<typeof setTimeout> | null>(\n null,\n );\n const { top: topInset } = useSafeAreaInsets();\n const toastHeight = useSharedValue(screenHeight);\n const translateYProgress = useSharedValue(-screenHeight);\n const topOffset = toastOptions?.topOffset ?? 0;\n const animatedStyle = useAnimatedStyle(() => ({\n transform: [{ translateY: translateYProgress.value + topOffset }],\n }));\n const baseStyle = useMemo(\n () =>\n [\n tw.style('absolute left-4 right-4 top-0'),\n animatedStyle,\n ] as StyleProp<ViewStyle>,\n [tw, animatedStyle],\n );\n const innerRef = useRef<ToasterRef | null>(null);\n\n const resetState = () => setToastOptions(undefined);\n\n const showToast = (options: ToastOptions) => {\n let timeoutDuration = 0;\n const normalizedOptions = {\n hasNoTimeout: false,\n ...options,\n };\n if (toastOptions) {\n cancelAnimation(translateYProgress);\n timeoutDuration = 100;\n setToastOptions(undefined);\n }\n if (replacementTimerRef.current !== null) {\n clearTimeout(replacementTimerRef.current);\n }\n replacementTimerRef.current = setTimeout(() => {\n replacementTimerRef.current = null;\n setToastOptions(normalizedOptions);\n }, timeoutDuration);\n };\n\n const closeToast = () => {\n if (replacementTimerRef.current !== null) {\n clearTimeout(replacementTimerRef.current);\n replacementTimerRef.current = null;\n }\n translateYProgress.value = withSpring(\n getHiddenTranslateY(toastHeight.value, topOffset),\n TOAST_SPRING_CONFIG,\n () => {\n scheduleOnRN(resetState);\n },\n );\n };\n\n innerRef.current = {\n closeToast,\n showToast,\n };\n\n useImperativeHandle(ref, () => innerRef.current as ToasterRef);\n\n useLayoutEffect(() => {\n registeredRef = innerRef;\n return () => {\n if (registeredRef === innerRef) {\n registeredRef = null;\n }\n };\n }, []);\n\n if (!toastOptions) {\n return null;\n }\n\n const { onClose: toastOnClose, twClassName: toastTwClassName } =\n toastOptions;\n const toastProps = getToastProps(toastOptions);\n const { actionButtonLabel, actionButtonOnPress, ...restToastProps } =\n toastProps;\n const toastTwClassNames = [twClassName, toastTwClassName]\n .filter(Boolean)\n .join(' ');\n\n const onAnimatedViewLayout = (e: LayoutChangeEvent) => {\n const { height } = e.nativeEvent.layout;\n const hiddenTranslateY = getHiddenTranslateY(height, topOffset);\n const visibleTranslateY = topInset + TOAST_TOP_PADDING;\n\n toastHeight.value = height;\n translateYProgress.value = hiddenTranslateY;\n\n if (toastOptions.hasNoTimeout) {\n translateYProgress.value = withSpring(\n visibleTranslateY,\n TOAST_SPRING_CONFIG,\n );\n } else {\n translateYProgress.value = withSpring(\n visibleTranslateY,\n TOAST_SPRING_CONFIG,\n () => {\n translateYProgress.value = withDelay(\n TOAST_VISIBILITY_DURATION,\n withSpring(hiddenTranslateY, TOAST_SPRING_CONFIG, () => {\n scheduleOnRN(resetState);\n }),\n );\n },\n );\n }\n };\n\n return (\n <Animated.View\n onLayout={onAnimatedViewLayout}\n style={baseStyle}\n {...props}\n >\n {actionButtonLabel && actionButtonOnPress ? (\n <Toast\n {...toastProps}\n actionButtonLabel={actionButtonLabel}\n actionButtonOnPress={actionButtonOnPress}\n onClose={() => {\n closeToast();\n toastOnClose?.();\n }}\n twClassName={toastTwClassNames}\n />\n ) : (\n <Toast\n {...restToastProps}\n onClose={() => {\n closeToast();\n toastOnClose?.();\n }}\n twClassName={toastTwClassNames}\n />\n )}\n </Animated.View>\n );\n },\n);\n\nToasterComponent.displayName = 'Toaster';\n\ntype ToastFunction = ((options: ToastOptions) => void) & {\n dismiss: () => void;\n};\n\nexport const Toaster = ToasterComponent;\n\nexport const toast = ((options: ToastOptions) => {\n assertRegisteredRef('toast').showToast(options);\n}) as ToastFunction;\n\ntoast.dismiss = () => {\n assertRegisteredRef('dismiss').closeToast();\n};\n"]}
1
+ {"version":3,"file":"Toaster.mjs","sourceRoot":"","sources":["../../../src/components/Toast/Toaster.tsx"],"names":[],"mappings":"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","sourcesContent":["// Third party dependencies.\nimport { useTailwind } from '@metamask/design-system-twrnc-preset';\nimport React, {\n forwardRef,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport type { RefObject } from 'react';\nimport { Dimensions } from 'react-native';\nimport type { LayoutChangeEvent, StyleProp, ViewStyle } from 'react-native';\nimport { Gesture, GestureDetector } from 'react-native-gesture-handler';\nimport Animated, {\n cancelAnimation,\n useAnimatedStyle,\n useSharedValue,\n withSpring,\n} from 'react-native-reanimated';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport { scheduleOnRN } from 'react-native-worklets';\n\n// Internal dependencies.\nimport { Toast } from './Toast';\nimport {\n TOAST_DISMISS_DISTANCE_THRESHOLD,\n TOAST_DISMISS_MIN_DISTANCE,\n TOAST_DISMISS_VELOCITY_THRESHOLD,\n TOAST_SPRING_CONFIG,\n TOAST_SWIPE_ACTIVE_OFFSET_Y,\n TOAST_SWIPE_FAIL_OFFSET_X,\n TOAST_TOP_PADDING,\n TOAST_VISIBILITY_DURATION,\n} from './Toast.constants';\nimport type {\n ToastOptions,\n ToastProps,\n ToasterProps,\n ToasterRef,\n} from './Toast.types';\n\nconst screenHeight = Dimensions.get('window').height;\n\nlet registeredRef: RefObject<ToasterRef | null> | null = null;\n\nconst assertRegisteredRef = (method: 'dismiss' | 'toast'): ToasterRef => {\n if (!registeredRef?.current) {\n const invocation = method === 'toast' ? 'toast()' : `toast.${method}()`;\n throw new Error(\n `${invocation} called before <Toaster /> mounted. Render <Toaster /> once at the root of your app.`,\n );\n }\n return registeredRef.current;\n};\n\nconst getToastProps = ({\n hasNoTimeout: _hasNoTimeout,\n onClose: _onClose,\n topOffset: _topOffset,\n twClassName: _twClassName,\n ...toastProps\n}: ToastOptions): Omit<ToastProps, 'twClassName'> => toastProps;\n\nconst getHiddenTranslateY = (height: number, offset: number) =>\n -(height + offset);\n\nconst ToasterComponent = forwardRef<ToasterRef, ToasterProps>(\n ({ twClassName, ...props }, ref) => {\n const tw = useTailwind();\n const [toastOptions, setToastOptions] = useState<ToastOptions | undefined>(\n undefined,\n );\n const replacementTimerRef = useRef<ReturnType<typeof setTimeout> | null>(\n null,\n );\n const autoDismissTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(\n null,\n );\n const animationStartedRef = useRef(false);\n const visibleAtRef = useRef<number | null>(null);\n const hasNoTimeoutRef = useRef(false);\n // Invalidates queued spring-back resumes after replace/dismiss. A completed\n // spring cannot be cancelled, so scheduleOnRN(resume) can still run later.\n const toastGenerationRef = useRef(0);\n const { top: topInset } = useSafeAreaInsets();\n const toastHeight = useSharedValue(screenHeight);\n const hiddenTranslateY = useSharedValue(-screenHeight);\n const visibleTranslateY = useSharedValue(0);\n const gestureStartY = useSharedValue(0);\n const translateYProgress = useSharedValue(-screenHeight);\n const isDismissing = useSharedValue(false);\n // True after onStart until onEnd/onFinalize recovers. Used so a failed pan\n // (e.g. failOffsetX after activation) still springs back and resumes dismiss.\n const isSwipeActive = useSharedValue(false);\n const toastGeneration = useSharedValue(0);\n const topOffset = toastOptions?.topOffset ?? 0;\n hasNoTimeoutRef.current = Boolean(toastOptions?.hasNoTimeout);\n const animatedStyle = useAnimatedStyle(() => ({\n transform: [{ translateY: translateYProgress.value + topOffset }],\n }));\n const baseStyle = useMemo(\n () =>\n [\n tw.style('absolute left-4 right-4 top-0'),\n animatedStyle,\n ] as StyleProp<ViewStyle>,\n [tw, animatedStyle],\n );\n const innerRef = useRef<ToasterRef | null>(null);\n\n const clearScheduledAutoDismiss = () => {\n if (autoDismissTimeoutRef.current !== null) {\n clearTimeout(autoDismissTimeoutRef.current);\n autoDismissTimeoutRef.current = null;\n }\n };\n\n const bumpToastGeneration = () => {\n toastGenerationRef.current += 1;\n toastGeneration.value = toastGenerationRef.current;\n };\n\n const resetState = () => {\n animationStartedRef.current = false;\n visibleAtRef.current = null;\n isDismissing.value = false;\n isSwipeActive.value = false;\n clearScheduledAutoDismiss();\n setToastOptions(undefined);\n };\n\n const startDismissAnimation = () => {\n bumpToastGeneration();\n clearScheduledAutoDismiss();\n isDismissing.value = true;\n visibleAtRef.current = null;\n translateYProgress.value = withSpring(\n hiddenTranslateY.value,\n TOAST_SPRING_CONFIG,\n (finished) => {\n if (finished) {\n scheduleOnRN(resetState);\n }\n },\n );\n };\n\n const scheduleAutoDismiss = (delayMs: number) => {\n clearScheduledAutoDismiss();\n autoDismissTimeoutRef.current = setTimeout(() => {\n autoDismissTimeoutRef.current = null;\n startDismissAnimation();\n }, delayMs);\n };\n\n const beginAutoDismiss = () => {\n visibleAtRef.current = Date.now();\n scheduleAutoDismiss(TOAST_VISIBILITY_DURATION);\n };\n\n const resumeAutoDismissAfterSwipe = () => {\n if (hasNoTimeoutRef.current || isDismissing.value) {\n return;\n }\n\n // Entrance was interrupted before auto-dismiss started — start a full timer.\n if (visibleAtRef.current === null) {\n beginAutoDismiss();\n return;\n }\n\n const elapsed = Date.now() - visibleAtRef.current;\n if (elapsed >= TOAST_VISIBILITY_DURATION) {\n startDismissAnimation();\n return;\n }\n\n scheduleAutoDismiss(TOAST_VISIBILITY_DURATION - elapsed);\n };\n\n const showToast = (options: ToastOptions) => {\n bumpToastGeneration();\n let timeoutDuration = 0;\n const normalizedOptions = {\n hasNoTimeout: false,\n ...options,\n };\n if (toastOptions) {\n // Always clear any pending auto-dismiss from the previous toast, including\n // when the replacement is persistent (hasNoTimeout). Otherwise the old\n // timer can fire and dismiss the new toast.\n clearScheduledAutoDismiss();\n cancelAnimation(translateYProgress);\n timeoutDuration = 100;\n animationStartedRef.current = false;\n visibleAtRef.current = null;\n isDismissing.value = false;\n isSwipeActive.value = false;\n setToastOptions(undefined);\n }\n if (replacementTimerRef.current !== null) {\n clearTimeout(replacementTimerRef.current);\n }\n replacementTimerRef.current = setTimeout(() => {\n replacementTimerRef.current = null;\n setToastOptions(normalizedOptions);\n }, timeoutDuration);\n };\n\n const closeToast = () => {\n if (replacementTimerRef.current !== null) {\n clearTimeout(replacementTimerRef.current);\n replacementTimerRef.current = null;\n }\n startDismissAnimation();\n };\n\n const closeToastRef = useRef(closeToast);\n const resumeAutoDismissAfterSwipeRef = useRef(resumeAutoDismissAfterSwipe);\n const clearScheduledAutoDismissRef = useRef(clearScheduledAutoDismiss);\n closeToastRef.current = closeToast;\n resumeAutoDismissAfterSwipeRef.current = resumeAutoDismissAfterSwipe;\n clearScheduledAutoDismissRef.current = clearScheduledAutoDismiss;\n\n const dismissToastFromSwipe = () => {\n closeToastRef.current();\n };\n\n const resumeAutoDismissFromSwipe = (generation: number) => {\n // Ignore resumes from a toast that was replaced or dismissed after the\n // spring-back started (completed springs cannot be cancelled).\n if (generation !== toastGenerationRef.current) {\n return;\n }\n resumeAutoDismissAfterSwipeRef.current();\n };\n\n const clearScheduledAutoDismissFromSwipe = () => {\n clearScheduledAutoDismissRef.current();\n };\n\n const swipeGesture = useMemo(() => {\n // These gesture callbacks need explicit 'worklet' directives because this\n // package ships a pre-built dist compiled by ts-bridge (tsc), which emits the\n // gesture chain as a namespaced call (react_native_gesture_handler_1.Gesture).\n // The consumer's Reanimated/Worklets Babel plugin does run over dist, but its\n // gesture auto-detection doesn't recognize that compiled namespaced form.\n const springBackAfterSwipe = () => {\n 'worklet';\n\n const generationAtSpringStart = toastGeneration.value;\n translateYProgress.value = withSpring(\n visibleTranslateY.value,\n TOAST_SPRING_CONFIG,\n (finished) => {\n // A new pan cancels this spring via cancelAnimation; only resume\n // auto-dismiss when the spring-back completed naturally.\n if (finished) {\n scheduleOnRN(resumeAutoDismissFromSwipe, generationAtSpringStart);\n }\n },\n );\n };\n\n return Gesture.Pan()\n .activeOffsetY(TOAST_SWIPE_ACTIVE_OFFSET_Y)\n .failOffsetX([-TOAST_SWIPE_FAIL_OFFSET_X, TOAST_SWIPE_FAIL_OFFSET_X])\n .onStart(() => {\n 'worklet';\n\n // Don't interrupt an in-progress dismiss animation.\n if (isDismissing.value) {\n return;\n }\n isSwipeActive.value = true;\n scheduleOnRN(clearScheduledAutoDismissFromSwipe);\n cancelAnimation(translateYProgress);\n gestureStartY.value = translateYProgress.value;\n })\n .onUpdate((event) => {\n 'worklet';\n\n if (isDismissing.value || !isSwipeActive.value) {\n return;\n }\n const nextTranslateY = gestureStartY.value + event.translationY;\n // Toast sits at the top; only allow dragging upward (more negative).\n translateYProgress.value = Math.min(\n nextTranslateY,\n visibleTranslateY.value,\n );\n })\n .onEnd((event) => {\n 'worklet';\n\n if (!isSwipeActive.value) {\n return;\n }\n isSwipeActive.value = false;\n\n if (isDismissing.value) {\n return;\n }\n const { translationY, velocityY } = event;\n const dismissDistance = Math.max(\n toastHeight.value * TOAST_DISMISS_DISTANCE_THRESHOLD,\n TOAST_DISMISS_MIN_DISTANCE,\n );\n const hasReachedDismissOffset = translationY <= -dismissDistance;\n const hasReachedSwipeThreshold =\n Math.abs(velocityY) > TOAST_DISMISS_VELOCITY_THRESHOLD;\n const isQuickDismissing = velocityY < 0;\n\n const shouldDismiss =\n hasReachedDismissOffset ||\n (hasReachedSwipeThreshold && isQuickDismissing);\n\n if (shouldDismiss) {\n scheduleOnRN(dismissToastFromSwipe);\n return;\n }\n\n springBackAfterSwipe();\n })\n .onFinalize(() => {\n 'worklet';\n\n // onEnd is skipped when the pan fails/cancels after activation\n // (e.g. horizontal travel past failOffsetX). Recover position and\n // auto-dismiss so the toast is not left stuck mid-offset.\n if (!isSwipeActive.value) {\n return;\n }\n // Clear before the dismiss check — same order as onEnd — so a pan\n // cancelled mid-dismiss cannot leave isSwipeActive stuck true for a\n // later toast (resetState alone is not enough if finalize races it).\n isSwipeActive.value = false;\n\n if (isDismissing.value) {\n return;\n }\n springBackAfterSwipe();\n });\n // Shared values and swipe JS wrappers are stable for the component lifetime.\n }, []);\n\n innerRef.current = {\n closeToast,\n showToast,\n };\n\n useImperativeHandle(ref, () => innerRef.current as ToasterRef);\n\n useLayoutEffect(() => {\n registeredRef = innerRef;\n return () => {\n if (registeredRef === innerRef) {\n registeredRef = null;\n }\n };\n }, []);\n\n if (!toastOptions) {\n return null;\n }\n\n const { onClose: toastOnClose, twClassName: toastTwClassName } =\n toastOptions;\n const toastProps = getToastProps(toastOptions);\n const { actionButtonLabel, actionButtonOnPress, ...restToastProps } =\n toastProps;\n const toastTwClassNames = [twClassName, toastTwClassName]\n .filter(Boolean)\n .join(' ');\n\n const onAnimatedViewLayout = (e: LayoutChangeEvent) => {\n const { height } = e.nativeEvent.layout;\n const nextHiddenTranslateY = getHiddenTranslateY(height, topOffset);\n const nextVisibleTranslateY = topInset + TOAST_TOP_PADDING;\n\n hiddenTranslateY.value = nextHiddenTranslateY;\n visibleTranslateY.value = nextVisibleTranslateY;\n toastHeight.value = height;\n\n if (animationStartedRef.current) {\n return;\n }\n\n animationStartedRef.current = true;\n translateYProgress.value = nextHiddenTranslateY;\n\n if (toastOptions.hasNoTimeout) {\n translateYProgress.value = withSpring(\n nextVisibleTranslateY,\n TOAST_SPRING_CONFIG,\n );\n } else {\n translateYProgress.value = withSpring(\n nextVisibleTranslateY,\n TOAST_SPRING_CONFIG,\n (finished) => {\n if (finished) {\n scheduleOnRN(beginAutoDismiss);\n }\n },\n );\n }\n };\n\n return (\n <GestureDetector gesture={swipeGesture}>\n <Animated.View\n onLayout={onAnimatedViewLayout}\n style={baseStyle}\n {...props}\n >\n {actionButtonLabel && actionButtonOnPress ? (\n <Toast\n {...toastProps}\n actionButtonLabel={actionButtonLabel}\n actionButtonOnPress={actionButtonOnPress}\n onClose={() => {\n closeToast();\n toastOnClose?.();\n }}\n twClassName={toastTwClassNames}\n />\n ) : (\n <Toast\n {...restToastProps}\n onClose={() => {\n closeToast();\n toastOnClose?.();\n }}\n twClassName={toastTwClassNames}\n />\n )}\n </Animated.View>\n </GestureDetector>\n );\n },\n);\n\nToasterComponent.displayName = 'Toaster';\n\ntype ToastFunction = ((options: ToastOptions) => void) & {\n dismiss: () => void;\n};\n\nexport const Toaster = ToasterComponent;\n\nexport const toast = ((options: ToastOptions) => {\n assertRegisteredRef('toast').showToast(options);\n}) as ToastFunction;\n\ntoast.dismiss = () => {\n assertRegisteredRef('dismiss').closeToast();\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask/design-system-react-native",
3
- "version": "0.38.1",
3
+ "version": "0.39.1",
4
4
  "description": "Design System React Native",
5
5
  "keywords": [
6
6
  "MetaMask",
@@ -47,7 +47,7 @@
47
47
  "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch"
48
48
  },
49
49
  "dependencies": {
50
- "@metamask/design-system-shared": "^0.31.0",
50
+ "@metamask/design-system-shared": "^0.32.0",
51
51
  "react-native-jazzicon": "^0.1.2"
52
52
  },
53
53
  "devDependencies": {