@reown/appkit-ui-react-native 2.0.0-alpha.3 → 2.0.0-alpha.4

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 (55) hide show
  1. package/lib/commonjs/components/wui-card/styles.js +1 -1
  2. package/lib/commonjs/components/wui-card/styles.js.map +1 -1
  3. package/lib/commonjs/components/wui-modal/index.js +2 -2
  4. package/lib/commonjs/components/wui-modal/index.js.map +1 -1
  5. package/lib/commonjs/components/wui-shimmer/index.js +92 -32
  6. package/lib/commonjs/components/wui-shimmer/index.js.map +1 -1
  7. package/lib/commonjs/composites/wui-card-select/index.js +1 -1
  8. package/lib/commonjs/composites/wui-card-select/index.js.map +1 -1
  9. package/lib/commonjs/composites/wui-card-select-loader/index.js +7 -3
  10. package/lib/commonjs/composites/wui-card-select-loader/index.js.map +1 -1
  11. package/lib/commonjs/composites/wui-qr-code/index.js +1 -1
  12. package/lib/commonjs/composites/wui-qr-code/index.js.map +1 -1
  13. package/lib/commonjs/hooks/useCustomDimensions.js +41 -0
  14. package/lib/commonjs/hooks/useCustomDimensions.js.map +1 -0
  15. package/lib/commonjs/index.js +7 -0
  16. package/lib/commonjs/index.js.map +1 -1
  17. package/lib/commonjs/utils/QRCodeUtil.js +2 -2
  18. package/lib/commonjs/utils/QRCodeUtil.js.map +1 -1
  19. package/lib/module/components/wui-card/styles.js +1 -1
  20. package/lib/module/components/wui-card/styles.js.map +1 -1
  21. package/lib/module/components/wui-modal/index.js +3 -3
  22. package/lib/module/components/wui-modal/index.js.map +1 -1
  23. package/lib/module/components/wui-shimmer/index.js +93 -32
  24. package/lib/module/components/wui-shimmer/index.js.map +1 -1
  25. package/lib/module/composites/wui-card-select/index.js +1 -1
  26. package/lib/module/composites/wui-card-select/index.js.map +1 -1
  27. package/lib/module/composites/wui-card-select-loader/index.js +5 -1
  28. package/lib/module/composites/wui-card-select-loader/index.js.map +1 -1
  29. package/lib/module/composites/wui-qr-code/index.js +1 -1
  30. package/lib/module/composites/wui-qr-code/index.js.map +1 -1
  31. package/lib/module/hooks/useCustomDimensions.js +38 -0
  32. package/lib/module/hooks/useCustomDimensions.js.map +1 -0
  33. package/lib/module/index.js +10 -0
  34. package/lib/module/index.js.map +1 -1
  35. package/lib/module/utils/QRCodeUtil.js +3 -3
  36. package/lib/module/utils/QRCodeUtil.js.map +1 -1
  37. package/lib/typescript/components/wui-modal/index.d.ts.map +1 -1
  38. package/lib/typescript/components/wui-shimmer/index.d.ts +11 -3
  39. package/lib/typescript/components/wui-shimmer/index.d.ts.map +1 -1
  40. package/lib/typescript/composites/wui-card-select-loader/index.d.ts +3 -1
  41. package/lib/typescript/composites/wui-card-select-loader/index.d.ts.map +1 -1
  42. package/lib/typescript/hooks/useCustomDimensions.d.ts +14 -0
  43. package/lib/typescript/hooks/useCustomDimensions.d.ts.map +1 -0
  44. package/lib/typescript/index.d.ts +6 -0
  45. package/lib/typescript/index.d.ts.map +1 -1
  46. package/package.json +2 -2
  47. package/src/components/wui-card/styles.ts +1 -1
  48. package/src/components/wui-modal/index.tsx +6 -3
  49. package/src/components/wui-shimmer/index.tsx +105 -39
  50. package/src/composites/wui-card-select/index.tsx +1 -1
  51. package/src/composites/wui-card-select-loader/index.tsx +5 -1
  52. package/src/composites/wui-qr-code/index.tsx +1 -1
  53. package/src/hooks/useCustomDimensions.ts +38 -0
  54. package/src/index.ts +7 -0
  55. package/src/utils/QRCodeUtil.tsx +3 -3
@@ -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
+ });
@@ -100,5 +100,5 @@ function _CardSelect({
100
100
  }
101
101
 
102
102
  export const CardSelect = memo(_CardSelect, (prevProps, nextProps) => {
103
- return prevProps.name === nextProps.name;
103
+ return prevProps.name === nextProps.name && prevProps.imageSrc === nextProps.imageSrc;
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
+ });
@@ -62,7 +62,7 @@ export function QrCode({ size, uri, imageSrc, testID, arenaClear, icon, style }:
62
62
  <View
63
63
  style={[
64
64
  styles.container,
65
- { width: size, backgroundColor: Theme['bg-100'], padding: containerPadding },
65
+ { width: size, backgroundColor: Theme['inverse-100'], padding: containerPadding },
66
66
  style
67
67
  ]}
68
68
  testID={testID}
@@ -0,0 +1,38 @@
1
+ import { useState, useEffect } from 'react';
2
+ import { useWindowDimensions } from 'react-native';
3
+
4
+ /**
5
+ * Hook used to get the width of the screen and the padding needed to accomplish portrait and landscape modes.
6
+ * @returns { width: number, isPortrait: boolean, isLandscape: boolean, padding: number }
7
+ */
8
+
9
+ type CustomDimensionsType = {
10
+ maxWidth: number;
11
+ maxHeight: number;
12
+ isPortrait: boolean;
13
+ isLandscape: boolean;
14
+ padding: number;
15
+ };
16
+
17
+ const MAX_HEIGHT_PERCENTAGE = 0.9;
18
+
19
+ const getMaxHeight = (width: number, height: number) => {
20
+ return Math.max(width, height) * MAX_HEIGHT_PERCENTAGE;
21
+ };
22
+
23
+ export function useCustomDimensions(): CustomDimensionsType {
24
+ const { width, height } = useWindowDimensions();
25
+ const [maxWidth, setMaxWidth] = useState<number>(Math.min(width, height));
26
+ const [maxHeight, setMaxHeight] = useState<number>(getMaxHeight(width, height));
27
+ const [isPortrait, setIsPortrait] = useState<boolean>(height > width);
28
+ const [padding, setPadding] = useState<number>(0);
29
+
30
+ useEffect(() => {
31
+ setMaxWidth(Math.min(width, height));
32
+ setMaxHeight(getMaxHeight(width, height));
33
+ setIsPortrait(height > width);
34
+ setPadding(width < height ? 0 : (width - height) / 2);
35
+ }, [width, height]);
36
+
37
+ return { maxWidth, maxHeight, isPortrait, isLandscape: !isPortrait, padding };
38
+ }
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ /********** Components **********/
1
2
  export { Card, type CardProps } from './components/wui-card';
2
3
  export { Icon, type IconProps } from './components/wui-icon';
3
4
  export { Image, type ImageProps } from './components/wui-image';
@@ -8,6 +9,7 @@ export { Text, type TextProps } from './components/wui-text';
8
9
  export { Visual, type VisualProps } from './components/wui-visual';
9
10
  export { Shimmer, type ShimmerProps } from './components/wui-shimmer';
10
11
 
12
+ /********** Composites **********/
11
13
  export { AccountButton, type AccountButtonProps } from './composites/wui-account-button';
12
14
  export { AccountPill, type AccountPillProps } from './composites/wui-account-pill';
13
15
  export { ActionEntry, type ActionEntryProps } from './composites/wui-action-entry';
@@ -68,6 +70,7 @@ export { Overlay, type OverlayProps } from './layout/wui-overlay';
68
70
  export { FlexView, type FlexViewProps } from './layout/wui-flex';
69
71
  export { Separator } from './layout/wui-separator';
70
72
 
73
+ /********** Types **********/
71
74
  export type {
72
75
  ButtonType,
73
76
  CardSelectType,
@@ -83,10 +86,14 @@ export type {
83
86
  VisualType,
84
87
  TransactionType
85
88
  } from './utils/TypesUtil';
89
+
90
+ /********** Utils **********/
86
91
  export { UiUtil } from './utils/UiUtil';
87
92
  export { TransactionUtil } from './utils/TransactionUtil';
88
93
  export { Spacing, BorderRadius } from './utils/ThemeUtil';
89
94
 
95
+ /********** Hooks **********/
90
96
  export { useTheme } from './hooks/useTheme';
91
97
  export { ThemeProvider } from './context/ThemeContext';
92
98
  export { useAnimatedValue } from './hooks/useAnimatedValue';
99
+ export { useCustomDimensions } from './hooks/useCustomDimensions';
@@ -1,7 +1,7 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import { Line, Rect, Circle } from 'react-native-svg';
3
3
  import QRCode from 'qrcode';
4
- import { DarkTheme, LightTheme } from '../utils/ThemeUtil';
4
+ import { LightTheme } from '../utils/ThemeUtil';
5
5
 
6
6
  type CoordinateMapping = [number, number[]];
7
7
 
@@ -34,8 +34,8 @@ function getMatrix(value: string, errorCorrectionLevel: QRCode.QRCodeErrorCorrec
34
34
 
35
35
  export const QRCodeUtil = {
36
36
  generate(uri: string, size: number, logoSize: number) {
37
- const dotColor = DarkTheme['bg-100'];
38
- const edgeColor = LightTheme['bg-100'];
37
+ const dotColor = LightTheme['inverse-000'];
38
+ const edgeColor = LightTheme['inverse-100'];
39
39
  const dots: ReactNode[] = [];
40
40
  const matrix = getMatrix(uri, 'Q');
41
41
  const cellSize = size / matrix.length;