11import { memo , useMemo } from 'react' ;
22import { View , type StyleProp , type ViewStyle } from 'react-native' ;
3- import Svg from 'react-native-svg' ;
3+ import Svg , { Circle , Line , Rect } from 'react-native-svg' ;
44import { Icon } from '../../components/wui-icon' ;
55import { Image } from '../../components/wui-image' ;
66import { Shimmer } from '../../components/wui-shimmer' ;
@@ -17,17 +17,32 @@ export interface QrCodeProps {
1717 testID ?: string ;
1818 arenaClear ?: boolean ;
1919 style ?: StyleProp < ViewStyle > ;
20+ logoSize ?: number ;
21+ logoBorderRadius ?: number ;
2022}
2123
22- export function QrCode_ ( { size, uri, imageSrc, testID, arenaClear, icon, style } : QrCodeProps ) {
24+ export function QrCode_ ( {
25+ size,
26+ uri,
27+ imageSrc,
28+ testID,
29+ arenaClear,
30+ icon,
31+ style,
32+ logoSize,
33+ logoBorderRadius
34+ } : QrCodeProps ) {
2335 const Theme = LightTheme ;
2436 const containerPadding = Spacing . l ;
2537 const qrSize = size - containerPadding * 2 ;
26- const logoSize = arenaClear ? 0 : qrSize / 4 ;
38+ const _logoSize = arenaClear ? 0 : logoSize ?? qrSize / 4 ;
2739
28- const dots = useMemo (
29- ( ) => ( uri ? QRCodeUtil . generate ( uri , qrSize , logoSize ) : [ ] ) ,
30- [ uri , qrSize , logoSize ]
40+ const dotColor = Theme [ 'inverse-000' ] ;
41+ const edgeColor = Theme [ 'inverse-100' ] ;
42+
43+ const qrData = useMemo (
44+ ( ) => ( uri ? QRCodeUtil . generate ( uri , qrSize , _logoSize , logoBorderRadius ) : null ) ,
45+ [ uri , qrSize , _logoSize , logoBorderRadius ]
3146 ) ;
3247
3348 const logoTemplate = ( ) => {
@@ -40,8 +55,12 @@ export function QrCode_({ size, uri, imageSrc, testID, arenaClear, icon, style }
4055 < Image
4156 source = { imageSrc }
4257 style = { [
43- styles . icon ,
44- { height : qrSize / 4 , width : qrSize / 4 , borderRadius : qrSize / 16 }
58+ {
59+ position : 'absolute' as const ,
60+ height : _logoSize ,
61+ width : _logoSize ,
62+ borderRadius : logoBorderRadius
63+ }
4564 ] }
4665 />
4766 ) ;
@@ -51,14 +70,18 @@ export function QrCode_({ size, uri, imageSrc, testID, arenaClear, icon, style }
5170 < Icon
5271 name = { icon ?? 'walletConnect' }
5372 color = "accent-100"
54- height = { qrSize / 3.5 }
55- width = { qrSize / 3.5 }
56- style = { styles . icon }
73+ height = { _logoSize }
74+ width = { _logoSize }
75+ style = { { position : 'absolute' as const } }
5776 />
5877 ) ;
5978 } ;
6079
61- return uri ? (
80+ if ( ! uri || ! qrData ) {
81+ return < Shimmer width = { size } height = { size } borderRadius = { BorderRadius . l } /> ;
82+ }
83+
84+ return (
6285 < View
6386 style = { [
6487 styles . container ,
@@ -68,19 +91,55 @@ export function QrCode_({ size, uri, imageSrc, testID, arenaClear, icon, style }
6891 testID = { testID }
6992 >
7093 < Svg height = { qrSize } width = { qrSize } >
71- { dots }
94+ { /* Render rectangles */ }
95+ { qrData . rects . map ( rect => (
96+ < Rect
97+ key = { `rect_${ rect . x } _${ rect . y } ` }
98+ fill = { rect . fillType === 'dot' ? dotColor : edgeColor }
99+ height = { rect . size }
100+ rx = { rect . size * 0.32 }
101+ ry = { rect . size * 0.32 }
102+ width = { rect . size }
103+ x = { rect . x }
104+ y = { rect . y }
105+ />
106+ ) ) }
107+
108+ { /* Render circles */ }
109+ { qrData . circles . map ( circle => (
110+ < Circle
111+ key = { `circle_${ circle . cx } _${ circle . cy } ` }
112+ cx = { circle . cx }
113+ cy = { circle . cy }
114+ fill = { dotColor }
115+ r = { circle . r }
116+ />
117+ ) ) }
118+
119+ { /* Render lines */ }
120+ { qrData . lines . map ( line => (
121+ < Line
122+ key = { `line_${ line . x1 } _${ line . y1 } _${ line . y2 } ` }
123+ x1 = { line . x1 }
124+ x2 = { line . x2 }
125+ y1 = { line . y1 }
126+ y2 = { line . y2 }
127+ stroke = { dotColor }
128+ strokeWidth = { line . strokeWidth }
129+ strokeLinecap = "round"
130+ />
131+ ) ) }
72132 </ Svg >
73133 { logoTemplate ( ) }
74134 </ View >
75- ) : (
76- < Shimmer width = { size } height = { size } borderRadius = { BorderRadius . l } />
77135 ) ;
78136}
79137
80138export const QrCode = memo ( QrCode_ , ( prevProps , nextProps ) => {
81139 return (
82140 prevProps . size === nextProps . size &&
83141 prevProps . uri === nextProps . uri &&
84- prevProps . style === nextProps . style
142+ prevProps . style === nextProps . style &&
143+ prevProps . logoBorderRadius === nextProps . logoBorderRadius
85144 ) ;
86145} ) ;
0 commit comments