@reown/appkit-ui-react-native 0.0.0-chore-solflare-20250730210452 → 0.0.0-chore-spring-effect-20250909214820

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/lib/commonjs/assets/svg/Reown.js +47 -0
  2. package/lib/commonjs/assets/svg/Reown.js.map +1 -0
  3. package/lib/commonjs/components/wui-card/index.js +1 -3
  4. package/lib/commonjs/components/wui-card/index.js.map +1 -1
  5. package/lib/commonjs/components/wui-card/styles.js +1 -1
  6. package/lib/commonjs/components/wui-card/styles.js.map +1 -1
  7. package/lib/commonjs/components/wui-icon/index.js +2 -0
  8. package/lib/commonjs/components/wui-icon/index.js.map +1 -1
  9. package/lib/commonjs/components/wui-modal/index.js +32 -35
  10. package/lib/commonjs/components/wui-modal/index.js.map +1 -1
  11. package/lib/commonjs/components/wui-modal/styles.js +7 -9
  12. package/lib/commonjs/components/wui-modal/styles.js.map +1 -1
  13. package/lib/commonjs/components/wui-shimmer/index.js +92 -32
  14. package/lib/commonjs/components/wui-shimmer/index.js.map +1 -1
  15. package/lib/commonjs/composites/wui-account-button/index.js +2 -2
  16. package/lib/commonjs/composites/wui-account-button/index.js.map +1 -1
  17. package/lib/commonjs/composites/wui-button/index.js +5 -5
  18. package/lib/commonjs/composites/wui-button/index.js.map +1 -1
  19. package/lib/commonjs/composites/wui-card-select/index.js +46 -44
  20. package/lib/commonjs/composites/wui-card-select/index.js.map +1 -1
  21. package/lib/commonjs/composites/wui-card-select-loader/index.js +7 -3
  22. package/lib/commonjs/composites/wui-card-select-loader/index.js.map +1 -1
  23. package/lib/commonjs/composites/wui-chip/index.js +5 -5
  24. package/lib/commonjs/composites/wui-chip/index.js.map +1 -1
  25. package/lib/commonjs/composites/wui-email-input/index.js +3 -3
  26. package/lib/commonjs/composites/wui-email-input/index.js.map +1 -1
  27. package/lib/commonjs/composites/wui-input-text/index.js +2 -2
  28. package/lib/commonjs/composites/wui-input-text/index.js.map +1 -1
  29. package/lib/commonjs/composites/wui-link/index.js +4 -4
  30. package/lib/commonjs/composites/wui-link/index.js.map +1 -1
  31. package/lib/commonjs/composites/wui-list-transaction/index.js +2 -2
  32. package/lib/commonjs/composites/wui-list-transaction/index.js.map +1 -1
  33. package/lib/commonjs/composites/wui-logo-select/index.js +1 -1
  34. package/lib/commonjs/composites/wui-logo-select/index.js.map +1 -1
  35. package/lib/commonjs/composites/wui-otp/index.js +1 -1
  36. package/lib/commonjs/composites/wui-otp/index.js.map +1 -1
  37. package/lib/commonjs/composites/wui-qr-code/index.js +7 -25
  38. package/lib/commonjs/composites/wui-qr-code/index.js.map +1 -1
  39. package/lib/commonjs/composites/wui-qr-code/styles.js +0 -3
  40. package/lib/commonjs/composites/wui-qr-code/styles.js.map +1 -1
  41. package/lib/commonjs/composites/wui-search-bar/index.js +2 -2
  42. package/lib/commonjs/composites/wui-search-bar/index.js.map +1 -1
  43. package/lib/commonjs/composites/wui-tabs/index.js +2 -2
  44. package/lib/commonjs/composites/wui-tabs/index.js.map +1 -1
  45. package/lib/commonjs/composites/wui-toggle/index.js +2 -2
  46. package/lib/commonjs/composites/wui-toggle/index.js.map +1 -1
  47. package/lib/commonjs/composites/wui-token-button/index.js +5 -5
  48. package/lib/commonjs/composites/wui-token-button/index.js.map +1 -1
  49. package/lib/commonjs/composites/wui-transaction-visual/index.js +3 -3
  50. package/lib/commonjs/composites/wui-transaction-visual/index.js.map +1 -1
  51. package/lib/commonjs/composites/wui-wallet-image/index.js +2 -2
  52. package/lib/commonjs/composites/wui-wallet-image/index.js.map +1 -1
  53. package/lib/commonjs/hooks/useCustomDimensions.js +42 -0
  54. package/lib/commonjs/hooks/useCustomDimensions.js.map +1 -0
  55. package/lib/commonjs/index.js +7 -0
  56. package/lib/commonjs/index.js.map +1 -1
  57. package/lib/commonjs/layout/wui-flex/index.js +3 -0
  58. package/lib/commonjs/layout/wui-flex/index.js.map +1 -1
  59. package/lib/commonjs/utils/QRCodeUtil.js +2 -2
  60. package/lib/commonjs/utils/QRCodeUtil.js.map +1 -1
  61. package/lib/commonjs/utils/UiUtil.js +1 -1
  62. package/lib/commonjs/utils/UiUtil.js.map +1 -1
  63. package/lib/module/assets/svg/Reown.js +42 -0
  64. package/lib/module/assets/svg/Reown.js.map +1 -0
  65. package/lib/module/components/wui-card/index.js +2 -4
  66. package/lib/module/components/wui-card/index.js.map +1 -1
  67. package/lib/module/components/wui-card/styles.js +1 -1
  68. package/lib/module/components/wui-card/styles.js.map +1 -1
  69. package/lib/module/components/wui-icon/index.js +2 -0
  70. package/lib/module/components/wui-icon/index.js.map +1 -1
  71. package/lib/module/components/wui-modal/index.js +34 -37
  72. package/lib/module/components/wui-modal/index.js.map +1 -1
  73. package/lib/module/components/wui-modal/styles.js +7 -9
  74. package/lib/module/components/wui-modal/styles.js.map +1 -1
  75. package/lib/module/components/wui-shimmer/index.js +93 -32
  76. package/lib/module/components/wui-shimmer/index.js.map +1 -1
  77. package/lib/module/composites/wui-account-button/index.js +2 -2
  78. package/lib/module/composites/wui-account-button/index.js.map +1 -1
  79. package/lib/module/composites/wui-button/index.js +5 -5
  80. package/lib/module/composites/wui-button/index.js.map +1 -1
  81. package/lib/module/composites/wui-card-select/index.js +47 -45
  82. package/lib/module/composites/wui-card-select/index.js.map +1 -1
  83. package/lib/module/composites/wui-card-select-loader/index.js +5 -1
  84. package/lib/module/composites/wui-card-select-loader/index.js.map +1 -1
  85. package/lib/module/composites/wui-chip/index.js +5 -5
  86. package/lib/module/composites/wui-chip/index.js.map +1 -1
  87. package/lib/module/composites/wui-email-input/index.js +3 -3
  88. package/lib/module/composites/wui-email-input/index.js.map +1 -1
  89. package/lib/module/composites/wui-input-text/index.js +2 -2
  90. package/lib/module/composites/wui-input-text/index.js.map +1 -1
  91. package/lib/module/composites/wui-link/index.js +4 -4
  92. package/lib/module/composites/wui-link/index.js.map +1 -1
  93. package/lib/module/composites/wui-list-transaction/index.js +2 -2
  94. package/lib/module/composites/wui-list-transaction/index.js.map +1 -1
  95. package/lib/module/composites/wui-logo-select/index.js +1 -1
  96. package/lib/module/composites/wui-logo-select/index.js.map +1 -1
  97. package/lib/module/composites/wui-otp/index.js +1 -1
  98. package/lib/module/composites/wui-otp/index.js.map +1 -1
  99. package/lib/module/composites/wui-qr-code/index.js +7 -25
  100. package/lib/module/composites/wui-qr-code/index.js.map +1 -1
  101. package/lib/module/composites/wui-qr-code/styles.js +0 -3
  102. package/lib/module/composites/wui-qr-code/styles.js.map +1 -1
  103. package/lib/module/composites/wui-search-bar/index.js +2 -2
  104. package/lib/module/composites/wui-search-bar/index.js.map +1 -1
  105. package/lib/module/composites/wui-tabs/index.js +2 -2
  106. package/lib/module/composites/wui-tabs/index.js.map +1 -1
  107. package/lib/module/composites/wui-toggle/index.js +2 -2
  108. package/lib/module/composites/wui-toggle/index.js.map +1 -1
  109. package/lib/module/composites/wui-token-button/index.js +5 -5
  110. package/lib/module/composites/wui-token-button/index.js.map +1 -1
  111. package/lib/module/composites/wui-transaction-visual/index.js +3 -3
  112. package/lib/module/composites/wui-transaction-visual/index.js.map +1 -1
  113. package/lib/module/composites/wui-wallet-image/index.js +2 -2
  114. package/lib/module/composites/wui-wallet-image/index.js.map +1 -1
  115. package/lib/module/hooks/useCustomDimensions.js +39 -0
  116. package/lib/module/hooks/useCustomDimensions.js.map +1 -0
  117. package/lib/module/index.js +10 -0
  118. package/lib/module/index.js.map +1 -1
  119. package/lib/module/layout/wui-flex/index.js +3 -0
  120. package/lib/module/layout/wui-flex/index.js.map +1 -1
  121. package/lib/module/utils/QRCodeUtil.js +3 -3
  122. package/lib/module/utils/QRCodeUtil.js.map +1 -1
  123. package/lib/module/utils/UiUtil.js +1 -1
  124. package/lib/module/utils/UiUtil.js.map +1 -1
  125. package/lib/typescript/assets/svg/Reown.d.ts +4 -0
  126. package/lib/typescript/assets/svg/Reown.d.ts.map +1 -0
  127. package/lib/typescript/components/wui-card/index.d.ts.map +1 -1
  128. package/lib/typescript/components/wui-icon/index.d.ts.map +1 -1
  129. package/lib/typescript/components/wui-modal/index.d.ts.map +1 -1
  130. package/lib/typescript/components/wui-modal/styles.d.ts +7 -9
  131. package/lib/typescript/components/wui-modal/styles.d.ts.map +1 -1
  132. package/lib/typescript/components/wui-shimmer/index.d.ts +11 -3
  133. package/lib/typescript/components/wui-shimmer/index.d.ts.map +1 -1
  134. package/lib/typescript/composites/wui-card-select/index.d.ts +2 -2
  135. package/lib/typescript/composites/wui-card-select/index.d.ts.map +1 -1
  136. package/lib/typescript/composites/wui-card-select-loader/index.d.ts +3 -1
  137. package/lib/typescript/composites/wui-card-select-loader/index.d.ts.map +1 -1
  138. package/lib/typescript/composites/wui-qr-code/index.d.ts.map +1 -1
  139. package/lib/typescript/composites/wui-qr-code/styles.d.ts +0 -3
  140. package/lib/typescript/composites/wui-qr-code/styles.d.ts.map +1 -1
  141. package/lib/typescript/composites/wui-token-button/index.d.ts.map +1 -1
  142. package/lib/typescript/hooks/useCustomDimensions.d.ts +13 -0
  143. package/lib/typescript/hooks/useCustomDimensions.d.ts.map +1 -0
  144. package/lib/typescript/index.d.ts +6 -0
  145. package/lib/typescript/index.d.ts.map +1 -1
  146. package/lib/typescript/layout/wui-flex/index.d.ts +3 -0
  147. package/lib/typescript/layout/wui-flex/index.d.ts.map +1 -1
  148. package/lib/typescript/utils/TypesUtil.d.ts +1 -1
  149. package/lib/typescript/utils/TypesUtil.d.ts.map +1 -1
  150. package/lib/typescript/utils/UiUtil.d.ts +1 -1
  151. package/lib/typescript/utils/UiUtil.d.ts.map +1 -1
  152. package/package.json +2 -2
  153. package/src/assets/svg/Reown.tsx +40 -0
  154. package/src/components/wui-card/index.tsx +3 -5
  155. package/src/components/wui-card/styles.ts +1 -1
  156. package/src/components/wui-icon/index.tsx +2 -0
  157. package/src/components/wui-modal/index.tsx +32 -38
  158. package/src/components/wui-modal/styles.ts +7 -9
  159. package/src/components/wui-shimmer/index.tsx +105 -39
  160. package/src/composites/wui-account-button/index.tsx +2 -2
  161. package/src/composites/wui-button/index.tsx +5 -5
  162. package/src/composites/wui-card-select/index.tsx +48 -48
  163. package/src/composites/wui-card-select-loader/index.tsx +5 -1
  164. package/src/composites/wui-chip/index.tsx +5 -5
  165. package/src/composites/wui-email-input/index.tsx +3 -3
  166. package/src/composites/wui-input-text/index.tsx +1 -1
  167. package/src/composites/wui-link/index.tsx +4 -4
  168. package/src/composites/wui-list-transaction/index.tsx +2 -2
  169. package/src/composites/wui-logo-select/index.tsx +1 -1
  170. package/src/composites/wui-otp/index.tsx +1 -1
  171. package/src/composites/wui-qr-code/index.tsx +6 -18
  172. package/src/composites/wui-qr-code/styles.ts +0 -3
  173. package/src/composites/wui-search-bar/index.tsx +2 -2
  174. package/src/composites/wui-tabs/index.tsx +2 -2
  175. package/src/composites/wui-toggle/index.tsx +2 -2
  176. package/src/composites/wui-token-button/index.tsx +5 -3
  177. package/src/composites/wui-transaction-visual/index.tsx +4 -4
  178. package/src/composites/wui-wallet-image/index.tsx +2 -2
  179. package/src/hooks/useCustomDimensions.ts +41 -0
  180. package/src/index.ts +7 -0
  181. package/src/layout/wui-flex/index.tsx +6 -0
  182. package/src/utils/QRCodeUtil.tsx +3 -3
  183. package/src/utils/TypesUtil.ts +1 -0
  184. package/src/utils/UiUtil.ts +2 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reown/appkit-ui-react-native",
3
- "version": "0.0.0-chore-solflare-20250730210452",
3
+ "version": "0.0.0-chore-spring-effect-20250909214820",
4
4
  "main": "lib/commonjs/index.js",
5
5
  "types": "lib/typescript/index.d.ts",
6
6
  "module": "lib/module/index.js",
@@ -39,7 +39,7 @@
39
39
  "access": "public"
40
40
  },
41
41
  "dependencies": {
42
- "@reown/appkit-common-react-native": "0.0.0-chore-solflare-20250730210452",
42
+ "@reown/appkit-common-react-native": "0.0.0-chore-spring-effect-20250909214820",
43
43
  "polished": "4.3.1",
44
44
  "qrcode": "1.5.3"
45
45
  },
@@ -0,0 +1,40 @@
1
+ import Svg, { Path, type SvgProps } from 'react-native-svg';
2
+ const SvgReown = (props: SvgProps) => (
3
+ <Svg viewBox="0 0 60 16" fill="none" {...props}>
4
+ <Path
5
+ d="M9.3335 4.66667C9.3335 2.08934 11.4229 0 14.0002 0H20.6669C23.2442 0 25.3335 2.08934 25.3335 4.66667V11.3333C25.3335 13.9106 23.2442 16 20.6669 16H14.0002C11.4229 16 9.3335 13.9106 9.3335 11.3333V4.66667Z"
6
+ fill="#363636"
7
+ />
8
+ <Path d="M15.6055 11.0003L17.9448 4.66699H18.6316L16.2923 11.0003H15.6055Z" fill="#F6F6F6" />
9
+ <Path
10
+ d="M0 4.33333C0 1.9401 1.9401 0 4.33333 0C6.72657 0 8.66669 1.9401 8.66669 4.33333V11.6667C8.66669 14.0599 6.72657 16 4.33333 16C1.9401 16 0 14.0599 0 11.6667V4.33333Z"
11
+ fill="#363636"
12
+ />
13
+ <Path d="M3.9165 9.99934V9.16602H4.74983V9.99934H3.9165Z" fill="#F6F6F6" />
14
+ <Path
15
+ d="M26 8C26 3.58172 29.3517 0 33.4863 0H52.5137C56.6483 0 60 3.58172 60 8C60 12.4183 56.6483 16 52.5137 16H33.4863C29.3517 16 26 12.4183 26 8Z"
16
+ fill="#363636"
17
+ />
18
+ <Path
19
+ d="M49.3687 9.95834V6.26232H50.0213V6.81966C50.256 6.40899 50.7326 6.16699 51.2606 6.16699C52.0599 6.16699 52.6173 6.67299 52.6173 7.65566V9.95834H51.972V7.69234C51.972 7.04696 51.6053 6.70966 51.07 6.70966C50.4906 6.70966 50.0213 7.17168 50.0213 7.82433V9.95834H49.3687Z"
20
+ fill="#F6F6F6"
21
+ />
22
+ <Path
23
+ d="M45.2538 9.95773L44.5718 6.26172H45.1877L45.6717 9.31242L46.3098 7.30306H46.9184L47.5491 9.29041L48.0404 6.26172H48.6564L47.9744 9.95773H47.2411L46.6178 8.03641L45.9871 9.95773H45.2538Z"
24
+ fill="#F6F6F6"
25
+ />
26
+ <Path
27
+ d="M42.3709 10.0536C41.2489 10.0536 40.5889 9.21765 40.5889 8.1103C40.5889 7.01035 41.2489 6.16699 42.3709 6.16699C43.4929 6.16699 44.1529 7.01035 44.1529 8.1103C44.1529 9.21765 43.4929 10.0536 42.3709 10.0536ZM42.3709 9.51096C43.1775 9.51096 43.4856 8.82164 43.4856 8.10296C43.4856 7.39163 43.1775 6.70966 42.3709 6.70966C41.5642 6.70966 41.2562 7.39163 41.2562 8.10296C41.2562 8.82164 41.5642 9.51096 42.3709 9.51096Z"
28
+ fill="#F6F6F6"
29
+ />
30
+ <Path
31
+ d="M38.2805 10.0536C37.1952 10.0536 36.5132 9.22499 36.5132 8.1103C36.5132 7.00302 37.1952 6.16699 38.2805 6.16699C39.1972 6.16699 40.0038 6.68766 39.9159 8.27896H37.1805C37.2319 8.96103 37.5472 9.5183 38.2805 9.5183C38.7718 9.5183 39.0945 9.21765 39.2045 8.87299H39.8499C39.7472 9.48903 39.1679 10.0536 38.2805 10.0536ZM37.1952 7.78765H39.2852C39.2338 7.04696 38.8892 6.70232 38.2805 6.70232C37.6132 6.70232 37.2832 7.18635 37.1952 7.78765Z"
32
+ fill="#F6F6F6"
33
+ />
34
+ <Path
35
+ d="M33.3828 9.95773V6.26172H34.0501V6.88506C34.2848 6.47439 34.6882 6.26172 35.1061 6.26172H35.9935V6.88506H35.0548C34.4682 6.88506 34.0501 7.26638 34.0501 8.00706V9.95773H33.3828Z"
36
+ fill="#F6F6F6"
37
+ />
38
+ </Svg>
39
+ );
40
+ export default SvgReown;
@@ -1,5 +1,5 @@
1
1
  import type { ReactNode } from 'react';
2
- import { type StyleProp, type ViewStyle, KeyboardAvoidingView, Platform } from 'react-native';
2
+ import { type StyleProp, type ViewStyle, View } from 'react-native';
3
3
 
4
4
  import { useTheme } from '../../hooks/useTheme';
5
5
  import styles from './styles';
@@ -13,9 +13,7 @@ export function Card({ children, style }: CardProps) {
13
13
  const Theme = useTheme();
14
14
 
15
15
  return (
16
- <KeyboardAvoidingView
17
- behavior="padding"
18
- enabled={Platform.OS === 'ios'}
16
+ <View
19
17
  style={[
20
18
  styles.container,
21
19
  { backgroundColor: Theme['bg-100'], borderColor: Theme['gray-glass-015'] },
@@ -23,6 +21,6 @@ export function Card({ children, style }: CardProps) {
23
21
  ]}
24
22
  >
25
23
  {children}
26
- </KeyboardAvoidingView>
24
+ </View>
27
25
  );
28
26
  }
@@ -4,7 +4,7 @@ import { BorderRadius } from '../../utils/ThemeUtil';
4
4
  export default StyleSheet.create({
5
5
  container: {
6
6
  borderRadius: BorderRadius.l,
7
- borderWidth: StyleSheet.hairlineWidth,
7
+ borderWidth: 0.5,
8
8
  borderBottomWidth: 0,
9
9
  overflow: 'hidden'
10
10
  }
@@ -49,6 +49,7 @@ import PaperplaneSvg from '../../assets/svg/Paperplane';
49
49
  import QrCodeSvg from '../../assets/svg/QrCode';
50
50
  import RecycleHorizontalSvg from '../../assets/svg/RecycleHorizontal';
51
51
  import RefreshSvg from '../../assets/svg/Refresh';
52
+ import ReownSvg from '../../assets/svg/Reown';
52
53
  import SearchSvg from '../../assets/svg/Search';
53
54
  import SettingsSvg from '../../assets/svg/Settings';
54
55
  import SwapHorizontalSvg from '../../assets/svg/SwapHorizontal';
@@ -113,6 +114,7 @@ const svgOptions: Record<IconType, (props: SvgProps) => JSX.Element> = {
113
114
  qrCode: QrCodeSvg,
114
115
  recycleHorizontal: RecycleHorizontalSvg,
115
116
  refresh: RefreshSvg,
117
+ reown: ReownSvg,
116
118
  search: SearchSvg,
117
119
  settings: SettingsSvg,
118
120
  swapHorizontal: SwapHorizontalSvg,
@@ -3,8 +3,9 @@ import {
3
3
  useWindowDimensions,
4
4
  Modal as RNModal,
5
5
  type ModalProps as RNModalProps,
6
- TouchableOpacity,
7
- Animated
6
+ Animated,
7
+ Pressable,
8
+ View
8
9
  } from 'react-native';
9
10
  import { useTheme } from '../../hooks/useTheme';
10
11
  import styles from './styles';
@@ -17,10 +18,11 @@ export type ModalProps = Pick<
17
18
  onBackdropPress?: () => void;
18
19
  };
19
20
 
21
+ const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
22
+
20
23
  export function Modal({ visible, onBackdropPress, onRequestClose, testID, children }: ModalProps) {
21
- const Theme = useTheme();
22
24
  const { height } = useWindowDimensions();
23
-
25
+ const Theme = useTheme();
24
26
  const backdropOpacity = useRef(new Animated.Value(0)).current;
25
27
  const translateY = useRef(new Animated.Value(height)).current;
26
28
  const [showBackdrop, setShowBackdrop] = useState(false);
@@ -29,7 +31,8 @@ export function Modal({ visible, onBackdropPress, onRequestClose, testID, childr
29
31
 
30
32
  const onContentLayout = (event: any) => {
31
33
  const { height: measuredHeight } = event.nativeEvent.layout;
32
- setContentHeight(measuredHeight);
34
+
35
+ setContentHeight(measuredHeight > height ? height : measuredHeight);
33
36
  };
34
37
 
35
38
  // Handle modal visibility
@@ -77,19 +80,17 @@ export function Modal({ visible, onBackdropPress, onRequestClose, testID, childr
77
80
 
78
81
  modalAnimation = Animated.spring(translateY, {
79
82
  toValue: targetY,
80
- damping: 25,
81
- stiffness: 220,
83
+ damping: 50,
84
+ stiffness: 300,
82
85
  mass: 1,
83
86
  useNativeDriver: true
84
87
  });
85
88
  modalAnimation.start();
86
89
  } else if (!visible && modalVisible) {
87
- // Hide modal to the bottom of the screen
88
- modalAnimation = Animated.spring(translateY, {
90
+ // Hide modal to the bottom of the screen. Not using spring as it blocks the UI for a bit when closed
91
+ modalAnimation = Animated.timing(translateY, {
89
92
  toValue: height,
90
- damping: 23,
91
- stiffness: 260,
92
- mass: 1,
93
+ duration: 150,
93
94
  useNativeDriver: true
94
95
  });
95
96
  modalAnimation.start(() => {
@@ -111,31 +112,24 @@ export function Modal({ visible, onBackdropPress, onRequestClose, testID, childr
111
112
  }, [modalVisible, translateY, backdropOpacity, height]);
112
113
 
113
114
  return (
114
- <>
115
- {showBackdrop && (
116
- <Animated.View style={[styles.outerBackdrop, { opacity: backdropOpacity }]} />
117
- )}
118
- <RNModal
119
- visible={modalVisible}
120
- transparent
121
- animationType="none"
122
- statusBarTranslucent
123
- onRequestClose={onRequestClose}
124
- testID={testID}
125
- >
126
- {showBackdrop && (
127
- <TouchableOpacity
128
- style={styles.innerBackdropTouchable}
129
- activeOpacity={1}
130
- onPress={onBackdropPress}
131
- />
132
- )}
133
- <Animated.View
134
- style={[styles.modal, { backgroundColor: Theme['bg-100'], transform: [{ translateY }] }]}
135
- >
136
- <Animated.View onLayout={onContentLayout}>{children}</Animated.View>
137
- </Animated.View>
138
- </RNModal>
139
- </>
115
+ <RNModal
116
+ visible={modalVisible}
117
+ transparent
118
+ animationType="none"
119
+ statusBarTranslucent
120
+ onRequestClose={onRequestClose}
121
+ testID={testID}
122
+ >
123
+ {showBackdrop ? (
124
+ <AnimatedPressable
125
+ style={[styles.backdrop, { opacity: backdropOpacity }]}
126
+ onPress={onBackdropPress}
127
+ />
128
+ ) : null}
129
+ <Animated.View style={[styles.modal, { transform: [{ translateY }] }]}>
130
+ <Animated.View onLayout={onContentLayout}>{children}</Animated.View>
131
+ <View style={[styles.bottomBackground, { backgroundColor: Theme['bg-100'] }]} />
132
+ </Animated.View>
133
+ </RNModal>
140
134
  );
141
135
  }
@@ -2,18 +2,13 @@ import { StyleSheet } from 'react-native';
2
2
  import { BorderRadius } from '../../utils/ThemeUtil';
3
3
 
4
4
  export default StyleSheet.create({
5
- outerBackdrop: {
6
- position: 'absolute',
7
- top: 0,
8
- left: 0,
9
- right: 0,
10
- bottom: 0,
5
+ backdrop: {
6
+ flexGrow: 1,
11
7
  backgroundColor: 'rgba(0, 0, 0, 0.5)'
12
8
  },
13
- innerBackdropTouchable: {
14
- flexGrow: 1
15
- },
16
9
  modal: {
10
+ backgroundColor: 'transparent',
11
+ borderWidth: 0,
17
12
  borderTopLeftRadius: BorderRadius.l,
18
13
  borderTopRightRadius: BorderRadius.l,
19
14
  position: 'absolute',
@@ -21,5 +16,8 @@ export default StyleSheet.create({
21
16
  left: 0,
22
17
  right: 0,
23
18
  bottom: 0
19
+ },
20
+ bottomBackground: {
21
+ flexGrow: 1
24
22
  }
25
23
  });
@@ -1,66 +1,132 @@
1
- import { Svg, Rect } from 'react-native-svg';
2
- import { Animated, StyleSheet, type StyleProp, type ViewStyle } from 'react-native';
1
+ import { Animated, StyleSheet, View, type StyleProp, type ViewStyle } from 'react-native';
2
+ import { memo, useEffect, useRef, useState } from 'react';
3
3
  import { useTheme } from '../../hooks/useTheme';
4
4
 
5
- const AnimatedRect = Animated.createAnimatedComponent(Rect);
5
+ type PercentString = `${number}%`;
6
+ type ShimmerDimension = number | PercentString;
6
7
 
7
8
  export interface ShimmerProps {
8
- width?: number | string;
9
- height?: number | string;
9
+ width?: ShimmerDimension;
10
+ height?: ShimmerDimension;
10
11
  duration?: number;
11
12
  borderRadius?: number;
12
13
  backgroundColor?: string;
13
14
  foregroundColor?: string;
15
+ highlightWidthRatio?: number;
16
+ highlightOpacity?: number;
17
+ angle?: number; // in degrees
14
18
  style?: StyleProp<ViewStyle>;
15
19
  }
16
20
 
17
- export const Shimmer = ({
21
+ function Shimmer_({
18
22
  width = 200,
19
23
  height = 200,
20
24
  duration = 1000,
21
25
  borderRadius = 0,
22
26
  backgroundColor,
23
27
  foregroundColor,
28
+ highlightWidthRatio = 0.3,
29
+ highlightOpacity = 0.5,
30
+ angle = 20,
24
31
  style
25
- }: ShimmerProps) => {
26
- const animatedValue = new Animated.Value(0);
32
+ }: ShimmerProps) {
27
33
  const Theme = useTheme();
28
34
 
29
- const animatedProps = {
30
- fill: animatedValue.interpolate({
31
- inputRange: [0, 0.5, 1],
32
- outputRange: [
33
- backgroundColor ?? Theme['bg-200'],
34
- foregroundColor ?? Theme['bg-300'],
35
- backgroundColor ?? Theme['bg-200']
36
- ]
37
- }),
35
+ const [measuredWidth, setMeasuredWidth] = useState<number | null>(null);
36
+ const [measuredHeight, setMeasuredHeight] = useState<number | null>(null);
37
+
38
+ const translateRef = useRef(new Animated.Value(0));
39
+ const loopRef = useRef<Animated.CompositeAnimation | null>(null);
40
+
41
+ useEffect(() => {
42
+ if (!measuredWidth) {
43
+ return undefined;
44
+ }
45
+ const translateX = translateRef.current;
46
+ translateX.setValue(0);
47
+ const timing = Animated.timing(translateX, {
48
+ toValue: 1,
49
+ duration,
50
+ useNativeDriver: true
51
+ });
52
+ const loop = Animated.loop(timing);
53
+ loopRef.current = loop;
54
+
55
+ loop.start();
56
+
57
+ return () => {
58
+ loop.stop();
59
+ if (loopRef.current === loop) {
60
+ loopRef.current = null;
61
+ }
62
+ translateX.stopAnimation(() => {
63
+ translateX.setValue(0);
64
+ });
65
+ };
66
+ }, [duration, measuredWidth]);
67
+
68
+ const baseColor = backgroundColor ?? Theme['bg-200'];
69
+ const highlightColor = foregroundColor ?? Theme['bg-300'];
70
+
71
+ const onLayout = (event: any) => {
72
+ const { width: w, height: h } = event.nativeEvent.layout;
73
+ // Update measurements whenever they change to adapt to dynamic layout/orientation
74
+ if (measuredWidth == null || Math.abs(w - measuredWidth) > 0.5) {
75
+ setMeasuredWidth(w);
76
+ }
77
+ if (measuredHeight == null || Math.abs(h - measuredHeight) > 0.5) {
78
+ setMeasuredHeight(h);
79
+ }
80
+ };
81
+
82
+ // Compute animated translateX only if we have width
83
+ let animatedTranslateX: any = 0;
84
+ let bandWidth = 0;
85
+ if (measuredWidth) {
86
+ bandWidth = Math.max(8, measuredWidth * highlightWidthRatio);
87
+ const travel = measuredWidth + bandWidth * 2;
88
+ animatedTranslateX = translateRef.current.interpolate({
89
+ inputRange: [0, 1],
90
+ outputRange: [-bandWidth, travel - bandWidth]
91
+ });
92
+ }
93
+
94
+ const containerStyle: ViewStyle = {
38
95
  width,
39
96
  height,
40
- x: 0,
41
- y: 0,
42
- rx: borderRadius,
43
- ry: borderRadius
97
+ borderRadius,
98
+ overflow: 'hidden',
99
+ borderWidth: StyleSheet.hairlineWidth,
100
+ borderColor: Theme['bg-300'],
101
+ backgroundColor: baseColor
44
102
  };
45
103
 
46
- Animated.loop(
47
- Animated.timing(animatedValue, {
48
- toValue: 1,
49
- duration,
50
- useNativeDriver: false
51
- })
52
- ).start();
104
+ const bandStyle: ViewStyle = {
105
+ position: 'absolute',
106
+ top: measuredHeight ? -measuredHeight * 0.25 : 0,
107
+ bottom: measuredHeight ? -measuredHeight * 0.25 : 0,
108
+ width: bandWidth,
109
+ backgroundColor: highlightColor,
110
+ opacity: highlightOpacity
111
+ };
53
112
 
54
113
  return (
55
- <Svg
56
- width={width}
57
- height={height}
58
- style={[
59
- { borderWidth: StyleSheet.hairlineWidth, borderColor: Theme['bg-300'], borderRadius },
60
- style
61
- ]}
62
- >
63
- <AnimatedRect {...animatedProps} />
64
- </Svg>
114
+ <View onLayout={onLayout} style={[containerStyle, style]}>
115
+ {measuredWidth && measuredHeight ? (
116
+ <Animated.View
117
+ pointerEvents="none"
118
+ style={[
119
+ bandStyle,
120
+ {
121
+ transform: [{ translateX: animatedTranslateX }, { rotate: `${angle}deg` }]
122
+ }
123
+ ]}
124
+ />
125
+ ) : null}
126
+ </View>
65
127
  );
66
- };
128
+ }
129
+
130
+ export const Shimmer = memo(Shimmer_, () => {
131
+ return true;
132
+ });
@@ -114,11 +114,11 @@ export function AccountButton({
114
114
  borderWidth={2}
115
115
  style={[styles.image, !avatarSrc && styles.avatarPlaceholder]}
116
116
  />
117
- {address && (
117
+ {address ? (
118
118
  <Text variant="paragraph-500" color="fg-200" style={styles.address}>
119
119
  {formattedAddress}
120
120
  </Text>
121
- )}
121
+ ) : null}
122
122
  </View>
123
123
  </AnimatedPressable>
124
124
  );
@@ -90,15 +90,15 @@ export function Button({
90
90
  {...rest}
91
91
  >
92
92
  <FlexView flexDirection="row" alignItems="center" justifyContent="center">
93
- {iconLeft && (
93
+ {iconLeft ? (
94
94
  <Icon
95
95
  color={iconColor}
96
96
  name={iconLeft}
97
97
  size={iconSize}
98
98
  style={[styles.iconLeft, iconStyle]}
99
99
  />
100
- )}
101
- {loading && <LoadingSpinner color={iconColor} size="md" />}
100
+ ) : null}
101
+ {loading ? <LoadingSpinner color={iconColor} size="md" /> : null}
102
102
  {!loading &&
103
103
  (typeof children === 'string' ? (
104
104
  <Text
@@ -110,14 +110,14 @@ export function Button({
110
110
  ) : (
111
111
  children
112
112
  ))}
113
- {iconRight && (
113
+ {iconRight ? (
114
114
  <Icon
115
115
  color={iconColor}
116
116
  name={iconRight}
117
117
  size={iconSize}
118
118
  style={[styles.iconRight, iconStyle]}
119
119
  />
120
- )}
120
+ ) : null}
121
121
  </FlexView>
122
122
  </AnimatedPressable>
123
123
  );
@@ -1,4 +1,4 @@
1
- import { memo } from 'react';
1
+ import { memo, useMemo } from 'react';
2
2
  import { Animated, Pressable, View, type StyleProp, type ViewStyle } from 'react-native';
3
3
  import { Text } from '../../components/wui-text';
4
4
  import { IconBox } from '../wui-icon-box';
@@ -9,6 +9,7 @@ import { NetworkImage } from '../wui-network-image';
9
9
  import { WalletImage } from '../wui-wallet-image';
10
10
  import styles, { getBackgroundColor, ITEM_HEIGHT, ITEM_WIDTH } from './styles';
11
11
  import { UiUtil } from '../../utils/UiUtil';
12
+ import { FlexView } from '../../layout/wui-flex';
12
13
 
13
14
  const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
14
15
 
@@ -28,7 +29,7 @@ export interface CardSelectProps {
28
29
  testID?: string;
29
30
  }
30
31
 
31
- function _CardSelect({
32
+ function CardSelect_({
32
33
  name,
33
34
  type = 'wallet',
34
35
  imageSrc,
@@ -43,6 +44,7 @@ function _CardSelect({
43
44
  const Theme = useTheme();
44
45
  const normalbackgroundColor = getBackgroundColor({ selected, disabled, pressed: false });
45
46
  const pressedBackgroundColor = getBackgroundColor({ selected, disabled, pressed: true });
47
+ const Image = useMemo(() => (type === 'wallet' ? WalletImage : NetworkImage), [type]);
46
48
 
47
49
  const { animatedValue, setStartValue, setEndValue } = useAnimatedValue(
48
50
  Theme[normalbackgroundColor],
@@ -51,54 +53,52 @@ function _CardSelect({
51
53
 
52
54
  const textColor = disabled ? 'fg-300' : selected ? 'accent-100' : 'fg-100';
53
55
 
54
- const Image = type === 'wallet' ? WalletImage : NetworkImage;
55
-
56
- const templateInstalled = () => {
57
- if (!installed) return null;
58
-
59
- return (
60
- <IconBox
61
- icon="checkmark"
62
- iconSize="xs"
63
- iconColor={'success-100'}
64
- border
65
- borderSize={6}
66
- borderColor="bg-150"
67
- background
68
- backgroundColor="icon-box-bg-success-100"
69
- size="sm"
70
- style={styles.installedBox}
71
- />
72
- );
73
- };
74
-
75
56
  return (
76
- <AnimatedPressable
77
- onPress={onPress}
78
- onPressIn={setEndValue}
79
- onPressOut={setStartValue}
80
- disabled={disabled}
81
- style={[styles.container, { backgroundColor: animatedValue }, style]}
82
- testID={testID}
83
- >
84
- <View>
85
- <Image
86
- imageSrc={imageSrc}
87
- imageHeaders={imageHeaders}
88
- size="md"
89
- style={disabled && styles.disabledImage}
90
- selected={selected}
91
- disabled={disabled}
92
- />
93
- {templateInstalled()}
94
- </View>
95
- <Text variant="tiny-500" color={textColor} style={styles.text} numberOfLines={1}>
96
- {UiUtil.getWalletName(name)}
97
- </Text>
98
- </AnimatedPressable>
57
+ <FlexView style={style} alignItems="center" justifyContent="center">
58
+ <AnimatedPressable
59
+ onPress={onPress}
60
+ onPressIn={setEndValue}
61
+ onPressOut={setStartValue}
62
+ disabled={disabled}
63
+ style={[styles.container, { backgroundColor: animatedValue }]}
64
+ testID={testID}
65
+ >
66
+ <View>
67
+ <Image
68
+ imageSrc={imageSrc}
69
+ imageHeaders={imageHeaders}
70
+ size="md"
71
+ style={disabled ? styles.disabledImage : null}
72
+ selected={selected}
73
+ disabled={disabled}
74
+ />
75
+ {installed ? (
76
+ <IconBox
77
+ icon="checkmark"
78
+ iconSize="xs"
79
+ iconColor={'success-100'}
80
+ border
81
+ borderSize={6}
82
+ borderColor="bg-150"
83
+ background
84
+ backgroundColor="icon-box-bg-success-100"
85
+ size="sm"
86
+ style={styles.installedBox}
87
+ />
88
+ ) : null}
89
+ </View>
90
+ <Text variant="tiny-500" color={textColor} style={styles.text} numberOfLines={1}>
91
+ {UiUtil.getWalletName(name)}
92
+ </Text>
93
+ </AnimatedPressable>
94
+ </FlexView>
99
95
  );
100
96
  }
101
97
 
102
- export const CardSelect = memo(_CardSelect, (prevProps, nextProps) => {
103
- return prevProps.name === nextProps.name;
98
+ export const CardSelect = memo(CardSelect_, (prevProps, nextProps) => {
99
+ return (
100
+ prevProps.name === nextProps.name &&
101
+ prevProps.imageSrc === nextProps.imageSrc &&
102
+ prevProps.selected === nextProps.selected
103
+ );
104
104
  });
@@ -1,3 +1,4 @@
1
+ import { memo } from 'react';
1
2
  import { type StyleProp, type ViewStyle } from 'react-native';
2
3
  import { BorderRadius, Spacing, WalletImageSize } from '../../utils/ThemeUtil';
3
4
  import { useTheme } from '../../hooks/useTheme';
@@ -11,7 +12,7 @@ export interface CardSelectLoaderProps {
11
12
  style?: StyleProp<ViewStyle>;
12
13
  }
13
14
 
14
- export function CardSelectLoader({ style }: CardSelectLoaderProps) {
15
+ export function CardSelectLoader_({ style }: CardSelectLoaderProps) {
15
16
  const Theme = useTheme();
16
17
 
17
18
  return (
@@ -34,3 +35,6 @@ export function CardSelectLoader({ style }: CardSelectLoaderProps) {
34
35
  </FlexView>
35
36
  );
36
37
  }
38
+ export const CardSelectLoader = memo(CardSelectLoader_, () => {
39
+ return true;
40
+ });
@@ -80,7 +80,7 @@ export function Chip({
80
80
  onPressOut={onPressOut}
81
81
  onPress={handlePress}
82
82
  >
83
- {imageSrc && (
83
+ {imageSrc ? (
84
84
  <Image
85
85
  style={[
86
86
  styles.image,
@@ -90,22 +90,22 @@ export function Chip({
90
90
  ]}
91
91
  source={imageSrc}
92
92
  />
93
- )}
94
- {leftIcon && <Icon name={leftIcon} color={themedTextColor as ColorType} />}
93
+ ) : null}
94
+ {leftIcon ? <Icon name={leftIcon} color={themedTextColor as ColorType} /> : null}
95
95
  <Text
96
96
  variant={size === 'md' ? 'paragraph-600' : 'small-600'}
97
97
  style={[styles.link, { color: Theme[themedTextColor] }]}
98
98
  >
99
99
  {label}
100
100
  </Text>
101
- {rightIcon && (
101
+ {rightIcon ? (
102
102
  <Icon
103
103
  name={rightIcon}
104
104
  size={iconSize}
105
105
  color={themedTextColor as ColorType}
106
106
  style={styles.icon}
107
107
  />
108
- )}
108
+ ) : null}
109
109
  </AnimatedPressable>
110
110
  );
111
111
  }